Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.offthehook.dev/llms.txt

Use this file to discover all available pages before exploring further.

Every subscription has a signing secret used to compute the HMAC-SHA256 signature on each delivery. You should rotate this secret periodically or immediately if you suspect it has been compromised. Off the Hook supports zero-downtime rotation by signing deliveries with both the old and new secrets during a configurable grace period, giving you time to deploy the updated secret before the old one expires.
The new secret is returned only in the rotation response. Store it immediately — there is no way to retrieve it again after the request completes.

Rotate the secret

Send a POST request to the rotate endpoint with the desired grace period in seconds.
curl -X POST https://api.offthehook.dev/v1/subscriptions/sub_2QkP9aB7xN.../secrets/rotate \
  -H "Authorization: Bearer oth_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: rotate-$(date +%s)" \
  -d '{ "gracePeriodSeconds": 3600 }'
{ "secret": "whsec_NEW_SECRET..." }
The gracePeriodSeconds field controls how long the old secret remains valid alongside the new one. Set it to 0 for an immediate cutover with no grace period.
Use a grace period of at least 3600 seconds (1 hour) to give yourself enough time to update and deploy your verification code across all services before the old secret expires.

How the grace period works

During the grace period, Off the Hook signs each delivery with both secrets. The webhook-signature header contains two space-separated v1, values:
webhook-signature: v1,<hmac-with-new-secret> v1,<hmac-with-old-secret>
The Svix verification library automatically accepts any valid signature in the header, so your existing verification code continues to work without modification while you roll out the new secret. Once the grace period expires, deliveries are signed only with the new secret. Any verification using the old secret will fail at that point.

Idempotency

Include an Idempotency-Key header on the rotation request to safely retry it without triggering a double rotation. If a request with the same key is already in flight, the API returns idempotency_in_flight. If a completed request with the same key is replayed, you receive the original response.
-H "Idempotency-Key: rotate-$(date +%s)"
Use a unique, stable key per intended rotation — for example, a timestamp or a UUID generated before you send the request.

Rotation workflow

1

Rotate the secret

Call the rotate endpoint and save the new whsec_... value returned in the response.
2

Deploy the new secret

Update your environment variables or secrets manager with the new value and deploy your service. Your verification code does not need to change — the Svix library handles both signatures automatically during the grace period.
3

Confirm the grace period has elapsed

After the grace period expires, the old secret is no longer valid. Verify that your service is successfully processing deliveries signed only with the new secret.