Error Handling
Learn how to handle errors gracefully when integrating with Circuit KYC.
All errors follow a consistent format:
{
"detail": "Error message describing what went wrong",
"error_code": "INVALID_API_KEY",
"request_id": "req_abc123"
}
| Field |
Description |
detail |
Human-readable error message |
error_code |
Machine-readable error code |
request_id |
Unique ID for support requests |
HTTP Status Codes
Client Errors (4xx)
| Status |
Meaning |
Common Causes |
| 400 |
Bad Request |
Invalid JSON, missing fields |
| 401 |
Unauthorized |
Invalid Bearer token |
| 402 |
Payment Required |
Insufficient credits |
| 403 |
Forbidden |
Invalid API key, account disabled |
| 404 |
Not Found |
Resource doesn't exist |
| 422 |
Unprocessable Entity |
Validation failed |
| 429 |
Too Many Requests |
Rate limit exceeded |
Server Errors (5xx)
| Status |
Meaning |
What to Do |
| 500 |
Internal Server Error |
Retry with backoff |
| 502 |
Bad Gateway |
Retry with backoff |
| 503 |
Service Unavailable |
Check status page, retry |
| 504 |
Gateway Timeout |
Retry with backoff |
Error Codes
Authentication Errors
| Code |
Description |
Solution |
MISSING_API_KEY |
No X-API-Key header |
Add API key header |
INVALID_API_KEY |
API key not recognized |
Check key is correct |
EXPIRED_API_KEY |
API key has been revoked |
Generate new key |
ACCOUNT_DISABLED |
Account suspended |
Contact support |
Validation Errors
| Code |
Description |
Solution |
INVALID_EMAIL |
Email format invalid |
Use valid email format |
INVALID_PHONE |
Phone not E.164 format |
Use +[country][number] |
MISSING_FIELD |
Required field not provided |
Check API docs |
INVALID_DATE |
Date format invalid |
Use YYYY-MM-DD |
Rate Limit Errors
| Code |
Description |
Solution |
RATE_LIMITED |
Too many requests |
Wait and retry |
BURST_EXCEEDED |
Burst limit hit |
Spread requests |
Credit Errors
| Code |
Description |
Solution |
INSUFFICIENT_CREDITS |
Not enough credits |
Purchase more credits |
CREDITS_DEPLETED |
Zero credits |
Enable auto-recharge |
Handling Errors in Code
Python
from circuit_kyc import CircuitKYC
from circuit_kyc.exceptions import (
AuthenticationError,
RateLimitError,
InsufficientCreditsError,
ValidationError,
APIError
)
client = CircuitKYC(api_key="sk_live_your_key")
try:
result = client.check_eligibility(
email="user@example.com",
phone_number="+15551234567"
)
except AuthenticationError as e:
# Invalid or missing API key
print(f"Auth failed: {e.message}")
except RateLimitError as e:
# Rate limited - wait and retry
print(f"Rate limited. Retry after {e.retry_after} seconds")
time.sleep(e.retry_after)
except InsufficientCreditsError as e:
# Need more credits
print("Please purchase more credits")
except ValidationError as e:
# Invalid input
print(f"Validation error: {e.message}")
for error in e.errors:
print(f" - {error['field']}: {error['message']}")
except APIError as e:
# Server error - retry with backoff
print(f"API error: {e.message}")
TypeScript
import { CircuitKYC } from '@circuit-kyc/sdk';
import {
AuthenticationError,
RateLimitError,
InsufficientCreditsError,
ValidationError,
APIError
} from '@circuit-kyc/sdk/errors';
const client = new CircuitKYC({ apiKey: 'sk_live_your_key' });
try {
const result = await client.checkEligibility({
email: 'user@example.com',
phoneNumber: '+15551234567'
});
} catch (error) {
if (error instanceof AuthenticationError) {
console.error('Auth failed:', error.message);
} else if (error instanceof RateLimitError) {
console.error(`Rate limited. Retry after ${error.retryAfter}s`);
await sleep(error.retryAfter * 1000);
} else if (error instanceof InsufficientCreditsError) {
console.error('Please purchase more credits');
} else if (error instanceof ValidationError) {
console.error('Validation error:', error.errors);
} else if (error instanceof APIError) {
console.error('API error:', error.message);
}
}
cURL / Raw HTTP
# Check response status
response=$(curl -s -w "\n%{http_code}" \
-X POST https://api.circuitkyc.com/api/v1/check-eligibility \
-H "X-API-Key: sk_live_your_key" \
-H "Content-Type: application/json" \
-d '{"email": "user@example.com", "phone_number": "+15551234567"}')
status_code=$(echo "$response" | tail -1)
body=$(echo "$response" | head -n -1)
case $status_code in
200)
echo "Success: $body"
;;
402)
echo "Need more credits"
;;
429)
retry_after=$(echo "$body" | jq -r '.retry_after')
echo "Rate limited. Retry after $retry_after seconds"
;;
*)
echo "Error $status_code: $body"
;;
esac
Retry Strategy
Implement exponential backoff for transient errors:
import time
import random
def retry_with_backoff(func, max_retries=3):
"""Retry a function with exponential backoff."""
for attempt in range(max_retries):
try:
return func()
except (RateLimitError, APIError) as e:
if attempt == max_retries - 1:
raise
# Exponential backoff with jitter
wait_time = (2 ** attempt) + random.uniform(0, 1)
# Use retry_after header if available
if hasattr(e, 'retry_after'):
wait_time = e.retry_after
print(f"Attempt {attempt + 1} failed. Retrying in {wait_time:.1f}s")
time.sleep(wait_time)
Recommended Retry Settings
| Error Type |
Max Retries |
Initial Delay |
| 429 Rate Limited |
3 |
Use Retry-After |
| 500 Server Error |
3 |
1 second |
| 502 Bad Gateway |
3 |
2 seconds |
| 503 Unavailable |
5 |
5 seconds |
| 504 Timeout |
3 |
2 seconds |
Every response includes rate limit headers:
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 295
X-RateLimit-Reset: 1705312260
Retry-After: 30 (only on 429 responses)
Use these to implement proactive rate limiting:
def check_rate_limit(response):
remaining = int(response.headers.get('X-RateLimit-Remaining', 0))
if remaining < 10:
print(f"Warning: Only {remaining} requests remaining")
if remaining == 0:
reset_time = int(response.headers.get('X-RateLimit-Reset'))
wait_time = reset_time - time.time()
print(f"Rate limit exhausted. Reset in {wait_time:.0f}s")
Debugging
Enable Debug Logging
import logging
# Enable debug logging
logging.basicConfig(level=logging.DEBUG)
client = CircuitKYC(api_key="sk_live_your_key")
Include Request ID in Support Requests
Always include the request_id when contacting support:
Subject: API Error - Request ID: req_abc123
I received an error when calling /check-eligibility:
Request ID: req_abc123
Status: 500
Time: 2024-01-15T10:30:00Z
Error: Internal Server Error
Best Practices
- Always handle errors - Don't let exceptions crash your app
- Implement retries - Use exponential backoff for 5xx errors
- Log errors - Include request_id for debugging
- Monitor rate limits - Track headers to avoid 429s
- Validate input - Check data before sending to API
- Use SDKs - They handle common errors automatically