Bearer sms_test_
Authentication
Bearer API keys prefixed sms_test_ or sms_live_. Keys are shown once at creation. TEST keys cannot send LIVE traffic.

SMS API
One REST API for transactional SMS, bulk sends, and OTP verification. Bearer keys, idempotent POST, inspectable delivery reports, and signed webhooks — the same pipeline the dashboard uses.
Quick start
export API_URL=https://api.taysend.com
export KEY=sms_test_your_key
curl -X POST "$API_URL/v1/messages" \
-H "Authorization: Bearer $KEY" \
-H "Idempotency-Key: 11111111-1111-1111-1111-111111111111" \
-H "Content-Type: application/json" \
-d '{
"to": "+233200000001",
"sender_id": "TAYSEND",
"message": "Hello from Taysend",
"type": "transactional"
}'Reference
One REST surface for send, OTP, delivery, and webhooks. The dashboard calls the same paths.
Bearer sms_test_
Bearer API keys prefixed sms_test_ or sms_live_. Keys are shown once at creation. TEST keys cannot send LIVE traffic.
POST /v1/messages
POST /v1/messages accepts to for one recipient or recipients for bulk. Include sender_id, message or templateId, and type (transactional or marketing).
POST /v1/verify/send
POST /v1/verify/send and POST /v1/verify/check handle codes on a dedicated queue. Codes are hashed at rest; TEST never hits a real handset.
GET /v1/messages/:id
GET /v1/messages/:id returns status, segments, encoding, and failure reason. HTTP 200 on send means accepted — delivery is a later DLR state.
t= · v1=
Signed payloads with t= timestamp and v1= HMAC signature. Events include message.delivered, message.failed, campaign.completed, and wallet.low_balance.
Idempotency-Key
Send Idempotency-Key with POST /v1/messages. Replay the same key and body for the original response. A different body with the same key returns a conflict.
Simulated numbers
TEST uses simulated numbers with known outcomes (+233200000001 delivers, +233200000002 fails, etc.). LIVE requires an approved sender ID.
INSUFFICIENT_BALANCE
Structured error envelope with codes like INSUFFICIENT_BALANCE. Rate limit headers document remaining quota — see /developers/errors and /developers/rate-limits.
Routing
Network is inferred from the recipient prefix: MTN, Telecel, or AT. Encoding is computed from the message body. GSM-7 allows 160 characters per segment. UCS-2 (Unicode) uses 70. The API returns segment count on acceptance so you can reconcile wallet charges.
GSM-7 160 · Unicode 70 · prefix picks the network
POST /v1/messages
{
"to": "+233200000001",
"sender_id": "TAYSEND",
"message": "Hello from Taysend",
"type": "transactional"
}Explore
Each page answers a different question. They are not copies of this one.
FAQ
If something here is product behaviour, it matches the dashboard and the API.
Production API host is https://api.taysend.com. Copy-paste examples in the docs use this host.
Create a TEST key at /register, then POST /v1/messages with Authorization: Bearer sms_test_..., an Idempotency-Key header, and a JSON body with to, sender_id, and message.
Yes. Pass a recipients array instead of to. Bulk responses include a count. Campaign snapshot logic applies when sending from the dashboard.
Each webhook includes t= (timestamp) and v1= (HMAC signature). Verify the signature before trusting the payload. Full reference at /developers/webhooks.