Quickstart: send your first SMS

By the end you will have sent an SMS through the Routeon API and confirmed its delivery. Time: ~5 minutes.

All requests go to the base URL https://client.routeon.io/api/v1 and are authenticated with the X-API-Key header. Responses use the envelope {"error": <bool>, "data": ...}.

Prerequisites

  • An active account. Give your account manager the email address for the invitation link, then create your credentials and sign in to the Client portal at https://client.routeon.io/. No access? Contact your account manager or support.
  • An API key with the omni-api scope. In the portal open API Accesses → API key generation, enter a name, optionally a webhook URL for delivery statuses (can be overridden per request), select the omni-api scope, and click Create API key. Store the value — it is used below as <API_KEY>. The key works only with the scopes you selected; a missing scope results in 401 / REJECTD.
  • Sender ID — none needed for the first send. Without your own registered Sender ID, a generic default is used, so you can send right away. For production traffic register your own sender in the portal (Assets → Sender IDs) and wait for approval — only a sender in Active status (status: 2) can be used. Approval times vary by country and operator, so start early.

1. Pre-flight checks

Confirm SMS is enabled, see which senders you can use, and check your balance.

curl -sS -H "X-API-Key: <API_KEY>" "https://client.routeon.io/api/v1/channels"

Expected response (SMS is channel 1):

{
  "error": false,
  "data": [
    { "id": 1, "type": "SMS", "description": "Sms channel type" }
  ]
}
curl -sS -H "X-API-Key: <API_KEY>" "https://client.routeon.io/api/v1/senders"

Expected response — pick a sender with channel: 1 and status: 2 (Active):

{
  "error": false,
  "data": [
    {
      "senderId": "Routeon",
      "displayName": "SMS Sender",
      "channel": 1,
      "status": 2,
      "webhookUrl": ""
    }
  ]
}
curl -sS -H "X-API-Key: <API_KEY>" "https://client.routeon.io/api/v1/balance"

Expected response:

[
  {
    "agreementId": 12,
    "balanceId": 34,
    "name": "Main",
    "amount": 12345.67,
    "currency": "USD"
  }
]

2. Send the SMS

POST /messages sends one message to one recipient. The phone number is digits with country code, without +. webhook (optional) overrides any webhook configured on the sender or the API key for this message; clientInfo (optional) is a free-form tag stored on the delivery record — useful for correlation.

curl -sS -X POST "https://client.routeon.io/api/v1/messages" 
  -H "X-API-Key: <API_KEY>" 
  -H "Content-Type: application/json" 
  -d '{
    "contact": "905063565285",
    "channel": 1,
    "senderId": "Routeon",
    "payload": { "text": "Hello from Routeon" },
    "webhook": "https://your.app/hooks/routeon",
    "clientInfo": "batchId=2026-07-14-001"
  }'

Sending an OTP? Add "isOtp": true to mask the message body in logs and reports.

3. Store the messageId

The API accepts the message and responds immediately — delivery happens asynchronously.

{
  "error": false,
  "data": {
    "channel": 1,
    "transactionId": "95e3e0da-9684-4ba4-88a3-e9207ddeca05",
    "messageId": "6719b5f4-36af-4fba-b111-49ff07f4f96b"
  }
}

Store data.messageId — it is the key for delivery tracking (webhooks and EDR lookups). Keep transactionId for support requests.

4. Verify it worked

Option A — webhook. If you passed a webhook URL (or configured one on the sender or API key), your endpoint receives messageStatus events as the message progresses (sent, then delivered):

{
  "event": "messageStatus",
  "message": {
    "messageId": "6719b5f4-36af-4fba-b111-49ff07f4f96b",
    "channel": 1,
    "senderId": "Routeon",
    "status": "delivered",
    "timestamp": "2026-07-14T08:11:02Z",
    "contact": "905063565285",
    "cost": "0.018"
  },
  "reason": { "code": 0, "text": "" }
}

Option B — EDR report. Pull the delivery record by messageId (up to 10 comma-separated IDs per call):

curl -sS -H "X-API-Key: <API_KEY>" 
  "https://client.routeon.io/api/v1/edrs?messageIds=6719b5f4-36af-4fba-b111-49ff07f4f96b"

Expected response (key fields):

{
  "count": 1,
  "data": [
    {
      "messageId": "6719b5f4-36af-4fba-b111-49ff07f4f96b",
      "channelType": 1,
      "senderId": "Routeon",
      "incomingDestNumber": "905063565285",
      "clientInfo": "batchId=2026-07-14-001",
      "mdnStatus": "DELIVRD",
      "isSent": true,
      "isDelivered": true,
      "rate": 0.018,
      "finalCost": 0.018,
      "errorMessage": "",
      "timeSent": "2026-07-14T08:11:01Z",
      "timeDelivered": "2026-07-14T08:11:02Z"
    }
  ]
}

mdnStatus: "DELIVRD" and isDelivered: true mean the SMS reached the handset; finalCost is what the message cost. Negative outcomes appear here too: UNDELIV (invalid number or unreachable subscriber), EXPIRED (operator delivery window expired), REJECTD (rejected — check the Sender ID status, key scope, and that the destination is open for your account).

Where to go next

  • Guides — task-oriented recipes, including launching a bulk campaign by template.
  • API Reference — full endpoint reference.
  • Webhooks & EventsmessageStatus and inbound-reply events, delivery mechanics.