Skip to main content

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"
}
}
FieldTypeDescription
codestringMachine-readable error code
messagestringHuman-readable description
paramstringThe request parameter that caused the error (when applicable)

Error codes reference

HTTP StatusCodeDescriptionResolution
400invalid_requestMalformed request or invalid parametersCheck request body and parameters. Phone numbers must be E.164 format.
401unauthorizedMissing or invalid API keyVerify your API key is correct and included in the x-api-key header.
402plan_limit_exceededMonthly message limit or resource limit reachedUpgrade your plan at app.texting.blue/billing.
403forbiddenValid API key but insufficient permissionsCreate a new API key with the required permissions.
404not_foundResource not foundCheck the resource ID. It may have been deleted.
409conflictResource already existsA resource with the same identifier already exists (e.g., duplicate phone number).
429rate_limitedToo many requestsWait and retry. See the Retry-After header for how long to wait.
500internal_errorServer errorRetry 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