Webhooks
Receive delivery receipts, click information, inbound SMS, and bot-click revocations on your platform
Webhooks allow our platform to post information back to your platform. Such information can be DLRs, incoming SMSs, clicks, or bot-click revocations.
Webhooks can be configured via the account preferences page or programmatically using the API endpoints below.
Managing Webhooks via API
Set Webhooks
POST /user/set-webhook
Set or clear webhook URLs. Only provided params are changed — omitted params are left as-is. Send an empty string "" to clear a field.
| Param | Description |
|---|---|
dlr_url | DLR delivery reports |
click_url | Click notifications |
inbound_url | Inbound SMS |
revoke_click_url | Bot-click revocation batch notifications |
auth | HTTP Basic Auth (user:pass), max 32 chars. DLR webhook only |
curl -X POST https://api.smsedge.com/v1/user/set-webhook \
-H "X-API-KEY: YOUR_API_KEY" \
-d "dlr_url=https://example.com/dlr" \
-d "click_url=https://example.com/click" \
-d "inbound_url=https://example.com/inbound" \
-d "revoke_click_url=https://example.com/revoke" \
-d "auth=myuser:mypass"{
"success": true,
"data": {
"dlr_url": "https://example.com/dlr",
"click_url": "https://example.com/click",
"inbound_url": "https://example.com/inbound",
"revoke_click_url": "https://example.com/revoke",
"auth": true
}
}Get Webhooks
GET /user/get-webhook
Read current webhook configuration. The auth field returns a boolean (whether credentials are set), never the actual value.
curl https://api.smsedge.com/v1/user/get-webhook \
-H "X-API-KEY: YOUR_API_KEY"{
"success": true,
"data": {
"dlr_url": "https://example.com/dlr",
"click_url": "https://example.com/click",
"inbound_url": null,
"revoke_click_url": "https://example.com/revoke",
"auth": true
}
}Test Webhooks
POST /user/test-webhook
Fire demo events to all configured webhook URLs. Returns per-webhook result.
curl -X POST https://api.smsedge.com/v1/user/test-webhook \
-H "X-API-KEY: YOUR_API_KEY"{
"success": true,
"data": {
"dlr": { "status": "ok", "http_code": 200, "time": 0.245 },
"click": { "status": "ok", "http_code": 200, "time": 0.156 },
"inbound": { "status": "skipped", "reason": "not configured" },
"revoke_click": { "status": "ok", "http_code": 200, "time": 0.132 }
}
}Status values: ok (HTTP 200), failed (non-200), skipped (not configured), error (curl failure)
Receive DLR information
This event will be fired after an SMS DLR is received by the telecom provider. Learn more about DLRs here.
POSTed as application/x-www-form-urlencoded with body sms=<json>. Uses HTTP Basic Auth if configured via the auth parameter.
{
"id": 12345,
"created": "2026-02-27 14:30:00",
"updated": "2026-02-27 14:35:00",
"from": "SenderID",
"to": 15551234567,
"verify_local": 0,
"shorten_url": 1,
"list_id": 456,
"reference": "api-0227-abc123xyz",
"transactional": 0,
"preferred_route_id": 789,
"campaign_id": 100,
"delay_time": null,
"country_id": 226,
"country_name": "United States",
"country_iso": "US",
"clicked": false,
"cost": 0.0175,
"parts": 1,
"original_url": "https://example.com/offer",
"shortened_url": "https://short.example.com/abc123",
"text": "Check out this offer: https://short.example.com/abc123",
"status": "sent",
"dlr_status": "Delivered"
}Possible dlr_status values: Delivered, Pending, Failed, Rejected, Expired, Unknown
DLRs are not always accurateTelecoms reserve the right to filter the SMS even after a DLR was sent. That's why in SMSEdge we rely heavily on CTR information to route messages properly.
Receive incoming SMS
The inbound SMS webhook will be fired when an SMS is received to one of your dedicated numbers.
POSTed as application/x-www-form-urlencoded with body sms=<json>. No Basic Auth.
{
"id": 5678,
"from": "15551234567",
"to": 1234,
"message": "Reply text from user",
"received": "2026-02-27 14:35:00"
}Clicks webhook
The clicks webhook will be fired when a click is made on an SMS sent by you.
- Only the initial click per message will trigger the webhook.
- If SMSEdge detects the click as a bot or a preview, the webhook will not be fired.
POSTed as application/x-www-form-urlencoded with body sms=<json> (same format as the DLR webhook, with "clicked": true). No Basic Auth.
{
"id": 12345,
"created": "2026-02-27 14:30:00",
"updated": "2026-02-27 14:35:00",
"from": "SenderID",
"to": 15551234567,
"verify_local": 0,
"shorten_url": 1,
"list_id": 456,
"reference": "api-0227-abc123xyz",
"transactional": 0,
"preferred_route_id": 789,
"campaign_id": 100,
"delay_time": null,
"country_id": 226,
"country_name": "United States",
"country_iso": "US",
"clicked": true,
"cost": 0.0175,
"parts": 1,
"original_url": "https://example.com/offer",
"shortened_url": "https://short.example.com/abc123",
"text": "Check out this offer: https://short.example.com/abc123",
"status": "sent",
"dlr_status": "Delivered"
}Revoke-click webhook
The revoke-click webhook is triggered when SMSEdge's bot detection system revokes clicks that were identified as non-human. This is sent as a batch notification.
POSTed as application/json (raw JSON body, NOT form-encoded). No Basic Auth.
{
"event": "clicks_revoked",
"count": 5,
"api_sms_ids": [100001, 100002],
"campaign_sms_ids": [200001, 200002, 200003]
}| Field | Description |
|---|---|
api_sms_ids | Message IDs for API-sent messages |
campaign_sms_ids | Message IDs for campaign-sent messages |
count | Total affected messages (sum of both ID arrays) |
Revoke-click dispatchRevoke-click webhooks are dispatched by a cron job every minute. Failed deliveries are retried up to 3 times with a 6-hour backoff between attempts.
Dispatch details
| Webhook | Content-Type | Auth | Retry |
|---|---|---|---|
| DLR | application/x-www-form-urlencoded | Basic Auth if set | 3 attempts, 6h backoff (24h window) |
| Click | application/x-www-form-urlencoded | None | 3 attempts, 6h backoff (24h window) |
| Inbound | application/x-www-form-urlencoded | None | 3 attempts, 6h backoff (24h window) |
| Revoke-click | application/json | None | 3 attempts, 6h backoff |
DLR, click, and inbound webhooks use 3 parallel curl threads with a 10-second timeout per request.
Updated 17 days ago
