Skip to content

Quickstart

Access updated

Try fixed samples without a key on the MCP setup page. Processing your own documents requires a key. New free subscriptions and anonymous trial keys are closed; existing keys retain their allowance.

Five minutes from zero to a compliant Factur-X invoice.

1. Get an API key

Try fixed samples without a key. To generate, embed, validate or extract your own documents, choose a paid plan, copy the key after checkout and send Authorization: Bearer <key>.

2. Describe the invoice

Amounts are decimal strings ("1200.00"), dates are ISO 8601. Totals and the VAT breakdown are computed server-side; do not send them unless you need to override.

invoice.json
{
  "number": "F-2026-0042",
  "issue_date": "2026-09-01",
  "due_date": "2026-10-01",
  "seller": {
    "name": "Atelier Numérique SAS",
    "siren": "732829320",
    "vat_id": "FR40732829320",
    "legal_info": "SAS au capital de 10 000 € - RCS Paris 732 829 320",
    "address": {"line1": "12 rue de la Paix", "postal_code": "75002", "city": "Paris", "country": "FR"}
  },
  "buyer": {
    "name": "Boulangerie Dupont SARL",
    "siren": "552081317",
    "vat_id": "FR09552081317",
    "address": {"line1": "8 avenue des Champs", "postal_code": "69002", "city": "Lyon", "country": "FR"}
  },
  "payment": {"means_code": "30", "iban": "FR7630006000011234567890189", "terms": "Paiement à 30 jours."},
  "lines": [
    {"item_name": "Développement site web", "quantity": "1", "unit_price": "2500.00", "vat_rate": "20"},
    {"item_name": "Hébergement annuel", "quantity": "12", "unit_code": "MON", "unit_price": "15.00", "vat_rate": "20"}
  ]
}

French sellers

Provide siren (the API derives the 0002 scheme), vat_id and a full postal address. The three mandatory French mentions (late-payment penalties, EUR 40 recovery fee, early-payment discount) are added automatically as notes; override them with french_mentions.

3. Generate

Set FACTURX_API_KEY in your environment. The curl example uses Bash; Python requires httpx (python -m pip install httpx); Node requires Node.js 22+ and a .mjs file. Each successful generation consumes your quota.

curl --fail --silent --show-error --max-time 60 -X POST https://facturx.orvel.dev/v1/invoices/generate \
  -H "Authorization: Bearer $FACTURX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"invoice": '"$(cat invoice.json)"', "options": {"profile": "en16931", "language": "fr"}}' \
  -o F-2026-0042-facturx.pdf -D -
import json
import os
from pathlib import Path

import httpx

API_KEY = os.environ["FACTURX_API_KEY"]
invoice = json.loads(Path("invoice.json").read_text(encoding="utf-8"))
r = httpx.post(
    "https://facturx.orvel.dev/v1/invoices/generate",
    headers={"Authorization": f"Bearer {API_KEY}"},
    json={"invoice": invoice, "options": {"profile": "en16931", "output": "facturx-pdf"}},
    timeout=60,
)
r.raise_for_status()
if r.headers.get("content-type", "").split(";")[0] != "application/pdf" or not r.content.startswith(b"%PDF-"):
    raise RuntimeError("Expected a PDF response")
with open("invoice-facturx.pdf", "xb") as output:
    output.write(r.content)
print(r.headers["X-Facturx-Amount-Due"])  # "3216.00"
import fs from "node:fs";

const apiKey = process.env.FACTURX_API_KEY;
if (!apiKey) throw new Error("Set FACTURX_API_KEY");
const invoice = JSON.parse(fs.readFileSync("invoice.json", "utf8"));
const res = await fetch("https://facturx.orvel.dev/v1/invoices/generate", {
  method: "POST",
  redirect: "error",
  signal: AbortSignal.timeout(60_000),
  headers: { Authorization: `Bearer ${apiKey}`, "Content-Type": "application/json" },
  body: JSON.stringify({ invoice, options: { profile: "en16931" } }),
});
if (!res.ok) throw new Error(`HTTP ${res.status}; check invoice fields, key and quota`);
const pdf = Buffer.from(await res.arrayBuffer());
if (res.headers.get("content-type")?.split(";")[0] !== "application/pdf" || pdf.subarray(0, 5).toString() !== "%PDF-") {
  throw new Error("Expected a PDF response");
}
fs.writeFileSync("invoice-facturx.pdf", pdf, { flag: "wx" });

The response is the PDF/A-3 file. Useful headers: X-Facturx-Profile, X-Facturx-Amount-Due, X-Facturx-Warnings, X-Usage-Used, X-Usage-Quota.

Want XML only? Set "output": "cii-xml" or "ubl-xml". Want a JSON envelope with the file in base64 plus the computed totals and validation report? Send Accept: application/json.

Runnable example: PDF and report in one call

Download generate.mjs and invoice.json into the same folder. The JSON is a demonstration fixture, not an invoice to send or evidence of the companies' identities. With Node.js 22+ and FACTURX_API_KEY set, run:

node generate.mjs invoice.json

The script makes one request with Accept: application/json. It requires successful XSD, EN 16931 and fr-ctc checks with none skipped, then writes invoice.pdf and validation.json into a new subdirectory of facturx-output. Both files contain invoice data: keep them private. The expected amount for this example is EUR 3,216.00 (EUR 2,680.00 net and EUR 536.00 VAT).

The report describes the service's checks on the generated XML; it is not an independent PDF/A verification or proof of delivery to a PA. The script never retries automatically: after a network interruption, check quota before rerunning. No second validation request is needed to obtain this report.

4. Validate anything

curl --fail --silent --show-error --max-time 60 -X POST "https://facturx.orvel.dev/v1/invoices/validate?check=fr-ctc" \
  -H "Authorization: Bearer $FACTURX_API_KEY" \
  -F file=@supplier-invoice.pdf
{
  "valid": false,
  "flavor": "factur-x",
  "profile": "en16931",
  "checks_run": ["pdf", "xsd", "schematron:base", "schematron:fr-ctc"],
  "error_count": 1,
  "findings": [
    {"source": "schematron:fr-ctc", "severity": "fatal", "rule": "BR-FR-08",
     "message": "[BR-FR-08] Le SIREN du vendeur (BT-30) doit être cohérent avec le SIRET ...",
     "location": "/rsm:CrossIndustryInvoice/..."}
  ],
  "pdf": {"pages": 1, "attachments": ["factur-x.xml"], "pdfa": "3B", "facturx_xmp": "EN 16931"}
}

5. Read an inbound e-invoice

curl --fail --silent --show-error --max-time 60 -X POST "https://facturx.orvel.dev/v1/invoices/extract?include_xml=false" \
  -H "Authorization: Bearer $FACTURX_API_KEY" \
  -F file=@supplier-invoice.pdf

Returns fields (number, dates, seller, buyer, totals, VAT breakdown, lines) and, unless disabled, the raw embedded XML.

Next