Registering
Rotation is not an outage. The old key stays valid for 24 hours and we sign
with both, so you add the new one, confirm it works, then drop the old one.
What your endpoint may receive is bounded by the scopes on the key that created
it. A key without
messages:read registers fine and gets no message.* events.
Create the endpoint with the key you actually intend to run on.The envelope
tenant_ref is the field you want. It is your identifier for the
merchant — the same string you provisioned them with and use in every URL.
tenant is our internal id and you have never seen it.2026-06-01.
Verifying
"{t}." followed by the exact raw body bytes with HMAC-SHA256 and your
secret, compare in constant time, and reject anything older than 300 seconds.
During a rotation window there may be several v1= values. Accept the delivery
if any of them matches.
Events
GET /api/v2/webhooks/catalogue/ returns the live list, including the resource
each event carries and the scope it needs. Your code probably wants that rather
than this table.
message.received fires for media before the voice note is transcribed, so
channel.media.transcription may be empty on arrival. Render the message
immediately rather than waiting — a customer’s voice note appearing thirty
seconds late looks like a broken inbox.Delivery behaviour
Retries
Retries
Three attempts: immediately, then 60s, 5min and 30min. 5xx responses, timeouts
and connection failures are retried. 4xx is not — a 4xx says our payload is
wrong, and sending the same thing again will not make it right.Our timeout is 5 seconds. Acknowledge with a 2xx as soon as you have the
body and do the work afterwards; a slow handler becomes a retried handler.
Ordering is not guaranteed
Ordering is not guaranteed
Deliveries are independent, so
message.sent can reach you before the
message.received it answers — and a shared endpoint interleaves every
merchant’s traffic.Dedupe on id (evt_…), which is stable across retries, and order by
created_at within a conversation. Never order by arrival.Bursts are delayed, not dropped
Bursts are delayed, not dropped
One endpoint carrying every merchant is a different traffic shape from a single
tenant’s. When you exceed the rate we hold deliveries back and retry with a
growing delay rather than failing them — our throttle is not your failure and
must not cost you an event.Per-merchant fairness still applies underneath, so one busy merchant cannot
starve the rest of your book.
Your endpoint is private to you
Your endpoint is private to you
Merchants cannot see, list or replay deliveries to your endpoint. It is your
infrastructure and they never configured it.
Requirements
Endpoints must behttps and publicly resolvable. Private, loopback and
link-local addresses are refused when the endpoint is created, not silently at
delivery time.
Before you go live: secret stored, signature verified against raw bytes,
timestamp checked, deduping on
evt_ id, not relying on arrival order, and
answering 2xx within five seconds.
