Receiving

Accept any EU e-invoice format. Get clean JSON.

When you issue an invoice, you choose the format. When you receive one, the sender chose it — and you still have to read it. One call auto-detects what arrived and returns the same normalised shape every time.

This is the half of the mandates that hits everyone. Issuing obligations phase in by company size over years; receiving obligations tend to land on every business at once.

Who has to be ready, and when

CountryDeadlineWho
🇫🇷France1 September 2026Every VAT-registered business, regardless of size
🇩🇪GermanyAlready live (January 2025)All domestic B2B
🇧🇪BelgiumAlready live (January 2026)B2B

Dates summarise publicly announced member-state timelines and are frequently revised — always confirm against the relevant tax authority. France's issuing obligation phases in separately, through September 2027.

One call, whatever they sent

curl -X POST https://api.invoicehub.dev/api/v1/parse \
  -H "Authorization: Bearer ih_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{"document": "<the invoice you were sent>"}'

Raw XML, or a Factur-X/ZUGFeRD PDF as base64 — same call either way. You get back what it was, the invoice data, and whether it actually conforms:

{
  "detected": {
    "formatId": "XRechnung_CII",
    "syntax": "cii",
    "customizationId": "urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0"
  },
  "invoice": {
    "invoiceNumber": "INV-2026-0142",
    "issueDate": "2026-06-19",
    "currency": "EUR",
    "seller": { "name": "Lieferant GmbH", "vatId": "DE123456789", … },
    "buyer":  { "name": "Acheteur SARL", … },
    "lines":  [ { "description": "Consulting", "quantity": 10, "netAmount": 1000.00, … } ],
    "totals": { "taxExclusiveAmount": 1000.00, "taxAmount": 190.00, "payableAmount": 1190.00 }
  },
  "report": { "valid": true, "assertionsEvaluated": 63, "errors": [] }
}

Formats we read

Every plan can parse every format, including the free tier. Charging you for the format your supplier happened to pick would be indefensible.

An invoice that fails validation still comes back.

You get the parsed data and the conformance report, not an error. You can't reject a supplier's invoice just because our validator dislikes it — that's a conversation with your supplier, not an HTTP status code. So we hand you both and let you decide.

In Node

npm install invoicehub

import { InvoiceHub } from 'invoicehub';
const ih = new InvoiceHub({ apiKey: process.env.INVOICEHUB_API_KEY });

const { detected, invoice, report } = await ih.parse(incomingDocument);

Get a free API key

Unlimited validation forever, plus 50 documents a month. No credit card, no sales call.

Issuing invoices instead? See format conversion and supported formats.