Invoices

Read an invoice document into the JSON model

Reads a UBL 2.1 or UN/CEFACT CII invoice document — or the CII invoice attached to a Factur-X or ZUGFeRD PDF — into InvoiceInput and stops there. No verdict is given.

THE FIRST TASK ON AN ERP INTEGRATION. Before anything can be validated, edited, stored or re-emitted, somebody has to get from a supplier's XML to an object. POST /v1/validate has read documents for a while, but it returns a verdict and throws the model away — so this returns the model. The invoice that comes back is the exact shape POST /v1/validate and POST /v1/generate accept, so parsing a UBL file and generating CII from the result is a syntax conversion with no mapping code of your own.

It is the SAME reader as the document half of /v1/validate, through the same module and the same engine call: a document that parses here parses identically there, and the model you get back is the model that would have been judged.

A 200 is not a verdict. It means the file parsed. A document that comes back cleanly can still break every rule EN 16931 has — send invoice to POST /v1/validate for the answer to that, which is a second document against your allowance.

Documents only, which inverts the default everywhere else here: this endpoint needs application/xml or text/xml for XML, application/pdf for a Factur-X or ZUGFeRD PDF, or application/octet-stream for either. Anything else is 415 unsupported_media_type, with a message that names what the body is and the content-type that works; a JSON body is refused because there would be nothing to parse. For a PDF, container names the attachment the XML was read from. No finding is returned here, the PDF's own included: POST /v1/validate reports the attachment and the XMP metadata as AW-PDF-* findings, and PDF/A conformance itself, and whether the page agrees with the XML, are not checked by either endpoint.

METERING: one document once the file has been read, on exactly the terms /v1/validate charges — reading is the work. A file that cannot be read at all (400, 413, 415) costs nothing and carries the unchanged X-RateLimit-* set.

post/v1/parse

Request

  • Base URL: https://api.attestwire.com
  • URL: https://api.attestwire.com/v1/parse
  • Auth: HTTP bearer

Query parameters

max_charactersinteger

Raise the XML reader's character cap for this one request, up to 16,000,000. The default is the engine's 8,000,000 and is unchanged for any request that does not ask.

THE CASE THIS EXISTS FOR is a document carrying a base64-embedded attachment (BG-24, EmbeddedDocumentBinaryObject): base64 spends four characters per three bytes, so a 300 kB PDF inside an otherwise ordinary invoice clears the default on the attachment alone.

Asking for it also raises the body ceiling of an application/xml or text/xml request from 1 MB to 32 MB — a raise the bytes cannot get through is not a raise. The two ceilings are independent and whichever you meet first refuses the request. For a PDF it raises the cap on the XML attached to it, as far as the 4 MB the reader takes out of one PDF, and leaves the PDF's own 10 MB ceiling where it is.

The depth, element and attribute caps do NOT move, and that is what makes this safe: the element cap bounds the parsed tree whatever the character count. A value above the ceiling, or one that is not a positive whole number, is a 400 — the number you ask for is never quietly clamped. Ignored on an application/json request, which has no document reader to configure.

Response

The document was read. One document was charged. No verdict is given.

syntax'ubl' | 'cii' required

Which reader ran, decided from the root element of the document you sent.

containerstring nullable required

When a Factur-X or ZUGFeRD PDF was sent: the name of the attachment the XML was read from. null for an XML file.

customizationIdstring nullable required

BT-24, exactly as the document states it — not as we would have written it. invoice.profile is derived from this. null when the document states none.

profileIdstring nullable required

BT-23, exactly as the document states it. null when it states none.

sourcestring required

One sentence saying that the document was converted and NOT judged, and where to send it for the verdict — and, for a PDF, which attachment was read.

Example response

{
  "container": "factur-x.xml",
  "invoice": {
    "currency": "EUR",
    "invoiceTypeCode": "380",
    "seller": {
      "vatId": "DE123456789",
      "address": {
        "countryCode": "DE"
      },
      "electronicAddress": {
        "schemeId": "9930"
      }
    },
    "buyer": {
      "vatId": "DE123456789",
      "address": {
        "countryCode": "DE"
      },
      "electronicAddress": {
        "schemeId": "9930"
      }
    },
    "taxRepresentative": {
      "address": {
        "countryCode": "DE"
      }
    },
    "lines": [
      {
        "unitCode": "C62",
        "itemClassifications": [
          {
            "schemeId": "TST"
          }
        ]
      }
    ],
    "payment": {
      "meansCode": "58"
    },
    "declaredTotals": {
      "defects": [
        {
          "field": "BT-115"
        }
      ],
      "overPrecise": [
        {
          "field": "BT-131"
        }
      ]
    }
  },
  "unmapped": [
    {
      "path": "/ubl:Invoice/cac:AccountingSupplierParty/cac:Party/cbc:WebsiteURI"
    }
  ],
  "provenance": {
    "engine": "@attestwire/en16931",
    "engine_version": "0.14.1",
    "ruleset": "en16931@0.14.1",
    "profile": "xrechnung-ubl",
    "kosit_conformance": {
      "recorded": "2026-09-24",
      "validator": "1.6.3",
      "configuration": "3.0.2",
      "configuration_published": "2026-08-31"
    }
  }
}

Changes

No recorded changes to this operation across all 1 revision of this API.