Reference
Errors
All error responses use a consistent JSON format.
Error format
{
"error": {
"code": "QUOTA_EXCEEDED",
"message": "Monthly quota of 20 invoices reached. Upgrade your plan or wait for next billing period."
}
}Always check error.code for programmatic handling — error.message is human-readable and may change.
Error codes
| HTTP | Code | Description |
|---|---|---|
| 400 | BAD_REQUEST | Request is missing a required field or is malformed. |
| 400 | UNSUPPORTED_FILE_TYPE | File type is not supported. Use PDF, PNG, JPG, WebP, or GIF. |
| 400 | FILE_TOO_SMALL | File is under 1KB and is unlikely to be a real document. |
| 401 | UNAUTHORIZED | Authorization header is missing, malformed, or the key is invalid. |
| 413 | FILE_TOO_LARGE | File exceeds the size limit for your plan (5MB free / 25MB paid). |
| 422 | UNUSABLE_RESULT | Document was uploaded but could not be parsed with sufficient confidence. May be unreadable, blank, or not a supported document. |
| 422 | PARSE_FAILED | Parsing failed due to an AI or processing error. |
| 429 | QUOTA_EXCEEDED | Monthly document quota for your plan has been reached. |
| 429 | RATE_LIMITED | Per-minute rate limit exceeded. Check X-RateLimit-Reset for when the window resets. |
| 500 | INTERNAL_ERROR | Server error. If this persists, contact support. |
Handling errors in Node.js
const res = await fetch('https://api.lumiparser.com/v1/invoices', {
method: 'POST',
headers: { Authorization: `Bearer ${apiKey}` },
body: formData,
});
if (!res.ok) {
const { error } = await res.json();
switch (error.code) {
case 'QUOTA_EXCEEDED':
console.log('Monthly limit reached — upgrade plan');
break;
case 'RATE_LIMITED':
const reset = res.headers.get('X-RateLimit-Reset');
console.log(`Rate limited. Retry after ${new Date(reset * 1000)}`);
break;
case 'UNUSABLE_RESULT':
console.log('Document could not be parsed — flag for manual review');
break;
default:
throw new Error(`API error: ${error.message}`);
}
}Rate limit headers
Check these headers on every response to stay within limits:
X-RateLimit-Limit: 60 # your plan's per-minute limit
X-RateLimit-Remaining: 0 # 0 means you'll be rate limited next request
X-RateLimit-Reset: 1706000060 # Unix timestamp — safe to retry after this