Error codes and the error envelope

One shape on every route: type, code, message, param, doc_url, request_id and errors.

One shape on every route: type, code, message, param, doc_url, request_id and errors.

← Back to the API documentation

Your first invoice in 6 steps

  1. Every 4xx and 5xx returns { "error": { type, code, message, param?, doc_url, request_id, errors? } }.
  2. Branch on type to decide whether a retry makes sense, and map code into your own system.
  3. param points at the offending field, e.g. lines.0.vat_rate; errors[] appears when there are several.
  4. Log request_id on every error — it lets us find the exact request in our logs.

What the 4invoices API is

json
{
  "error": {
    "type": "invalid_request_error",
    "code": "validation_failed",
    "message": "Datele trimise nu sunt valide.",
    "param": "lines.0.vat_rate",
    "doc_url": "https://4invoices.net/ro/api-dezvoltatori#errors",
    "request_id": "req_8a893f2f33d4472da8d6e144",
    "errors": [
      { "param": "lines.0.vat_rate", "message": "VAT rate must be a percent (21), not a fraction", "type": "value_error" }
    ]
  }
}

https://api.4invoices.net/v1 · https://api.4invoices.net/v1/openapi.json

Errors

StatusTypeCode
401authentication_errormissing_bearer_token
401authentication_errorunauthorized
403permission_errorforbidden
404not_found_errornot_found
409conflict_erroridempotency_key_reuse
409conflict_erroridempotency_in_progress
422invalid_request_errorvalidation_failed
422invalid_request_errorinvalid_json_number
502upstream_errorupstream_error
503service_unavailable_errorservice_unavailable

Common mistakes

  • rate_limit_error and the two upstream types are retryable. authentication_error, permission_error and invalid_request_error are not fixed by retrying.
  • A 404 is also returned for an id that belongs to another tenant: we never confirm that someone else's data exists.
  • 409 idempotency_key_reuse means you reused a key with a different body. Do not force it: check what was already issued.
  • The doc_url in every error points straight at the errors section of this documentation.
  • Messages are in Romanian because the API serves a Romanian fiscal flow; do not parse message, branch on code.

Developer questions and answers

Can I rely on code values across versions?

Yes, code is stable and exists precisely for that. message is human text and may be rephrased.

What should I do on a 502 or 503?

Retry with exponential backoff. Those are upstream or temporary-availability errors, not problems with your request.

Why 422 and not 400 for invalid data?

422 marks well-formed but semantically invalid JSON — for example vat_rate as a fraction. 400 is reserved for a malformed request.