The Trackly SMS API uses standard HTTP status codes and returns detailed error information in the response body.
All errors follow this format:
{
"error": "Human-readable error message",
"code": "machine_readable_code"
}
HTTP Status Codes
| Status | Meaning |
|---|
200 | Success |
201 | Created (for POST requests) |
400 | Bad Request - Invalid parameters |
401 | Unauthorized - Invalid or missing API key |
404 | Not Found - Resource doesn’t exist |
429 | Too Many Requests - Rate limit exceeded |
500 | Internal Server Error - Something went wrong |
Authentication Errors (401)
| Code | Message | Solution |
|---|
missing_api_key | API key required | Include X-Api-Key header |
invalid_api_key | Invalid API key | Check your API key is correct and active |
{
"error": "API key required",
"code": "missing_api_key"
}
Validation Errors (400)
Message Endpoints
| Code | Message | Solution |
|---|
missing_to | Recipient phone number (to) is required | Provide the to field |
missing_body | Message body is required | Provide the body field |
missing_from | Sending number ID (from_phone_number_id) is required | Provide from_phone_number_id |
invalid_phone | Invalid phone number format | Use E.164 format (+1…) |
too_many_messages | Maximum 1000 messages per request | Split into smaller batches |
missing_messages | Messages array is required | Provide the messages array |
Example: Missing Field
{
"error": "Recipient phone number (to) is required",
"code": "missing_to"
}
Example: Invalid Phone
{
"error": "Invalid phone number format",
"code": "invalid_phone"
}
Resource Errors (404)
| Code | Message | Solution |
|---|
list_not_found | Sending number not found | Verify the from_phone_number_id exists and is active |
{
"error": "Sending number not found",
"code": "list_not_found"
}
Handling Errors
Python Example
import requests
response = requests.post(
"https://app.tracklysms.com/api/v1/messages",
headers={"X-Api-Key": "your_key", "Content-Type": "application/json"},
json={"to": "+14155551234", "body": "Hello", "from_phone_number_id": "pn_123"}
)
if response.status_code == 201:
result = response.json()
print(f"Message queued: {result['message_id']}")
elif response.status_code == 401:
print("Authentication failed - check your API key")
elif response.status_code == 400:
error = response.json()
print(f"Validation error: {error['error']} (code: {error['code']})")
elif response.status_code == 404:
print("Resource not found - check your from_phone_number_id")
else:
print(f"Unexpected error: {response.status_code}")
JavaScript Example
try {
const response = await axios.post(
'https://app.tracklysms.com/api/v1/messages',
{ to: '+14155551234', body: 'Hello', from_phone_number_id: 'pn_123' },
{ headers: { 'X-Api-Key': 'your_key' } }
);
console.log('Message queued:', response.data.message_id);
} catch (error) {
if (error.response) {
const { status, data } = error.response;
switch (status) {
case 401:
console.error('Authentication failed');
break;
case 400:
console.error(`Validation error: ${data.error}`);
break;
case 404:
console.error('Resource not found');
break;
default:
console.error(`Error ${status}: ${data.error}`);
}
}
}
All v1 API responses include deprecation headers:
X-API-Deprecated: v1 is deprecated
Deprecation: true
These headers indicate the API version is deprecated. Watch for announcements about the v2 API.
Rate Limiting
If you exceed rate limits, you’ll receive a 429 response:
{
"error": "Rate limit exceeded",
"code": "rate_limit"
}
Implement exponential backoff when you receive a 429 response. Wait and retry with increasing delays.
Getting Help
If you encounter persistent errors: