Rechnungsextraktions-API
Referenz fuer Text-, Datei-, Bild-URL- und ZUGFeRD-Extraktion mit aktueller Antwortstruktur.
Parsurai stellt Extraktionsendpunkte fuer Text, Datei-Uploads, Remote-URLs und Pro-ZUGFeRD-PDFs bereit. Standardextraktion verwendet fuer alle Eingabearten dieselbe Antwort-Huelle.
Endpunktuebersicht
| Endpunkt | Eingabe | Tarif |
|---|---|---|
POST /v1/extract | JSON-Body mit text | Free und hoeher |
POST /v1/extract/file | Multipart-PDF oder Bild | Free und hoeher |
POST /v1/extract/url | JSON-Body mit url | Free und hoeher |
POST /v1/extract/zugferd | Multipart-PDF mit eingebettetem XML | Pro und Business |
Text extrahieren
/v1/extractFree{
"text": "Rechnung von Supplier Inc. Rechnungsnummer INV-9812. Gesamt: 1500 EUR. USt: 19%.",
"locale": "auto"
}
| Feld | Typ | Pflicht | Beschreibung |
|---|---|---|---|
text | string | Ja | Roher Rechnungstext, 1 bis 8000 Zeichen |
locale | string | Nein | auto, en, de, fr, es oder nl; explizite Locales erfordern Hobby oder hoeher |
curl -X POST https://api.parsurai.com/v1/extract \
-H "X-API-Key: $PARSURAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"text": "Rechnung von Supplier Inc. INV-9812. Gesamt: 1500 EUR. USt: 19%.", "locale": "auto"}'
Datei extrahieren
/v1/extract/fileFreeSenden Sie ein PDF oder Bild als Multipart-Daten. Der Locale-Hinweis wird aus der Query gelesen.
curl -X POST "https://api.parsurai.com/v1/extract/file?locale=de" \
-H "X-API-Key: $PARSURAI_API_KEY" \
-F "file=@invoice.pdf"
URL extrahieren
/v1/extract/urlFree{
"url": "https://example.com/invoices/inv-01.jpg",
"locale": "auto"
}
Antwortschema
{
"invoice_id": "2f7d7f8a-32fb-4a7c-a3b1-53b61b64252f",
"invoice": {
"document_type": "invoice",
"vendor": {
"name": "Supplier Inc.",
"address": "Main Street 1, 10115 Berlin",
"email": null,
"phone": null,
"tax_id": "DE123456789",
"iban": "DE89370400440532013000",
"bank_name": null
},
"buyer": {
"name": "Buyer GmbH",
"address": null,
"email": null,
"phone": null,
"tax_id": "DE987654321",
"iban": null,
"bank_name": null
},
"invoice_number": "INV-9812",
"issue_date": "2026-06-13",
"due_date": "2026-07-13",
"billing_period_start": null,
"billing_period_end": null,
"reference_numbers": [{ "type": "order", "value": "PO-7781" }],
"line_items": [
{
"description": "Consulting",
"quantity": 1,
"unit": "hour",
"unit_price": 1500.0,
"discount": null,
"total": 1500.0,
"tax_rate": 0.19
}
],
"subtotal": 1500.0,
"discount_total": null,
"tax_breakdown": [
{
"tax_type": "VAT",
"rate": 0.19,
"taxable_amount": 1500.0,
"tax_amount": 285.0
}
],
"tax_total": 285.0,
"total_amount": 1785.0,
"amount_paid": null,
"amount_due": 1785.0,
"currency": "EUR",
"payment_terms": "Net 30",
"payment_instructions": "Pay by bank transfer.",
"locale": "de",
"confidence": 0.97,
"field_confidence": {},
"notes": []
},
"duplicate_risk": null,
"anomalies": [],
"confidence_low": false,
"field_bboxes": null
}
Feldreferenz
| Feld | Typ | Beschreibung |
|---|---|---|
invoice_id | UUID-String | Eindeutige Extraktions-ID |
invoice.document_type | string | invoice, credit_note, pro_forma, receipt oder other |
invoice.vendor.* | object | Verkaeuferfelder: name, address, email, phone, tax_id, iban, bank_name |
invoice.buyer.* | object | Kaeuferfelder mit derselben Struktur |
invoice.reference_numbers[] | array | Referenzen mit type und value |
invoice.line_items[].tax_rate | number oder null | Dezimaler Steuersatz |
invoice.tax_breakdown[] | array | Steuerzeilen mit tax_type, rate, taxable_amount und erforderlichem tax_amount |
invoice.total_amount | number | Erforderlicher Gesamtbetrag |
invoice.confidence | number | Extraktionskonfidenz von 0.0 bis 1.0 |
duplicate_risk | object oder null | Duplikatsignal fuer Pro und Business |
anomalies | array | Anomalie-Flags fuer Pro und Business |
field_bboxes | object oder null | Feld-Bounding-Boxes fuer Pro- und Business-Dateiuploads, wenn verfuegbar |
Locale-Unterstuetzung
| Code | Sprache |
|---|---|
auto | Automatische Erkennung |
en | Englisch |
de | Deutsch |
fr | Franzoesisch |
es | Spanisch |
nl | Niederlaendisch |
Explizite Locale-Werte ausser auto erfordern Hobby, Starter, Pro oder Business.
Tarifabhaengige Antwortfelder
Die Top-Level-Antwort enthaelt immer duplicate_risk, anomalies, confidence_low und field_bboxes; die Werte haengen aber von Tarif und Eingabetyp ab.
| Feld | Wann es befuellt wird |
|---|---|
duplicate_risk | Pro- und Business-Extraktionsflows, nachdem die Duplikatbewertung ausgefuehrt wurde |
anomalies | Pro- und Business-Extraktionsflows, nachdem Anomaliepruefungen ausgefuehrt wurden |
field_bboxes | Pro- und Business-Dateiuploads, wenn OCR-Spans verfuegbar sind |
confidence_low | Immer vorhanden; aktuell false, sofern das Backend keine niedrige Konfidenz markiert |
accuracy | Pro- und Business-Tarife, um Metadaten fuer Standard- und Enhanced-Modus auszugeben |
Genauigkeitsmodus (Accuracy Mode)
Zur Unterstuetzung von Hochpraezisions-Workflows bietet Parsurai einen Genauigkeitsmodus (Enhanced Accuracy Mode), der exklusiv fuer die Tarife Pro und Business verfuegbar ist.
Parameter
accuracy_mode(string): Standardmaessig aufstandardoderenhanced.- Standardwert:
standard - Unterstuetzt bei: JSON-Body fuer
POST /v1/extractundPOST /v1/extract/url; Query-Parameteraccuracy_modefuerPOST /v1/extract/file. - Tarif-Beschraenkung:
enhancederfordert Pro oder Business. Anfragen mitenhancedGenauigkeitsmodus in niedrigeren Tarifen schlagen mit dem Fehler402 feature_not_in_planfehl.
- Standardwert:
Funktionsweise
Im Gegensatz zur Standardextraktion wendet der Enhanced Accuracy Mode Folgendes an:
- Deterministische Validatoren: Pruefregeln werden ausgefuehrt (z.B. Abgleich, ob Einzelposten mit Zwischensummen und Gesamtbetraegen, USt/Steuerberechnungen sowie Rechnungsdaten uebereinstimmen).
- Ein begrenzter Korrekturversuch: Wenn eine Validierungspruefung fehlschlaegt, unternimmt die Engine einen einzelnen Korrekturversuch ueber das LLM mit den Fehlerdetails.
- Tradeoffs: Aufgrund der Validierungs- und Korrekturschleife fuehrt der Enhanced-Modus zu hoeherer Latenz und zusätzlichen Modellkosten (bis zu zwei LLM-Aufrufe pro Rechnungsextraktion).
Beispiel fuer das accuracy-Antwortobjekt
Wenn accuracy_mode angefordert wird (oder in einer tarifbeschraenkten Antwort enthalten ist), enthaelt die Top-Level-Extraktionsantwort ein accuracy-Metadatenobjekt mit detaillierten Ausführungsstatistiken:
{
"invoice_id": "2f7d7f8a-32fb-4a7c-a3b1-53b61b64252f",
"invoice": {
"document_type": "invoice",
"vendor": {
"name": "Supplier Inc.",
"tax_id": "DE123456789",
"iban": "DE89370400440532013000"
},
"subtotal": 1500.0,
"tax_total": 285.0,
"total_amount": 1785.0,
"confidence": 0.97
},
"accuracy": {
"mode": "enhanced",
"correction_attempted": true,
"correction_used": true,
"validators_failed": [
"subtotal_tax_match"
],
"unresolved_warnings": [],
"findings": [],
"latency_ms": 1250,
"model_calls": 2,
"tokens_input": 1850,
"tokens_output": 450
}
}
Feldreferenz fuer das accuracy-Objekt
| Feld | Typ | Beschreibung |
|---|---|---|
mode | string | Entweder standard oder enhanced |
correction_attempted | boolean | true, wenn eine Validierungsregel fehlschlug und eine Korrektur versucht wurde |
correction_used | boolean | true, wenn die Korrektur erfolgreich war und auf die Endausgabe angewendet wurde |
validators_failed | array of strings | Liste der IDs der Validierungsregeln, die im ersten Durchlauf fehlgeschlagen sind |
unresolved_warnings | array of objects | Warnungen, die nicht behoben werden konnten |
findings | array of objects | Validierungsergebnisse der Engine |
latency_ms | integer | Gesamtdauer der Extraktion in Millisekunden |
model_calls | integer | Anzahl der LLM-Aufrufe (1 fuer standard, bis zu 2 fuer enhanced) |
tokens_input | integer | Anzahl der verbrauchten Input-Token |
tokens_output | integer | Anzahl der verbrauchten Output-Token |
Dokumentgrenzen
Jeder Upload wird vor der Extraktion begrenzt. Ein Dokument oberhalb einer Grenze wird mit dem jeweiligen Code abgelehnt, statt teilweise verarbeitet zu werden.
| Grenze | Wert | Code bei Ueberschreitung |
|---|---|---|
| Uploadgroesse, Extraktions-Endpunkte | 25 MB | upload_too_large |
Uploadgroesse, /v1/documents/split | 25 MB | upload_too_large |
Uploadgroesse, /v1/documents/classify und /v1/documents/crop | 10 MB | upload_too_large |
| Uploadgroesse, AP-Workflow-Artefakt | 25 MB | artifact_too_large |
| Uploadgroesse, oeffentliche Demo | 5 MB | upload_too_large |
| PDF-Seiten, Standardextraktion | 30 | pdf_too_many_pages |
| PDF-Seiten, AP-Endpunkte | AP-Kontingent Ihres Tarifs (Pro 10, Business 100) | pdf_too_many_pages |
Dekodierte Bildgroesse (/v1/documents/crop) | 100 Megapixel | image_too_large_to_process |
| Eingebetteter E-Rechnungs-Anhang | 10 MB | einvoice_attachment_too_large |
| Dauer der PDF-Textextraktion | 20 Sekunden | pdf_extraction_timeout |
100 Seiten sind eine absolute serverseitige Obergrenze, kein Tarifanspruch. Das fuer eine Anfrage geltende Seitenlimit ist der niedrigere Wert aus dieser Obergrenze und dem Kontingent Ihres Tarifs fuer den aufgerufenen Endpunkt. Kein Endpunkt und kein kuenftiger Tarif kann mehr als 100 Seiten senden.
Extrahierter Text ist auf 400.000 Zeichen begrenzt. Diese Grenze kuerzt, statt fehlzuschlagen: ein laengeres Dokument wird bis dahin extrahiert und normal verarbeitet.
Gescannte und reine Bild-PDFs
Ein aus einem Scan erzeugtes PDF enthaelt keine Textebene, sodass das Auslesen des PDFs nichts liefert. Parsurai erkennt das und liest dieselbe Datei vor der Extraktion per OCR erneut, sodass sich ein als PDF verpackter Scan wie derselbe Scan als JPEG oder PNG verhaelt.
Der OCR-Rueckfallpfad ist unabhaengig von den obigen Seitenlimits begrenzt: er laeuft auf Dokumenten mit hoechstens 10 Seiten. Ein laengerer Scan wird mit 422 pdf_no_extractable_text abgelehnt, statt zur Erkennung gesendet zu werden. Kann auch OCR die Datei nicht lesen oder ist die Erkennung momentan nicht verfuegbar, schlaegt die Anfrage mit 422 pdf_no_extractable_text bzw. 503 ocr_unavailable fehl -- die Anfrage erreicht das Modell nie mit einem leeren Dokument.
Haeufige Fehlerantworten
| Status | Code | Typische Ursache |
|---|---|---|
401 | invalid_api_key | Fehlender, inaktiver oder unbekannter X-API-Key |
402 | feature_not_in_plan | Explizite Locale im Free-Tarif oder Pro-only Extraktionsfunktion unterhalb von Pro |
413 | upload_too_large | Datei oberhalb des Uploadlimits dieses Endpunkts |
413 | artifact_too_large | AP-Workflow-Artefakt oberhalb des Limits von 25 MB |
422 | upload_not_authorized | Dashboard-Upload vor dem Senden abgelehnt: angegebener Typ oder angegebene Groesse ausserhalb der Endpunktlimits |
422 | validation_error | Leerer Text, fehlerhafte UUID oder ungueltige Request-Struktur |
422 | unsupported_einvoice_profile | Wohlgeformtes XML, dessen UBL/CII-Profil noch nicht unterstuetzt wird |
422 | pdf_too_many_pages | PDF oberhalb des fuer den Endpunkt geltenden Seitenlimits |
422 | pdf_unreadable | Beschaedigtes, verschluesseltes oder passwortgeschuetztes PDF |
422 | pdf_no_extractable_text | Gescanntes PDF ohne Textebene, das auch OCR nicht lesen konnte |
422 | image_too_large_to_process | Bild oberhalb des Dekodierlimits von 100 Megapixeln bei /v1/documents/crop |
422 | einvoice_attachment_too_large | Eingebetteter E-Rechnungs-Anhang groesser als 10 MB |
428 | legal_reacceptance_required | Aktualisierte AGB oder Datenschutzerklaerung fuer das Konto noch nicht akzeptiert |
428 | email_verification_required | E-Mail-Adresse des Kontoinhabers noch nicht bestaetigt |
429 | rate_limit_exceeded | Request-Limit pro Minute ueberschritten |
429 | quota_exceeded | Monatliches Extraktionskontingent erschoepft |
503 | extraction_capacity_exhausted | Alle PDF-Extraktionsplaetze sind gerade belegt |
503 | ocr_unavailable | Texterkennung war fuer ein gescanntes PDF noetig und ist momentan nicht verfuegbar |
504 | pdf_extraction_timeout | Textextraktion hat das 20-Sekunden-Budget ueberschritten |
428 ist der einzige Fehler, den ein Retry nicht aufloest. Er bedeutet, dass der Kontoinhaber aktualisierte AGB oder eine aktualisierte Datenschutzerklaerung noch nicht akzeptiert hat. Jeder authentifizierte Endpunkt gibt ihn zurueck, bis das im Dashboard geschieht — ein API-Schluessel kann nicht stellvertretend akzeptieren. In einer unbeaufsichtigten Integration gehoert dieser Fall auf einen Alarm, nicht in die Retry-Schleife.
503 extraction_capacity_exhausted, 503 ocr_unavailable und 504 pdf_extraction_timeout beschreiben den Dienst, nicht Ihr Dokument. Wiederholen Sie beide mit exponentiellem Backoff, genauso wie 429 rate_limit_exceeded. Jeder andere Code in der Tabelle schlaegt bei identischer Eingabe erneut fehl -- korrigieren Sie das Dokument, statt es erneut zu senden.
Speichern Sie das rohe invoice-Objekt unveraendert, wenn Sie Vorwaertskompatibilitaet brauchen. Optionale Felder koennen null sein, aber document_type, vendor, buyer, total_amount und confidence gehoeren zum Extraktionsschema.
AP-Dokumentenextraktion (Pro und Business)
Die /v1/documents-Endpunkte extrahieren Accounts-Payable-Dokumente ueber Standardrechnungen hinaus. Sie unterstuetzen DACH-E-Rechnungen sowie Einkaufs-, Liefer-, Zahlungs- und Bankdokumente.
Endpunktuebersicht
| Endpunkt | Eingabe | Tarif |
|---|---|---|
POST /v1/documents/extract | JSON-Body mit text | Pro und Business |
POST /v1/documents/extract/file | Multipart-Datei (PDF, Bild, XML) | Pro und Business |
POST /v1/documents/extract/url | JSON-Body mit url | Pro und Business |
Dokumenttypen und Quellformate
AP-Antworten verwenden eine eigene document-Huelle mit document_type und source_format. document_type beschreibt den Geschaeftsbeleg, zum Beispiel purchase_order, delivery_note, remittance_advice, payment_advice oder bank_statement. source_format beschreibt das Eingabeformat, zum Beispiel pdf, image, xrechnung, zugferd, factur_x oder peppol_bis_billing.
XRechnung, ZUGFeRD/Factur-X und Peppol BIS Billing 3.0 werden deterministisch geparst, wenn das Profil unterstuetzt ist. Nicht unterstuetzte XML-Profile liefern 422 unsupported_einvoice_profile.
{
"document_id": "3a1b2c4d-...",
"document_type": "invoice",
"source_format": "xrechnung",
"schema_version": "1.0",
"document": {},
"classification": {
"document_type": "invoice",
"confidence": 0.98,
"signals": ["xml_profile_xrechnung"]
},
"warnings": []
}