Error Codes
All API errors follow a consistent JSON format with an HTTP status code, error code, and human-readable message.
Error response format
{
"error": {
"code": "invalid_request",
"message": "The 'to' field must be a valid E.164 phone number",
"param": "to"
}
}
| Field | Type | Description |
|---|---|---|
code | string | Machine-readable error code |
message | string | Human-readable description |
param | string | The request parameter that caused the error (when applicable) |
Error codes reference
| HTTP Status | Code | Description | Resolution |
|---|---|---|---|
| 400 | invalid_request | Malformed request or invalid parameters | Check request body and parameters. Phone numbers must be E.164 format. |
| 401 | unauthorized | Missing or invalid API key | Verify your API key is correct and included in the x-api-key header. |
| 402 | plan_limit_exceeded | Monthly message limit or resource limit reached | Upgrade your plan at app.texting.blue/billing. |
| 403 | forbidden | Valid API key but insufficient permissions | Create a new API key with the required permissions. |
| 404 | not_found | Resource not found | Check the resource ID. It may have been deleted. |
| 409 | conflict | Resource already exists | A resource with the same identifier already exists (e.g., duplicate phone number). |
| 429 | rate_limited | Too many requests | Wait and retry. See the Retry-After header for how long to wait. |
| 500 | internal_error | Server error | Retry the request. If the problem persists, contact support. |
Common error scenarios
Invalid phone number
{
"error": {
"code": "invalid_request",
"message": "The 'to' field must be a valid E.164 phone number",
"param": "to"
}
}
Fix: Use E.164 format: + followed by country code and number (e.g., +14155551234).
From number not registered
{
"error": {
"code": "invalid_request",
"message": "The \"from\" number is not registered or verified for this team",
"param": "from"
}
}
Fix: The from number must be a connected, verified number on your account. Check your numbers list.
From number paused
{
"error": {
"code": "invalid_request",
"message": "The \"from\" number is currently paused",
"param": "from"
}
}
Fix: Resume the number via the API (PUT /v1/numbers/:id with {"status": "active"}) or in the dashboard.
Plan limit exceeded
{
"error": {
"code": "plan_limit_exceeded",
"message": "Monthly message limit reached (1000/1000). Upgrade your plan.",
"limit": 1000,
"current": 1000,
"upgrade_url": "https://app.texting.blue/billing"
}
}
Fix: Upgrade your plan or wait for the next billing cycle.
Rate limited
{
"error": {
"code": "rate_limited",
"message": "Rate limit exceeded. Retry after 15 seconds."
}
}
Fix: Wait for the duration specified in the Retry-After header, then retry. Implement exponential backoff in your code.
Handling errors in code
const response = await fetch('https://api.texting.blue/v1/messages/send', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': API_KEY,
},
body: JSON.stringify({ to, from, content }),
});
if (!response.ok) {
const { error } = await response.json();
switch (error.code) {
case 'rate_limited':
const retryAfter = response.headers.get('Retry-After');
// Wait and retry
break;
case 'plan_limit_exceeded':
// Notify user to upgrade
break;
case 'unauthorized':
// Check API key
break;
default:
console.error(`API error: ${error.code} - ${error.message}`);
}
}
Next steps
- Rate limits -- Understand request limits per plan
- Authentication -- API key setup