CodeB eForms Server von Aloaha

E-Rechnungs-API E-Rechnungs-API: ZUGFeRD und XRechnung aus JSON.

Ein API-Aufruf macht aus strukturierten Rechnungsdaten eine rechtskonforme elektronische Rechnung: ein PDF/A-3, das Menschen wie jedes PDF lesen, mit den Rechnungsdaten als eingebettetem XML nach EN 16931 (ZUGFeRD / Factur-X). Mit Käuferreferenz (Leitweg-ID) erfüllt die Rechnung die XRechnung-Regeln für deutsche öffentliche Auftraggeber.

Der Endpunkt füllt das Rechnungsformular Ihres Servers aus und sendet es ab: Die Rechnung wird versiegelt, auf Wunsch signiert und per E-Mail versandt wie eine im Browser erfasste Rechnung.

So funktioniert es

  1. Ihre Software sendet POST /api/v1/einvoices mit einem Bearer-Token (siehe Ein Bearer-Token erhalten) und der Rechnung als JSON.
  2. Der Server prüft die Daten, berechnet fehlende Summen und ordnet jeden Wert den Feldern seines Rechnungsformulars zu (standardmäßig das Formular zugferd).
  3. Das Formular wird über die normale Formularverarbeitung abgesendet. Sie erzeugt das XML nach EN 16931 (Cross Industry Invoice, ZUGFeRD- / Factur-X-Profil EN 16931, geschrieben nach den KoSIT-Regeln der XRechnung), bettet es in ein PDF/A-3 ein und versiegelt das PDF.
  4. Das PDF geht an Ihre Software zurück (als Base64 im JSON oder mit Accept: application/pdf als Datei) und, wie beim Webformular, per E-Mail an den Geschäftsinhaber des Formulars und an die E-Mail-Adressen in der Rechnung (Verkäufer und Käufer).

"action": "preview" endet nach Schritt 2: Sie erhalten das ausgefüllte Rechnungsformular als PDF, nichts wird versiegelt oder versandt. Damit prüfen Sie Layout und Zuordnung.

Kleinste Anfrage

Rechnungsnummer, Verkäufer, Käufer und mindestens eine Position sind Pflicht. Das Rechnungsdatum ist standardmäßig heute, die Währung die Vorgabe des Formulars (EUR beim Beispielformular), alle Summen werden berechnet.

curl -X POST https://forms.example.com/api/v1/einvoices \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" -H "Accept: application/pdf" \
  -o rechnung.pdf -d '{
  "invoice": { "number": "2026-0042", "taxPercent": 19 },
  "seller":  { "name": "Example Supplies GmbH", "street": "Musterstraße 1", "postCode": "10115", "town": "Berlin", "country": "DE", "vatId": "DE123456789" },
  "buyer":   { "name": "Example Hotel AG", "street": "Seestraße 1", "postCode": "12345", "town": "Musterstadt", "country": "DE" },
  "items":   [ { "name": "Beratung (Stunden)", "quantity": 4, "netPrice": 120 } ]
}'

Vollständiges Beispiel (XRechnung)

Eine Rechnung an eine deutsche Behörde mit Leitweg-ID, Kontaktdaten, Lieferdatum und SEPA-Zahlung. Datumsangaben nach ISO 8601 (yyyy-MM-dd; dd.MM.yyyy wird auch angenommen), Beträge als Zahlen mit Punkt als Dezimaltrennzeichen.

