eliDocs
API Reference

Error reference

Complete reference of all Beliq API error codes, HTTP statuses, and remediation guidance.

All API errors use the same response shape:

{
  "success": false,
  "error": {
    "code": "ERROR_CODE",
    "message": "Human-readable description of the error",
    "details": {}
  }
}
Field Type Description
code string Stable, machine-readable error code
message string Human-readable explanation
details object? Structured data for the codes that carry it: fields on a schema VALIDATION_ERROR, validationResult on INVALID_INVOICE, allowedProfiles on PROFILE_STANDARD_MISMATCH, creditNoteCapableStandards on DOCUMENT_TYPE_STANDARD_MISMATCH, unmappablePaths on CONVERSION_LOSSY_FAILCLOSED. Absent on every other code
incidentId string? Support correlation ID, present on 5xx responses only. Quote it together with the x-request-id header when you email hello@beliq.eu
Error codes

Error codes

Code HTTP Status Meaning Endpoints Remediation
VALIDATION_ERROR 400 / 413 / 415 / 422 Request body is invalid. This code is also the catch-all for client errors that have no more specific code, so read the status to tell them apart: 400 the body failed the schema, 413 it exceeded the size limit and was never read, 415 the content type is not accepted on that route, 422 the engine judged the document unprocessable All For 400, check required fields and types in the generate schema. For the others the status is the diagnosis; the message names the specific cause
INVALID_INVOICE 422 Invoice data is structurally valid JSON but fails validation: EN 16931 or CIUS Schematron for UBL/CII, or authority XSD for Italy FatturaPA /v1/generate Inspect details.validationResult.errors (and for FatturaPA, structural XSD findings where applicable)
PROFILE_STANDARD_MISMATCH 422 The chosen profile is not allowed for the chosen standard /v1/generate Use a compatible combination — the response details includes standard, profile, and allowedProfiles. See the profile compatibility table.
DOCUMENT_TYPE_STANDARD_MISMATCH 422 documentType: "creditnote" with a standard that does not accept CreditNote payloads — today fatturapa and facturae (invoices only). /v1/generate Inspect details.creditNoteCapableStandards; it lists standards that honour CreditNotes in the deployed engine (facturx, peppol-bis, xrechnung, zugferd, eslog). See the Peppol Credit notes section.
PARSE_FAILED 400 Input file could not be parsed as a valid e-invoice /v1/parse Verify the input is a well-formed UBL 2.1 or CII XML, or a ZUGFeRD / Factur-X hybrid PDF with an embedded CII attachment. FatturaPA and SDI messaggio inputs are not handled by parse — use /v1/validate for those.
AUTHENTICATION_REQUIRED 401 No API key provided or key format is invalid All /v1/* Include Authorization: Bearer <key> or X-API-Key: <key> in the request headers
INVALID_API_KEY 403 API key does not exist or has been revoked All /v1/* Verify the API key in the dashboard. Generate a new key if it was revoked
QUOTA_EXCEEDED 429 Monthly usage quota exhausted /v1/generate, /v1/validate, /v1/parse Upgrade your subscription plan in the dashboard, or wait until the window rolls over (Retry-After is the seconds until then; /v1/me reports the same instant as resetsAt)
RATE_LIMITED 429 Too many requests in the current one-minute burst window All Respect Retry-After and retry with backoff. Retry-After here is seconds, not minutes
ACCOUNT_THROTTLED 429 The account is temporarily throttled after sustained pressure on its own limits. Unlike RATE_LIMITED, this blocks every /v1 route until it expires All Respect Retry-After, which can be several minutes — much longer than a burst window. Stop retrying in a tight loop: further requests while throttled extend it. Reaching this state means requests were being sent well beyond the plan’s allowance for a sustained period
ENGINE_UNAVAILABLE 503 Beliq could not process the request: the engine was unavailable, or a burst was larger than could be served inside the request deadline /v1/generate, /v1/validate, /v1/parse, /v1/convert Retry after Retry-After. The document’s quota unit is refunded (see Quota refunds), so a retry does not cost you a second document. Safe to retry automatically. If persistent, check the status page and email hello@beliq.eu with the error.incidentId value
INTERNAL_ERROR 500 Unexpected server error All Retry the request. If persistent, email hello@beliq.eu with the error.incidentId value and the x-request-id response header
NOT_FOUND 404 No route exists at the requested path and method All Check the path and HTTP method against this reference. A POST route called with GET returns this too
PDF_TEMPLATE_AUTH_REQUIRED 400 pdfTemplateId was sent without an authenticated organization. Stored PDF templates are org-scoped, so they require an API key (the free, unauthenticated generator can use template: "standard" instead). /v1/generate Send the request with your Authorization: Bearer <key>, or drop pdfTemplateId and use template: "standard" for the built-in layout
PDF_TEMPLATE_NOT_FOUND 404 The referenced pdfTemplateId does not exist in your organization /v1/generate Check the template’s ref in the dashboard under PDF templates
PDF_TEMPLATE_INVALID 422 The stored template definition could not be parsed /v1/generate Re-save the template in the dashboard designer; if it persists, email hello@beliq.eu with the x-request-id
CONVERSION_UNSUPPORTED_PAIR 422 The source format is outside the EN 16931 family, or the source PDF carries no embedded invoice XML /v1/convert Check the supported pairs. National formats (FatturaPA, Facturae, KSeF, SDI messaggio) have no cross-format converter
CONVERSION_LOSSY_FAILCLOSED 422 The source carries fields the target cannot represent, so the conversion was refused rather than performed silently. No body is returned /v1/convert Read details.unmappablePaths. For a France CTC Flux 2 code on a UBL target, opt in with ?dropFranceCtcOverlay=true; for a synthesised Peppol endpoint pair there is no opt-in, so use POST /v1/generate. See lossy conversions
CONVERSION_TOOL_UNAVAILABLE 503 A converter the engine needs for this pair is not deployed. Operational, and not expected in production /v1/convert Retry after Retry-After. The quota unit is refunded (see Quota refunds). If it persists, email hello@beliq.eu with the error.incidentId
CONVERSION_TOOL_ERROR 500 The converter ran on this document and exited non-zero /v1/convert Retrying the same bytes fails the same way. The quota unit is refunded. Email hello@beliq.eu with the error.incidentId
Transmission errors (preview)

Transmission errors (preview)

Code HTTP Status Meaning Remediation
TRANSMISSION_DISABLED 503 Transmission is not enabled on this deployment, so every transmission endpoint refuses the request. Build and validate the file and deliver it through your own channel. Subscribe for the launch date.
TRANSMISSION_NO_PROVIDER 503 Transmission is enabled, but no provider is currently available for the target network in your key’s mode, so the document would queue with no path forward. Retry after Retry-After. If it persists, check the status page and email hello@beliq.eu with the error.incidentId value.
IDEMPOTENCY_KEY_REUSED 409 An Idempotency-Key was reused with a different request body. Use a fresh key for a different document, or resend the identical body to get the existing transmission back. See Idempotency.
INVALID_IDEMPOTENCY_KEY 400 The Idempotency-Key header is longer than 255 characters or contains something other than printable ASCII. Shorten the key and keep it to printable ASCII. A UUID is the usual choice. Rejected before any quota is spent.
SENDER_NOT_REGISTERED 403 The sender identifier is not a registered, active participant of your organization, so you may not send as it. Register the identifier and complete the ownership check before sending as it. The message says whether there is no registration at all or one that is not active yet.
CONTENT_ALREADY_SENT 409 This exact document was already sent to this recipient and that transmission can still arrive, so nothing was queued. details.transmissionId names it. Poll the existing transmission. To make retries unambiguous, send an Idempotency-Key. A resend is accepted once the earlier transmission reaches failed, or rejected on a network where a rejection does not burn the invoice number (see FRANCE_INVOICE_NUMBER_BURNED).
SENDER_COUNTRY_MISSING 409 The participant registration you are sending as records no country. Every Peppol envelope carries the sending entity’s country, so the registration cannot send until it is set. Email hello@beliq.eu to complete the registration.
RECIPIENT_NOT_ROUTABLE 400 The recipient identifier is not in a form the Peppol Network can address. A Peppol identifier is a four-digit scheme code and a value, for example 0088:5790000435975.
DOCUMENT_PARTY_MISMATCH 400 The document’s own electronic address for the sender or the recipient names a different party than the request does. details says which role and gives both identifiers. Make the document and the request agree. The EndpointID in the invoice must be the participant you are sending as, and the one you are sending to.
FRENCH_DOMESTIC_FLOW 409 Sender and recipient are both French, so this is a regulated domestic flow under the French B2B reform and must reach the network through a plateforme agréée rather than over Peppol. details gives both canonical identifiers. Not a document defect: the invoice may be perfectly valid. Email hello@beliq.eu to enable the French transmission lane. A French sender can still reach a non-French recipient over Peppol.
FRANCE_CTC_BLOCKING_FINDINGS 422 The document trips one or more BR-FR-CTC Flux 2 rules. A plateforme agréée refuses a document carrying any of them whatever severity the rule pack assigns, so Beliq refuses before the send spends the invoice number. details.ruleIds lists them. Note that POST /v1/validate can report valid: true for the same document: the French pack flags most of these rules as warnings, and franceCtcBlockingRuleIds on the validation result is the field that answers for transmission. Correct what the listed rules point at and send again. Validate first with POST /v1/validate and check franceCtcBlockingRuleIds is absent.
FRANCE_CTC_NOT_JUDGED 422 The document was not judged against the French CTC rules at all, so Beliq holds no verdict it can stand behind for a plateforme agréée. Almost always this is a missing BT-23 cadre de facturation, which is also what keeps BR-FR-08 — the rule that would have reported it — from running. Add BT-23 from the closed cadre list, or declare the EXTENDED-CTC-FR profile in BT-24. See France.
FRANCE_INVOICE_NUMBER_BURNED 409 A plateforme agréée already rejected this exact document. A French invoice number is unique on (number, supplier SIREN, invoice year) and a rejected invoice must be reissued under a new number, so Beliq refuses the resend rather than queue a second document under a spent one. details.transmissionId names the rejected transmission. Issue a corrected invoice under a new number and send that. Do not retry the same bytes: the platform’s own uniqueness check does not stop the reuse, which is why this one is on Beliq’s side.
UNSUPPORTED_SYNTAX 400 Only UBL and CII documents can be sent over Peppol. Convert the document first: see POST /v1/convert.
MISSING_CUSTOMIZATION_ID 400 The document carries no CustomizationID, so its Peppol document type identifier cannot be derived and no receiving Access Point can be looked up. Add the CustomizationID for the profile you are sending, for example urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0.
MISSING_PROCESS_ID 400 The document carries no ProfileID (UBL) or business process identifier (CII), so its Peppol process identifier cannot be derived. Add it, for example urn:fdc:peppol.eu:2017:poacc:billing:01:1.0.
MALFORMED_DOCUMENT 400 The document is not well-formed XML, or it declares a DOCTYPE. Fix the XML. A DOCTYPE is refused outright: no valid e-invoice declares one.
EMPTY_DOCUMENT 400 The document body is empty. Send the invoice XML in the request body.
INBOX_UNKNOWN_PROVIDER 404 An inbound network callback referenced a provider that is not registered. Provider-side authentication error, not reachable with an API key.
INBOX_VERIFICATION_FAILED 401 An inbound network callback or document failed signature verification. Provider-side authentication error, not reachable with an API key.
INBOX_SIGNATURE_EXPIRED 401 An inbound network callback carried a valid signature whose timestamp fell outside the accepted freshness window, so it is refused as a replay. Provider-side authentication error, not reachable with an API key.
HTTP status code summary

HTTP status code summary

Status Meaning
200 Success
400 Bad request: invalid JSON, missing required fields, or unsupported format combination
401 Unauthorized: no API key or invalid key format
403 Forbidden: API key is revoked or does not exist, or you may not send as the sender identifier (transmission, preview)
404 Not found: a referenced resource (e.g. a pdfTemplateId) does not exist in your organization
409 Conflict: an Idempotency-Key was reused with a different body, or the same document was already sent to that recipient (transmission, preview)
413 Payload too large: the request body exceeds the endpoint’s size limit. The body is not read, so no validation runs
415 Unsupported media type: the Content-Type is not one this route accepts. /v1/validate, /v1/parse and /v1/convert take application/xml, text/xml, application/octet-stream or application/pdf; the free public demo is narrower still and takes XML only
422 Unprocessable entity: input is syntactically valid but fails business rules or parsing
429 Too many requests: quota exceeded or rate limited
500 Internal server error
503 Service unavailable: engine is temporarily down, or transmission is not enabled
Request size limits

Request size limits

Each endpoint caps the size of the request body. The cap is enforced before the body is read, so an oversize request is refused without being parsed or validated, and it never spends a quota unit.

Endpoint Limit
POST /v1/validate 1 MB
POST /v1/parse 1 MB
POST /v1/generate 1 MB
POST /v1/convert 1 MB
POST /v1/send (preview) 1 MB
POST /v1/receive (preview) 1 MB
POST /v1/transmissions (preview) 5 MB
POST /v1/inbox/:providerId (preview) 5 MB

Exceeding the limit returns 413 with code VALIDATION_ERROR:

{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Request body exceeds the size limit of 1 MB for this endpoint. The body was not read, so this is not a validation failure. Send a smaller document."
  }
}

The code is the coarse class tag shared by every 4xx that is not one of the specific codes above; the 413 status is the discriminator. Read the status, not the code, to tell an oversize body from a schema failure.

Quota refunds on a Beliq-side failure

Quota refunds on a Beliq-side failure

When a request fails for a reason on our side rather than in your document, the quota unit that request spent goes back. That covers every ENGINE_UNAVAILABLE (503), and the conversion-tool failures on /v1/convert (CONVERSION_TOOL_UNAVAILABLE, CONVERSION_TOOL_ERROR). It does not cover a 4xx that names something in your document: that is an answer you asked for, and it keeps its unit.

Every response that refunds, or should have, says so on the x-beliq-quota-refunded header:

Header Meaning
true The unit went back. A retry costs you nothing.
false The unit was not returned. See the cap below.
absent No live unit was at stake (a successful call, a document error, or a test-key request, which meters against the sandbox allowance instead).

Refunds are unconditional for the failures where nothing was computed: an unreachable engine, a shed request, a missing conversion tool. Where a failure did consume engine compute — a timeout, or a fault raised part-way through processing — refunds are capped at 50 per organization per clock hour. The cap exists so a deliberately expensive document cannot be run repeatedly at no cost; normal traffic through a real incident stays well under it. If you see x-beliq-quota-refunded: false on volume you consider legitimate, email hello@beliq.eu with the error.incidentId and we will reconcile it.

VALIDATION_ERROR details

VALIDATION_ERROR details

A VALIDATION_ERROR raised by JSON schema validation carries details.fields, one entry per rejected constraint. This is the 400 on POST /v1/generate; the other statuses that share the code (413, 415, and any other 4xx with no more specific code) reject before or outside the schema and carry no details at all.

Field Type Description
path string Where the constraint failed. A JSON Pointer into the request body (/invoice/lines/0/unitPrice), except for a property missing at the top level, where it is the bare property name (standard)
message string The constraint in words, relative to path (must have required property 'number', must be number)
keyword string The JSON Schema keyword that rejected it (required, type, const, anyOf, minimum)

A missing nested property reports the parent object as path and names the child in message, so { "standard": "xrechnung", "output": "xml", "invoice": { "issueDate": "2026-04-13" } } answers:

{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "body/invoice must have required property 'number'",
    "details": {
      "fields": [
        {
          "path": "/invoice",
          "message": "must have required property 'number'",
          "keyword": "required"
        }
      ]
    }
  }
}

One bad value can produce several entries. A standard outside the accepted set is checked against each allowed value in turn, so it yields one const entry per candidate plus a closing anyOf entry, all of them on the same path. Read fields as the list of constraints that failed, not as a list of distinct problems, and key your own error reporting on path.

INVALID_INVOICE details

INVALID_INVOICE details

INVALID_INVOICE includes a full validationResult in details, matching the validation result from /v1/validate:

{
  "success": false,
  "error": {
    "code": "INVALID_INVOICE",
    "message": "Invoice validation failed with 1 error",
    "details": {
      "validationResult": {
        "valid": false,
        "format": "cii",
        "schematronVersion": "1.3.16",
        "ciusVersion": "XRechnung-2.6.0",
        "errors": [
          {
            "ruleId": "BR-DE-15",
            "severity": "error",
            "location": "/rsm:CrossIndustryInvoice",
            "message": "An XRechnung invoice must contain a buyer reference (BT-10)."
          }
        ],
        "warnings": []
      }
    }
  }
}
PROFILE_STANDARD_MISMATCH details

PROFILE_STANDARD_MISMATCH details

PROFILE_STANDARD_MISMATCH includes the rejected combination so you can correct the request:

{
  "success": false,
  "error": {
    "code": "PROFILE_STANDARD_MISMATCH",
    "message": "Profile 'extended' is not allowed for standard 'peppol-bis'.",
    "details": {
      "standard": "peppol-bis",
      "profile": "extended",
      "allowedProfiles": ["peppol"]
    }
  }
}
DOCUMENT_TYPE_STANDARD_MISMATCH details

DOCUMENT_TYPE_STANDARD_MISMATCH details

DOCUMENT_TYPE_STANDARD_MISMATCH is returned when documentType: "creditnote" is sent for a standard that only supports invoices — notably fatturapa and facturae. The four EN 16931 hybrid/XML routes peppol-bis, facturx, xrechnung, and zugferd accept CreditNotes, as does the national eslog route (document type code 381 on the same e-SLOG message). Inspect creditNoteCapableStandards in error details; it mirrors the deployed engine capability set.

{
  "success": false,
  "error": {
    "code": "DOCUMENT_TYPE_STANDARD_MISMATCH",
    "message": "documentType='creditnote' is not supported for standard 'fatturapa'. Accepted for CreditNote payloads: ['eslog', 'facturx', 'peppol-bis', 'xrechnung', 'zugferd'].",
    "details": {
      "standard": "fatturapa",
      "documentType": "creditnote",
      "creditNoteCapableStandards": ["eslog", "facturx", "peppol-bis", "xrechnung", "zugferd"]
    }
  }
}
PDF template errors

PDF template errors

These are returned only when a pdfTemplateId is referenced on POST /v1/generate. Stored templates are designed in the dashboard and are scoped to your organization, so they require an authenticated request.

Code When Fix
PDF_TEMPLATE_AUTH_REQUIRED pdfTemplateId sent on an unauthenticated request Use your API key, or switch to template: "standard"
PDF_TEMPLATE_NOT_FOUND The ref is not a template in your organization Verify the ref in the dashboard
PDF_TEMPLATE_INVALID The stored definition is corrupt and cannot be rendered Re-save the template in the designer
{
  "success": false,
  "error": {
    "code": "PDF_TEMPLATE_NOT_FOUND",
    "message": "PDF template k3d-9mp was not found."
  }
}
Request ID and incident ID

Request ID and incident ID

Every API response includes an x-request-id header (UUID). Quote it to hello@beliq.eu for faster troubleshooting.

x-request-id: 7f3d2a1b-4e5c-6d7f-8a9b-0c1d2e3f4a5b

Server-side failures (HTTP 500 and 503) additionally carry an error.incidentId in the response body. It links the response directly to the captured error event on our side, so quoting it in a support request is the fastest path to a diagnosis:

{
  "success": false,
  "error": {
    "code": "ENGINE_UNAVAILABLE",
    "message": "The e-invoice processing service is temporarily unavailable. Please try again shortly.",
    "incidentId": "V7mKp2XwQd"
  }
}