Error Handling
The anyformat API uses conventional HTTP response codes and provides structured error responses to help you build robust integrations.
HTTP Status Codes
| Status Code | Meaning | Description |
|---|
200 | OK | Request succeeded |
201 | Created | Resource was successfully created |
202 | Accepted | Request accepted for processing (async operations) |
204 | No Content | Request succeeded with no response body |
400 | Bad Request | Invalid request data or parameters |
401 | Unauthorized | Missing or invalid API key |
403 | Forbidden | Authenticated but lacking permission |
404 | Not Found | Resource doesn’t exist |
500 | Internal Server Error | Unexpected server error |
All error responses follow a consistent JSON structure:
{
"error": "Brief, human-readable error description",
"detail": "Detailed explanation of what went wrong",
"error_code": "MACHINE_READABLE_ERROR_CODE"
}
| Field | Description |
|---|
error | Short, human-readable summary |
detail | Detailed explanation for debugging |
error_code | Machine-readable code for programmatic handling |
Error Codes Reference
Authentication Errors
AUTH_FAILED (401)
{
"error": "Authentication failed",
"detail": "Invalid or missing authentication credentials.",
"error_code": "AUTH_FAILED"
}
Validation Errors
VALIDATION_ERROR (400)
{
"error": "Validation failed",
"detail": "{'name': ['This field is required.'], 'fields': ['This field is required.']}",
"error_code": "VALIDATION_ERROR"
}
INVALID_JSON (400)
{
"error": "Invalid JSON format",
"detail": "The request body contains invalid JSON. Please check your JSON syntax.",
"error_code": "INVALID_JSON"
}
Resource Errors
NOT_FOUND (404)
{
"error": "Resource not found",
"detail": "The requested resource could not be found.",
"error_code": "NOT_FOUND"
}
Server Errors
INTERNAL_ERROR (500)
{
"error": "Internal server error",
"detail": "An unexpected error occurred while processing your request. Please try again or contact support.",
"error_code": "INTERNAL_ERROR",
"reference_id": "err_1234"
}
Server errors (500) include a reference_id field. Use this ID when contacting support to help identify and resolve the specific issue.
Error Handling Best Practices
1. Check HTTP Status Codes
import requests
response = requests.get(
"https://api.anyformat.ai/workflows/",
headers={"x-api-key": "your-api-key"}
)
if response.status_code == 200:
workflows = response.json()
elif response.status_code == 401:
print("Authentication failed. Check your API key.")
elif response.status_code == 404:
print("Resource not found.")
elif response.status_code >= 500:
print("Server error. Retry with backoff.")
else:
error = response.json()
print(f"Error: {error.get('detail')}")
2. Use Error Codes for Logic
def handle_api_error(response):
if response.status_code >= 400:
error_data = response.json()
error_code = error_data.get('error_code')
if error_code == 'AUTH_FAILED':
refresh_authentication()
elif error_code == 'VALIDATION_ERROR':
show_validation_error(error_data.get('detail'))
elif error_code == 'NOT_FOUND':
handle_missing_resource()
elif error_code == 'INTERNAL_ERROR':
retry_with_backoff()
else:
log_unexpected_error(error_data)
3. Implement Retry Logic
For server errors (5xx), implement exponential backoff:
import time
import random
def api_request_with_retry(url, headers, max_retries=3):
for attempt in range(max_retries + 1):
try:
response = requests.get(url, headers=headers)
# Don't retry client errors (4xx)
if 400 <= response.status_code < 500:
return response
# Retry server errors (5xx)
if response.status_code >= 500 and attempt < max_retries:
delay = (2 ** attempt) + random.uniform(0, 1)
time.sleep(delay)
continue
return response
except requests.exceptions.RequestException as e:
if attempt < max_retries:
delay = (2 ** attempt) + random.uniform(0, 1)
time.sleep(delay)
continue
raise e
4. Validate Before Sending
def create_workflow(name, description, fields):
# Validate required fields locally first
if not name:
raise ValueError("Workflow name is required")
if not fields or len(fields) == 0:
raise ValueError("At least one field is required")
for field in fields:
if not field.get('name'):
raise ValueError("Field name is required")
if not field.get('data_type'):
raise ValueError("Field data_type is required")
# Make API request
response = requests.post(
"https://api.anyformat.ai/workflows/",
headers={"x-api-key": "your-api-key", "Content-Type": "application/json"},
json={"name": name, "description": description, "fields": fields}
)
return handle_response(response)
5. Log Errors for Debugging
import logging
def log_api_error(response, context=""):
try:
error_data = response.json()
error_code = error_data.get('error_code', 'UNKNOWN')
reference_id = error_data.get('reference_id', 'N/A')
logging.error(
f"API Error {response.status_code}: {error_code} - "
f"{error_data.get('detail', 'No detail')} "
f"[Context: {context}] [Reference: {reference_id}]"
)
except ValueError:
logging.error(f"API Error {response.status_code}: {response.text}")
Testing Error Scenarios
When building your integration, test these common scenarios:
| Scenario | How to Test |
|---|
| Missing API key | Omit the x-api-key header |
| Invalid API key | Use a fake or expired key |
| Missing required fields | Create workflow without name or fields |
| Invalid JSON | Send malformed JSON in request body |
| Nonexistent resource | Request a workflow/job ID that doesn’t exist |
| Server errors | Test retry logic (mock 500 responses) |
Framework-Level Errors
While most errors use the structured { "error", "detail", "error_code" } format, some framework-level responses (e.g., unknown URL path) may return a simpler format:{ "detail": "Not found." }