Send SMS
Send an individual SMS message to a phone number using the TextFlow API.
Endpoint
Section titled “Endpoint”POST /api/v1/messages/sendAuthentication
Section titled “Authentication”Requires a valid API key in the X-API-Key header.
Request Parameters
Section titled “Request Parameters”| Parameter | Type | Required | Description |
|---|---|---|---|
to | string | Yes | Recipient phone number (10 or 11 digits, with or without formatting) |
message | string | Yes | Message content to send (up to 1,600 characters) |
from | string | No | Sender phone number (must be an active number in your account). If omitted, uses your default phone number. |
Phone Number Format
Section titled “Phone Number Format”Phone numbers can be provided in any of these formats:
- E.164 format (preferred):
+15551234567 - 11 digits:
15551234567 - 10 digits:
5551234567(automatically adds +1 country code) - With formatting:
(555) 123-4567(formatting is automatically removed)
All phone numbers are normalized to E.164 format (+1XXXXXXXXXX) before sending.
Message Content
Section titled “Message Content”- Maximum length: 1,600 characters
- Single segment: Up to 160 characters (GSM-7) or 70 characters (Unicode)
- Multiple segments: Messages longer than 160/70 characters are split into segments
- Supported characters: All UTF-8 characters including emojis
Request Example
Section titled “Request Example”curl -X POST https://textflow.telair.net/api/v1/messages/send \ -H "X-API-Key: sk_live_your_api_key_here" \ -H "Content-Type: application/json" \ -d '{ "to": "+15551234567", "message": "Hello! Your order #1234 has shipped and will arrive tomorrow." }'import requests
url = "https://textflow.telair.net/api/v1/messages/send"headers = { "X-API-Key": "sk_live_your_api_key_here", "Content-Type": "application/json"}payload = { "to": "+15551234567", "message": "Hello from Python!"}
response = requests.post(url, json=payload, headers=headers)print(response.json())const axios = require('axios');
const sendSMS = async () => { try { const response = await axios.post( 'https://textflow.telair.net/api/v1/messages/send', { to: '+15551234567', message: 'Hello from Node.js!' }, { headers: { 'X-API-Key': 'sk_live_your_api_key_here', 'Content-Type': 'application/json' } } ); console.log(response.data); } catch (error) { console.error('Error:', error.response.data); }};
sendSMS();<?php$url = 'https://textflow.telair.net/api/v1/messages/send';$data = [ 'to' => '+15551234567', 'message' => 'Hello from PHP!'];
$options = [ 'http' => [ 'header' => [ 'X-API-Key: sk_live_your_api_key_here', 'Content-Type: application/json' ], 'method' => 'POST', 'content' => json_encode($data) ]];
$context = stream_context_create($options);$result = file_get_contents($url, false, $context);$response = json_decode($result);
print_r($response);?>With Custom Sender Number
Section titled “With Custom Sender Number”curl -X POST https://textflow.telair.net/api/v1/messages/send \ -H "X-API-Key: sk_live_your_api_key_here" \ -H "Content-Type: application/json" \ -d '{ "to": "5551234567", "from": "+15559876543", "message": "This is a notification from your custom sender number." }'Response
Section titled “Response”Success Response (200 OK)
Section titled “Success Response (200 OK)”{ "success": true, "message": "Message sent successfully", "data": { "messageId": "msg_1700000000_abc123def", "to": "+15551234567", "from": "+15559876543", "status": "sent" }}| Field | Type | Description |
|---|---|---|
success | boolean | Always true for successful requests |
message | string | Human-readable success message |
data.messageId | string | Unique identifier for this message |
data.to | string | Recipient phone number (E.164 format) |
data.from | string | Sender phone number (E.164 format) |
data.status | string | Message status (usually "sent") |
Error Responses
Section titled “Error Responses”Missing API Key (401 Unauthorized)
Section titled “Missing API Key (401 Unauthorized)”{ "success": false, "error": "API key required"}Invalid API Key (401 Unauthorized)
Section titled “Invalid API Key (401 Unauthorized)”{ "success": false, "error": "Invalid or inactive API key"}Missing Required Field (400 Bad Request)
Section titled “Missing Required Field (400 Bad Request)”{ "success": false, "error": "Recipient phone number (to) is required"}{ "success": false, "error": "Message content is required"}Invalid Phone Number (400 Bad Request)
Section titled “Invalid Phone Number (400 Bad Request)”{ "success": false, "error": "Invalid phone number format (must be 10 or 11 digits)"}Rate Limit Exceeded (429 Too Many Requests)
Section titled “Rate Limit Exceeded (429 Too Many Requests)”{ "success": false, "error": "Daily message limit reached"}No Phone Numbers Available (400 Bad Request)
Section titled “No Phone Numbers Available (400 Bad Request)”{ "success": false, "error": "No active phone numbers available"}Invalid Sender Number (400 Bad Request)
Section titled “Invalid Sender Number (400 Bad Request)”{ "success": false, "error": "Invalid or inactive phone number"}Internal Error (500 Internal Server Error)
Section titled “Internal Error (500 Internal Server Error)”{ "success": false, "error": "Failed to send message", "details": "Additional error information"}Usage Tracking
Section titled “Usage Tracking”Every message sent via the API counts toward your:
- Daily message limit (resets at midnight UTC)
- Monthly message allowance (based on your subscription plan)
You can check your current usage in the Dashboard or via the API.
Message Status
Section titled “Message Status”Messages go through the following status flow:
queued- Message received and queued for sendingsent- Message successfully sent to carrierdelivered- Message delivered to recipient (when delivery receipts are available)failed- Message failed to send
Common Use Cases
Section titled “Common Use Cases”Send Order Confirmation
Section titled “Send Order Confirmation”curl -X POST https://textflow.telair.net/api/v1/messages/send \ -H "X-API-Key: sk_live_your_api_key_here" \ -H "Content-Type: application/json" \ -d '{ "to": "+15551234567", "message": "Thank you for your order! Order #12345 is confirmed and will ship within 24 hours." }'Send Appointment Reminder
Section titled “Send Appointment Reminder”curl -X POST https://textflow.telair.net/api/v1/messages/send \ -H "X-API-Key: sk_live_your_api_key_here" \ -H "Content-Type: application/json" \ -d '{ "to": "+15551234567", "message": "Reminder: You have an appointment tomorrow at 2:00 PM. Reply CONFIRM or call us at (555) 123-4567." }'Send Verification Code
Section titled “Send Verification Code”curl -X POST https://textflow.telair.net/api/v1/messages/send \ -H "X-API-Key: sk_live_your_api_key_here" \ -H "Content-Type: application/json" \ -d '{ "to": "+15551234567", "message": "Your verification code is: 847293. This code expires in 10 minutes." }'Error Handling Best Practices
Section titled “Error Handling Best Practices”Always check the success field in the response:
const response = await fetch('https://textflow.telair.net/api/v1/messages/send', { method: 'POST', headers: { 'X-API-Key': 'sk_live_your_api_key_here', 'Content-Type': 'application/json' }, body: JSON.stringify({ to: '+15551234567', message: 'Hello!' })});
const data = await response.json();
if (data.success) { console.log('Message sent:', data.data.messageId);} else { console.error('Failed to send:', data.error);
// Handle specific errors if (response.status === 429) { console.log('Rate limit exceeded - retry later'); } else if (response.status === 400) { console.log('Invalid request - check parameters'); }}Testing
Section titled “Testing”Use a test API key (sk_test_*) to send test messages without affecting your production message count.
Rate Limiting
Section titled “Rate Limiting”The send SMS endpoint is rate-limited to prevent abuse:
- Per-minute limit: Varies by plan (see API Overview)
- Daily limit: Based on your subscription plan
- Retry after: If rate-limited, wait 60 seconds before retrying