Error Handling
Understanding API errors and how to handle them
The Verity API uses conventional HTTP response codes and returns consistent error responses to help you handle errors gracefully.
Error Response Format
All error responses follow this structure:
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Human-readable error message",
"hint": "Suggestion for fixing the error",
"details": { ... }
},
"meta": {
"request_id": "req_abc123"
}
}HTTP Status Codes
| Code | Description |
|---|---|
200 | Success |
400 | Bad Request - Invalid parameters |
401 | Unauthorized - Invalid or missing API key |
403 | Forbidden - Valid key but insufficient permissions |
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 Codes
Authentication Errors
| Code | Description |
|---|---|
AUTH_MISSING | No Authorization header provided |
AUTH_INVALID_FORMAT | Authorization header format is incorrect |
AUTH_INVALID_KEY | API key is invalid or not found |
AUTH_REVOKED_KEY | API key has been revoked |
AUTH_SUSPENDED_KEY | API key is suspended |
AUTH_SCOPE_INSUFFICIENT | Key doesn't have required scope |
Validation Errors
| Code | Description |
|---|---|
VALIDATION_ERROR | Generic validation error - check details |
VALIDATION_INVALID_JSON | Request body is not valid JSON |
VALIDATION_MISSING_FIELD | Required field is missing |
VALIDATION_INVALID_TYPE | Field has wrong type |
Resource Errors
| Code | Description |
|---|---|
RESOURCE_NOT_FOUND | Requested resource doesn't exist |
RESOURCE_POLICY_NOT_FOUND | Policy ID not found |
RESOURCE_CODE_NOT_FOUND | Procedure code not found |
Rate Limiting
| Code | Description |
|---|---|
RATE_LIMIT_EXCEEDED | Too many requests |
RATE_LIMIT_MINUTE | Minute-based limit exceeded |
Request Errors
| Code | Description |
|---|---|
REQUEST_INVALID_CURSOR | Pagination cursor is invalid |
REQUEST_MISSING_IDEMPOTENCY | POST request missing idempotency key |
REQUEST_DUPLICATE | Duplicate idempotent request |
Handling Errors
JavaScript Example
async function makeApiRequest(url) {
const response = await fetch(url, {
headers: {
'Authorization': `Bearer ${API_KEY}`
}
});
const data = await response.json();
if (!data.success) {
const { code, message, hint } = data.error;
switch (code) {
case 'AUTH_INVALID_KEY':
// Handle invalid API key
console.error('Invalid API key. Check your credentials.');
break;
case 'RATE_LIMIT_EXCEEDED':
// Implement retry logic
const retryAfter = response.headers.get('Retry-After');
console.log(`Rate limited. Retry after ${retryAfter} seconds.`);
break;
case 'VALIDATION_ERROR':
// Handle validation errors
console.error('Validation error:', data.error.details);
break;
default:
console.error(`Error ${code}: ${message}`);
}
throw new Error(message);
}
return data.data;
}Python Example
import requests
class VerityAPIError(Exception):
def __init__(self, code, message, hint=None):
self.code = code
self.message = message
self.hint = hint
super().__init__(message)
def make_api_request(url, api_key):
response = requests.get(url, headers={'Authorization': f'Bearer {api_key}'})
data = response.json()
if not data.get('success'):
error = data.get('error', {})
raise VerityAPIError(
error.get('code'),
error.get('message'),
error.get('hint')
)
return data['data']Request ID
Every response includes a request_id in the meta object. Include this when contacting support to help us debug issues:
{
"meta": {
"request_id": "req_abc123def456"
}
}Retry Strategy
For transient errors (5xx status codes), implement an exponential backoff retry strategy:
- Wait 1 second, retry
- Wait 2 seconds, retry
- Wait 4 seconds, retry
- Give up after 3 retries
For 429 errors, use the Retry-After header value instead.