Die Ironfang Finance API hat zwei Versionen, die nebeneinander laufen. V1 unter /finance/v1 bleibt unverändert: Seine Clients behalten ihre Peppol-Strukturen, und V1 liefert nie ein Ergebnis von V2. V2 unter /finance/v2 validiert mehr Familien und Formate und meldet genau, was geprüft wurde. Nichts muss umziehen: Eine Integration mit V1 funktioniert weiter, und V2 validiert jede Familie, Peppol eingeschlossen.
Welche API was abdeckt
| Was | API |
|---|---|
| Validierung nach Peppol BIS Billing 3 (UBL) | Beide. V2 (family=peppol-bis-billing-3 oder aus dem Dokument erkannt) führt dasselbe Release auf demselben Peppol-Validator aus und meldet dieselben Prüfschritte und Befunde in seinem eigenen Ergebnis. |
| Validierung nach XRechnung 3.0.2 (UBL oder CII) | Nur V2 (family=xrechnung). |
| Validierung nach ZUGFeRD 2.5.2 / Factur-X 1.09.2 (CII-XML oder hybrides PDF) | Nur V2 (family=zugferd-facturx). |
| Erzeugung von Rechnungen aus JSON | Nur V1 (POST /finance/v1/einvoices/generate). |
| Lesbares PDF einer erzeugten Rechnung | Nur V1 (POST /finance/v1/einvoices/render). |
| Signierte Nachweisberichte | Beide. POST /finance/v2/einvoices/reports signiert einen Bericht zu jedem gespeicherten Ergebnis in dessen eigener Version, V1 oder V2; POST /finance/v1/einvoices/reports von V1 signiert nur Ergebnisse von V1. POST /finance/v2/einvoices/reports/verify prüft Berichte beider Versionen. |
| Gespeicherte Ergebnisse, Zustellungen, Jobs und Batches | Beide. V2 listet Datensätze von V1 und V2 gemeinsam auf; V1 nur seine eigenen. |
| Ziele (Webhooks und S3) | Routen von V1 (/finance/v1/einvoices/destinations); ein Ziel empfängt Events von V1 und V2. |
GET /finance/v2/einvoices/rulesets listet genau auf, welche Familie, Variante, Syntax, welchen Dokumenttyp und Prüfumfang jedes aktive Release von V2 abdeckt; nichts anderes wird unterstützt. Mehr dazu in den Leitfäden der Familien: XRechnung und ZUGFeRD / Factur-X.
Anfragen
Beide Versionen nehmen das Dokument als Body der Anfrage an, mit der Auswahl über Query-Parameter, oder als multipart/form-data mit einem Teil document und einem optionalen Teil options, der dieselbe Auswahl als JSON enthält. Bei Multipart-Anfragen werden Query-Parameter nicht gelesen, und ein unbekannter oder wiederholter Parameter oder Teil ergibt in beiden 400 malformed_request.
| V1 | V2 | |
|---|---|---|
| Body | application/xml oder text/xml | Dasselbe, oder application/pdf für eine hybride Rechnung. Der Inhalt wird geprüft; XML, das ein PDF enthält, oder umgekehrt, ergibt 415. |
| Auswahl | ruleset, profile, document_type | ruleset, family, variant, document_type, scope |
| Erkennung | Ohne Profil aus CustomizationID und ProfileID des Dokuments | Ohne Familie aus der Deklaration des Dokuments. Widerspricht das Dokument einer angegebenen Familie, ergibt das 422 family_mismatch, mit seiner eigenen Angabe in detected. |
| Prüfumfang | Nur XML | xml für XML, hybrid_pdf für ein PDF; jede andere Kombination ergibt 422 scope_unavailable. |
| Größe | XML bis 5 MiB | XML bis 5 MiB; ein PDF bis 20 MiB, 200 Seiten und 20 eingebettete Dateien, mit seinem Rechnungs-XML bis 5 MiB. |
| Frist | 10 Sekunden | 10 Sekunden für XML, 30 Sekunden für ein PDF |
Ergebnisse
Ein Ergebnis von V1 hat das Schema financewolf/einvoice/validation-result/v1, ein Ergebnis von V2 ironfang/finance/einvoice/validation-result/v2. Beide melden outcome valid oder invalid für eine abgeschlossene Validierung, allein nach den fatalen Befunden entschieden; alles, was ein Ergebnis verhindert hat, ist in beiden ein Problem mit outcome: indeterminate, und nichts wird berechnet. Die Felder, die sich unterscheiden:
| Feld | V1 | V2 |
|---|---|---|
input | sha256, bytes, content_type, document_type | media_type statt content_type; bei einem PDF zusätzlich embedded_xml, das geprüfte XML |
ruleset | requested, id, selection_method, state, vesid, official_release | Kein vesid; zusätzlich family, variant, syntax, scope und technical_release |
profile | Die Profilfamilie | Nicht vorhanden: ruleset.family und ruleset.variant |
declared | Nicht vorhanden | Was das Dokument über sich selbst angibt, übernommen: Syntax, Wurzelelement, Spezifikations- und Prozesskennungen, Typcode und bei einem PDF, was seine Metadaten deklarieren |
layers | Immer dieselben fünf: input, xml, xsd, en16931, peppol | Die eigene Abfolge der Familie aus input, pdfa, hybrid_binding, xml, xsd, en16931, peppol, xrechnung und zugferd_profile |
groups | Nicht vorhanden | Die Prüfschritte gruppiert: immer invoice_xml, bei einem PDF davor pdfa und attachment_metadata |
coverage | Nicht vorhanden | Der Prüfumfang, die ausgeführten Prüfschritte und not_checked: was das Ergebnis nicht feststellen kann, etwa ein PDF, das nicht mitgeliefert wurde |
engine / engines | Eine engine: Name, Image-Digest, Version des Hinweispakets | Eine Liste engines, jede mit einer role: xml, und pdf bei einer hybriden Prüfung |
links / next_actions | links | next_actions: view, und extract_xml bei einem PDF |
operation_id, status, counts, findings_summary, timing und usage gibt es in beiden. counts zählt in V2 zusätzlich Befunde mit information.
Befunde
| V1 | V2 | |
|---|---|---|
| Schweregrad | fatal oder warning | fatal, warning oder information; rule_flag ist die eigene Stufe der Regel, wo die Konfiguration der Familie eine andere setzt |
| Fundstelle | location (eine Zeichenkette) und location_kind: none, xpath oder line-column | Ein Objekt location mit kind (auch pdf, ein Objektpfad im PDF) und value |
| Quelle | Eine Regel-ID mit FW- kennzeichnet eine eigene Prüfung von Ironfang | rule_source: official oder ironfang |
| Hinweise | hint_code, hint, source_url, ruleset_id | hint_code, source_url |
In beiden ist message eine der festen Meldungen von Ironfang: Die offiziellen Regeltexte werden nicht wiederholt, weil sie Rechnungswerte enthalten können. rule_id ist die offizielle Kennung, unverändert.
Gespeicherte Ergebnisse
GET /finance/v2/einvoices/results listet Validierungen und Erzeugungen über V1 und Validierungen über V2 gemeinsam auf, jeweils mit der API, über die sie entstanden sind (api_version), dem Schema ihres gespeicherten Dokuments (result_schema) und ihrer Familie, und kann nach jedem davon filtern. GET /finance/v2/einvoices/results/{id} liefert jedes davon in dem Schema, in dem es entstanden ist, und DELETE löscht beide Arten. Die eigene Liste von V1 zeigt nur Ergebnisse von V1, und das Lesen eines Ergebnisses von V2 über V1 ergibt 404: Ein Ergebnis von V2 ist kein Dokument, das das Schema von V1 beschreibt. Ergebnisse werden in beiden 30 Tage aufbewahrt.
Webhook-Events und Zustellungen
Ein abgeschlossener Vorgang reiht ein Event ein, das an jedes aktivierte Webhook- oder S3-Ziel zugestellt und auf dieselbe Weise signiert wird, gleich über welche API der Vorgang lief. Ein Vorgang über V1 sendet financewolf/einvoice/event/v1, dessen result_url unter /finance/v1 liegt. Ein Vorgang über V2 sendet ironfang/finance/einvoice/event/v2, dessen result_url unter /finance/v2 liegt und dessen data zusätzlich family, variant und scope des Ergebnisses enthält. Ein Empfänger, der beide annimmt, sollte nach schema unterscheiden.
GET /finance/v2/einvoices/deliveries listet Zustellungen beider Arten auf, jede mit ihrer api_version und ihrem Event, wie es eingereiht wurde, und kann nach api_version filtern. POST /finance/v2/einvoices/deliveries/{id}/retry wiederholt eine fehlgeschlagene Zustellung beider Arten. Liste, Abruf und Wiederholung von Zustellungen in V1 sehen nur Zustellungen von Events aus V1.
Jobs und Batches
POST /finance/v2/einvoices/jobs reiht eine Validierung über V2 ein und POST /finance/v2/einvoices/batches 1 bis 100 gemeinsam, alle oder keine. Jeder Job enthält document_base64, seinen media_type und die synchronen options. Ein Dokument, das die synchrone Validierung ablehnen würde, wird schon bei der Annahme mit demselben Problem abgelehnt, und nichts wird eingereiht oder berechnet. Ergebnis, Nutzung und Event eines Jobs sind genau die einer synchronen Validierung.
| V1 | V2 | |
|---|---|---|
| Vorgänge | Validierung und Erzeugung | Validierung |
| Dokument | XML bis 5 MiB | XML bis 5 MiB oder ein PDF bis 20 MiB |
| Umschlag eines Jobs | 8 MiB | 28 MiB |
| Batch | 1 bis 100 Jobs, Umschlag 32 MiB | 1 bis 100 Jobs, Dokumente zusammen 25 MiB, Umschlag 36 MiB |
Jobs von V1 und V2 teilen sich die Warteschlange jeder Organisation: höchstens 100 nicht abgeschlossene Jobs und 25 MiB ihrer Dokumente, verschlüsselt aufbewahrt, bis sie abgeschlossen sind, höchstens 24 Stunden. Die Job- und Batch-Listen von V1 zeigen nur Arbeit aus V1; die von V2 zeigen beides.
Was beide gemeinsam haben
- API-Schlüssel der Ironfang-Plattform (
Authorization: Bearer) mit denselben Berechtigungen:finance:einvoices:writezum Validieren,finance:einvoices:readzum Lesen. - Anonyme Validierung ohne Schlüssel: Nichts wird gespeichert, und es gelten strengere Ratenbegrenzungen.
- Ein optionaler
Idempotency-Keybei authentifizierten Anfragen: Derselbe Key und dieselbe Anfrage liefern das erste Ergebnis und werden nicht erneut berechnet. Die Keys von V2 gehören V2 allein, getrennt von denen von V1. - Probleme nach RFC 9457 als
application/problem+json; unterscheiden Sie nachcode. - Ein Finance-Kontingent: Eine abgeschlossene Validierung über eine der beiden APIs ist ein Vorgang.
- Hochgeladene Dokumente werden bei der synchronen Validierung nicht gespeichert.
Beispiel
Eine Peppol-Rechnung über beide APIs, dann eine XRechnung und ein PDF nach ZUGFeRD / Factur-X, die nur V2 validiert.
# V1: a Peppol BIS Billing 3 invoice (UBL).
curl --fail-with-body --silent --show-error \
"https://api.ironfang.uk/finance/v1/einvoices/validate?ruleset=latest&profile=peppol-bis-billing-3" \
-H "Authorization: Bearer $IRONFANG_API_KEY" \
-H "Content-Type: application/xml" \
-H "Idempotency-Key: peppol-invoice-0001" \
--data-binary @peppol-invoice.xml
# V2: the same invoice. The same release runs on the same engine; the
# answer is the V2 result, with the family named instead of a profile.
curl --fail-with-body --silent --show-error \
"https://api.ironfang.uk/finance/v2/einvoices/validate?ruleset=latest&family=peppol-bis-billing-3" \
-H "Authorization: Bearer $IRONFANG_API_KEY" \
-H "Content-Type: application/xml" \
-H "Idempotency-Key: peppol-invoice-0001-v2" \
--data-binary @peppol-invoice.xml
# V2: an XRechnung invoice (UBL or CII). Only V2 validates XRechnung.
curl --fail-with-body --silent --show-error \
"https://api.ironfang.uk/finance/v2/einvoices/validate?ruleset=latest&family=xrechnung" \
-H "Authorization: Bearer $IRONFANG_API_KEY" \
-H "Content-Type: application/xml" \
-H "Idempotency-Key: xrechnung-invoice-0001" \
--data-binary @xrechnung-invoice.xml
# V2: a ZUGFeRD / Factur-X hybrid PDF. Only V2 takes a PDF.
curl --fail-with-body --silent --show-error \
"https://api.ironfang.uk/finance/v2/einvoices/validate?family=zugferd-facturx" \
-H "Authorization: Bearer $IRONFANG_API_KEY" \
-H "Content-Type: application/pdf" \
--data-binary @zugferd-invoice.pdf
