Quickstart¶
Five minutes from zero to a compliant Factur-X invoice.
1. Get an API key¶
- Validate / extract: no key needed, up to 20 requests per minute per IP.
- Generate / embed: get a key on the pricing page (Free plan at EUR 0, 50 documents per month, no card). Your license key is your API key; send it as
Authorization: Bearer <key>. The same key opens the MCP server.
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.
{
"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¶
import httpx, json
invoice = json.load(open("invoice.json"))
r = httpx.post(
"https://facturx-api.fly.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()
open("invoice-facturx.pdf", "wb").write(r.content)
print(r.headers["X-Facturx-Amount-Due"]) # "3278.98"
const invoice = JSON.parse(fs.readFileSync("invoice.json", "utf8"));
const res = await fetch("https://facturx-api.fly.dev/v1/invoices/generate", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.FACTURX_API_KEY}`, "Content-Type": "application/json" },
body: JSON.stringify({ invoice, options: { profile: "en16931" } }),
});
if (!res.ok) throw new Error(await res.text());
fs.writeFileSync("invoice-facturx.pdf", Buffer.from(await res.arrayBuffer()));
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.
4. Validate anything¶
curl -X POST "https://facturx-api.fly.dev/v1/invoices/validate?check=fr-ctc" \
-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": "error", "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 -X POST "https://facturx-api.fly.dev/v1/invoices/extract?include_xml=false" \
-F file=@supplier-invoice.pdf
Returns fields (number, dates, seller, buyer, totals, VAT breakdown, lines) and, unless disabled, the raw embedded XML.
Next¶
- Full endpoint reference: REST API
- Use it from an AI agent: MCP server
- Every field explained: Invoice fields