| name | telnyx-api |
| description | Use this skill when working with Telnyx communication APIs for SMS/MMS messaging, voice calls, phone number management, messaging profiles, webhook integration, two-way SMS conversations, bulk sending, message scheduling, or production deployment of telephony features. Applies to building communication features, SMS notification systems, voice IVR systems, or integrating telephony capabilities. |
Telnyx API - Comprehensive Communication Platform
When to Use This Skill
Use this skill when working with Telnyx's communication APIs for:
- SMS/MMS Messaging - Send and receive text messages programmatically
- Voice Communication - Build voice calling applications with Call Control API
- Phone Number Management - Search, purchase, and configure phone numbers
- Messaging Profiles - Configure messaging settings and webhooks
- Webhook Integration - Handle real-time events and delivery notifications
- Two-Way SMS Conversations - Build interactive SMS experiences
- Bulk SMS Sending - Send messages to multiple recipients with rate limiting
- Message Scheduling - Schedule messages for future delivery
- Production Deployment - Deploy messaging features with error handling and monitoring
This skill applies to building communication features in applications, setting up SMS notification systems, creating voice IVR systems, or integrating telephony capabilities.
Quick Reference
1. Send Simple SMS
const axios = require('axios');
async function sendSMS(to, from, text) {
const response = await axios.post(
'https://api.telnyx.com/v2/messages',
{ from, to, text },
{
headers: {
'Authorization': `Bearer ${process.env.TELNYX_API_KEY}`,
'Content-Type': 'application/json'
}
}
);
return response.data;
}
sendSMS('+14155552671', '+14155559999', 'Hello from Telnyx!');
2. Send MMS with Media
async function sendMMS(to, from, text, mediaUrls) {
const response = await axios.post(
'https://api.telnyx.com/v2/messages',
{
from,
to,
text,
media_urls: mediaUrls,
type: 'MMS'
},
{
headers: {
'Authorization': `Bearer ${process.env.TELNYX_API_KEY}`,
'Content-Type': 'application/json'
}
}
);
return response.data;
}
sendMMS('+14155552671', '+14155559999', 'Check this out!',
['https://example.com/image.jpg']);
3. Handle Incoming Messages (Webhook)
const express = require('express');
const app = express();
app.use(express.json());
app.post('/webhooks/telnyx', (req, res) => {
const event = req.body.data;
if (event.event_type === 'message.received') {
const from = event.payload.from.phone_number;
const text = event.payload.text;
const to = event.payload.to[0].phone_number;
console.log(`Received: "${text}" from ${from}`);
sendSMS(from, to, 'Thanks for your message!');
}
res.status(200).send('OK');
});
4. Validate Phone Numbers
function validateE164(phoneNumber) {
const e164Regex = /^\+[1-9]\d{1,14}$/;
if (!e164Regex.test(phoneNumber)) {
return {
valid: false,
error: 'Phone number must be in E.164 format (e.g., +14155552671)'
};
}
return { valid: true };
}
const validation = validateE164('+14155552671');
if (!validation.valid) {
throw new Error(validation.error);
}
5. Send with Error Handling
async function sendWithRetry(to, from, text, maxRetries = 3) {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
return await sendSMS(to, from, text);
} catch (error) {
if (error.response?.status === 500 && attempt < maxRetries) {
const delayMs = Math.pow(2, attempt) * 1000;
console.log(`Retry in ${delayMs}ms...`);
await new Promise(resolve => setTimeout(resolve, delayMs));
} else {
throw error;
}
}
}
}
6. Bulk Sending with Rate Limiting
async function sendBulkSMS(recipients, from, text) {
const delayMs = 100;
const results = [];
for (const recipient of recipients) {
try {
const result = await sendSMS(recipient, from, text);
results.push({ success: true, to: recipient, id: result.data.id });
} catch (error) {
results.push({ success: false, to: recipient, error: error.message });
}
await new Promise(resolve => setTimeout(resolve, delayMs));
}
return results;
}
7. Verify Webhook Signatures
const crypto = require('crypto');
function verifyWebhook(body, signature, timestamp, publicKey) {
const timestampMs = parseInt(timestamp);
const now = Date.now();
if (Math.abs(now - timestampMs) > 5 * 60 * 1000) {
return false;
}
const payload = `${timestamp}.${JSON.stringify(body)}`;
const hmac = crypto.createHmac('sha256', publicKey);
const digest = hmac.update(payload).digest('hex');
return signature === digest;
}
app.post('/webhooks/telnyx', (req, res) => {
const signature = req.headers['telnyx-signature-ed25519'];
const timestamp = req.headers['telnyx-timestamp'];
if (!verifyWebhook(req.body, signature, timestamp, process.env.TELNYX_PUBLIC_KEY)) {
return res.status(401).send('Invalid signature');
}
res.status(200).send('OK');
});
8. Schedule Message for Later
async function scheduleMessage(to, from, text, sendAt) {
const response = await axios.post(
'https://api.telnyx.com/v2/messages',
{
from,
to,
text,
send_at: sendAt
},
{
headers: {
'Authorization': `Bearer ${process.env.TELNYX_API_KEY}`,
'Content-Type': 'application/json'
}
}
);
return response.data;
}
const futureTime = new Date(Date.now() + 3600000).toISOString();
scheduleMessage('+14155552671', '+14155559999', 'Reminder!', futureTime);
9. Two-Way Conversation Flow
const conversations = new Map();
app.post('/webhooks/telnyx', async (req, res) => {
const event = req.body.data;
if (event.event_type === 'message.received') {
const from = event.payload.from.phone_number;
const to = event.payload.to[0].phone_number;
const text = event.payload.text.toLowerCase();
let state = conversations.get(from) || 'start';
let reply;
switch (state) {
case 'start':
reply = "Welcome! What's your name?";
conversations.set(from, 'asked_name');
break;
case 'asked_name':
reply = `Nice to meet you, ${text}! How can I help?`;
conversations.set(from, 'helping');
break;
case 'helping':
reply = 'Thanks! A human will respond shortly.';
conversations.delete(from);
break;
}
await sendSMS(from, to, reply);
}
res.status(200).send('OK');
});
10. Python Example
import requests
import os
def send_sms(to, from_number, text):
url = 'https://api.telnyx.com/v2/messages'
headers = {
'Authorization': f"Bearer {os.environ['TELNYX_API_KEY']}",
'Content-Type': 'application/json'
}
payload = {
'from': from_number,
'to': to,
'text': text
}
response = requests.post(url, json=payload, headers=headers)
response.raise_for_status()
return response.json()
result = send_sms('+14155552671', '+14155559999', 'Hello from Python!')
print(f"Message ID: {result['data']['id']}")
Key Concepts
1. E.164 Phone Number Format
International phone number format: +[country code][number]
- US Example:
+14155552671
- UK Example:
+442071234567
- Always include the
+ prefix
2. Messaging Profile
A configuration container that groups numbers and defines webhook settings. Benefits:
- Centralized webhook management
- Number pools for load distribution
- Alphanumeric sender IDs
- Easy number management
3. Message Encoding
- GSM-7: 160 chars/segment for standard ASCII (cheaper)
- UCS-2: 70 chars/segment for emoji/unicode (more expensive)
- Long messages split into segments (max 10)
- Multi-part messages: GSM-7 = 153 chars/segment, UCS-2 = 67 chars/segment
4. Webhook Events
Real-time notifications about message status:
message.sent - Sent to carrier
message.delivered - Delivered to recipient
message.failed - Delivery failed
message.received - Inbound message received
message.finalized - Reached final state
5. Authentication
All API requests require Bearer token authentication:
Authorization: Bearer YOUR_API_KEY
Store API keys in environment variables, never hardcode.
Reference Files
The references/ directory contains detailed documentation:
authentication.md
Complete guide to API key management and security:
- Creating and managing API keys
- Environment variable setup (Node.js, Python, Docker, Kubernetes)
- Best practices for key rotation and security
- IP whitelisting configuration
- Webhook signature verification
- Common authentication errors and solutions
messaging-api.md
Full Messaging API reference:
- Complete endpoint documentation (
/v2/messages)
- All request/response parameters
- Message status values and lifecycle
- Character encoding details (GSM-7 vs UCS-2)
- Message segmentation rules
- MMS limitations and supported formats
- Pagination and filtering options
webhooks.md
Comprehensive webhook reference:
- All webhook event types with payload examples
- Signature verification (HMAC-SHA256)
- Webhook configuration (global, profile, per-message)
- Best practices (idempotency, async processing, retries)
- Testing webhooks locally with ngrok
- Complete webhook handler example
- Troubleshooting guide
error-codes.md
Complete error reference and handling:
- All HTTP status codes and meanings
- Common error codes with solutions
- Validation errors (10001-10007)
- Rate limiting errors (429)
- Server errors (500, 502, 503)
- Webhook-specific delivery errors
- Comprehensive error handler implementation
- Retry strategies with backoff
best-practices.md
Production deployment patterns:
- Using messaging profiles in production
- Robust error handling patterns
- Exponential backoff retry logic
- Rate limiting for bulk sending
- Message tracking and status monitoring
- Phone number validation and formatting
- Message content optimization
- Character limit handling
- Webhook async processing with queues
- Idempotency implementation
- Structured logging and monitoring
- Cost optimization strategies
- Testing patterns
- Production deployment checklist
number-management.md
Phone number operations:
- Searching available numbers
- Purchasing phone numbers
- Configuring number settings
- Porting existing numbers
- Number pool management
10dlc.md
10DLC (10-Digit Long Code) registration and compliance:
- Campaign approval stages (TCR_ACCEPTED → MNO_PENDING → MNO_PROVISIONED)
- Brand and campaign registration process
- Use case selection (Customer Care, Marketing, 2FA, etc.)
- TCPA and CTIA compliance requirements
- Required message elements (opt-in, opt-out, HELP)
- Monitoring campaign status via API
- Phone number association (portal-only, not via API)
- Cost structure and timeline expectations
- Common issues and troubleshooting
- Production checklist
Working with This Skill
For Beginners
Start Here:
- Use Quick Reference Example #1 (Send Simple SMS)
- Set up environment variables for API key
- Test sending to your own phone number
- Set up Quick Reference Example #3 (Handle Incoming Messages)
- Test two-way messaging
Key Concepts to Learn:
- E.164 phone number format
- Bearer token authentication
- Basic webhook handling
Reference Files:
- Start with
authentication.md for setup
- Check
messaging-api.md for basic API usage
- Review
error-codes.md when errors occur
For Intermediate Users
Focus Areas:
- Implement Quick Reference Example #7 (Verify Webhook Signatures)
- Use Quick Reference Example #5 (Error Handling with Retry)
- Build conversation flows with Quick Reference Example #9
- Create a messaging profile in
best-practices.md
Key Concepts to Master:
- Messaging profiles
- Webhook security
- Error handling patterns
- Message segmentation
Reference Files:
- Study
webhooks.md for event types and security
- Review
best-practices.md for production patterns
- Use
error-codes.md for comprehensive error handling
For Advanced Users
Advanced Patterns:
- Implement bulk messaging from
best-practices.md with queue system
- Build IVR systems with Call Control API
- Set up number pools for high-volume messaging
- Implement comprehensive monitoring and alerting
- Optimize message costs with encoding strategies
Key Topics:
- Message queue systems (Bull/Redis)
- Database-backed idempotency
- Structured logging (Winston)
- Metrics collection (Prometheus)
- Production deployment patterns
Reference Files:
- Deep dive into
best-practices.md for all production patterns
- Study
error-codes.md for comprehensive error handling
- Review
webhooks.md for advanced webhook patterns
API Essentials
Base URL
https://api.telnyx.com/v2
Authentication Header
Authorization: Bearer YOUR_API_KEY
Environment Variables
TELNYX_API_KEY=KEY019A080F468AAFD4AF4F6888D7795244_xxx
TELNYX_PUBLIC_KEY=your_public_key_for_webhook_validation
TELNYX_MESSAGING_PROFILE_ID=abc85f64-5717-4562-b3fc-2c9600000000
Rate Limits
- Standard accounts: 10 requests/second per endpoint
- High-volume accounts: Contact Telnyx for increased limits
- Implement exponential backoff for 429 responses
Common Response Structure
{
"data": {
"id": "message-uuid",
"type": "SMS",
"from": { "phone_number": "+18445550001" },
"to": [{ "phone_number": "+18665550001", "status": "queued" }],
"text": "Hello!",
"cost": { "amount": "0.0051", "currency": "USD" }
}
}
Quick Start Checklist
Additional Resources
Common Patterns
Pattern: Message with Tracking
const tracker = new Map();
async function sendTrackedMessage(to, from, text) {
const response = await sendSMS(to, from, text);
tracker.set(response.data.data.id, {
to, from, text,
status: 'queued',
sentAt: new Date()
});
return response;
}
app.post('/webhooks/telnyx', (req, res) => {
const event = req.body.data;
if (event.event_type === 'message.delivered') {
const msg = tracker.get(event.payload.id);
if (msg) msg.status = 'delivered';
}
res.status(200).send('OK');
});
Pattern: Idempotent Webhook Processing
const processedEvents = new Set();
async function processWebhook(event) {
if (processedEvents.has(event.id)) {
return;
}
processedEvents.add(event.id);
}
Pattern: Format to E.164
function formatToE164(number, defaultCountryCode = '1') {
let digits = number.replace(/\D/g, '');
if (!digits.startsWith(defaultCountryCode)) {
digits = defaultCountryCode + digits;
}
return '+' + digits;
}
formatToE164('415-555-2671');
formatToE164('(415) 555-2671');
Support and Troubleshooting
Getting Help
- Check
error-codes.md for specific error messages
- Review
best-practices.md for common patterns
- Visit https://status.telnyx.com/ for service status
- Contact support through Mission Control Portal
Common Issues
- 401 Unauthorized: Check API key format (
Bearer YOUR_API_KEY)
- 10001 Invalid phone number: Ensure E.164 format (
+14155552671)
- 429 Rate limit: Implement rate limiting (Quick Reference #6)
- Webhooks not received: Verify URL is publicly accessible with valid SSL
Debugging Tips
axios.interceptors.request.use(request => {
console.log('Request:', request.url, request.data);
return request;
});
axios.interceptors.response.use(
response => {
console.log('Response:', response.status, response.data);
return response;
},
error => {
console.error('Error:', error.response?.data);
return Promise.reject(error);
}
);