Code Examples
Complete code examples for integrating TextFlow API into your applications.
Prerequisites
Section titled “Prerequisites”Before running these examples:
- Get your API key from Settings → API Keys
- Replace
sk_live_your_api_key_herewith your actual API key - Use a test key (
sk_test_*) for development
Quick Examples
Section titled “Quick Examples”# Send a basic SMScurl -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 from TextFlow!" }'Python
Section titled “Python”import requests
def send_sms(to, message): """Send an SMS message using TextFlow API""" 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": to, "message": message }
response = requests.post(url, json=payload, headers=headers) return response.json()
# Usageresult = send_sms("+15551234567", "Hello from Python!")print(result)Node.js / JavaScript
Section titled “Node.js / JavaScript”const axios = require('axios');
async function sendSMS(to, message) { try { const response = await axios.post( 'https://textflow.telair.net/api/v1/messages/send', { to: to, message: message }, { headers: { 'X-API-Key': 'sk_live_your_api_key_here', 'Content-Type': 'application/json' } } ); return response.data; } catch (error) { console.error('Error sending SMS:', error.response.data); throw error; }}
// UsagesendSMS('+15551234567', 'Hello from Node.js!') .then(result => console.log('Success:', result)) .catch(err => console.error('Failed:', err));<?phpfunction sendSMS($to, $message) { $url = 'https://textflow.telair.net/api/v1/messages/send'; $data = [ 'to' => $to, 'message' => $message ];
$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); return json_decode($result);}
// Usage$response = sendSMS('+15551234567', 'Hello from PHP!');print_r($response);?>require 'net/http'require 'json'require 'uri'
def send_sms(to, message) uri = URI('https://textflow.telair.net/api/v1/messages/send') http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true
request = Net::HTTP::Post.new(uri.path) request['X-API-Key'] = 'sk_live_your_api_key_here' request['Content-Type'] = 'application/json' request.body = { to: to, message: message }.to_json
response = http.request(request) JSON.parse(response.body)end
# Usageresult = send_sms('+15551234567', 'Hello from Ruby!')puts resultpackage main
import ( "bytes" "encoding/json" "fmt" "io/ioutil" "net/http")
type SMSRequest struct { To string `json:"to"` Message string `json:"message"`}
type SMSResponse struct { Success bool `json:"success"` Message string `json:"message"` Data struct { MessageID string `json:"messageId"` To string `json:"to"` From string `json:"from"` Status string `json:"status"` } `json:"data"`}
func sendSMS(to, message string) (*SMSResponse, error) { url := "https://textflow.telair.net/api/v1/messages/send"
payload := SMSRequest{ To: to, Message: message, }
jsonData, _ := json.Marshal(payload)
req, _ := http.NewRequest("POST", url, bytes.NewBuffer(jsonData)) req.Header.Set("X-API-Key", "sk_live_your_api_key_here") req.Header.Set("Content-Type", "application/json")
client := &http.Client{} resp, err := client.Do(req) if err != nil { return nil, err } defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
var result SMSResponse json.Unmarshal(body, &result)
return &result, nil}
func main() { result, err := sendSMS("+15551234567", "Hello from Go!") if err != nil { fmt.Println("Error:", err) return } fmt.Printf("Response: %+v\n", result)}C# / .NET
Section titled “C# / .NET”using System;using System.Net.Http;using System.Text;using System.Text.Json;using System.Threading.Tasks;
public class TextFlowClient{ private readonly HttpClient _httpClient; private const string ApiKey = "sk_live_your_api_key_here"; private const string BaseUrl = "https://textflow.telair.net/api";
public TextFlowClient() { _httpClient = new HttpClient(); _httpClient.DefaultRequestHeaders.Add("X-API-Key", ApiKey); }
public async Task<SMSResponse> SendSMSAsync(string to, string message) { var payload = new { to = to, message = message };
var content = new StringContent( JsonSerializer.Serialize(payload), Encoding.UTF8, "application/json" );
var response = await _httpClient.PostAsync( $"{BaseUrl}/v1/messages/send", content );
var responseBody = await response.Content.ReadAsStringAsync(); return JsonSerializer.Deserialize<SMSResponse>(responseBody); }}
public class SMSResponse{ public bool Success { get; set; } public string Message { get; set; } public SMSData Data { get; set; }}
public class SMSData{ public string MessageId { get; set; } public string To { get; set; } public string From { get; set; } public string Status { get; set; }}
// Usagevar client = new TextFlowClient();var result = await client.SendSMSAsync("+15551234567", "Hello from C#!");Console.WriteLine($"Message ID: {result.Data.MessageId}");Advanced Examples
Section titled “Advanced Examples”Send SMS with Error Handling
Section titled “Send SMS with Error Handling”import requestsimport time
def send_sms_with_retry(to, message, max_retries=3): """Send SMS with automatic retry on rate limit""" 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": to, "message": message}
for attempt in range(max_retries): try: response = requests.post(url, json=payload, headers=headers)
if response.status_code == 200: result = response.json() if result.get('success'): print(f"✓ Message sent: {result['data']['messageId']}") return result else: print(f"✗ Failed: {result.get('error')}") return None
elif response.status_code == 429: # Rate limited - wait and retry print(f"Rate limited, retrying in 60 seconds... (attempt {attempt + 1}/{max_retries})") time.sleep(60) continue
elif response.status_code == 400: # Bad request - don't retry error = response.json().get('error', 'Unknown error') print(f"✗ Bad request: {error}") return None
elif response.status_code == 401: # Authentication error - don't retry print(f"✗ Authentication failed - check your API key") return None
else: print(f"✗ Unexpected error: {response.status_code}") return None
except requests.exceptions.RequestException as e: print(f"✗ Network error: {e}") if attempt < max_retries - 1: time.sleep(5) continue return None
print(f"✗ Failed after {max_retries} attempts") return None
# Usagesend_sms_with_retry("+15551234567", "Hello with retry logic!")Bulk SMS Sending
Section titled “Bulk SMS Sending”const axios = require('axios');
class TextFlowClient { constructor(apiKey) { this.apiKey = apiKey; this.baseUrl = 'https://textflow.telair.net/api'; }
async sendSMS(to, message, from = null) { try { const response = await axios.post( `${this.baseUrl}/v1/messages/send`, { to: to, message: message, ...(from && { from: from }) }, { headers: { 'X-API-Key': this.apiKey, 'Content-Type': 'application/json' } } ); return { success: true, data: response.data }; } catch (error) { return { success: false, error: error.response?.data?.error || error.message }; } }
async sendBulk(recipients, message, delayMs = 100) { const results = [];
for (const recipient of recipients) { const result = await this.sendSMS(recipient, message); results.push({ to: recipient, ...result });
// Add delay between sends to avoid rate limiting if (delayMs > 0) { await new Promise(resolve => setTimeout(resolve, delayMs)); } }
return results; }}
// Usageconst client = new TextFlowClient('sk_live_your_api_key_here');
const recipients = [ '+15551234567', '+15559876543', '+15555555555'];
const message = 'Important update: Our store will be closed tomorrow.';
client.sendBulk(recipients, message, 100) .then(results => { const successful = results.filter(r => r.success).length; const failed = results.filter(r => !r.success).length; console.log(`Sent: ${successful} successful, ${failed} failed`);
// Show failed recipients results.filter(r => !r.success).forEach(r => { console.log(`Failed to send to ${r.to}: ${r.error}`); }); });Send Personalized Messages
Section titled “Send Personalized Messages”import requestsimport csv
class TextFlowClient: def __init__(self, api_key): self.api_key = api_key self.base_url = "https://textflow.telair.net/api"
def send_sms(self, to, message): """Send a single SMS""" url = f"{self.base_url}/v1/messages/send" headers = { "X-API-Key": self.api_key, "Content-Type": "application/json" } payload = {"to": to, "message": message}
try: response = requests.post(url, json=payload, headers=headers) return response.json() except Exception as e: return {"success": False, "error": str(e)}
def send_personalized_bulk(self, csv_file): """Send personalized messages from CSV file
CSV format: phone,first_name,appointment_date +15551234567,John,2024-12-15 +15559876543,Jane,2024-12-16 """ results = {"sent": 0, "failed": 0, "errors": []}
with open(csv_file, 'r') as file: reader = csv.DictReader(file)
for row in reader: # Personalize message with CSV data message = f"Hi {row['first_name']}! Your appointment is confirmed for {row['appointment_date']}. Reply CONFIRM or call (555) 123-4567."
result = self.send_sms(row['phone'], message)
if result.get('success'): results['sent'] += 1 print(f"✓ Sent to {row['first_name']} ({row['phone']})") else: results['failed'] += 1 results['errors'].append({ 'phone': row['phone'], 'error': result.get('error') }) print(f"✗ Failed: {row['phone']} - {result.get('error')}")
return results
# Usageclient = TextFlowClient('sk_live_your_api_key_here')results = client.send_personalized_bulk('appointments.csv')
print(f"\nResults: {results['sent']} sent, {results['failed']} failed")Environment-Based Configuration
Section titled “Environment-Based Configuration”require('dotenv').config();
const config = { apiKey: process.env.TEXTFLOW_API_KEY, baseUrl: process.env.TEXTFLOW_BASE_URL || 'https://textflow.telair.net/api', environment: process.env.NODE_ENV || 'development'};
module.exports = config;
// textflow.jsconst axios = require('axios');const config = require('./config');
class TextFlowClient { constructor() { this.apiKey = config.apiKey; this.baseUrl = config.baseUrl;
if (!this.apiKey) { throw new Error('TEXTFLOW_API_KEY environment variable is required'); }
// Warn if using production key in development if (config.environment === 'development' && this.apiKey.startsWith('sk_live_')) { console.warn('⚠️ WARNING: Using production API key in development mode'); } }
async sendSMS(to, message) { try { const response = await axios.post( `${this.baseUrl}/v1/messages/send`, { to, message }, { headers: { 'X-API-Key': this.apiKey, 'Content-Type': 'application/json' } } ); return response.data; } catch (error) { throw new Error(error.response?.data?.error || error.message); } }}
module.exports = TextFlowClient;
// .env file// TEXTFLOW_API_KEY=sk_test_your_test_key_here// TEXTFLOW_BASE_URL=https://textflow.telair.net/api// NODE_ENV=development
// Usageconst TextFlowClient = require('./textflow');const client = new TextFlowClient();
client.sendSMS('+15551234567', 'Hello!') .then(result => console.log('Sent:', result)) .catch(error => console.error('Error:', error.message));Order Confirmation Integration
Section titled “Order Confirmation Integration”<?phpclass TextFlowClient { private $apiKey; private $baseUrl = 'https://textflow.telair.net/api';
public function __construct($apiKey) { $this->apiKey = $apiKey; }
public function sendSMS($to, $message, $from = null) { $url = $this->baseUrl . '/v1/messages/send'; $data = [ 'to' => $to, 'message' => $message ];
if ($from) { $data['from'] = $from; }
$options = [ 'http' => [ 'header' => [ 'X-API-Key: ' . $this->apiKey, 'Content-Type: application/json' ], 'method' => 'POST', 'content' => json_encode($data) ] ];
$context = stream_context_create($options); $result = @file_get_contents($url, false, $context);
if ($result === false) { return ['success' => false, 'error' => 'Failed to connect']; }
return json_decode($result, true); }}
// order_confirmation.phprequire_once 'TextFlowClient.php';
function sendOrderConfirmation($orderId, $customerPhone, $customerName, $total, $estimatedDelivery) { $client = new TextFlowClient(getenv('TEXTFLOW_API_KEY'));
$message = "Hi {$customerName}! Your order #{$orderId} for \${$total} is confirmed. " . "Estimated delivery: {$estimatedDelivery}. " . "Track your order at: https://yourstore.com/orders/{$orderId}";
$result = $client->sendSMS($customerPhone, $message);
if ($result['success']) { // Log success in database logNotification($orderId, 'sms', 'sent', $result['data']['messageId']); return true; } else { // Log error logNotification($orderId, 'sms', 'failed', $result['error']); return false; }}
// Usage in checkout process$orderComplete = processOrder($cartItems, $paymentInfo);
if ($orderComplete) { sendOrderConfirmation( $orderComplete['id'], $customer['phone'], $customer['name'], $orderComplete['total'], $orderComplete['estimated_delivery'] );}?>Framework Integrations
Section titled “Framework Integrations”Django (Python)
Section titled “Django (Python)”import requestsfrom django.conf import settings
class TextFlowClient: def __init__(self): self.api_key = settings.TEXTFLOW_API_KEY self.base_url = 'https://textflow.telair.net/api'
def send_sms(self, to, message): url = f"{self.base_url}/v1/messages/send" headers = { "X-API-Key": self.api_key, "Content-Type": "application/json" } payload = {"to": to, "message": message}
response = requests.post(url, json=payload, headers=headers) return response.json()
# views.pyfrom django.http import JsonResponsefrom .client import TextFlowClient
def send_verification_code(request): phone = request.POST.get('phone') code = generate_verification_code()
client = TextFlowClient() result = client.send_sms( phone, f"Your verification code is: {code}. This code expires in 10 minutes." )
if result.get('success'): # Store code in session or database request.session['verification_code'] = code return JsonResponse({'success': True}) else: return JsonResponse({ 'success': False, 'error': result.get('error') }, status=400)
# settings.pyTEXTFLOW_API_KEY = os.environ.get('TEXTFLOW_API_KEY')Laravel (PHP)
Section titled “Laravel (PHP)”<?phpnamespace App\Services;
use Illuminate\Support\Facades\Http;
class TextFlowService{ protected $apiKey; protected $baseUrl = 'https://textflow.telair.net/api';
public function __construct() { $this->apiKey = config('services.textflow.key'); }
public function sendSMS($to, $message) { $response = Http::withHeaders([ 'X-API-Key' => $this->apiKey, 'Content-Type' => 'application/json' ])->post("{$this->baseUrl}/v1/messages/send", [ 'to' => $to, 'message' => $message ]);
return $response->json(); }}
// config/services.phpreturn [ 'textflow' => [ 'key' => env('TEXTFLOW_API_KEY'), ],];
// app/Http/Controllers/NotificationController.php<?phpnamespace App\Http\Controllers;
use App\Services\TextFlowService;
class NotificationController extends Controller{ protected $textflow;
public function __construct(TextFlowService $textflow) { $this->textflow = $textflow; }
public function sendOrderUpdate($orderId) { $order = Order::findOrFail($orderId);
$message = "Order #{$order->id} has been shipped! " . "Track at: https://yourstore.com/track/{$order->tracking_number}";
$result = $this->textflow->sendSMS($order->customer_phone, $message);
if ($result['success']) { $order->sms_sent_at = now(); $order->save(); }
return response()->json($result); }}Testing Your Integration
Section titled “Testing Your Integration”Unit Test Example (Python)
Section titled “Unit Test Example (Python)”import unittestfrom unittest.mock import patch, Mockfrom textflow_client import TextFlowClient
class TestTextFlowClient(unittest.TestCase):
@patch('requests.post') def test_send_sms_success(self, mock_post): # Mock successful response mock_response = Mock() mock_response.json.return_value = { 'success': True, 'data': { 'messageId': 'msg_123', 'status': 'sent' } } mock_post.return_value = mock_response
# Test client = TextFlowClient('sk_test_123') result = client.send_sms('+15551234567', 'Test message')
# Assertions self.assertTrue(result['success']) self.assertEqual(result['data']['messageId'], 'msg_123')
@patch('requests.post') def test_send_sms_rate_limit(self, mock_post): # Mock rate limit response mock_response = Mock() mock_response.status_code = 429 mock_response.json.return_value = { 'success': False, 'error': 'Daily message limit reached' } mock_post.return_value = mock_response
# Test client = TextFlowClient('sk_test_123') result = client.send_sms('+15551234567', 'Test message')
# Assertions self.assertFalse(result['success']) self.assertIn('limit', result['error'].lower())
if __name__ == '__main__': unittest.main()