{"openapi":"3.1.0","info":{"title":"Invoice Navigator API v3","version":"3.0.0","summary":"Validate, repair, convert and render EU e-invoices with the patch engine.","description":"v3 is served by the **patch engine**: repairs are targeted edits on your own document, never a re-render, and every result is judged by the official validators (XSD, CEN EN 16931 schematron, KoSIT for XRechnung / Peppol / EN 16931). Same engine, oracle and fidelity guard as the web tool. No LLM is called. Invoices are not stored.\n\n**Authentication:** `Authorization: Bearer sk_live_…` or `sk_test_…`. Try it without an account: `curl -X POST https://www.invoicenavigator.eu/api/developers/instant-key` returns a one-hour, 10-request `sk_test_` key.\n\n**Versioning:** breaking changes get a new major path (`/api/v4`). v2 (`/api/v2/*`) keeps working but runs the earlier engine and is deprecated for new integrations; it will not be switched off without at least six months notice.","contact":{"name":"Invoice Navigator","url":"https://www.invoicenavigator.eu/developers/v3","email":"support@invoicenavigator.eu"}},"servers":[{"url":"https://www.invoicenavigator.eu/api/v3","description":"Production"}],"security":[{"bearerAuth":[]}],"tags":[{"name":"Validate","description":"Official verdict + structured findings"},{"name":"Fix","description":"Patch-engine repair"},{"name":"Convert","description":"Syntax / CIUS conversion"},{"name":"Render","description":"Human-readable rendering"},{"name":"Meta","description":"Health and spec"}],"paths":{"/validate":{"post":{"tags":["Validate"],"operationId":"validate","summary":"Official verdict with structured findings","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","oneOf":[{"required":["xml"]},{"required":["xmlBase64"]}],"properties":{"xml":{"type":"string","description":"The invoice XML as text (UBL 2.1 Invoice/CreditNote or CII D16B). At most 10 MB. DOCTYPE/ENTITY declarations are refused. Send either xml or xmlBase64."},"xmlBase64":{"type":"string","contentEncoding":"base64","description":"The invoice file bytes, base64 (alternative to xml). Decoded as a strict XML parser reads them (BOM, encoding declaration, ISO-8859-1, UTF-16); bytes that contradict their own encoding are refused with 422 XML_ENCODING_CONFLICT (class + byte offset). Prefer this when you read the invoice from a file: a text field cannot carry a non-UTF-8 encoding or invalid bytes faithfully."}}}}}},"responses":{"200":{"description":"Verdict (an invalid invoice is still 200; see data.valid)","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/ValidateResult"},"meta":{"type":"object","properties":{"processingTimeMs":{"type":"integer"},"testMode":{"const":true}}}}}}}},"400":{"description":"Bad request: INVALID_JSON, INVALID_UTF8 (body not UTF-8; details.offset), MISSING_XML, INVALID_XML, INVALID_BASE64, XML_DOCTYPE_REFUSED, or an invalid option","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED / KEY_EXPIRED — missing, invalid or expired key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"QUOTA_EXCEEDED — monthly allowance used up (error.details.upgradeUrl)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"KEY_INACTIVE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"XML_TOO_LARGE — more than 10 MB","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"XML_ENCODING_CONFLICT (bytes or text contradict their encoding; details: class, offset, declared, bom), MALFORMED_XML (not well-formed), NOT_EVALUABLE (a validator cannot evaluate this document; details.erroredOracles) or UNSUPPORTED_FORMAT (not a recognised e-invoice)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED — honour Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"ORACLE_UNAVAILABLE — the official validator did not answer; nothing was changed; retry (Retry-After: 60)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/fix":{"post":{"tags":["Fix"],"operationId":"fix","summary":"Repair with the patch engine; answer open questions in the same call","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","oneOf":[{"required":["xml"]},{"required":["xmlBase64"]}],"properties":{"xml":{"type":"string","description":"The invoice XML as text (UBL 2.1 Invoice/CreditNote or CII D16B). At most 10 MB. DOCTYPE/ENTITY declarations are refused. Send either xml or xmlBase64."},"xmlBase64":{"type":"string","contentEncoding":"base64","description":"The invoice file bytes, base64 (alternative to xml). Decoded as a strict XML parser reads them (BOM, encoding declaration, ISO-8859-1, UTF-16); bytes that contradict their own encoding are refused with 422 XML_ENCODING_CONFLICT (class + byte offset). Prefer this when you read the invoice from a file: a text field cannot carry a non-UTF-8 encoding or invalid bytes faithfully."},"mode":{"enum":["strict","permissive"],"default":"strict","description":"strict: values the engine is not sure of become questions. permissive: the engine fills them with its best inference."},"answers":{"type":"array","maxItems":40,"items":{"$ref":"#/components/schemas/Answer"},"description":"Answers to `questions` from a previous call; applied to the document before the repair."}}}}}},"responses":{"200":{"description":"Repair result","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/FixResult"},"meta":{"type":"object","properties":{"processingTimeMs":{"type":"integer"},"testMode":{"const":true}}}}}}}},"400":{"description":"Bad request: INVALID_JSON, INVALID_UTF8 (body not UTF-8; details.offset), MISSING_XML, INVALID_XML, INVALID_BASE64, XML_DOCTYPE_REFUSED, or an invalid option","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED / KEY_EXPIRED — missing, invalid or expired key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"QUOTA_EXCEEDED — monthly allowance used up (error.details.upgradeUrl)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"KEY_INACTIVE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"XML_TOO_LARGE — more than 10 MB","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"XML_ENCODING_CONFLICT (bytes or text contradict their encoding; details: class, offset, declared, bom), MALFORMED_XML, NOT_EVALUABLE, UNSUPPORTED_SYNTAX (not UBL/CII) or UNPARSEABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED — honour Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"ORACLE_UNAVAILABLE — the official validator did not answer; nothing was changed; retry (Retry-After: 60)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/convert":{"post":{"tags":["Convert"],"operationId":"convert","summary":"Convert to another syntax / CIUS, with the verdict of the output","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["target"],"oneOf":[{"required":["xml"]},{"required":["xmlBase64"]}],"properties":{"xml":{"type":"string","description":"The invoice XML as text (UBL 2.1 Invoice/CreditNote or CII D16B). At most 10 MB. DOCTYPE/ENTITY declarations are refused. Send either xml or xmlBase64."},"xmlBase64":{"type":"string","contentEncoding":"base64","description":"The invoice file bytes, base64 (alternative to xml). Decoded as a strict XML parser reads them (BOM, encoding declaration, ISO-8859-1, UTF-16); bytes that contradict their own encoding are refused with 422 XML_ENCODING_CONFLICT (class + byte offset). Prefer this when you read the invoice from a file: a text field cannot carry a non-UTF-8 encoding or invalid bytes faithfully."},"target":{"enum":["xrechnung-ubl","xrechnung-cii","peppol-bis","en16931-ubl","en16931-cii"]},"allowLoss":{"type":"boolean","default":false,"description":"Return the conversion even when EN 16931 values would be lost (listed in data.loss)."},"answers":{"type":"array","maxItems":40,"description":"Answers to MISSING_INPUT questions (peppol-bis), by question id. Endpoints need scheme + value; periods are YYYY-MM-DD/YYYY-MM-DD.","items":{"type":"object","required":["id","value"],"properties":{"id":{"type":"string"},"value":{"type":"string"},"scheme":{"type":"string"}}}}}}}}},"responses":{"200":{"description":"Converted document","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/ConvertResult"},"meta":{"type":"object","properties":{"processingTimeMs":{"type":"integer"},"testMode":{"const":true}}}}}}}},"400":{"description":"Bad request: INVALID_JSON, INVALID_UTF8 (body not UTF-8; details.offset), MISSING_XML, INVALID_XML, INVALID_BASE64, XML_DOCTYPE_REFUSED, or an invalid option","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED / KEY_EXPIRED — missing, invalid or expired key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"QUOTA_EXCEEDED — monthly allowance used up (error.details.upgradeUrl)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"KEY_INACTIVE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"XML_TOO_LARGE — more than 10 MB","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"XML_ENCODING_CONFLICT, MALFORMED_XML, NOT_EVALUABLE, UNSUPPORTED_TARGET (error.details.supported / planned: nl-si-ubl, cius-ro, fatturapa, ksef-fa3), UNSUPPORTED_SYNTAX, UNPARSEABLE, CONVERSION_LOSSY (error.details = the result without xml), MISSING_INPUT (peppol-bis: inputs the target's official rules need, checked before rendering — error.details.questions[]: id, label, terms, rules, current, kind) or INVALID_ANSWERS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED — honour Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"ORACLE_UNAVAILABLE — the official validator did not answer; nothing was changed; retry (Retry-After: 60)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/render":{"post":{"tags":["Render"],"operationId":"render","summary":"Complete human-readable rendering (every BT of the XML)","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","oneOf":[{"required":["xml"]},{"required":["xmlBase64"]}],"properties":{"xml":{"type":"string","description":"The invoice XML as text (UBL 2.1 Invoice/CreditNote or CII D16B). At most 10 MB. DOCTYPE/ENTITY declarations are refused. Send either xml or xmlBase64."},"xmlBase64":{"type":"string","contentEncoding":"base64","description":"The invoice file bytes, base64 (alternative to xml). Decoded as a strict XML parser reads them (BOM, encoding declaration, ISO-8859-1, UTF-16); bytes that contradict their own encoding are refused with 422 XML_ENCODING_CONFLICT (class + byte offset). Prefer this when you read the invoice from a file: a text field cannot carry a non-UTF-8 encoding or invalid bytes faithfully."},"format":{"enum":["html","json"],"default":"html"},"locale":{"enum":["de","en"],"default":"en"}}}}}},"responses":{"200":{"description":"Rendering","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"const":true},"data":{"$ref":"#/components/schemas/RenderResult"},"meta":{"type":"object","properties":{"processingTimeMs":{"type":"integer"},"testMode":{"const":true}}}}}}}},"400":{"description":"Bad request: INVALID_JSON, INVALID_UTF8 (body not UTF-8; details.offset), MISSING_XML, INVALID_XML, INVALID_BASE64, XML_DOCTYPE_REFUSED, or an invalid option","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED / KEY_EXPIRED — missing, invalid or expired key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"QUOTA_EXCEEDED — monthly allowance used up (error.details.upgradeUrl)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"KEY_INACTIVE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"XML_TOO_LARGE — more than 10 MB","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"XML_ENCODING_CONFLICT (bytes or text contradict their encoding; details: class, offset, declared, bom), MALFORMED_XML, UNSUPPORTED_FORMAT (e.g. \"pdf\": not available yet; details.supported), UNSUPPORTED_LOCALE, NOT_AN_INVOICE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED — honour Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"ORACLE_UNAVAILABLE — the official validator did not answer; nothing was changed; retry (Retry-After: 60)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/health":{"get":{"tags":["Meta"],"operationId":"health","summary":"Engine and validator status (no key)","security":[],"responses":{"200":{"description":"Healthy","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Health"}}}},"503":{"description":"KoSIT enabled but unreachable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Health"}}}}}}},"/openapi.json":{"get":{"tags":["Meta"],"operationId":"openapi","summary":"This document (no key)","security":[],"responses":{"200":{"description":"OpenAPI 3.1"}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"sk_live_… or sk_test_…"}},"schemas":{"Error":{"type":"object","required":["success","error"],"properties":{"success":{"const":false},"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}}}}},"Text":{"type":"object","required":["en","de"],"properties":{"en":{"type":"string"},"de":{"type":["string","null"]}}},"Verdict":{"type":"object","properties":{"state":{"enum":["valid","invalid"]},"valid":{"type":"boolean"},"kositVerified":{"type":"boolean","description":"A KoSIT-daemon-backed oracle ran and passed"},"format":{"type":"object","properties":{"key":{"type":"string"},"family":{"type":["string","null"]},"profile":{"type":["string","null"]},"country":{"type":["string","null"]}}},"oracles":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":["string","null"]},"authority":{"type":["string","null"]},"version":{"type":"string"},"verdict":{"enum":["pass","fail","error"]}}}}}},"Field":{"type":"object","properties":{"id":{"type":"string"},"label":{"$ref":"#/components/schemas/Text"},"help":{"oneOf":[{"$ref":"#/components/schemas/Text"},{"type":"null"}]},"examples":{"type":"array","items":{"type":"string"}},"pattern":{"type":["string","null"]},"xpath":{"type":["string","null"]},"scheme":{"type":["object","null"],"properties":{"attr":{"type":"string"},"label":{"$ref":"#/components/schemas/Text"},"options":{"type":"array","items":{"type":"object","properties":{"value":{"type":"string"},"label":{"$ref":"#/components/schemas/Text"}}}}}}}},"Action":{"oneOf":[{"type":"object","properties":{"kind":{"const":"ask"},"fields":{"type":"array","items":{"$ref":"#/components/schemas/Field"}}}},{"type":"object","properties":{"kind":{"const":"choose"},"choice":{"type":"object","properties":{"id":{"type":"string"},"label":{"$ref":"#/components/schemas/Text"},"options":{"type":"array","items":{"type":"object","properties":{"value":{"type":"string"},"label":{"$ref":"#/components/schemas/Text"}}}}}}}},{"type":"object","properties":{"kind":{"const":"explain"},"reason":{"$ref":"#/components/schemas/Text"}}}]},"Finding":{"type":"object","properties":{"ruleId":{"type":"string","examples":["BR-DE-15"]},"severity":{"enum":["error","warning","info"]},"oracle":{"type":"string"},"bt":{"type":"array","items":{"type":"string"},"description":"EN 16931 terms the rule names (BT-/BG-)"},"xpath":{"type":["string","null"]},"message":{"$ref":"#/components/schemas/Text"},"plain":{"oneOf":[{"$ref":"#/components/schemas/Text"},{"type":"null"}]},"action":{"oneOf":[{"$ref":"#/components/schemas/Action"},{"type":"null"}],"description":"errors only"}}},"LineArithmeticWarning":{"type":"object","properties":{"rule":{"enum":["EN16931-CALC-131","EN16931-CALC-146"]},"officialRule":{"enum":["PEPPOL-EN16931-R120","PEPPOL-EN16931-R046"],"description":"The Peppol BIS rule that tests the same relation"},"term":{"enum":["BT-131","BT-146"]},"bts":{"type":"array","items":{"type":"string"}},"line":{"type":"object","properties":{"position":{"type":"integer","description":"1-based"},"id":{"type":["string","null"],"description":"BT-126"}}},"expected":{"type":"string","examples":["200.00"]},"actual":{"type":"string","examples":["100.00"]},"difference":{"type":"string"},"xpath":{"type":"string"},"message":{"$ref":"#/components/schemas/Text"}}},"Question":{"type":"object","description":"kind \"field\": answer with { id, value, scheme? }; kind \"choice\": answer with { id, option }.","properties":{"kind":{"enum":["field","choice"]},"id":{"type":"string"},"source":{"enum":["engine","rule"]},"label":{"$ref":"#/components/schemas/Text"},"codes":{"type":"array","items":{"type":"string"}}}},"Answer":{"type":"object","required":["id"],"properties":{"id":{"type":"string"},"value":{"type":"string","maxLength":500},"scheme":{"type":"string"},"option":{"type":"string"}}},"ValidateResult":{"type":"object","properties":{"valid":{"type":"boolean"},"syntax":{"enum":["UBL","CII",null]},"verdict":{"$ref":"#/components/schemas/Verdict"},"counts":{"type":"object","properties":{"errors":{"type":"integer"},"warnings":{"type":"integer"},"info":{"type":"integer"}}},"findings":{"type":"array","items":{"$ref":"#/components/schemas/Finding"},"description":"Official findings, plus line-arithmetic warnings (oracle \"invoice-navigator-line-arithmetic\"; see lineArithmetic)"},"lineArithmetic":{"type":"array","items":{"$ref":"#/components/schemas/LineArithmeticWarning"},"description":"Line amounts that don't add up. The official CEN EN 16931 check does not test line arithmetic; these are warnings only — they never change `valid` and never count as errors."},"actions":{"type":"array","description":"Deduped actions for all error codes","items":{"type":"object"}},"sha256":{"type":"string"}}},"FixResult":{"type":"object","properties":{"outcome":{"enum":["already_compliant","compliant","partial","needs_input","lossy_refused"]},"valid":{"type":"boolean"},"syntax":{"enum":["UBL","CII"]},"xml":{"type":["string","null"],"description":"The repaired document; null if it would lose content"},"sha256":{"type":["string","null"]},"verdict":{"$ref":"#/components/schemas/Verdict"},"changes":{"type":"array","items":{"type":"object","properties":{"synthesizer":{"type":"string"},"field":{"type":"string"},"confidence":{"type":"string"},"reason":{"type":"string"},"value":{"type":"string"}}}},"patches":{"type":"array","description":"The edits applied to your document (set_text / set_attr / insert_tree / remove_node)","items":{"type":"object"}},"remaining":{"type":"array","items":{"$ref":"#/components/schemas/Finding"}},"questions":{"type":"array","items":{"$ref":"#/components/schemas/Question"}},"answers":{"type":"object","properties":{"applied":{"type":"integer"},"rejected":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"reason":{"type":"string"}}}}}},"fidelity":{"type":"object","properties":{"critical":{"type":"integer"},"benign":{"type":"integer"},"examples":{"type":"array","items":{"type":"string"}}}},"patchGaps":{"type":"array","items":{"type":"string"}},"mode":{"enum":["strict","permissive"]}}},"ConvertResult":{"type":"object","properties":{"target":{"type":"object","properties":{"id":{"enum":["xrechnung-ubl","xrechnung-cii","peppol-bis","en16931-ubl","en16931-cii"]},"label":{"type":"string"},"syntax":{"enum":["UBL","CII"]}}},"source":{"type":"object","properties":{"syntax":{"enum":["UBL","CII"]},"format":{"type":"string"}}},"method":{"enum":["identity_patch","canonical_render"]},"lossless":{"type":"boolean"},"xml":{"type":["string","null"]},"sha256":{"type":["string","null"]},"loss":{"type":"object","properties":{"terms":{"type":"array","items":{"type":"object","properties":{"bt":{"type":"string"},"value":{"type":"string"},"src":{"type":"string"}}}},"other":{"type":"array","items":{"type":"object"}},"sourceTerms":{"type":"integer"}}},"verdict":{"$ref":"#/components/schemas/Verdict"},"findings":{"type":"array","items":{"$ref":"#/components/schemas/Finding"}}}},"RenderResult":{"type":"object","properties":{"format":{"enum":["html","json"]},"locale":{"enum":["de","en"]},"syntax":{"enum":["UBL","CII"]},"values":{"type":"integer","description":"Values rendered"},"outsideStandard":{"type":"integer","description":"XML values outside EN 16931, shown under \"further details\""},"html":{"type":"string","description":"format=html: standalone page (inline CSS, no scripts)"},"document":{"type":"object","description":"format=json: the structured reading"}}},"Health":{"type":"object","properties":{"status":{"enum":["ok","degraded"]},"version":{"type":"string"},"engine":{"const":"patch"},"llm":{"const":false},"validator":{"type":"object"},"convertTargets":{"type":"array","items":{"type":"string"}},"renderFormats":{"type":"array","items":{"type":"string"}}}}}}}