Receiving SMS
Learn how to receive and process incoming SMS messages using the textbee.dev API and webhooks.
textbee.dev forwards SMS messages sent to your registered Android device to your account. Use this for verification codes, customer inquiries, and two-way messaging.
Prerequisites
- A textbee.dev account
- A registered Android device
- SMS receiving enabled in the app
Enabling SMS receiving
- Open the textbee.dev app on your Android device.
- Go to Settings or Receive SMS and turn Receive SMS (or Enable Receiving) ON.
- Incoming SMS will be forwarded to textbee.dev. You can confirm in the dashboard under Devices that receiving is enabled.
Recommended: use a webhook
For real-time handling of incoming SMS, set up a webhook. Your server gets a POST when each message is received - no polling needed.
- In the dashboard, go to Webhooks and add a webhook URL.
- Subscribe to the MESSAGE_RECEIVED event.
- Implement your endpoint to accept the payload and return 200.
Details, payload format, and signing: Webhooks.
Fetching message history (API)
To list received messages (e.g. for history or backfill), use the account-level message history endpoint with direction=received:
GET https://api.textbee.dev/api/v1/gateway/messages
Headers: x-api-key: YOUR_API_KEY
Query parameters:
- direction (optional):
all,sent, orreceived. Usereceivedfor incoming SMS only. Default:all. - deviceIds (optional): Comma-separated device ids to include. Default: every device on your account. Messages from deleted devices are not included.
- smsBatchId (optional): Only messages from one batch, using the
smsBatchIda send returns. Combine withstatus=failedto list the recipients of a batch that failed. - status (optional): Delivery state to return, e.g.
failedordelivered. - search (optional): Match against the message text and the other party's number.
- from / to (optional): Time window on when the platform stored the message. ISO-8601 with an explicit timezone (
2026-08-01T00:00:00Zor+03:00form), or a plain date (read as UTC midnight).fromis inclusive,tois exclusive, so back-to-back windows never double-count a message. A datetime without a timezone is rejected. - order (optional):
desc(default, newest first) orasc(oldest first). - page (optional): Page number. Default: 1.
- limit (optional): Items per page. Default: 50, max: 100.
- cursor (optional): Opaque position from a previous response's
meta.nextCursor. Use it instead ofpagewhen polling.
Example (cURL):
curl -X GET "https://api.textbee.dev/api/v1/gateway/messages?direction=received&page=1&limit=50" \
-H "x-api-key: YOUR_API_KEY"
The response includes a data array of messages and a meta object (page, limit, total, totalPages, plus nextCursor and hasMore). Each message includes fields such as _id, message, direction, sender, receivedAt, and device.
Polling for new messages
Webhooks are the push option; this is the reliable pull option. Ask for messages in ascending order from a starting time, then follow the cursor:
- 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, so this never re-reads pages, never misses a message that arrived while you were reading, and never returns the same message twice. Prefer Z timestamps for rolling windows, and note that from/to filter on when the platform stored the message: a phone that was offline uploads its backlog later, and cursor polling still picks those up.
The device-scoped route (GET /gateway/devices/{DEVICE_ID}/messages) keeps working but is deprecated; new integrations should use /gateway/messages.
Next Steps
- Set up webhooks - Enable real-time notifications
- Send SMS - Reply to received messages
- Overview - Explore more capabilities
Need help? Check our FAQ or contact support.