Messages API
The Messages API allows you to retrieve message history and check delivery status for SMS messages sent through your TextFlow account.
Base URL
Section titled “Base URL”All message endpoints are available at:
https://textflow.telair.net/api/v1/messagesAuthentication
Section titled “Authentication”All requests require API key authentication via the X-API-Key header:
curl -H "X-API-Key: sk_live_your_api_key_here" \ https://textflow.telair.net/api/v1/messagesEndpoints
Section titled “Endpoints”List Messages
Section titled “List Messages”Retrieve a paginated list of messages.
GET /v1/messagesQuery Parameters
Section titled “Query Parameters”| Parameter | Type | Description |
|---|---|---|
page | integer | Page number (default: 1) |
limit | integer | Results per page, max 100 (default: 50) |
direction | string | Filter by "inbound" or "outbound" |
status | string | Filter by status: "queued", "sent", "delivered", "failed" |
to | string | Filter by recipient phone number |
from | string | Filter by sender phone number |
Example Request
Section titled “Example Request”curl -X GET "https://textflow.telair.net/api/v1/messages?page=1&limit=20&status=delivered" \ -H "X-API-Key: sk_live_your_api_key_here"Example Response
Section titled “Example Response”{ "success": true, "data": [ { "id": 12345, "uuid": "550e8400-e29b-41d4-a716-446655440000", "direction": "outbound", "to": "+15551234567", "from": "+15559876543", "body": "Your order has shipped!", "status": "delivered", "errorMessage": null, "segments": 1, "sentAt": "2024-01-15T10:30:00Z", "deliveredAt": "2024-01-15T10:30:05Z", "createdAt": "2024-01-15T10:29:55Z" } ], "pagination": { "page": 1, "limit": 20, "total": 150, "pages": 8 }}Get Message
Section titled “Get Message”Retrieve a single message by ID or UUID to check its status.
GET /v1/messages/:idPath Parameters
Section titled “Path Parameters”| Parameter | Type | Description |
|---|---|---|
id | string | Message ID (numeric) or UUID |
Example Request
Section titled “Example Request”curl -X GET "https://textflow.telair.net/api/v1/messages/12345" \ -H "X-API-Key: sk_live_your_api_key_here"Or using UUID:
curl -X GET "https://textflow.telair.net/api/v1/messages/550e8400-e29b-41d4-a716-446655440000" \ -H "X-API-Key: sk_live_your_api_key_here"Example Response
Section titled “Example Response”{ "success": true, "data": { "id": 12345, "uuid": "550e8400-e29b-41d4-a716-446655440000", "direction": "outbound", "to": "+15551234567", "from": "+15559876543", "body": "Your order has shipped!", "status": "delivered", "errorMessage": null, "segments": 1, "sentAt": "2024-01-15T10:30:00Z", "deliveredAt": "2024-01-15T10:30:05Z", "createdAt": "2024-01-15T10:29:55Z", "updatedAt": "2024-01-15T10:30:05Z" }}Message Status Values
Section titled “Message Status Values”Messages progress through the following statuses:
| Status | Description |
|---|---|
queued | Message is queued for sending |
sent | Message has been sent to the carrier |
delivered | Message was delivered to the recipient |
failed | Message failed to send or deliver |
Polling for Delivery Status
Section titled “Polling for Delivery Status”To check if a message was delivered, poll the message endpoint:
async function waitForDelivery(messageId, maxAttempts = 10) { const API_KEY = 'sk_live_your_api_key_here';
for (let i = 0; i < maxAttempts; i++) { const response = await fetch( `https://textflow.telair.net/api/v1/messages/${messageId}`, { headers: { 'X-API-Key': API_KEY } } );
const data = await response.json();
if (data.data.status === 'delivered') { console.log('Message delivered!'); return data.data; }
if (data.data.status === 'failed') { console.error('Message failed:', data.data.errorMessage); return data.data; }
// Wait 2 seconds before next check await new Promise(resolve => setTimeout(resolve, 2000)); }
console.log('Max attempts reached, message still pending'); return null;}Error Responses
Section titled “Error Responses”Common Errors
Section titled “Common Errors”| Status | Error | Description |
|---|---|---|
401 | API key required | Missing X-API-Key header |
401 | Invalid or inactive API key | API key is invalid or revoked |
403 | API access not enabled | Your plan doesn’t include API access |
404 | Message not found | Message doesn’t exist or belongs to another organization |
429 | Rate limit exceeded | Too many requests |
Error Response Format
Section titled “Error Response Format”{ "success": false, "error": "Error message describing what went wrong"}Code Examples
Section titled “Code Examples”Python
Section titled “Python”import requestsimport time
API_KEY = "sk_live_your_api_key_here"BASE_URL = "https://textflow.telair.net/api"
def get_message(message_id): """Get a single message by ID""" headers = {"X-API-Key": API_KEY} response = requests.get(f"{BASE_URL}/v1/messages/{message_id}", headers=headers) return response.json()
def list_messages(page=1, limit=50, status=None): """List messages with optional filters""" headers = {"X-API-Key": API_KEY} params = {"page": page, "limit": limit} if status: params["status"] = status
response = requests.get(f"{BASE_URL}/v1/messages", params=params, headers=headers) return response.json()
def wait_for_delivery(message_id, max_attempts=10): """Poll for delivery status""" for i in range(max_attempts): result = get_message(message_id) if result["success"]: status = result["data"]["status"] if status == "delivered": return result["data"] if status == "failed": raise Exception(result["data"]["errorMessage"]) time.sleep(2 * (i + 1)) # Exponential backoff return None
# Usagemessages = list_messages(status="delivered")print(f"Found {messages['pagination']['total']} delivered messages")
message = get_message(12345)print(f"Message status: {message['data']['status']}")Node.js
Section titled “Node.js”const axios = require('axios');
const API_KEY = 'sk_live_your_api_key_here';const BASE_URL = 'https://textflow.telair.net/api';
async function getMessage(messageId) { const response = await axios.get(`${BASE_URL}/v1/messages/${messageId}`, { headers: { 'X-API-Key': API_KEY } }); return response.data;}
async function listMessages(params = {}) { const response = await axios.get(`${BASE_URL}/v1/messages`, { params, headers: { 'X-API-Key': API_KEY } }); return response.data;}
async function waitForDelivery(messageId, maxAttempts = 10) { for (let i = 0; i < maxAttempts; i++) { const result = await getMessage(messageId); if (result.success) { if (result.data.status === 'delivered') return result.data; if (result.data.status === 'failed') throw new Error(result.data.errorMessage); } await new Promise(r => setTimeout(r, 2000 * (i + 1))); } return null;}
// UsagelistMessages({ status: 'delivered', limit: 10 }) .then(result => console.log(`Found ${result.pagination.total} delivered messages`));
getMessage(12345) .then(result => console.log(`Message status: ${result.data.status}`));Rate Limits
Section titled “Rate Limits”Message API requests share the same rate limits as other API endpoints:
| Plan | Per-Minute Limit |
|---|---|
| Starter | 100 |
| Marketer | 300 |
| Enterprise | Custom |