{
  "action": "submit",
  "invoice": {
    "number": "2026-0042", "date": "2026-10-11", "currency": "EUR",
    "dueDate": "2026-10-25", "deliveryDate": "2026-10-09", "paymentTerms": "14 Tage netto",
    "buyerReference": "04011000-12345-34", "buyerOrderReference": "PO-7781",
    "taxPercent": 19, "taxCategory": "S", "note": "Vielen Dank für Ihren Auftrag."
  },
  "seller": { "name": "Example Supplies GmbH", "contactName": "Erika Muster", "street": "Musterstraße 1",
              "postCode": "10115", "town": "Berlin", "country": "DE", "phone": "+49 30 1234567",
              "email": "billing@example.com", "vatId": "DE123456789" },
  "buyer":  { "name": "Stadt Musterstadt", "contactName": "Max Beispiel", "street": "Rathausplatz 1",
              "postCode": "12345", "town": "Musterstadt", "country": "DE", "email": "rechnungen@example.org" },
  "payment": { "iban": "DE02120300000000202051", "bic": "BYLADEM1001", "accountName": "Example Supplies GmbH" },
  "items": [
    { "name": "Beratung (Stunden)", "quantity": 4, "netPrice": 120, "sellerAssignedId": "C-100" },
    { "name": "Reisekostenpauschale", "netPrice": 80 }
  ]
}

Feldreferenz

Jedes JSON-Feld, der Geschäftsbegriff (BT) nach EN 16931, den es füllt, und der Feldname im Rechnungsformular. Pflichtfelder sind markiert.

JSONBedeutungEN 16931Formularfeld
invoice.number PflichtRechnungsnummerBT-1InvoiceID
invoice.dateRechnungsdatum (Standard: heute)BT-2date
invoice.currencyWährung nach ISO 4217 (EUR, CHF, …)BT-5InvoiceCurrencyCode
invoice.dueDateFälligkeitsdatumBT-9DueDate
invoice.buyerReferenceKäuferreferenz; bei XRechnung die Leitweg-IDBT-10BuyerReference
invoice.buyerOrderReferenceBestellnummer des KäufersBT-13BuyerOrderReference
invoice.paymentTermsZahlungsbedingungen als TextBT-20PaymentTerms
invoice.noteRechnungshinweisBT-22InvoiceNote
invoice.deliveryDateTatsächliches LieferdatumBT-72DeliveryDate
invoice.paymentReferenceVerwendungszweck (nur wenn das Formular das Feld hat)BT-83PaymentReference
invoice.taxPercentUmsatzsteuersatz in Prozent für die ganze RechnungBT-152 / BT-119TAXPercent
invoice.taxCategorySteuerkategorie: S, Z, E, AE oder G (siehe unten)BT-151 / BT-118TaxCategory
invoice.taxExemptionReasonBefreiungsgrund bei E, AE, GBT-120TaxExemptionReason
seller.name PflichtName des VerkäufersBT-27SellerName
seller.street, street2AdresszeilenBT-35, BT-36SellerStreet1, SellerStreet2
seller.postCode, town, countryPLZ, Ort, Land (ISO 3166-1, z. B. DE)BT-38, BT-37, BT-40SellerPostCode, SellerTown, SellerCountry
seller.vatIdUmsatzsteuer-IdentifikationsnummerBT-31SellerVAT
seller.contactName, phoneAnsprechpartner und TelefonBT-41, BT-42SellerPersonName, SellerPhone
seller.emailE-Mail des Verkäufers als elektronische AdresseBT-34SellerEmail
buyer.name PflichtName des KäufersBT-44BuyerName
buyer.street, street2, postCode, town, countryAdresse des KäufersBT-50 bis BT-55BuyerStreet1 … BuyerCountry
buyer.vatIdUSt-IdNr. des KäufersBT-48BuyerVAT
buyer.contactName, phoneAnsprechpartner beim KäuferBT-56, BT-57BuyerPersonName, BuyerPhone
buyer.emailE-Mail des Käufers als elektronische AdresseBT-49BuyerEmail
payment.iban, bic, accountNameBankverbindung für die SEPA-ÜberweisungBT-84, BT-86, BT-85IBAN, BIC, AccountName
items[].name PflichtArtikelbezeichnungBT-153ItemName1, ItemName2, …
items[].quantityMenge (Standard 1, Einheit C62 = Stück)BT-129BilledQuantity1, …
items[].netPrice PflichtNettoeinzelpreisBT-146NetPriceProductTradePrice1, …
items[].lineTotalNettobetrag der Position (Standard: Menge × Preis)BT-131LineTotalAmount1, …
items[].sellerAssignedIdArtikelnummer des Verkäufers (nur wenn das Formular das Feld hat)BT-155SellerAssignedID1, …
totals.lineTotal, taxTotal, grandTotalSummen; werden berechnet, wenn sie fehlenBT-106, BT-110, BT-112LineTotalAmount, TaxTotalAmount, GrandTotalAmount

