Error Handling
The Prepzo API uses consistent error formats across all endpoints. Every response tells you exactly what went wrong and how to fix it.
Response Format
All API responses follow the same structure:
// Success
{
"success": true,
"data": { ... },
"meta": { "total": 50, "limit": 50, "offset": 0, "has_more": false },
"errors": null
}
// Error
{
"success": false,
"data": null,
"meta": null,
"errors": [
{
"code": "not_found",
"message": "Candidate not found",
"field": null
}
]
}HTTP Status Codes
| Code | Meaning |
|---|---|
200 | Success |
201 | Created successfully |
401 | Unauthorized - missing or invalid API key |
403 | Forbidden - API key lacks required scope |
404 | Not found - resource doesn't exist |
409 | Conflict - duplicate resource |
422 | Validation error - missing or invalid fields |
429 | Rate limited - too many requests |
500 | Server error - something went wrong on our end |
Error Codes
| Code | Description |
|---|---|
unauthorized | API key is missing or invalid |
forbidden | Insufficient permissions for this endpoint |
not_found | The requested resource was not found |
duplicate | Resource already exists (unique constraint) |
validation_error | Request body failed validation |
rate_limited | Rate limit exceeded |
server_error | Internal server error |
Validation Errors
Validation errors include a field property pointing to the problematic field:
{
"success": false,
"data": null,
"errors": [
{
"code": "validation_error",
"message": "email is required",
"field": "email"
}
]
}Best Practices
- Always check
success: Don't rely solely on HTTP status codes - Handle 429s gracefully: Implement exponential backoff with the
Retry-Afterheader - Log error codes: The
codefield is stable and safe for programmatic handling - Don't parse messages: The
messagefield is human-readable and may change - Retry 500s: Server errors are typically transient. Retry with backoff.
- Don't retry 4xx: Client errors (except 429) won't succeed on retry without changes