API Reference
Errors & Rate Limits
Error codes, rate limits, and how to handle them.
Error Format
All errors return a consistent JSON structure:
{
"error": "error_code",
"message": "Human-readable description"
}Error Codes
| HTTP | Code | Description |
|---|---|---|
401 | invalid_api_key | Missing, malformed, or revoked API key |
402 | insufficient_credits | Monthly scan limit reached or async requires paid plan |
413 | file_too_large | File exceeds 100MB |
415 | unsupported_media | Unrecognized file type |
429 | rate_limited | Too many requests |
500 | internal_error | Server error — retry after a moment |
Rate Limits
Each plan has different rate limits:
| Plan | Requests/Min | Daily Limit | Monthly Scans |
|---|---|---|---|
| Free | 5 | 10 | 200 |
| Starter | 20 | — | 2,000 |
| Pro | 60 | — | 10,000 |
Rate Limit Headers
Every response includes rate limit information:
X-RateLimit-Limit: 5
X-RateLimit-Remaining: 3
X-RateLimit-Reset: 1711454400Handling Rate Limits
When you receive a 429 response, the body includes a retry_after value in seconds:
{
"error": "rate_limited",
"message": "Rate limit exceeded. Retry after 60 seconds.",
"retry_after": 60
}Wait for the specified duration before retrying. Implement exponential backoff for production integrations.
Best Practices
- Check
X-RateLimit-Remainingbefore each request to avoid hitting limits - Use
GET /v1/usageto monitor your monthly quota - Use async mode for batch processing to avoid timeout issues
- Implement retry logic with exponential backoff for
429and500errors