Create an endpoint
Create endpoints in the dashboard (Developer > Webhooks) or with the API (POST /webhooks, Manage integrations permission):
The response contains the signing
secret, shown only once. Store it with your other secrets.
An endpoint receives payloads in the API version used to create it (
api_version), so a new API version never changes what you receive.Events
GET /webhooks/events returns the catalog.
New event types can be added at any time: ignore the types you do not handle.
Payload
Every delivery is aPOST with a JSON body:
data depends on the type:
Headers
Verify the signature
Check every request before trusting it:- Read the raw body, before any JSON parsing: re-encoding it changes the bytes and breaks the signature.
- Reject requests whose timestamp is more than 5 minutes away from your clock (replays).
- Compare
expectedwithX-Shortext-Signaturein constant time.
Respond and deduplicate
- Answer with any 2xx status within 10 seconds. Do the work after answering, in a queue.
- Anything else (another status, a timeout, a redirect, a network error) is a failure and is retried.
- The same event can arrive more than once. Deduplicate on the event
id(evt_...), which stays the same on retries and redeliveries. - Events can arrive out of order: rely on
created_atand on the API when order matters.
Retries
A failed delivery is retried with an increasing delay: after 10 seconds, 1 minute, 5 minutes, 30 minutes, 2 hours, 6 hours and 12 hours, that is 8 attempts over about 21 hours. After the last one, the delivery is marked failed. An endpoint that keeps failing for 72 hours is disabled:is_enabled becomes false and disabled_reason says why. Fix your server, then enable the endpoint again (PUT /webhooks/{id} with "is_enabled": true).