Agent quickstart
The two textbee API endpoints an AI agent needs: account-level send and message history with cursor polling, with copy-paste curl and SDK examples.
Updated
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-smscurl -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": ["+12015550123"],
"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. A 200 response means the API accepted the message, not that the phone sent it. See Delivery status.
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: ['+12015550123'],
message: 'Hello from textbee',
})
// result.smsBatchId when the account uses the SMS queueRead messages
GET https://api.textbee.dev/api/v1/gateway/messagesOne 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).deliveredandfailedare final. Many carriers send no delivery report, so a message can staysent. See Delivery status for each state. - 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. Message history documents every filter and field. 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
- Messages not sending - Diagnose a send that stays pending or fails
- API reference - Every field of every endpoint
Need help? Check our FAQ or contact support.