Send a message

The endpoint that queues an SMS on one of your phones.

POSThttps://api.droidsender.com/api/v1/sms/send

The message joins the device's queue and goes out in arrival order. The response does not wait for the send: queued means accepted.

Request body

FieldTypeRequiredDescription
tostringyesNumber in E.164 format, with country code
messagestringyesMessage text, up to 1530 characters (10 segments)
deviceIdstringnoPhone to use. Without it, we pick the one with the shortest queue
referencestringnoYour own identifier, returned in this message's webhooks

Request

bash
curl -X POST https://api.droidsender.com/api/v1/sms/send \
  -H "Content-Type: application/json" \
  -H "X-API-Key: DS-live-your-key" \
  -d '{
    "to": "+351912345678",
    "message": "Your appointment on 10/08 at 11:15 is confirmed.",
    "deviceId": "dev_oppo_cph2577",
    "reference": "appointment_8841"
  }'

Response

json
{
  "id": "msg_01H8X2",
  "status": "queued",
  "to": "+351912345678",
  "deviceId": "dev_oppo_cph2577",
  "reference": "appointment_8841",
  "segments": 1,
  "encoding": "GSM-7",
  "quota": { "used": 128, "included": 5000, "remaining": 4872 },
  "deviceOnline": true,
  "createdAt": "2026-08-16T14:22:05Z"
}

Retrying without sending twice

Send an Idempotency-Key header. Repeating a request with the same key returns the original response instead of a second SMS. Keys last 24 hours; a different body with the same key returns 409 idempotency_conflict.

bash
curl -X POST https://api.droidsender.com/api/v1/sms/send \
  -H "X-API-Key: DS-live-your-key" \
  -H "Idempotency-Key: appointment_8841_reminder" \
  -H "Content-Type: application/json" \
  -d '{ "to": "+351912345678", "message": "Reminder" }'

Reading a conversation

GEThttps://api.droidsender.com/api/v1/conversations/:id/messages

Returns the thread in chronological order. The conversationId arrives in the received webhook. limit takes 1 to 100, default 20.

json
{
  "conversationId": "conv_9f21",
  "phone": "+351912345678",
  "deviceId": "dev_oppo_cph2577",
  "messages": [
    {
      "id": "msg_01H8X",
      "direction": "outbound",
      "body": "Your appointment on 10/08 at 11:15 is confirmed.",
      "status": "delivered",
      "reference": "appointment_8841",
      "at": "2026-08-14T09:02:11Z"
    },
    {
      "id": "msg_01H8Z",
      "direction": "inbound",
      "body": "Thursday morning, if possible.",
      "status": "delivered",
      "reference": null,
      "at": "2026-08-14T10:30:44Z"
    }
  ]
}

Checking a message later

GEThttps://api.droidsender.com/api/v1/messages/:id

Returns the current state of one message. Use it to reconcile when a webhook did not arrive.

json
{
  "id": "msg_01H8X2",
  "status": "delivered",
  "to": "+351912345678",
  "deviceId": "dev_oppo_cph2577",
  "segments": 1,
  "encoding": "GSM-7",
  "reference": "appointment_8841",
  "createdAt": "2026-08-16T14:22:05Z",
  "deliveredAt": "2026-08-16T14:22:41Z",
  "error": null
}

One SMS can cost more than one SMS

Each segment counts as a send. The segments field in the response says how many the message used.