error.code and a human-readable error.message. Use the error.code field in your error handling logic, not the HTTP status code alone.
Error Response Format
Every error response follows this structure:{
"error": {
"code": "validation_error",
"message": "One or more request parameters are invalid.",
"details": [
{
"field": "experience_min",
"issue": "must be a positive integer"
}
]
}
}
HTTP Status Codes
| Code | Name | When it occurs |
|---|---|---|
200 | OK | Request completed successfully |
201 | Created | POST request succeeded (job or webhook created) |
400 | Bad Request | Missing required parameter or invalid format |
401 | Unauthorized | Missing or invalid API key |
403 | Forbidden | Plan does not include this endpoint |
404 | Not Found | Candidate or job ID does not exist |
409 | Conflict | Resource already exists (e.g., duplicate webhook URL) |
422 | Unprocessable | Request valid but business rule violated |
429 | Too Many Requests | Slow down and retry after the Retry-After header |
500 | Internal Server Error | Cutshort internal error; retry after a short delay |
Error Codes
error.code | Description | Action |
|---|---|---|
validation_error | One or more parameters invalid | Check details array for field-level issues |
authentication_error | Invalid or missing API key | Verify your Authorization header |
authorization_error | Valid key, insufficient access | Check your plan includes this feature |
not_found | Resource does not exist | Verify the ID is correct |
rate_limit_exceeded | Too many requests | Wait for Retry-After seconds, then retry |
invite_limit_exceeded | Daily invite quota reached | Wait until next day or contact support |
job_closed | Action on a closed job | Reopen the job or use a different job ID |
server_error | Unexpected server error | Retry with exponential backoff |
Handling Errors in Code
import requests, time
def api_call_with_retry(url, headers, params, max_retries=3):
for attempt in range(max_retries):
response = requests.get(url, headers=headers, params=params)
if response.status_code == 200:
return response.json()
elif response.status_code == 429:
retry_after = int(response.headers.get('Retry-After', 60))
print(f"Rate limited. Waiting {retry_after}s...")
time.sleep(retry_after)
elif response.status_code == 401:
raise ValueError("Invalid API key")
else:
error = response.json().get('error', {})
raise Exception(f"{error.get('code')}: {error.get('message')}")
raise Exception("Max retries exceeded")
async function apiCallWithRetry(url, headers, params, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
const queryString = new URLSearchParams(params).toString();
const response = await fetch(`${url}?${queryString}`, { headers });
if (response.ok) return response.json();
if (response.status === 429) {
const retryAfter = parseInt(response.headers.get('Retry-After') || '60');
await new Promise(r => setTimeout(r, retryAfter * 1000));
} else {
const { error } = await response.json();
throw new Error(`${error.code}: ${error.message}`);
}
}
throw new Error('Max retries exceeded');
}