Errors & Rate Limits
Error Format
All error responses follow a consistent format:
{
"success": false,
"error": "Description of the error"
}
HTTP Status Codes
| Code | Meaning |
|---|---|
200 | Success - request completed. |
201 | Created - resource was created successfully. |
202 | Accepted - file uploaded, document record will appear shortly. |
400 | Bad Request - missing or invalid parameters, unsupported file type, or Content-Type mismatch. |
401 | Unauthorized - missing or invalid API key. |
403 | Forbidden - API key lacks required scope or space access. |
404 | Not Found - resource does not exist or is not accessible. |
413 | Payload Too Large - uploaded file exceeds the 50 MB limit. |
429 | Too Many Requests - rate limit exceeded (60 requests per minute per API key; document uploads are limited to 10 per minute). |
500 | Internal Server Error - something went wrong on our end. |
Note on duplicates: uploading a file that already exists in your library is not rejected with an error. The upload is accepted and the document finishes processing with status skipped.
Rate Limits
API requests are rate-limited to ensure fair usage:
- 60 requests per minute per API key
- 10 document uploads per minute (POST /v1/documents)
Rate limit information is included in every response using the standard RateLimit-* headers:
RateLimit-Limit: 60
RateLimit-Remaining: 55
RateLimit-Reset: 42
RateLimit-Reset is the number of seconds until the current window resets. A 429 response additionally includes a Retry-After header (seconds) and a retryAfter field in the JSON body.
Handling Rate Limits
When you receive a 429 response, wait for the number of seconds indicated by the Retry-After header before retrying. Implement exponential backoff for robustness:
async function fetchWithRetry(url, options, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
const response = await fetch(url, options);
if (response.status === 429) {
const retryAfter = Number(response.headers.get("Retry-After") || 5);
await new Promise(r => setTimeout(r, Math.max(retryAfter * 1000, 1000)));
continue;
}
return response;
}
throw new Error("Rate limit exceeded after retries");
}
Common Error Scenarios
| Error | Cause | Solution |
|---|---|---|
| "Invalid or missing API key" | Missing Authorization header or malformed key. | Check your API key format and header. |
| "Insufficient scope" | API key doesn't have the required scope. | Update key scopes in Settings > API Keys. |
| "Access denied to this space" | API key is restricted and can't access the requested space. | Add the space to the key's allowed spaces or use a key with broader access. |
| "Document not found" | Document doesn't exist or is in an inaccessible space. | Verify the document ID and your key's space access. |
| "File content does not match any supported format" | Uploaded file bytes don't match PDF, JPEG, PNG, TIFF, or Office document signatures. | Ensure you're uploading a valid file in a supported format. |
| "Content-Type mismatch" | The Content-Type header doesn't match the actual file content. | Set the correct Content-Type for your file or let your HTTP client detect it. |