Skip to main content

einvoicekit

Check a Factur-X, ZUGFeRD, XRechnung, UBL or CII invoice against the full official EN 16931 rule set, from one command or one function call. No Java, no Saxon, no rule files to download.

pipx run --spec einvoicekit facturx invoice.pdf
invoice.pdf  INVALID  (cii, urn:cen.eu:en16931:2017)
  BR-CO-15  /Q{urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100}CrossIndustryInvoice[1]
            [BR-CO-15]-Invoice total amount with VAT (BT-112) = Invoice total amount without VAT (BT-109) + Invoice total VAT amount (BT-110).

Exit code 0 means every file is valid, 1 means at least one is not, 2 means at least one could not be validated. That is the whole integration for a CI pipeline.

What this package is, honestly

It is a thin client. Each call sends the invoice over HTTPS to einvoicekit's validator, which processes it in memory to produce the verdict and drops it; nothing is stored. What you get in exchange is the real thing: the official rule sets, EN 16931, XRechnung 3.0.2, Factur-X 1.09 and Peppol BIS 3.0, run by the reference validator, not a hand-written subset of them.

Two promises follow from that:

  • A verdict is a verdict. valid=False lists every broken rule with its official id, the official message and the XPath of the element at fault.
  • No silent green. If the service cannot be reached, you get an exception, never valid=True. The package has no fallback and no retry; a retry policy is yours to write.

Install

pip install einvoicekit

Python 3.10 or later. No dependencies.

Import einvoicekit, run facturx: the module carries the package's name, the command carries the format's. The package never installs a facturx module, because another distribution already owns that path and two packages writing the same path would corrupt each other's install.

Use it from code

from einvoicekit import validate, FacturxError

with open("invoice.pdf", "rb") as f:
    result = validate(f.read())

result.valid  # True or False
result.errors  # [Finding(rule, message, path), ...]
result.warnings  # same shape, never change the verdict
result.syntax  # 'cii' or 'ubl'
result.profile  # the profile URN the document declares, or None
result.raw  # the API's JSON as a dict, untouched

validate(data, ...) takes the bytes of an XML invoice, or of a Factur-X / ZUGFeRD PDF, which is unwrapped first so its embedded XML is what gets validated. The result carries the API's JSON, field for field.

Keyword arguments:

argument meaning
api_key an einvoicekit key; defaults to EINVOICEKIT_API_KEY; with neither, the free pool is used
target "france" adds the BR-FR rules French platforms apply, opt-in per call
base_url the API to call, default https://api.einvoicekit.com
timeout seconds to wait for the answer, default 30

Use it from the command line

facturx invoice.pdf
facturx a.xml b.pdf --target france
facturx invoice.pdf --json
facturx invoice.pdf --warnings
EINVOICEKIT_API_KEY=eik_live_... facturx invoice.pdf

--json prints the API's verdict as JSON on stdout, an array when several files are given, and nothing else there; refusals go to stderr. --help lists every option.

Limits, plainly

  • Without a key: 10 validations a day per IP address, shared with the free tools on einvoicekit.com. The eleventh call is refused with the time the pool resets (midnight UTC) and a link to the free key.
  • With a free key: 100 validations a month, plus 20 generated invoices in an allowance of their own. No card. Get one by signing in with GitHub.
  • Pro: 29 € a month for 1,000 pooled credits, a validation spending one. Details.

Only a delivered verdict counts. A document the API cannot assess, a refused call and an error on the service's side cost nothing.

Errors

Everything that is not a verdict raises FacturxError with a stable code:

code HTTP meaning
bad_request 400 the request itself was wrong (bad target, empty body)
unauthorized 401 a key was sent and it is unknown, malformed or disabled
too_large 413 over 5 MB
unreadable_document 422 the API read the file and cannot assess it: a plain PDF, an unsupported profile
pool_exhausted 429 the free daily pool is spent; resets_at and upgrade say when and where
rate_limited 429 too many calls in a short window; slow down
quota_exceeded 429 the key's monthly allowance is spent; upgrade says where to get more
service_unavailable 5xx the service answered but could not validate
network 0 no response at all

A wrong key is never a fallback into the free pool: send no key at all to use it.

Scope

Validation checks the invoice XML: the schema and every business rule of the profile the document declares. It does not check the PDF container's own PDF/A conformance; that check runs on the generation side of the API.

Full API documentation, the French rules and the generation endpoint: einvoicekit.com/docs.

Licence

MIT.

Release files for einvoicekit 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for einvoicekit 0.1.1
File Size Uploaded
einvoicekit-0.1.1.tar.gz 13.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for einvoicekit 0.1.1
File Interpreter ABI Platform
einvoicekit-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 24.8 kB

Release files / einvoicekit-0.1.1.tar.gz

Download URL einvoicekit-0.1.1.tar.gz
Size 13.6 kB
Tags Source
SHA-256 checksum
How to use checksums
665cf9decc78d7277375503cdcf09d091852f5d45fa6b86fe064e7bd25a9fbc1
BLAKE2b-256 checksum
How to use checksums
14c5990dff28cac1d9b0233b79365aab64b71ded6683a628c81ea7684b3bdee8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 4, 2026.

Transparency log

Release files / einvoicekit-0.1.1-py3-none-any.whl

Download URL einvoicekit-0.1.1-py3-none-any.whl
Size 11.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
286eefe371841223c2b48553a739b3b3db117ddd2d6fa2706e5d4eb142b3553d
BLAKE2b-256 checksum
How to use checksums
c894db676de6d2336436c3c278dcc0f25f2506bfa6087b0e5825172a7a8863fe
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 4, 2026.

Transparency log

Release history Release notifications | RSS feed

0.2.0

2 release files

This release

0.1.1 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page