API reference
Webhooks
Register and manage the endpoints SMSend delivers events to.
This page covers the endpoints. For the payload shapes, the signature algorithm and the retry policy, read the webhooks guide.
List webhook endpoints
/public/v1/webhooksReturns every endpoint registered to the account, newest first, with its current health.
Request
Responses
Possible errors
| Code | Status | Meaning |
|---|---|---|
UNAUTHORIZED | 401 | No key, a malformed key, a wrong secret, a revoked or expired key, or a suspended account. All indistinguishable by design. |
INSUFFICIENT_SCOPE | 403 | The key is valid but does not carry the scope this endpoint requires. The scope is named in the detail. |
RATE_LIMITED | 429 | The key's request limit was exceeded. Wait for the interval in Retry-After. |
INTERNAL_ERROR | 500 | An unexpected failure on SMSend's side. Quote the request id to support. |
Create a webhook endpoint
/public/v1/webhooksRegisters an endpoint and issues its signing secret. This is the only response that ever contains the secret.
Body parameters
urlstringRequiredWhere to deliver events. Must be HTTPS and must not resolve to a private, loopback or link-local address. A hostname whose DNS has not propagated yet is accepted.
max 2048 characters, must be HTTPS, no private or loopback address
descriptionstringOptionalA label for your own use, shown in the console.
max 255 characters
eventsarrayOptionalWhich events to deliver. Duplicates are removed; an empty array falls back to the default.
default ["MESSAGE_TERMINAL", "BATCH_SETTLED"]
Request
Responses
Possible errors
| Code | Status | Meaning |
|---|---|---|
VALIDATION_FAILED | 422 | The request was malformed: a missing or invalid parameter, a bad idempotency key length, a rejected webhook URL, or an unsupported method or content type. |
UNAUTHORIZED | 401 | No key, a malformed key, a wrong secret, a revoked or expired key, or a suspended account. All indistinguishable by design. |
INSUFFICIENT_SCOPE | 403 | The key is valid but does not carry the scope this endpoint requires. The scope is named in the detail. |
RATE_LIMITED | 429 | The key's request limit was exceeded. Wait for the interval in Retry-After. |
INTERNAL_ERROR | 500 | An unexpected failure on SMSend's side. Quote the request id to support. |
Rotate the signing secret
/public/v1/webhooks/{webhook_id}/rotateIssues a new secret and keeps the previous one valid for 24 hours. Both verify during the window while SMSend signs with the new one, so you can deploy without dropping deliveries.
Path parameters
webhook_idstringRequiredThe endpoint identifier, returned when it was created.
26-character ULID
Request
Responses
Possible errors
| Code | Status | Meaning |
|---|---|---|
NOT_FOUND | 404 | No such resource — including one that belongs to another account, which is deliberately indistinguishable from one that never existed. |
UNAUTHORIZED | 401 | No key, a malformed key, a wrong secret, a revoked or expired key, or a suspended account. All indistinguishable by design. |
INSUFFICIENT_SCOPE | 403 | The key is valid but does not carry the scope this endpoint requires. The scope is named in the detail. |
RATE_LIMITED | 429 | The key's request limit was exceeded. Wait for the interval in Retry-After. |
INTERNAL_ERROR | 500 | An unexpected failure on SMSend's side. Quote the request id to support. |
Enable an endpoint
/public/v1/webhooks/{webhook_id}/enableRe-enables a disabled endpoint and resets its failure counter, so a recovered endpoint is not switched off again by the first failure after it comes back.
Path parameters
webhook_idstringRequiredThe endpoint identifier, returned when it was created.
26-character ULID
Request
Responses
Possible errors
| Code | Status | Meaning |
|---|---|---|
NOT_FOUND | 404 | No such resource — including one that belongs to another account, which is deliberately indistinguishable from one that never existed. |
UNAUTHORIZED | 401 | No key, a malformed key, a wrong secret, a revoked or expired key, or a suspended account. All indistinguishable by design. |
INSUFFICIENT_SCOPE | 403 | The key is valid but does not carry the scope this endpoint requires. The scope is named in the detail. |
RATE_LIMITED | 429 | The key's request limit was exceeded. Wait for the interval in Retry-After. |
INTERNAL_ERROR | 500 | An unexpected failure on SMSend's side. Quote the request id to support. |
Disable an endpoint
/public/v1/webhooks/{webhook_id}/disableStops delivery to an endpoint without deleting it. Events created while it is disabled are not queued for later — recover them from the messages feed.
Path parameters
webhook_idstringRequiredThe endpoint identifier, returned when it was created.
26-character ULID
Request
Responses
Possible errors
| Code | Status | Meaning |
|---|---|---|
NOT_FOUND | 404 | No such resource — including one that belongs to another account, which is deliberately indistinguishable from one that never existed. |
UNAUTHORIZED | 401 | No key, a malformed key, a wrong secret, a revoked or expired key, or a suspended account. All indistinguishable by design. |
INSUFFICIENT_SCOPE | 403 | The key is valid but does not carry the scope this endpoint requires. The scope is named in the detail. |
RATE_LIMITED | 429 | The key's request limit was exceeded. Wait for the interval in Retry-After. |
INTERNAL_ERROR | 500 | An unexpected failure on SMSend's side. Quote the request id to support. |
Endpoint statuses
The two disabled states are kept apart on purpose: one is a decision you made, the other is a failure you need to investigate, and they call for different responses.
| Value | Meaning |
|---|---|
ENABLED | Receiving deliveries. |
DISABLED_BY_USER | Paused by the account. Re-enable it when you are ready. |
DISABLED_AFTER_FAILURES | Switched off by SMSend after 20 consecutive failures. Fix the endpoint, then re-enable it explicitly. |
Not on this surface
Changing an endpoint's URL, its event subscriptions or its description, and deleting an endpoint entirely, are done in the customer console rather than through the API. Creating and revoking API keys is likewise console-only — a published key-minting endpoint would turn a single leaked key into permanent access.