Error handling
HTTP error codes
| Code | Meaning | Common cause | Recommended action |
|---|---|---|---|
| 400 | Bad Request | Missing required field medical_note or invalid request format | Ensure medical_note field is provided (required) |
| 401 | Unauthorized | Invalid or expired token | Verify your Bearer token and that it’s active |
| 413 | Payload Too Large | medical_note exceeds 50KB or pdf_file exceeds 5MB decoded | Reduce input size or split content |
| 422 | Unprocessable Entity | Invalid PDF structure, malformed base64 data, invalid mime_type | Validate PDF file structure and encoding |
| 429 | Too Many Requests | Rate limit exceeded | Wait and retry with exponential backoff |
| 500 | Internal Server Error | Unexpected server error, database issues, misconfiguration | Retry with exponential backoff; if persists, report run_id |
| 503 | Service Unavailable | AI service temporarily unavailable | Retry after a few seconds |
| 504 | Gateway Timeout | Request exceeded 10-minute processing time limit | Reduce input size or split content |
Error response format
All errors follow this consistent structure:{
"success": false,
"error": "Bad Request",
"details": "medical_note is required"
}
Error fields
| Field | Description |
|---|---|
success | Always false for error responses |
error | Error name/type (e.g., “Bad Request”, “Unauthorized”) |
details | Detailed error message explaining what went wrong |
Retry strategy
When to retry?
Yes, retry:- 5xx errors (500, 502, 503, 504)
- 429 error (Too Many Requests)
- Network/timeout errors
- 4xx errors except 429 (client errors)
- 401 error (invalid token)
- 422 error (invalid schema)
Exponential backoff
Attempt 1: immediate
Attempt 2: wait 1 second
Attempt 3: wait 2 seconds
Attempt 4: wait 4 seconds
Attempt 5: wait 8 seconds
...
Implementation
import time
import requests
from requests.exceptions import RequestException
def codify_with_retry(payload, max_retries=3):
"""Call Codify API with exponential retries"""
url = "https://{your-endpoint}/v1/codify"
headers = {
"Authorization": "Bearer YOUR_TOKEN",
"Content-Type": "application/json"
}
for attempt in range(max_retries):
try:
response = requests.post(
url=url,
json=payload,
headers=headers,
timeout=600 # 10-minute timeout for Codify
)
# If 429 or 5xx, retry
if response.status_code in [429, 500, 502, 503, 504]:
if attempt < max_retries - 1:
wait_time = 2 ** attempt
print(f"Retrying in {wait_time}s...")
time.sleep(wait_time)
continue
# For other errors, raise exception
response.raise_for_status()
return response.json()
except RequestException as e:
if attempt < max_retries - 1:
wait_time = 2 ** attempt
print(f"Network error, retrying in {wait_time}s...")
time.sleep(wait_time)
else:
raise
raise Exception("Maximum retries reached")
# Usage
try:
result = codify_with_retry({
"medical_note": "Patient with Type 2 Diabetes...",
"model": "balanced"
})
print(f"Success! Codes: {len(result['final_code_assessments'])}")
except Exception as e:
print(f"Error: {e}")
async function codifyWithRetry(payload, maxRetries = 3) {
const url = 'https://{your-endpoint}/v1/codify';
const headers = {
'Authorization': 'Bearer YOUR_TOKEN',
'Content-Type': 'application/json'
};
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
const response = await axios.post(url, payload, {
headers,
timeout: 600000 // 10-minute timeout for Codify
});
return response.data;
} catch (error) {
const status = error.response?.status;
// Retry on 429 and 5xx
if ([429, 500, 502, 503, 504].includes(status)) {
if (attempt < maxRetries - 1) {
const waitTime = Math.pow(2, attempt) * 1000;
console.log(`Retrying in ${waitTime/1000}s...`);
await new Promise(resolve => setTimeout(resolve, waitTime));
continue;
}
}
// For other errors, throw
throw error;
}
}
throw new Error('Maximum retries reached');
}
// Usage
try {
const result = await codifyWithRetry({
medical_note: 'Patient with Type 2 Diabetes...',
model: 'balanced'
});
console.log(`Success! Codes: ${result.final_code_assessments.length}`);
} catch (error) {
console.error('Error:', error.response?.data || error.message);
}
Tracking and auditing
Using run_id for debugging
Every response includes a uniquerun_id that you should store for tracking and debugging:
def save_codification_result(patient_id, result):
"""Save codification result with run_id for tracking"""
database.insert({
'patient_id': patient_id,
'run_id': result['run_id'],
'codes': result['final_code_assessments'],
'discarded_codes': result['discarded_code_assessments'],
'timestamp': datetime.now(),
'processed': True
})
print(f"✅ Saved codification (run_id: {result['run_id']})")
return result['run_id']
# Usage
result = codify_with_retry({"medical_note": "..."})
run_id = save_codification_result("pt_456", result)
Deduplication by content hash
To avoid processing the same note multiple times, use content hashing:import hashlib
import json
def get_content_hash(medical_note):
"""Generate hash of medical note content"""
return hashlib.sha256(medical_note.encode()).hexdigest()
def codify_with_deduplication(medical_note):
"""Process note only if not already processed"""
content_hash = get_content_hash(medical_note)
# Check if already processed
existing = database.query(
"SELECT * FROM codifications WHERE content_hash = ?",
content_hash
)
if existing:
print(f"✅ Already processed (run_id: {existing['run_id']})")
return existing['result']
# Process new note
result = codify_with_retry({"medical_note": medical_note})
# Save with hash
database.insert({
'content_hash': content_hash,
'run_id': result['run_id'],
'result': json.dumps(result),
'processed_at': datetime.now()
})
return result
Optional tracking headers
Use thedoctor and patient headers to enhance audit trails:
def codify_with_tracking(medical_note, doctor_id, patient_id):
"""Codify with complete tracking information"""
url = "https://{your-endpoint}/v1/codify"
headers = {
"Authorization": "Bearer YOUR_TOKEN",
"Content-Type": "application/json",
"x-doctor": doctor_id,
"x-patient": patient_id
}
payload = {"medical_note": medical_note}
response = requests.post(url, json=payload, headers=headers)
result = response.json()
# Log with full context
logger.info(f"Codified note for patient {patient_id} by doctor {doctor_id}, run_id: {result['run_id']}")
return result
Next steps
Quick start
Your first call
Request Structure
Complete field reference
Examples
Real use cases
OpenAPI Reference
Complete specification