Beträge, Umsatzsteuer und Rundung

  • Positionsbetrag = Menge × Nettopreis, auf 2 Nachkommastellen gerundet (kaufmännisch), außer Sie senden lineTotal.
  • Summe der Positionen = Summe der Positionsbeträge; sie ist zugleich Bemessungsgrundlage und Gesamtbetrag ohne Umsatzsteuer.
  • Umsatzsteuer = Summe der Positionen × taxPercent / 100, auf 2 Stellen gerundet. Gesamtbetrag = Summe + Umsatzsteuer; der Zahlbetrag entspricht dem Gesamtbetrag.
  • Summen, die Sie in totals senden, haben Vorrang vor der Berechnung; so übernehmen Sie die exakten Zahlen Ihrer Buchhaltung.
  • Ein Steuersatz gilt für die ganze Rechnung. Bei mehreren Steuersätzen senden Sie je Satz eine Rechnung oder fragen Sie uns nach dem ZUGFeRD Pro SDK.
  • Zahlen: 1234.5 oder "1234.50". Ein Komma wird abgelehnt, so wird aus "12,50" nie 1250.

Steuerkategorien

  • S Normalsatz (Standard). Mit Satz 0 wird daraus Z.
  • Z Nullsatz.
  • E steuerbefreit; ohne taxExemptionReason wird „Steuerfreie Leistung“ eingetragen.
  • AE Umkehr der Steuerschuld (Code VATEX-EU-AE); Standardgrund „Steuerschuldnerschaft des Leistungsempfängers“.
  • G Ausfuhr außerhalb der EU (VATEX-EU-G).

Bei E, AE und G ist der Steuersatz 0.

Zahlung

Mit iban enthält die Rechnung eine SEPA-Überweisung (Zahlungsart 58) mit BIC und Kontoinhaber. Ohne IBAN ist die Zahlungsart „nicht angegeben“ (Code 1). Zahlungsbedingungen (paymentTerms) und Fälligkeit (dueDate) werden in jedem Fall geschrieben; ohne Fälligkeitsdatum gilt das Rechnungsdatum.

Checkliste XRechnung

Rechnungen an deutsche öffentliche Auftraggeber müssen der XRechnung entsprechen. Senden Sie mindestens:

  • invoice.buyerReference = die Leitweg-ID der Behörde (ohne sie schreibt der Server eine erzeugte Referenz, die eine Behörde ablehnt).
  • seller.email und buyer.email (elektronische Adressen), seller.contactName, seller.phone.
  • seller.vatId, vollständige Adressen mit Ländercodes, invoice.dueDate oder paymentTerms.
  • Zahlungsdaten (payment.iban), wenn die Behörde überweist.

Das XML wird nach den KoSIT-Regeln geschrieben. Prüfen Sie Ihre ersten Rechnungen einmal mit dem KoSIT-Validator oder einem Viewer Ihrer Wahl.

Die Antwort

201 Created mit der Einsendungs-ID, dem PDF und den verwendeten Summen:

HTTP/1.1 201 Created
{
  "submissionId": "7f3c2a9e0d5b4e1fa2c8b6d4e9f01a23",
  "formId": "zugferd",
  "action": "submit",
  "status": "submitted",
  "pdf": { "fileName": "zugferd.pdf", "contentType": "application/pdf", "size": 152331,
           "sha256": "…", "eInvoice": true, "data": "JVBERi0xLjc…" },
  "totals": { "lineTotal": 560.00, "taxTotal": 106.40, "grandTotal": 666.40, "currency": "EUR" },
  "notOnForm": [ "PaymentReference", "SellerAssignedID1", "SellerAssignedID2" ]
}
  • pdf.eInvoice ist true, wenn das E-Rechnungs-XML im PDF eingebettet ist.
  • notOnForm nennt Werte, für die das gewählte Formular kein Feld hat (sie sind nicht Teil der Rechnung).
  • Mit Accept: application/pdf (oder "returnPdf": "binary") ist die Antwort das PDF selbst; der Header X-Submission-Id enthält die ID. "returnPdf": "none" lässt die PDF-Daten weg.
  • "action": "preview" antwortet mit 200 und der ausgefüllten, nicht versandten Rechnung.

