Agent quickstart
The two textbee API endpoints an AI agent or automation needs: account-level send and account-level message history with cursor polling. Copy-paste curl and SDK examples.
Everything an AI agent or automation needs from textbee is two endpoints: one to send, one to read. Both are account-level, so there is no device id to manage. Authenticate every request with the x-api-key header using a key from the dashboard.
If your agent speaks MCP, use the MCP server instead of calling these directly. This page is for HTTP-level integrations and for LLMs writing textbee code.
Send an SMS
POST https://api.textbee.dev/api/v1/gateway/send-sms
curl -X POST https://api.textbee.dev/api/v1/gateway/send-sms \
-H 'Content-Type: application/json' \
-H 'x-api-key: YOUR_API_KEY' \
-d '{
"recipients": ["+15550100123"],
"message": "Hello from textbee"
}'
- recipients (array, required): phone numbers in E.164 format with the country code.
- message (string, required): the text to send.
- deviceId (string, optional): omit it. textbee picks your default device, otherwise the enabled device with the most recent heartbeat. Pass it only to force a specific phone.
- simSubscriptionId (number, optional): which SIM on a dual-SIM phone.
- scheduledAt (ISO 8601, optional): send later instead of now.
The response includes an smsBatchId when the account uses the SMS queue. Keep it: it is how you check delivery.
With the JavaScript SDK:
pnpm add @textbee/sdkimport { Textbee } from '@textbee/sdk'
const textbee = new Textbee({ apiKey: process.env.TEXTBEE_API_KEY })
const result = await textbee.sendSms({
recipients: ['+15550100123'],
message: 'Hello from textbee',
})
// result.smsBatchId when the account uses the SMS queue
Read messages
GET https://api.textbee.dev/api/v1/gateway/messages
One endpoint for every device on the account. The useful filters for agents:
- direction:
receivedfor inbound only (replies, verification codes),sentto review outgoing messages and their delivery status,allfor both. - smsBatchId: only messages from one send, using the
smsBatchIdthe send returned. This is the delivery-status lookup: each row carries astatus(pending,dispatched,sent,delivered,failed,unknown,received).delivered,failed, andunknownare final. - search: free-text match across the message body and the other party's number.
- from / to: time window, ISO 8601 with an explicit timezone.
fromis inclusive,toexclusive, so consecutive windows never double-count a message. - order:
desc(default, newest first) orascto walk forward when polling. - cursor: opaque position from a previous response's
meta.nextCursor.
curl "https://api.textbee.dev/api/v1/gateway/messages?direction=received&limit=25" \
-H 'x-api-key: YOUR_API_KEY'
Check the delivery of a send:
curl "https://api.textbee.dev/api/v1/gateway/messages?smsBatchId=BATCH_ID_FROM_SEND" \
-H 'x-api-key: YOUR_API_KEY'
Poll for new messages without duplicates
Webhooks are the push option (see Webhooks); this is the reliable pull option:
- First call:
GET /gateway/messages?direction=received&order=asc&from=2026-08-01T00:00:00Z - Follow
meta.nextCursoruntilmeta.hasMoreisfalse. - On the next poll, resume from the last
nextCursoryou saw.
The cursor is your resume token: no re-read pages, no missed messages, no duplicates. The SDK wraps this as an async iterator:
for await (const message of textbee.iterateMessages({ direction: 'received' })) {
handle(message)
}
Use only the endpoints on this page. Older device-scoped routes still work for existing integrations but are deprecated and should never appear in new code.
Rate limits and quotas
Sends count against your plan's daily and monthly quotas, enforced server-side. A send over quota fails with HTTP 429 and a body containing hasReachedLimit: true plus your remaining counts. Do not retry those automatically; the quota does not reset because you retried.
Next Steps
- MCP server - The same capabilities as tools for Claude, Cursor, and other MCP clients
- Webhooks - Get pushed incoming messages instead of polling
- API reference - Every field of every endpoint
Need help? Check our FAQ or contact support.