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 traffic


Step 1: Send SMS

POST /v1/sms/send-single

ParamRequiredDefaultDescription
toYesRecipient phone number (E.164 or local format)
textYesMessage body. URLs are auto-shortened if shorten_url=1
fromYesSender ID (alphanumeric or phone number)
country_idNoauto-detectForce country for number validation
shorten_urlNo11 = shorten URLs (enables click tracking + click webhooks). Recommended — see note below
verify_localNo11 = validate number format locally
referenceNoYour custom reference string (returned in webhook payloads)
transactionalNo01 = transactional message (bypasses marketing filters)
preferred_route_idNoForce a specific route/gateway
campaign_idNoAssociate with an existing campaign
list_idNoSave number to this contact list
delayNoDelay sending by N seconds
📘

Using shorten_url=1 is recommended

Shortened 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

ParamWebhook typeDescription
dlr_urlDelivery reportsStatus updates (delivered, failed, expired)
click_urlClick trackingRecipient clicked a shortened link
inbound_urlInbound SMSReply received on a dedicated number
revoke_click_urlBot click revocationClicks flagged as bot traffic
authHTTP 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 sends
  • campaign_sms_ids — SMS IDs from campaign sends
  • count — 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:

FieldDescription
idSMS ID (returned in send-single response)
referenceYour custom reference string (set at send time)
campaign_idCampaign association (if set)


Retry & Reliability

DetailValue
Parallel threads3
Timeout per request10 seconds
Retry window24 hours
Retry interval6 hours
Revoke-click retries3 attempts, 6-hour backoff

Your endpoint must return HTTP 2xx to acknowledge receipt. Non-2xx triggers retry.