Error Handling
The Annie Insights API uses standard HTTP status codes and returns structured JSON error responses.
Error Response Format​
{
"error": "Error Type",
"message": "Human-readable description",
"statusCode": 400
}
HTTP Status Codes​
| Code | Status | Description | Common Cause |
|---|---|---|---|
| 400 | Bad Request | Invalid request body or missing required parameters | Missing PatientID, TimeStamp, or ImageName |
| 401 | Unauthorized | Invalid or missing API key | Wrong x-api-key header value |
| 422 | Unprocessable Entity | Image could not be processed | Corrupted image, unsupported format, or non-dental content |
| 429 | Too Many Requests | Rate limit exceeded | Too many requests in the current window |
| 500 | Internal Server Error | Unexpected server failure | Contact support if persistent |
Handling Errors​
401 — Unauthorized​
{
"error": "Unauthorized",
"message": "Invalid or missing API key",
"statusCode": 401
}
Fix: Verify your x-api-key header is present and contains a valid key.
429 — Rate Limited​
{
"error": "Too Many Requests",
"message": "Rate limit exceeded. Retry after 60 seconds.",
"statusCode": 429
}
Fix: Implement exponential backoff. Check the Retry-After header for the wait duration.
422 — Unprocessable Entity​
{
"error": "Unprocessable Entity",
"message": "The provided image could not be analyzed",
"statusCode": 422
}
Fix: Ensure the image is a valid JPEG/PNG dental image with sufficient resolution.
Retry Strategy​
For transient errors (429, 500), implement exponential backoff:
import time
import requests
def call_api_with_retry(url, headers, body, max_retries=3):
for attempt in range(max_retries):
response = requests.post(url, json=body, headers=headers)
if response.status_code == 200:
return response.json()
if response.status_code in [429, 500]:
wait = 2 ** attempt # 1s, 2s, 4s
time.sleep(wait)
continue
response.raise_for_status()
raise Exception("Max retries exceeded")