Error Handling
Understanding and handling API errors
The telco.dev API uses conventional HTTP response codes and returns detailed error messages to help you handle issues gracefully.
HTTP Status Codes
| Code | Meaning |
|---|---|
200 | Success - Request completed successfully |
400 | Bad Request - Invalid parameters or missing required fields |
401 | Unauthorized - Missing or invalid API key |
404 | Not Found - Resource doesn't exist |
429 | Too Many Requests - Rate limit exceeded |
500 | Internal Server Error - Something went wrong on our end |
Error Response Format
All errors return a JSON object with the following structure:
{
"error": "error_code",
"message": "Human-readable description of the error",
"details": {
// Optional additional information
}
}
Fields
| Field | Type | Description |
|---|---|---|
error | string | Machine-readable error code |
message | string | Human-readable error description |
details | object | Optional additional context (varies by error type) |
Error Codes
Authentication Errors (401)
unauthorized
Missing API key:
{
"error": "unauthorized",
"message": "API key required. Pass via X-API-Key header or api_key query param."
}
Invalid API key:
{
"error": "unauthorized",
"message": "Invalid API key"
}
Validation Errors (400)
invalid_request
Missing required parameter:
{
"error": "invalid_request",
"message": "Missing required parameter 'tn' (10-digit telephone number). Usage: /v1/lookup?tn=XXXXXXXXXX"
}
Invalid parameter format:
{
"error": "invalid_request",
"message": "Invalid 'tn' parameter: '415555'. Must be exactly 10 digits."
}
Not Found Errors (404)
not_found
Resource not found:
{
"error": "not_found",
"message": "No data found for NPA-NXX 415-555"
}
Endpoint not found:
{
"error": "not_found",
"message": "Endpoint not found: /v1/invalid"
}
Rate Limit Errors (429)
rate_limited
Per-minute limit exceeded:
{
"error": "rate_limited",
"message": "Per-minute rate limit exceeded. Limit: 6/minute. Resets in 45 seconds.",
"details": {
"limit_type": "minute",
"limit": 6,
"remaining": 0,
"reset": 1705363260
}
}
Daily limit exceeded:
{
"error": "rate_limited",
"message": "Daily rate limit exceeded. Limit: 100/day. Resets at 2025-01-16T00:00:00.000Z",
"details": {
"limit_type": "daily",
"limit": 100,
"remaining": 0,
"reset": 1705449600
}
}
Server Errors (500)
internal_error
{
"error": "internal_error",
"message": "An unexpected error occurred"
}
Handling Errors
JavaScript Example
async function lookupNumber(tn) {
const response = await fetch(
`https://api.telco.dev/v1/lookup/${tn}`,
{
headers: { "X-API-Key": process.env.TELCO_API_KEY }
}
);
const data = await response.json();
if (!response.ok) {
switch (response.status) {
case 400:
throw new Error(`Invalid request: ${data.message}`);
case 401:
throw new Error("Invalid or missing API key");
case 404:
return null; // Number not found
case 429:
// Handle rate limiting
const resetTime = data.details?.reset || Date.now() + 60000;
const waitMs = resetTime * 1000 - Date.now();
console.log(`Rate limited. Waiting ${waitMs}ms...`);
await new Promise(r => setTimeout(r, waitMs));
return lookupNumber(tn); // Retry
case 500:
throw new Error("Server error. Please try again later.");
default:
throw new Error(`API error: ${data.message}`);
}
}
return data;
}
Python Example
import requests
import time
import os
class TelcoAPIError(Exception):
def __init__(self, status_code, error_code, message, details=None):
self.status_code = status_code
self.error_code = error_code
self.message = message
self.details = details or {}
super().__init__(f"{error_code}: {message}")
def lookup_number(tn, max_retries=3):
for attempt in range(max_retries):
response = requests.get(
f"https://api.telco.dev/v1/lookup/{tn}",
headers={"X-API-Key": os.environ["TELCO_API_KEY"]}
)
if response.ok:
return response.json()
data = response.json()
if response.status_code == 404:
return None # Number not found
if response.status_code == 429:
# Rate limited - wait and retry
reset_time = data.get("details", {}).get("reset", time.time() + 60)
wait_time = max(0, reset_time - time.time())
print(f"Rate limited. Waiting {wait_time:.0f}s...")
time.sleep(wait_time)
continue
raise TelcoAPIError(
response.status_code,
data.get("error"),
data.get("message"),
data.get("details")
)
raise Exception("Max retries exceeded")
Best Practices
- Always check response status before processing data
- Handle 404s gracefully - not all numbers are in the database
- Implement retry logic for rate limits and server errors
- Use exponential backoff for retries to avoid overwhelming the API
- Log errors with full context for debugging
- Display user-friendly messages based on error codes