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
| Field | Type | Required | Description |
|---|---|---|---|
to | string | yes | Number in E.164 format, with country code |
message | string | yes | Message text, up to 1530 characters (10 segments) |
deviceId | string | no | Phone to use. Without it, we pick the one with the shortest queue |
reference | string | no | Your 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.