Metadata-Version: 2.5
Name: einvoicekit
Version: 0.1.1
Summary: Check a Factur-X, ZUGFeRD, XRechnung, UBL or CII e-invoice against the full official EN 16931 rule set. One command, no key needed to start.
Project-URL: Homepage, https://einvoicekit.com/docs/
Project-URL: Repository, https://github.com/eInvoiceKit/facturx
Project-URL: Issues, https://github.com/eInvoiceKit/facturx/issues
Author: Vizalgo SAS
License-Expression: MIT
License-File: LICENSE
Keywords: cii,e-invoice,einvoice,en16931,factur-x,facturx,peppol,ubl,validation,validator,xrechnung,zugferd
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Office/Business :: Financial :: Accounting
Classifier: Topic :: Software Development :: Libraries
Classifier: Typing :: Typed
Requires-Python: >=3.10
Description-Content-Type: text/markdown

# 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.

```sh
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](https://einvoicekit.com)'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

```sh
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

```python
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

```sh
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](https://einvoicekit.com/get-started?from=facturx-pypi) by
  signing in with GitHub.
- **Pro**: 29 € a month for 1,000 pooled credits, a validation spending one.
  [Details](https://einvoicekit.com/pricing).

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](https://einvoicekit.com/docs/).

## Licence

MIT.
