The Neuratel API returns a consistent error format across all endpoints, designed for programmatic handling and debugging.
Error Response Format
Every error response follows this structure:
{
"error": {
"type": "authentication_error",
"code": "AUTH_1001",
"message": "Invalid API key",
"request_id": "req_abc123"
}
}
| Field | Type | Description |
|---|
type | string | Error category for programmatic handling |
code | string | Unique error code for precise identification |
message | string | Human-readable explanation |
details | object | Optional — additional context (e.g. which field failed validation) |
request_id | string | Unique ID for this request — include when contacting support |
Error Types
| Type | HTTP Status | Description |
|---|
authentication_error | 401, 403 | Authentication or authorization failures |
validation_error | 400, 422 | Invalid request body or query parameters |
not_found_error | 404 | Requested resource does not exist |
conflict_error | 409 | Resource conflict (duplicate, version mismatch) |
rate_limit_error | 429 | Too many requests |
external_service_error | 502 | An upstream provider returned an error |
internal_error | 500 | Unexpected server error |
Error Code Reference
AUTH_1xxx — Authentication and Authorization
| Code | Message | Resolution |
|---|
AUTH_1001 | Invalid API key | Check the key is correct and not revoked. Keys start with nk_live_ |
AUTH_1002 | API key expired | Rotate the key via Settings → API Keys in the dashboard |
AUTH_1003 | Insufficient permissions | The key lacks the required scope. Create a new key with the correct scopes from Settings → API Keys |
AUTH_1004 | Token expired | Re-authenticate. Session tokens expire after the configured TTL |
AUTH_1005 | Permission denied | Your role does not allow this action. Contact your organization admin |
Example:
{
"error": {
"type": "authentication_error",
"code": "AUTH_1001",
"message": "Invalid API key",
"request_id": "req_abc123"
}
}
NOT_FOUND_2xxx — Resource Not Found
| Code | Message | Resolution |
|---|
NOT_FOUND_2001 | Resource not found | Verify the resource ID is correct |
NOT_FOUND_2002 | Resource not found | Verify the resource ID is correct |
NOT_FOUND_2003 | Agent not found | Verify the agent_id. List agents: GET /v1/agents |
NOT_FOUND_2004 | Organization not found | The organization ID in the token does not match any organization |
NOT_FOUND_2005 | Phone number not found | Verify the number_id. List numbers: GET /v1/numbers |
NOT_FOUND_2006 | Call list not found | Verify the call_list_id |
VALIDATION_3xxx — Request Validation
| Code | Message | Resolution |
|---|
VALIDATION_3001 | Invalid input | The request body contains invalid values. Check details for specifics |
VALIDATION_3002 | Invalid UUID | The provided ID is not a valid UUID |
VALIDATION_3003 | Invalid email address | Provide a valid email |
VALIDATION_3004 | Invalid phone number | Use E.164 format: + followed by country code and number |
VALIDATION_3005 | Missing required field | Include all required fields. Check details.field for which one |
VALIDATION_3006 | Invalid file type | Check accepted file types for the endpoint |
VALIDATION_3007 | File too large | Reduce file size. Knowledge base: 21MB max. Contact CSV: 10MB max |
Example with details:
{
"error": {
"type": "validation_error",
"code": "VALIDATION_3005",
"message": "Missing required field",
"details": {
"field": "agent_id",
"reason": "required"
},
"request_id": "req_def456"
}
}
CONFLICT_4xxx — Conflict
| Code | Message | Resolution |
|---|
CONFLICT_4001 | Resource already exists | A resource with this identifier already exists |
CONFLICT_4002 | Client already assigned | This client is already assigned to another resource |
CONFLICT_4003 | Duplicate phone number | The phone number is already in use. Unassign it first |
CONFLICT_4004 | Version conflict | Another request modified this resource. Fetch the latest version and retry |
CONFLICT_4005 | Agent name already exists | An agent with this name already exists in your organization |
BUSINESS_5xxx — Business Logic Errors
| Code | Message | Resolution |
|---|
BUSINESS_5001 | Operation failed | The requested operation could not be completed |
BUSINESS_5002 | Agent not deployed | The agent must be deployed before it can handle calls |
BUSINESS_5003 | Insufficient credits | Reach out to your account team to restore service |
BUSINESS_5004 | Rate limit exceeded | Wait and retry with exponential backoff. Check X-RateLimit-Reset header |
BUSINESS_5005 | Workspace creation failed | Contact support if this persists |
Response headers included with 429:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1712505600
EXTERNAL_6xxx — External Service Errors
| Code | Message | Resolution |
|---|
EXTERNAL_6001 | External service error | An upstream provider returned an error. Retry after a brief delay |
EXTERNAL_6002 | Media server error | The Neuratel media server is temporarily unavailable |
EXTERNAL_6003 | Telephony provider error | The telephony provider returned an error. Contact support if this persists |
EXTERNAL_6004 | OpenAI error | OpenAI returned an error. Check your BYOK key or retry |
EXTERNAL_6005 | ElevenLabs error | ElevenLabs returned an error. Check your BYOK key or retry |
EXTERNAL_6006 | Deepgram error | Deepgram returned an error. Check your BYOK key or retry |
EXTERNAL_6007 | Email service error | The email service failed to deliver. Retry or contact support |
INTERNAL_9xxx — Internal Errors
| Code | Message | Resolution |
|---|
INTERNAL_9001 | Unexpected error | An internal error occurred. Retry the request. If persistent, contact support with the request_id |
INTERNAL_9002 | Database error | A database error occurred. Retry the request or contact support |
INTERNAL_9003 | Cache error | A cache error occurred. Retry the request |
INTERNAL_9004 | Configuration error | A server configuration error occurred. Contact support |
HTTP Status Code Summary
| Status | Meaning | When Returned |
|---|
| 200 | OK | Request succeeded |
| 201 | Created | Resource created |
| 204 | No Content | Delete succeeded |
| 400 | Bad Request | Validation error |
| 401 | Unauthorized | Missing or invalid authentication |
| 403 | Forbidden | Insufficient permissions |
| 404 | Not Found | Resource does not exist |
| 409 | Conflict | Resource conflict |
| 422 | Unprocessable Entity | Valid JSON but invalid content |
| 429 | Too Many Requests | Rate limit exceeded |
| 500 | Internal Server Error | Unexpected server error |
| 502 | Bad Gateway | Upstream provider error |
Handling Errors in Code
import httpx
response = client.post("/v1/agents", json=agent_data)
if response.status_code >= 400:
error = response.json()["error"]
if error["code"] == "VALIDATION_3005":
print(f"Missing field: {error['details']['field']}")
elif error["code"] == "AUTH_1003":
print(f"Need scope: {error['message']}")
else:
print(f"Error {error['code']}: {error['message']}")
print(f"Request ID: {error['request_id']}")
const response = await fetch("https://api.neuratel.ai/v1/agents", {
method: "POST",
headers: {
Authorization: "Bearer nk_live_your_api_key",
"Content-Type": "application/json",
},
body: JSON.stringify(agentData),
});
if (!response.ok) {
const { error } = await response.json();
console.error(`[${error.code}] ${error.message} (${error.request_id})`);
}
Next Steps
Last modified on