Eigenes Rechnungsformular

Standardmäßig nutzt der Server sein Rechnungsformular (Einstellung Form for e-invoices, Vorgabe zugferd). Mit "formId" wählen Sie ein anderes, zum Beispiel eines mit Ihrem Briefkopf. Das Formular muss freigegeben sein und Felder mit den Namen aus der Feldreferenz haben; Positionen werden ab 1 (oder ab 0) nummeriert. Die Zahl der ItemName…-Felder ist die Höchstzahl der Positionen: Das Beispielformular hat 8.

Gestalten Sie das Formular im Editor, benennen Sie die Felder wie aufgeführt, geben Sie es frei und prüfen Sie die Zuordnung mit "action": "preview". GET /api/v1/forms/{formId}/fields zeigt die Feldnamen eines Formulars.

Grenzen und Fehler

Fehler kommen als Problem Details (application/problem+json); siehe auch die Fehlerliste der API.

StatusCodeBedeutung
422validation_failedEin Pflichtwert fehlt (Nummer, Name von Verkäufer oder Käufer, Bezeichnung oder Preis einer Position), ein Datum oder eine Zahl ist nicht lesbar, oder ein Wert passt nicht zum Formular (z. B. unbekannte Währung oder Land in einer Auswahlliste).
422too_many_itemsMehr Positionen, als das Formular aufnehmen kann.
422not_an_invoice_formDas gewählte Formular hat keine Positionsfelder.
403role_requiredRechnungen erstellen erfordert die Rolle user oder admin.
404 / 409form_not_found, form_not_releasedDas Rechnungsformular gibt es für dieses Token nicht oder es ist nicht freigegeben.
429rate_limited, daily_limitZu viele Anfragen oder Tagesgrenze der API-Einsendungen erreicht.
502form_processing_failedDie Rechnung konnte nicht erstellt oder versandt werden; nichts wurde zugestellt.

Fragen und Antworten

Welches ZUGFeRD-Profil erzeugt die API?

Das Profil EN 16931 (in ZUGFeRD 1 COMFORT genannt): Cross-Industry-Invoice-XML, eingebettet in ein PDF/A-3, identisch mit Factur-X. Das XML wird nach den KoSIT-Regeln geschrieben, die auch die XRechnung verwendet.

Wie erstelle ich eine XRechnung?

Senden Sie die Leitweg-ID der Behörde als invoice.buyerReference und füllen Sie E-Mail-Adressen und Kontaktdaten von Verkäufer und Käufer aus. Die API erstellt dann eine Rechnung nach EN 16931, die den XRechnung-Regeln entspricht, eingebettet im PDF.

Kann ich die Summen aus meiner Buchhaltung übergeben?

Ja. Werte in totals (lineTotal, taxTotal, grandTotal) und items[].lineTotal haben Vorrang vor der Berechnung.

Wird die Rechnung automatisch per E-Mail versandt?

Ja, wie beim Rechnungs-Webformular: an den Geschäftsinhaber des Formulars und an die E-Mail-Adressen in den Daten. Mit "action": "preview" erhalten Sie das PDF ohne Versand.

Kann eine Rechnung mehrere Steuersätze haben?

Über diesen Endpunkt nicht: Ein Satz gilt für die ganze Rechnung. Senden Sie je Satz eine Rechnung oder nutzen Sie für komplexe Rechnungen das ZUGFeRD Pro SDK.

Ihre erste E-Rechnung erstellen

Fordern Sie Testzugangsdaten an und testen Sie die E-Rechnungs-API auf unserem Online-Server.

Stand: