Webhook API overview
The Webhook API provides a RESTful HTTP interface for managing the authenticated user account's webhook subscription. Each user account supports a single active webhook configuration, allowing your application to register an HTTP or HTTPS endpoint URL to receive real-time event notifications (such as incoming SMS messages and outbound delivery status updates), query the active configuration, or remove it.
Table of contents
Base path & user context
All Webhook API operations operate relative to the V2 base path. The user account context is resolved implicitly from the authentication credentials supplied in the Authorization request header:
http://localhost:9509/api/v2
Authentication
Every request must include a valid Authorization header identifying the user account context. Two authentication schemes are supported:
- Bearer Token (API Key):
Authorization: Bearer <api_key> - Basic Authentication:
Authorization: Basic <base64(username:password)>
Requests with missing or invalid credentials are rejected with 401 Unauthorized.
Data format conventions
- Media type: Requests with a body (
POSTandPUT) and JSON responses useContent-Type: application/json. - Property naming: JSON field names are strictly case-sensitive and use
camelCase. - Null omission: Properties with
nullvalues (such assecretonGET /api/v2/webhookresponses) are omitted from serialized JSON responses. - Target URLs: The webhook
urlmust be a valid absolutehttp://orhttps://URL. - Webhook identifiers: Each webhook registration is assigned a unique server-generated UUID (
webhookId).
Endpoints summary
| Operation | HTTP method | Endpoint path | Success status | Documentation |
| Configure webhook | POST, PUT |
/api/v2/webhook |
201 Created / 200 OK |
configure_webhook.html |
| Retrieve webhook | GET |
/api/v2/webhook |
200 OK |
retrieve_webhook.html |
| Delete webhook | DELETE |
/api/v2/webhook |
204 No Content |
delete_webhook.html |
Core concepts
Single active webhook & POST vs. PUT behavior
Each user account can have at most one active account-level webhook subscription at any time. The /api/v2/webhook endpoint supports both POST and PUT for configuring the subscription:
| Method | When no webhook exists | When a webhook already exists |
POST /api/v2/webhook |
Creates the webhook subscription, generates a new signing secret, and returns 201 Created (with Location: /api/v2/webhook). |
Rejects the request with 409 Conflict. |
PUT /api/v2/webhook |
Creates the webhook subscription, generates a new signing secret, and returns 201 Created (with Location: /api/v2/webhook). |
Replaces the existing webhook subscription, generates a new signing secret, and returns 200 OK. |
Supported webhook event types
When configuring a webhook via POST or PUT, the events array must specify at least one of the following supported event types:
| Event type | Trigger condition | Callback documentation |
"message.received" |
Triggered whenever a new inbound SMS arrives in the user account's inbox folder. |
webhook_message_received.html |
"message.status.updated" |
Triggered whenever an outbound SMS transitions delivery status (moving into the sent or notsent folder, or updating its delivery/view state). |
webhook_message_status_updated.html |
Signing secret (secret) & rotation
- Generation: Whenever a webhook is created (
POSTorPUT) or replaced (PUT), the server generates a new shared signingsecretprefixed withwhsec_(e.g.,"whsec_9f83a04b12c845d09e3a7b6c5d4e1f2a"). - One-time exposure: For security reasons, the
secretfield is returned only in thePOST /api/v2/webhookandPUT /api/v2/webhookresponses. SubsequentGET /api/v2/webhookrequests omitsecret. - Secret rotation: To rotate a compromised or lost signing secret, send a
PUT /api/v2/webhookrequest with your desiredurlandevents. This replaces the existing registration and issues a newly generatedsecret. - Signature verification: The shared
secretis used by the gateway to compute theX-Hub-Signature-256HMAC-SHA256 header (sha256=<hex_digest>) over the raw UTF-8 request body of every webhook delivery.
Account-level vs. per-message webhooks
- Inbound messages (
message.received): Can only be received by registering an account-level webhook viaPOST /api/v2/webhookorPUT /api/v2/webhooksubscribed to"message.received". - Outbound status updates (
message.status.updated): Can be received either via an account-level webhook subscribed to"message.status.updated"or via a per-messagewebhookconfiguration ({"url": "...", "notify": true}) supplied when dispatching messages viaPOST /api/v2/messagesorPOST /api/v2/messages:batchSend. - Signing behavior: When an account-level webhook
secretis configured, webhook deliveries include theX-Hub-Signature-256signature header. If per-message webhooks are dispatched when no account-level webhook secret is configured, theX-Hub-Signature-256header is omitted.