Error codes
All errors share a uniform JSON shape with a machine-readable code, a human-readable message, and optional details (e.g. field-level validation errors).
Error shape
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid input data",
"details": [
{ "field": "items", "message": "Must contain at least one item" }
]
}
}Code reference
| HTTP | Code | Meaning / resolution |
|---|---|---|
| 400 | VALIDATION_ERROR | Invalid input. See details for field-level errors. |
| 401 | UNAUTHORIZED | Missing/invalid X-API-Key or an expired session. |
| 403 | FORBIDDEN | The key doesn't have access to this organization or operation. |
| 403 | PLAN_LIMIT_REACHED | Plan limit reached (e.g. number of keys). |
| 403 | PLAN_FEATURE_UNAVAILABLE | The feature isn't included in the current plan. |
| 404 | NOT_FOUND | The resource doesn't exist or you don't have access to it. |
| 409 | CONFLICT | Conflict (e.g. a duplicate invoice number). |
| 409 | PARTNER_CLAIM_COLLISION | peppol-claim/confirm: another real org already exists for the same IČO, so the company can't be assigned automatically. Contact support. |
| 429 | RATE_LIMITED | Rate limit exceeded: respect Retry-After. |
| 402 | INSUFFICIENT_CREDIT | Insufficient Peppol credit for a live send (POST /agent/peppol/send/*). Top up your credit. |
| 422 | INVOICE_ISSUE_DATE_NOT_SEND_DATE | The invoice's issue date (BT-2) doesn't match today in Europe/Bratislava (from 1.1.2027). Re-issue the document with today's date. See Scheduled and bulk Peppol sending. |
| 422 | INVOICE_ISSUE_DATE_TOO_OLD | A live invoice was issued more than 10 days ago (until 31.12.2026; an internal safety limit, not a statutory deadline). Review the invoice. See Scheduled and bulk Peppol sending. |
| 402 | SEAT_PAYMENT_FAILED | The payment for a seat increase failed. |
| 500 | INTERNAL_ERROR | Server-side error: try again later / contact support. |
Two endpoints return a non-standard shape (not the
{ "error": { … } } envelope):POST /agent/peppol/send/*returns402with a flat body{ "error": "INSUFFICIENT_CREDIT", "message": "…" }on insufficient credit. Hereerroris a string, not an object. The same flat shape applies to422 INVOICE_ISSUE_DATE_NOT_SEND_DATEand422 INVOICE_ISSUE_DATE_TOO_OLDonPOST /agent/peppol/send/{invoiceId}.POST /agent/organizations/{id}/peppol-claimreturns the status directly:{ "organization_id": "…", "status": "…", "reason": "…" }(e.g.status: "collision"withreason: "real_org_exists_for_ico"), not wrapped in anerrorenvelope.
Recommendations
For 4xx, don't retry without changing the request. For 429 and 5xx, use exponential backoff. When issuing invoices, we recommend storing theid of the created document to avoid duplicates on retry.