Skip to content

Latest commit

 

History

History
303 lines (239 loc) · 6.66 KB

File metadata and controls

303 lines (239 loc) · 6.66 KB

Errors

The Texting Blue API uses conventional HTTP status codes to indicate the success or failure of a request. Codes in the 2xx range indicate success. Codes in the 4xx range indicate a client error. Codes in the 5xx range indicate a server error.

Error Response Format

All error responses follow the same JSON structure:

{
  "error": {
    "code": "invalid_request",
    "message": "The 'to' field must be a valid E.164 phone number.",
    "param": "to"
  }
}
Field Type Description
code string A machine-readable error code.
message string A human-readable description of the error.
param string or null The request parameter that caused the error, if applicable.

Error Codes

HTTP Status Code Description
400 invalid_request Malformed request or invalid parameters.
401 unauthorized Missing or invalid API key.
402 plan_limit_exceeded Monthly message limit reached. Upgrade your plan.
403 forbidden Insufficient permissions for this action.
404 not_found The requested resource does not exist.
409 conflict The resource already exists (e.g., duplicate webhook URL).
429 rate_limited Too many requests. Check the Retry-After header.
500 internal_error An unexpected server error occurred.

Common Error Scenarios

400 -- Invalid Request

Returned when the request body is malformed or a parameter has an invalid value.

Invalid phone number format:

{
  "error": {
    "code": "invalid_request",
    "message": "The 'to' field must be a valid E.164 phone number.",
    "param": "to"
  }
}

Missing required field:

{
  "error": {
    "code": "invalid_request",
    "message": "The 'content' field is required.",
    "param": "content"
  }
}

Content exceeds maximum length:

{
  "error": {
    "code": "invalid_request",
    "message": "The 'content' field must not exceed 5000 characters.",
    "param": "content"
  }
}

Invalid media URL:

{
  "error": {
    "code": "invalid_request",
    "message": "The 'media_url' field must be a valid HTTPS URL.",
    "param": "media_url"
  }
}

401 -- Unauthorized

Returned when the x-api-key header is missing, the key is invalid, or the key has been revoked.

{
  "error": {
    "code": "unauthorized",
    "message": "Invalid or missing API key."
  }
}

402 -- Plan Limit Exceeded

Returned when you have reached your plan's monthly message limit.

{
  "error": {
    "code": "plan_limit_exceeded",
    "message": "You have reached your monthly limit of 1,000 messages. Upgrade your plan to send more."
  }
}

403 -- Forbidden

Returned when your API key does not have the required permission for the endpoint.

{
  "error": {
    "code": "forbidden",
    "message": "Your API key does not have the 'messages:send' permission.",
    "param": null
  }
}

404 -- Not Found

Returned when the requested resource does not exist.

{
  "error": {
    "code": "not_found",
    "message": "Message 'msg_xxxxxxxxxxxx' not found."
  }
}

409 -- Conflict

Returned when a resource already exists and cannot be duplicated.

{
  "error": {
    "code": "conflict",
    "message": "A webhook with the URL 'https://example.com/webhook' already exists."
  }
}

429 -- Rate Limited

Returned when you have exceeded the rate limit for your plan. The response includes a Retry-After header with the number of seconds to wait.

{
  "error": {
    "code": "rate_limited",
    "message": "Too many requests. Please retry after 12 seconds."
  }
}

Response headers:

Retry-After: 12

500 -- Internal Error

Returned when an unexpected server error occurs. If you consistently receive this error, contact support.

{
  "error": {
    "code": "internal_error",
    "message": "An unexpected error occurred. Please try again later."
  }
}

Handling Errors

cURL

response=$(curl -s -w "\n%{http_code}" -X POST https://api.texting.blue/v1/messages/send \
  -H "x-api-key: tb_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6" \
  -H "Content-Type: application/json" \
  -d '{ "to": "invalid", "from": "+14155559876", "content": "Hello" }')

http_code=$(echo "$response" | tail -1)
body=$(echo "$response" | sed '$d')

if [ "$http_code" -ge 400 ]; then
  echo "Error ($http_code): $body"
fi

Node.js

const response = await fetch("https://api.texting.blue/v1/messages/send", {
  method: "POST",
  headers: {
    "x-api-key": "tb_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    to: "+14155551234",
    from: "+14155559876",
    content: "Hello!",
  }),
});

if (!response.ok) {
  const { error } = await response.json();
  console.error(`Error ${response.status}: [${error.code}] ${error.message}`);

  if (response.status === 429) {
    const retryAfter = response.headers.get("Retry-After");
    console.log(`Retry after ${retryAfter} seconds`);
  }

  return;
}

const message = await response.json();

Python

import requests

response = requests.post(
    "https://api.texting.blue/v1/messages/send",
    headers={
        "x-api-key": "tb_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6",
        "Content-Type": "application/json",
    },
    json={
        "to": "+14155551234",
        "from": "+14155559876",
        "content": "Hello!",
    },
)

if not response.ok:
    error = response.json()["error"]
    print(f"Error {response.status_code}: [{error['code']}] {error['message']}")

    if response.status_code == 429:
        retry_after = response.headers.get("Retry-After")
        print(f"Retry after {retry_after} seconds")
else:
    message = response.json()

PHP

$ch = curl_init("https://api.texting.blue/v1/messages/send");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    "x-api-key: tb_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6",
    "Content-Type: application/json",
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
    "to" => "+14155551234",
    "from" => "+14155559876",
    "content" => "Hello!",
]));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$body = substr($response, $headerSize);
curl_close($ch);

if ($httpCode >= 400) {
    $error = json_decode($body, true)["error"];
    echo "Error {$httpCode}: [{$error['code']}] {$error['message']}\n";
} else {
    $message = json_decode($body, true);
}