SMS
Send an SMS (Tier 2)
POST /v1/sms
- Scope
messages:send- Tier
- Tier 2 (reaches or unlocks real people)
- Data
- Personal data
- Idempotency
- Idempotency-Key: required
Tier 2. This operation can reach or unlock real people. It needs the scope messages:send and the account switch tier2_sms_send_enabled, which is off for every account unless DialerBee turns it on at your request. Until then it answers 403 tier_not_enabled. Daily cap: set before launch.
TIER 2: needs the scope messages:send, the account switch tier2_sms_send_enabled (403 tier_not_enabled otherwise) and a key made by the account's guided sending setup (IP allow-list, daily cap, per-minute cap). The message is sent from the account's own sender name. Before anything is sent the number goes through the same compliance checks as the console: Do-Not-Call (422 on_dnc), blocked countries (422 blocked_country), calling hours and consent (422 message_refused, errors[0].code says why) and the balance (402 insufficient_balance). Every message carries your own client_reference: a second message with the same reference answers 409 duplicate_client_reference and nothing is sent again. Messages count against the key's and the account's daily and per-minute caps and the account's estimated-spend limit (429 daily_cap_reached / rate_limit_exceeded / spend_cap_reached). An administrator's "stop all sending" answers 403 sending_suspended; a new self-service account answers 403 outbound_not_approved until DialerBee approves its outbound messaging.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
Idempotency-Key | header | string | yes | Your unique value for this logical operation (a UUID is fine). Scoped to your API client, kept 24 hours. (min length 1; max length 255) |
X-Correlation-ID | header | string | no | Your own trace value, logged with the request. Metadata only, never identity. (min length 1; max length 128) |
Request body
The message.
JSON: SmsSendRequest
Response
202: Accepted for sending.
| Header | Meaning |
|---|---|
X-Request-ID | The DialerBee request id. Quote it to support. Every response carries X-Request-ID: req_<ULID>, or edge_<32 hex> when the edge answered before the request reached the API. |
Cache-Control | Always no-store. |
Idempotency-Replayed | true when this answer is the stored answer of an earlier request with the same Idempotency-Key. |
Examples
Request example
curl
curl -sS -X POST \
"https://app.dialerbee.com/api/v1/sms" \
-H "Authorization: Bearer $DIALERBEE_API_KEY" \
-H 'Idempotency-Key: 5f2b7c1e-8a3d-4c6f-9b0e-2d4a6c8e1f3a' \
-H "Content-Type: application/json" \
--data '{
"to": "+12125550123",
"body": "Your appointment is confirmed for Thursday at 2 pm.",
"client_reference": "order-1001"
}'
Python (SDK)
from dialerbee import DialerBee
db = DialerBee() # reads DIALERBEE_API_KEY from the environment
result = db.sms.send(
to="+12125550123",
body="Your appointment is confirmed for Thursday at 2 pm.",
client_reference="order-1001",
idempotency_key="5f2b7c1e-8a3d-4c6f-9b0e-2d4a6c8e1f3a",
)
Response example
202
{
"id": "msg_0f8fad5b-d9cb-469f-a165-70867728950e",
"to": "+12125550123",
"status": "queued",
"client_reference": "order-1001",
"created_at": "2026-09-29T09:15:00Z"
}
Error examples
422 on_dnc
{
"type": "https://docs.dialerbee.com/errors/on-dnc",
"title": "Destination is on DNC",
"status": 422,
"detail": "The number is on the account's Do-Not-Call list, so this action is refused.",
"instance": "urn:dialerbee:request:req_01K6BZ3M9X4T7Q2V8N5R6P1W0C",
"code": "on_dnc",
"request_id": "req_01K6BZ3M9X4T7Q2V8N5R6P1W0C"
}
422 blocked_country
{
"type": "https://docs.dialerbee.com/errors/blocked-country",
"title": "Destination country blocked",
"status": 422,
"detail": "The platform does not contact numbers in this country.",
"instance": "urn:dialerbee:request:req_01K6BZ3M9X4T7Q2V8N5R6P1W0C",
"code": "blocked_country",
"request_id": "req_01K6BZ3M9X4T7Q2V8N5R6P1W0C"
}
422 message_refused
{
"type": "https://docs.dialerbee.com/errors/message-refused",
"title": "Message refused by a compliance check",
"status": 422,
"detail": "A compliance check refused the message (for example calling hours or missing consent), so nothing was sent.",
"instance": "urn:dialerbee:request:req_01K6BZ3M9X4T7Q2V8N5R6P1W0C",
"code": "message_refused",
"request_id": "req_01K6BZ3M9X4T7Q2V8N5R6P1W0C"
}
Errors
| Status | Code | Title |
|---|---|---|
| 401 | invalid_api_key | Invalid API key |
| 403 | api_access_disabled | API access disabled |
| 403 | ip_not_allowed | IP address not allowed |
| 403 | insufficient_scope | Not permitted |
| 403 | tier_not_enabled | Capability not enabled |
| 400 | credential_in_url | Credential in URL |
| 400 | credential_in_body | Credential in body |
| 400, 422 | validation_failed | Invalid request |
| 413 | payload_too_large | Payload too large |
| 415 | unsupported_media_type | Unsupported media type |
| 400 | idempotency_key_required | Idempotency-Key required |
| 422 | on_dnc | Destination is on DNC |
| 422 | blocked_country | Destination country blocked |
| 422 | message_refused | Message refused by a compliance check |
| 402 | insufficient_balance | Balance too low |
| 403 | sending_suspended | Sending is stopped |
| 403 | outbound_not_approved | Outbound not approved yet |
| 409 | conflict | Request in progress |
| 409 | idempotency_conflict | Idempotency key reused |
| 409 | duplicate_client_reference | Duplicate client reference |
| 409 | outcome_unknown | Outcome unknown |
| 429 | rate_limit_exceeded | Too many requests |
| 429 | daily_cap_reached | Daily limit reached |
| 429 | spend_cap_reached | Daily estimated-spend limit reached |
| 503 | temporarily_unavailable | Temporarily unavailable |
| 503 | upstream_unavailable | Temporarily unavailable |
| 502 | upstream_invalid_response | Upstream error |
| 500 | internal_error | Internal error |
Objects
SmsSendRequest
| Field | Type | Required | Description |
|---|---|---|---|
to | string (E.164 phone) | yes | A phone number in E.164 form. |
body | string | yes | (min length 1; max length 918) |
client_reference | string | yes | Your unique reference for this message; a duplicate is refused. (min length 1; max length 64) |
SmsMessage
| Field | Type | Required | Description |
|---|---|---|---|
id | string (SmsMessageId) | yes | An outbound message (SMS or WhatsApp). msg_ + a lower-case UUID. |
to | string | yes | |
status | string | yes | |
client_reference | string | yes | |
created_at | string (date-time) | yes |