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.

ParamDescription
dlr_urlDLR delivery reports
click_urlClick notifications
inbound_urlInbound SMS
revoke_click_urlBot-click revocation batch notifications
authHTTP 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 accurate

Telecoms 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]
}
FieldDescription
api_sms_idsMessage IDs for API-sent messages
campaign_sms_idsMessage IDs for campaign-sent messages
countTotal affected messages (sum of both ID arrays)
📘

Revoke-click dispatch

Revoke-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

WebhookContent-TypeAuthRetry
DLRapplication/x-www-form-urlencodedBasic Auth if set3 attempts, 6h backoff (24h window)
Clickapplication/x-www-form-urlencodedNone3 attempts, 6h backoff (24h window)
Inboundapplication/x-www-form-urlencodedNone3 attempts, 6h backoff (24h window)
Revoke-clickapplication/jsonNone3 attempts, 6h backoff

DLR, click, and inbound webhooks use 3 parallel curl threads with a 10-second timeout per request.