Error Handling
Understand the error response format and common error codes.
The ErzyCall REST API uses standard HTTP status codes and returns errors in a consistent JSON envelope.
All error responses follow this format:
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid query parameters",
"details": [
{
"field": "phone",
"message": "Must be E.164 format (e.g., +14155551234)"
}
]
}
}
| Field | Type | Description |
|---|
code | string | Machine-readable error code (use this for programmatic handling) |
message | string | Human-readable description |
details | array | Optional — field-level validation errors |
| Status | Meaning |
|---|
200 | OK — request succeeded |
201 | Created — resource was created |
204 | No Content — deletion succeeded (no body) |
| Status | Meaning |
|---|
400 | Bad Request — malformed JSON or invalid parameters |
401 | Unauthorized — missing, invalid, expired, or revoked API key |
403 | Forbidden — API key lacks required scope |
404 | Not Found — resource doesn't exist or belongs to another organization |
409 | Conflict — duplicate resource or idempotency key mismatch |
422 | Unprocessable Entity — request is valid but cannot be fulfilled |
429 | Too Many Requests — rate limit exceeded |
| Status | Meaning |
|---|
500 | Internal Server Error — unexpected failure |
| Code | Status | Description |
|---|
UNAUTHORIZED | 401 | Missing or invalid API key |
KEY_REVOKED | 401 | API key has been revoked |
KEY_EXPIRED | 401 | API key has expired |
INSUFFICIENT_SCOPE | 403 | Key lacks required scope for this endpoint |
VALIDATION_ERROR | 400 | Request body or query params failed validation |
INVALID_JSON | 400 | Request body is not valid JSON |
INVALID_ID | 400 | Missing or malformed resource ID |
NOT_FOUND | 404 | Resource not found (or belongs to another org) |
CONFLICT | 409 | Duplicate resource (e.g., contact with same phone) |
IDEMPOTENCY_MISMATCH | 409 | Idempotency key reused with different request body |
INVALID_STATE | 422 | Operation not allowed in current state (e.g., cancelling a finished call) |
INVALID_PHONE | 422 | Phone number not assigned to your organization |
MAX_ENDPOINTS | 422 | Maximum 5 webhook endpoints per organization |
RATE_LIMITED | 429 | Rate limit exceeded |
INTERNAL_ERROR | 500 | Unexpected server error |
For POST requests, you can include an Idempotency-Key header to safely retry requests without creating duplicate resources.
curl -X POST "https://app.erzycall.com/api/v1/calls" \
-H "X-API-Key: ek_live_abc123" \
-H "Idempotency-Key: unique-request-id-12345" \
-H "Content-Type: application/json" \
-d '{"to": "+14155551234", "from": "+14155559999"}'
- The first request creates the resource and caches the response.
- Subsequent requests with the same
Idempotency-Key, method, and path return the cached response.
- If you reuse the key with a different request body, the API returns a
409 IDEMPOTENCY_MISMATCH error.
- Always check the
error.code field for programmatic error handling, not the HTTP status alone.
- Handle 429 errors with backoff and retry logic. See Rate Limiting.
- Use idempotency keys for all POST requests to safely handle network retries.
- Log error responses including the full error envelope for debugging.