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

HTTPCodeMeaning / resolution
400VALIDATION_ERRORInvalid input. See details for field-level errors.
401UNAUTHORIZEDMissing/invalid X-API-Key or an expired session.
403FORBIDDENThe key doesn't have access to this organization or operation.
403PLAN_LIMIT_REACHEDPlan limit reached (e.g. number of keys).
403PLAN_FEATURE_UNAVAILABLEThe feature isn't included in the current plan.
404NOT_FOUNDThe resource doesn't exist or you don't have access to it.
409CONFLICTConflict (e.g. a duplicate invoice number).
409PARTNER_CLAIM_COLLISIONpeppol-claim/confirm: another real org already exists for the same IČO, so the company can't be assigned automatically. Contact support.
429RATE_LIMITEDRate limit exceeded: respect Retry-After.
402INSUFFICIENT_CREDITInsufficient Peppol credit for a live send (POST /agent/peppol/send/*). Top up your credit.
402SEAT_PAYMENT_FAILEDThe payment for a seat increase failed.
500INTERNAL_ERRORServer-side error: try again later / contact support.
Two endpoints return a non-standard shape (not the { "error": { … } } envelope):
  • POST /agent/peppol/send/* returns 402 with a flat body { "error": "INSUFFICIENT_CREDIT", "message": "…" } on insufficient credit. Here error is a string, not an object.
  • POST /agent/organizations/{id}/peppol-claim returns the status directly: { "organization_id": "…", "status": "…", "reason": "…" } (e.g. status: "collision" with reason: "real_org_exists_for_ico"), not wrapped in an error envelope.

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.