Developers
Error Codes and Troubleshooting
What the error codes mean, when they fire, and how to handle each.
Error Codes and Troubleshooting
Every Papyrus API error response follows the ApiResponse envelope:
{
"success": false,
"errors": [
{
"code": "DOC_NOT_FOUND",
"message": "Document f47ac10b-... not found.",
"field": null,
"severity": "error"
}
],
"meta": { "requestId": "req_8a3b9c2d" }
}
requestId in the meta block is what to include when filing support tickets.
Common error codes
Authentication / authorization
| Code | HTTP | Meaning |
|---|---|---|
UNAUTHORIZED |
401 | Missing or invalid API key / token |
KEY_REVOKED |
401 | API key has been revoked |
KEY_EXPIRED |
401 | API key has expired |
TENANT_NOT_FOUND |
400 | X-Tenant-Id header missing or invalid |
FORBIDDEN |
403 | Authenticated but lacks permission |
SCOPE_INSUFFICIENT |
403 | API key doesn't have the required scope |
IP_NOT_ALLOWED |
403 | Source IP not in the key's allowlist |
Validation
| Code | HTTP | Meaning |
|---|---|---|
VALIDATION_FAILED |
400 | One or more fields failed validation (see field per error) |
FILE_TOO_LARGE |
413 | Upload exceeds plan / config limit |
FILE_TYPE_NOT_SUPPORTED |
400 | File extension not in allowed list |
DUPLICATE_HASH |
409 | Identical content already exists |
Resource not found / conflict
| Code | HTTP | Meaning |
|---|---|---|
DOC_NOT_FOUND |
404 | Document doesn't exist or not accessible to caller |
FOLDER_NOT_FOUND |
404 | Folder doesn't exist or not accessible |
WORKFLOW_NOT_FOUND |
404 | Workflow template / instance not found |
WORKFLOW_CONFLICT |
409 | Trying to advance a workflow already in a terminal state |
LOCK_HELD |
409 | Document is checked out by another user |
Rate limiting and quotas
| Code | HTTP | Meaning |
|---|---|---|
RATE_LIMIT_EXCEEDED |
429 | Too many requests; see Retry-After |
STORAGE_QUOTA_EXCEEDED |
402 | Tenant storage limit reached |
AI_QUOTA_EXCEEDED |
402 | Plan's AI operations limit reached |
USER_QUOTA_EXCEEDED |
402 | Plan's user seat limit reached |
Server
| Code | HTTP | Meaning |
|---|---|---|
INTERNAL_ERROR |
500 | Unhandled exception (always logged with requestId) |
BAD_GATEWAY |
502 | Upstream dependency (vector store, AI provider) failed |
SERVICE_UNAVAILABLE |
503 | Maintenance window or overload |
GATEWAY_TIMEOUT |
504 | Upstream timed out |
Retry rules
Retry with exponential backoff for:
- 429 (respecting
Retry-After) - 502, 503, 504
- 500 if you can confirm the operation was idempotent
Do not retry:
- 4xx other than 429 (something's wrong with your request)
- 5xx for non-idempotent operations without an idempotency key
The Request ID
Every response carries meta.requestId. Include it in:
- Support tickets
- Internal incident reports
- Debug logs in your application
Papyrus's server logs are indexed by request ID — we can find your exact call in seconds.