Send SMS via API
Send SMS via API and receive real-time delivery, click, and inbound notifications via webhooks
This guide walks through sending SMS via the API and receiving real-time webhook notifications for delivery status, link clicks, inbound replies, and bot-click revocations.
Base URL: https://api.smsedge.com/v1
Auth: X-API-KEY header on all requests
Quick Start
# 1. Configure webhooks
curl -X POST https://api.smsedge.com/v1/user/set-webhook \
-H "X-API-KEY: YOUR_API_KEY" \
-d "dlr_url=https://yourserver.com/webhooks/dlr" \
-d "click_url=https://yourserver.com/webhooks/click" \
-d "inbound_url=https://yourserver.com/webhooks/inbound" \
-d "revoke_click_url=https://yourserver.com/webhooks/revoke"
# 2. Test webhooks (fires demo events to all configured URLs)
curl -X POST https://api.smsedge.com/v1/user/test-webhook \
-H "X-API-KEY: YOUR_API_KEY"
# 3. Send an SMS
curl -X POST https://api.smsedge.com/v1/sms/send-single \
-H "X-API-KEY: YOUR_API_KEY" \
-d "from=MyBrand" \
-d "to=15551234567" \
-d "text=Hello! Check out https://example.com/offer" \
-d "shorten_url=1" \
-d "reference=order-12345"
# 4. Webhooks fire automatically:
# - DLR webhook when delivery status updates
# - Click webhook when recipient clicks the shortened link
# - Revoke-click webhook if click is later flagged as bot trafficStep 1: Send SMS
POST /v1/sms/send-single
| Param | Required | Default | Description |
|---|---|---|---|
to | Yes | — | Recipient phone number (E.164 or local format) |
text | Yes | — | Message body. URLs are auto-shortened if shorten_url=1 |
from | Yes | — | Sender ID (alphanumeric or phone number) |
country_id | No | auto-detect | Force country for number validation |
shorten_url | No | 1 | 1 = shorten URLs (enables click tracking + click webhooks). Recommended — see note below |
verify_local | No | 1 | 1 = validate number format locally |
reference | No | — | Your custom reference string (returned in webhook payloads) |
transactional | No | 0 | 1 = transactional message (bypasses marketing filters) |
preferred_route_id | No | — | Force a specific route/gateway |
campaign_id | No | — | Associate with an existing campaign |
list_id | No | — | Save number to this contact list |
delay | No | — | Delay sending by N seconds |
Usingshorten_url=1is recommendedShortened URLs enable click tracking and click webhooks. In many cases they also improve deliverability, as carriers are less likely to filter messages containing short, trusted domains.
{
"success": true,
"data": {
"id": 12345,
"created": "2026-02-27 14:30:00",
"from": "MyBrand",
"to": 15551234567,
"country_id": 226,
"country_name": "United States",
"country_iso": "US",
"reference": "order-12345",
"shorten_url": 1,
"original_url": "https://example.com/offer",
"shortened_url": "https://short.example.com/abc123",
"text": "Hello! Check out https://short.example.com/abc123",
"status": "waiting",
"dlr_status": "unknown",
"cost": 0.0175,
"parts": 1,
"clicked": false
}
}Save data.id — this is the SMS ID that appears in webhook payloads.
Step 2: Configure Webhooks
POST /v1/user/set-webhook
| Param | Webhook type | Description |
|---|---|---|
dlr_url | Delivery reports | Status updates (delivered, failed, expired) |
click_url | Click tracking | Recipient clicked a shortened link |
inbound_url | Inbound SMS | Reply received on a dedicated number |
revoke_click_url | Bot click revocation | Clicks flagged as bot traffic |
auth | — | HTTP Basic Auth for DLR webhook only (user:pass, max 32 chars) |
- Omit a param to leave it unchanged
- Send empty string
""to clear a webhook
GET /v1/user/get-webhook
Returns current webhook configuration. The auth field returns a boolean only (whether credentials are set), never the actual value.
POST /v1/user/test-webhook
Fires demo events to all configured webhook URLs. Returns per-webhook HTTP status and response time.
For full webhook configuration details, see Webhooks.
Step 3: Receive Webhook Events
All webhooks POST as application/x-www-form-urlencoded with body sms=<json>, except the revoke-click webhook which uses application/json.
DLR Webhook — Delivery Status
Fires when SMS delivery status changes. Uses HTTP Basic Auth if configured via auth param.
{
"id": 12345,
"created": "2026-02-27 14:30:00",
"updated": "2026-02-27 14:35:00",
"from": "MyBrand",
"to": 15551234567,
"verify_local": 0,
"shorten_url": 1,
"list_id": 456,
"reference": "order-12345",
"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": "Hello! Check out https://short.example.com/abc123",
"status": "sent",
"dlr_status": "Delivered"
}dlr_status values: Delivered, Pending, Failed, Rejected, Expired, Unknown
Click Webhook — Link Clicked
Same payload as DLR with "clicked": true. Fires when recipient clicks a shortened URL.
Requires shorten_url=1 when sending — otherwise no short link is created and click tracking is disabled.
Inbound SMS Webhook — Reply Received
Fires when an inbound SMS is received on a dedicated number.
{
"id": 5678,
"from": "15551234567",
"to": 1234,
"message": "Reply text from user",
"received": "2026-02-27 14:35:00"
}Revoke-Click Webhook — Bot Detection
Fires when clicks are flagged as bot traffic and revoked. Batched per user. POSTed as application/json (raw JSON body, NOT form-encoded).
{
"event": "clicks_revoked",
"count": 5,
"api_sms_ids": [100001, 100002],
"campaign_sms_ids": [200001, 200002, 200003]
}api_sms_ids— SMS IDs from API sendscampaign_sms_ids— SMS IDs from campaign sendscount— total affected messages
Event Timeline
Typical lifecycle for a single SMS with a URL:
1. POST /v1/sms/send-single → API response (id: 12345, status: waiting)
2. SMS queued & sent → DLR webhook (dlr_status: Pending)
3. Carrier confirms delivery → DLR webhook (dlr_status: Delivered)
4. Recipient clicks link → Click webhook (clicked: true)
5. Bot detection runs (if any) → Revoke-click webhook (clicks_revoked)
DLR webhooks may fire multiple times for the same SMS as the status progresses.
Matching Webhooks to Your SMS
Use these fields to correlate webhook events back to your system:
| Field | Description |
|---|---|
id | SMS ID (returned in send-single response) |
reference | Your custom reference string (set at send time) |
campaign_id | Campaign association (if set) |
Retry & Reliability
| Detail | Value |
|---|---|
| Parallel threads | 3 |
| Timeout per request | 10 seconds |
| Retry window | 24 hours |
| Retry interval | 6 hours |
| Revoke-click retries | 3 attempts, 6-hour backoff |
Your endpoint must return HTTP 2xx to acknowledge receipt. Non-2xx triggers retry.
Updated about 13 hours ago
