The short answer: save an HTTPS address of yours with PUT /v1/sms/webhook and, from then on, whenever a message is sent or fails, we post a signed notice to that address. Your system marks the notice as sent, or tries another channel, without anyone opening the history.
How it works
| 1 |
Your system asks for the send through the API, with the number, the text and, if you like, a scheduled time.
|
|
| 2 |
The message joins the queue: it is scheduled or queued and goes out in its turn.
|
|
| 3 |
It goes out or fails. When it becomes sent or failed, we POST to your address.
|
|
| 4 |
Your system reacts: it updates the notice status, or switches to e-mail if it failed.
|
|
Saving the address
| Field |
What it is |
| url |
Your HTTPS address, on port 443. Internal or private addresses are refused. |
| events |
The events you want: sms.sent, sms.failed or both (both by default). |
| rotate_secret |
Set to true to create a new secret. |
The signing secret is only shown when the webhook is created, or when you ask for a new one with rotate_secret: store it straight away. Saving needs a key with sms:write; GET /v1/sms/webhook with sms:read shows the address, the events and the last delivery, never the secret.
What reaches your address
POST https://your-system/webhook
X-Webhook-Signature: t=1763625600,v1=...
{"event": "sms.sent",
"created_at": "...",
"data": {"id": "412", "status": "sent", ...}}
The data field has the same fields as looking up a message. Before trusting the notice, check the signature in the X-Webhook-Signature header: see receiving a webhook in PHP and checking its signature and, if something does not arrive, SMS webhook not arriving.
|
It only counts from now on. The webhook reports on messages created after it was saved. Earlier ones are looked up with GET /v1/sms/messages/{id}.
|
Testing and switching off
POST /v1/sms/webhook/test sends a signed webhook.test notice right away and returns what your server answered. DELETE /v1/sms/webhook switches the webhook off and cancels any deliveries still pending.
|
"Sent" means it left for the mobile operator, not that it was read. For your system, sms.sent means "the notice is on its way" and sms.failed means "I need to do something else". Why being told beats asking is explained in webhook or polling.
|
|
Want your system to know on its own what happened to each notice? See the API page.
See the API page
|