SmsHandleWebhook¶
POST sms/handleWebhooks/:uuid
The public endpoint an SMS provider posts delivery reports to. It is not called by integrations — the URL is configured in the provider dashboard and comes from SmsAddWebhook.
The module finds the webhook by uuid, verifies the signature with the webhook secret, asks
the provider adapter to translate the payload, and applies the result to the message.
Access Control¶
Public. There is no session: the request is authenticated by the unguessable uuid plus the signature check against the webhook secret.
Request¶
{}
{
"command": "SmsHandleWebhook",
"extID": "1",
"data": {}
}
const res = await platform.SmsHandleWebhook({});
Path Parameters¶
| Parameter | Type | Description |
|---|---|---|
uuid |
string | Webhook identifier from the URL |
Behavior¶
- The endpoint always answers
200, even when the event is rejected: a provider retry cannot fix a wrong signature or an unknown message, and retry storms are worse than a recorded rejection. - The real outcome is in
result, and every event — accepted or not — is stored and visible through SmsGetWebhookEvents. - Events are deduplicated by the provider event id, so a repeated delivery report does not move the message state twice.
- Inbound
STOPreplies handled by an adapter add the sender to the blacklist withsource: "OPT_OUT"instead of updating a message.
Response Data¶
A rejected event answers with the same shape, where result is not PROCESSED and reason says why: WEBHOOK_NOT_FOUND, PROFILE_NOT_FOUND, PROFILE_NOT_IN_WEBHOOK_MODE, PROVIDER_NOT_FOUND, PROVIDER_WEBHOOKS_DISABLED, ADAPTER_HAS_NO_WEBHOOK_SUPPORT, NO_EXTERNAL_CALL_ID, UNVERIFIED, NO_MESSAGE.
{
"result": "PROCESSED",
"smsId": 812,
"changed": true,
"status": "DELIVERED"
}
Errors¶
| Code | Error | Description |
|---|---|---|
200 |
UNVERIFIED |
Signature did not match the webhook secret; the event is stored and ignored |
200 |
DUPLICATE |
This provider event was already applied |
500 |
INTERNAL_ERROR |
Module could not process the event; it is stored with result: "ERROR" |