Eine API für den gesamten Rechnungsverkehr.
Senden Sie Rechnungen im kanonischen Modell. Weesh erzeugt das Format, prüft die Konformität und übernimmt die Zustellung. XRechnung, ZUGFeRD oder Peppol BIS bauen Sie nie selbst.
- REST & JSON
- Scoped API-Keys
- Signierte Webhooks
Einführung
Die Weesh API nimmt Rechnungen in einem einzigen, kanonischen Datenmodell entgegen und übernimmt alles Weitere: Formaterzeugung, mehrstufige Validierung, Zustellung über den passenden Kanal und revisionssichere Archivierung. Basis-URL ist https://api.weesh.org, alle Antworten sind JSON in UTF-8, alle Zeitstempel ISO 8601 in UTC.
Ein Modell, alle Formate
Sie senden JSON. Weesh erzeugt XRechnung, ZUGFeRD, UBL oder CII.
Konformität eingebaut
EN 16931, nationale CIUS und Peppol-Regeln werden vor dem Versand geprüft.
Ereignisgesteuert
Jeder Zustandswechsel erzeugt ein signiertes Webhook-Ereignis.
Quickstart
In vier Schritten von null zur ersten zugestellten Rechnung.
- 1
Workspace anlegen
Konto erstellen und Firmenprofil inkl. USt-IdNr. und Bankdaten vervollständigen.
- 2
API-Key erzeugen
Im Bereich API einen Key mit den benötigten Scopes anlegen und serverseitig hinterlegen.
- 3
Rechnung senden
POST /v1/invoices mit dem kanonischen Payload, Format und Kanal wählt Weesh automatisch.
- 4
Webhook abonnieren
Endpunkt registrieren und auf invoice.delivered bzw. invoice.rejected reagieren.
curl https://api.weesh.org/v1/invoices \
-X POST \
-H "Authorization: Bearer $WEESH_API_KEY" \
-H "Idempotency-Key: RE-2026-00125" \
-H "Content-Type: application/json" \
-d '{
"invoiceNumber": "RE-2026-00125",
"issueDate": "2026-08-26",
"currency": "EUR",
"buyer": { "peppolId": "9930:DE310558921", "buyerReference": "MG-2026-0042" },
"lineItems": [
{ "description": "Sensormodul IS-200", "quantity": 40, "unitPrice": 48, "taxRate": 19 }
],
"delivery": { "channel": "peppol", "format": "automatic" }
}'Authentifizierung
Senden Sie Ihren Organisations-API-Key als Bearer-Token. Keys gelten für genau eine Organisation, tragen feste Scopes und können jederzeit im Bereich API widerrufen werden. Verwenden Sie Keys ausschließlich serverseitig, niemals im Browser, in mobilen Apps oder in einem Git-Repository.
curl https://api.weesh.org/v1/invoices \ -H "Authorization: Bearer wsh_live_•••••••••••••" \ -H "Content-Type: application/json"
| Scope | Berechtigung |
|---|---|
| invoices:read | Rechnungen, Positionen, Status und Dokumente lesen. |
| invoices:write | Rechnungen anlegen, ändern, validieren und versenden. |
| contacts:read | Geschäftspartner und Netzwerkdaten lesen. |
| contacts:write | Geschäftspartner anlegen und pflegen. |
| p2p:read | Bestellungen, Matching, Freigaben und Zahlungen lesen. |
| p2p:write | Freigaben entscheiden und Bestellungen pflegen. |
| webhooks:manage | Webhook-Endpunkte registrieren und widerrufen. |
Umgebungen
Test-Keys (wsh_test_…) arbeiten gegen die Sandbox: Dokumente werden vollständig erzeugt und validiert, aber nicht an reale Empfänger übertragen. Live-Keys (wsh_live_…) nutzen produktive Zustellkanäle.
Sandbox
Volle API-Oberfläche, isolierte Testzustellung, frei erzeugbare Ereignisse zum Testen Ihrer Webhooks.
Produktion
Reale Zustellung, revisionssichere Archivierung, vollständiger Audit-Trail je Organisation.
Achten Sie darauf, Test- und Live-Keys strikt zu trennen. Dokumente aus der Sandbox erreichen niemals reale Empfänger.
Kanonisches Datenmodell
Alle Dokumente werden intern in einem einheitlichen Modell abgebildet, das sich an der EN 16931 orientiert. Ein- und ausgehende Rechnungen nutzen dieselbe Struktur. unabhängig davon, ob sie per API, Peppol, E-Mail oder Upload entstanden sind.
| Feld | Typ | Beschreibung |
|---|---|---|
| invoiceNumber | string | Eindeutige Rechnungsnummer der Organisation. |
| issueDate | date | Rechnungsdatum (ISO 8601). |
| dueDate | date? | Fälligkeitsdatum; optional, wenn Zahlungsbedingungen gesetzt sind. |
| currency | string | ISO-4217-Code, z. B. EUR. |
| buyer | object | Empfänger inkl. Adresse, USt-IdNr., Peppol-ID und Leitweg-ID. |
| seller | object? | Überschreibt das Firmenprofil der Organisation. |
| lineItems[] | array | Positionen mit Menge, Einheit, Einzelpreis und Steuersatz. |
| allowances[] | array? | Nachlässe und Zuschläge auf Dokumentebene. |
| paymentTerms | object? | Zahlungsziel, Skonto, Bankverbindung. |
| attachments[] | array? | Zusätzliche Anlagen (PDF, CSV) bis 10 MB je Dokument. |
| delivery | object | Kanal und Zielformat der Zustellung. |
Formate & Profile
Mit format: "automatic" wählt Weesh anhand von Empfängerland, Netzwerkfähigkeiten und Vertragsvorgaben das passende Zielformat. Ein festes Format setzen Sie nur, wenn es vertraglich gefordert ist.
xrechnung
Deutsche CIUS der EN 16931, Pflicht im Verkehr mit öffentlichen Auftraggebern.
zugferd
Hybrid: PDF/A-3 mit eingebettetem CII-XML, ideal für gemischte Empfängerlandschaften.
ubl
UBL 2.1 Invoice, Standard im Peppol-Netzwerk.
cii
UN/CEFACT Cross Industry Invoice D16B.
Validierung
Jedes Dokument durchläuft vor der Zustellung mehrere Ebenen. Schlägt eine Ebene fehl, antwortet die API mit 422 validation_failed und einer strukturierten Regelliste, die Rechnung bleibt im Status invalid und wird nicht zugestellt.
- 1
Syntax: Wohlgeformtheit und XSD-Konformität des erzeugten XML.
- 2
Schematron: EN-16931-Regeln sowie nationale CIUS-Regeln (z. B. BR-DE-*).
- 3
Geschäftsregeln: Summenprüfung, Steuerlogik, Pflichtfelder je Empfängerprofil.
- 4
Netzwerk: Empfängerfähigkeiten laut SMP, kann der Empfänger dieses Dokument annehmen?
HTTP/1.1 422 Unprocessable Entity
{
"error": {
"code": "validation_failed",
"message": "Das Dokument verletzt 2 Regeln des Profils xrechnung-3.0.",
"requestId": "req_2f90ab11",
"issues": [
{ "rule": "BR-DE-15", "field": "buyerReference", "message": "Leitweg-ID fehlt." },
{ "rule": "BR-CO-10", "field": "totals.net", "message": "Summe der Positionen stimmt nicht." }
]
}
}Status-Lebenszyklus
Jeder Zustandswechsel erzeugt einen Audit-Eintrag und ein Webhook-Ereignis.
Zustellkanäle
Setzen Sie delivery.channel explizit oder überlassen Sie Weesh die Wahl: Ist der Empfänger im Netzwerk registriert, wird Peppol verwendet, sonst greift der hinterlegte Fallback.
peppol
Zustellung über das Peppol-Netzwerk mit MLR-Quittung.
Versand als E-Mail mit XML-Anhang und visueller PDF-Darstellung.
portal
Bereitstellung im Lieferantenportal inkl. Zugriffsprotokoll.
download
Nur Erzeugung und Archivierung, Abholung über signierte Links.
Endpunkte
Alle Pfade sind relativ zu https://api.weesh.org.
Rechnungen
Netzwerk
Procure-to-Pay
Plattform
Rechnung erstellen
Nutzen Sie format: "automatic", sofern kein vertraglicher Grund für ein festes Format besteht. Die Antwort enthält Status, Validierungsergebnis und signierte Links zu allen erzeugten Dokumenten.
POST /v1/invoices
{
"invoiceNumber": "RE-2026-00125",
"issueDate": "2026-08-26",
"dueDate": "2026-09-25",
"currency": "EUR",
"buyer": {
"legalName": "Muster GmbH",
"vatId": "DE310558921",
"peppolId": "9930:DE310558921",
"buyerReference": "MG-2026-0042",
"address": {
"street": "Lindenallee 5",
"postalCode": "20095",
"city": "Hamburg",
"countryCode": "DE"
}
},
"lineItems": [
{
"description": "Industrie Sensormodul IS-200",
"quantity": 40,
"unit": "pcs",
"unitPrice": 48.00,
"taxRate": 19
}
],
"delivery": { "channel": "peppol", "format": "automatic" }
}Antwort
HTTP/1.1 201 Created
{
"id": "inv_8f21c0b4",
"invoiceNumber": "RE-2026-00125",
"status": "queued",
"totals": { "net": 1920.00, "tax": 364.80, "gross": 2284.80 },
"validation": {
"profile": "xrechnung-3.0",
"passed": true,
"layers": ["syntax", "schematron", "business-rules"]
},
"delivery": {
"channel": "peppol",
"recipient": "9930:DE310558921",
"scheduledAt": "2026-08-26T09:14:22Z"
},
"documents": [
{ "type": "xml", "format": "xrechnung", "url": "https://api.weesh.org/v1/files/…" },
{ "type": "pdf", "format": "visual", "url": "https://api.weesh.org/v1/files/…" }
]
}Filter & Pagination
Listen-Endpunkte arbeiten cursor-basiert. Übergeben Sie limit (max. 200) und den nextCursor der vorherigen Antwort. Filter lassen sich frei kombinieren: direction, status, contactId, issuedFrom, issuedTo, search.
GET /v1/invoices?direction=incoming&status=delivered&limit=50&cursor=eyJpZCI6…
{
"data": [ /* … */ ],
"hasMore": true,
"nextCursor": "eyJpZCI6Imludl84ZjIxYzBiNCJ9"
}Idempotenz & Retries
Jeder POST akzeptiert den Header Idempotency-Key. Wiederholte Anfragen mit demselben Key liefern innerhalb von 24 Stunden die ursprüngliche Antwort, statt ein zweites Dokument zu erzeugen. Bei 5xx und 429 empfehlen wir exponentielles Backoff mit Jitter (max. 5 Versuche).
POST /v1/invoices Idempotency-Key: RE-2026-00125 # Wiederholung mit gleichem Key → 200 OK mit identischem Body statt 201 Created
Fehler & Statuscodes
Jede Fehlerantwort enthält error.code, eine lesbare Nachricht und eine requestId, die Sie bei Rückfragen an den Support geben.
| HTTP | Code | Bedeutung |
|---|---|---|
| 400 | invalid_request | Payload ist syntaktisch oder semantisch fehlerhaft. |
| 401 | unauthorized | API-Key fehlt, ist widerrufen oder abgelaufen. |
| 403 | forbidden_scope | Der Key besitzt den benötigten Scope nicht. |
| 404 | not_found | Ressource existiert nicht in dieser Organisation. |
| 409 | duplicate_invoice | Rechnungsnummer wurde in dieser Organisation bereits verwendet. |
| 422 | validation_failed | Formatregeln (EN 16931, XRechnung, Peppol BIS) verletzt. |
| 429 | rate_limited | Ratenlimit überschritten, siehe Retry-After-Header. |
| 500 | internal_error | Unerwarteter Fehler. Anfrage kann idempotent wiederholt werden. |
| 503 | channel_unavailable | Zustellkanal temporär nicht erreichbar, automatischer Retry läuft. |
Ratenlimits
Limits gelten pro Organisation. Jede Antwort enthält X-RateLimit-Remaining und X-RateLimit-Reset; bei 429 zusätzlich Retry-After.
| Tarif | Anfragen/Min. | Burst | Webhooks |
|---|---|---|---|
| Starter | 60 | 120 | 3 Endpunkte |
| Business | 300 | 600 | 10 Endpunkte |
| Professional | 1.200 | 2.400 | 25 Endpunkte |
| Enterprise | individuell | individuell | unbegrenzt |
Webhooks
Registrieren Sie einen HTTPS-Endpunkt und abonnieren Sie die benötigten Ereignisse. Zustellversuche werden bis zu 8-mal mit exponentiellem Backoff wiederholt, bis Ihr System mit 2xx antwortet.
invoice.received
Ein Dokument kam über Peppol, E-Mail, Upload oder API an.
invoice.validated
Alle Validierungsebenen wurden bestanden.
invoice.validation_failed
Mindestens eine Ebene meldet einen Fehler.
invoice.sent
Die Rechnung wurde an einen Zustellkanal übergeben.
invoice.delivered
Die Zustellung wurde von der Gegenseite bestätigt.
invoice.rejected
Der Empfänger hat das Dokument abgelehnt.
invoice.approved
Eine freigebende Person hat die Rechnung im Workflow freigegeben.
match.completed
Der Abgleich mit Bestellung und Wareneingang ist abgeschlossen.
anomaly.detected
Eine Auffälligkeit wurde erkannt (Dublette, Betrag, Bankdaten).
payment.matched
Eine Zahlung wurde einer Rechnung zugeordnet.
POST https://ihr-system.de/hooks/weesh
Weesh-Signature: t=1787753892,v1=8b1f…c93a
{
"id": "evt_5c81ad02",
"type": "invoice.delivered",
"createdAt": "2026-08-26T09:15:41Z",
"organizationId": "org_7ac1",
"data": {
"invoiceId": "inv_8f21c0b4",
"invoiceNumber": "RE-2026-00125",
"channel": "peppol",
"recipient": "9930:DE310558921",
"deliveredAt": "2026-08-26T09:15:39Z"
}
}Signatur prüfen
Jede Zustellung trägt den Header Weesh-Signature (HMAC-SHA256 über timestamp.body). Prüfen Sie die Signatur gegen den rohen Request-Body, bevor Sie das Payload verarbeiten. Verwerfen Sie Ereignisse, die älter als fünf Minuten sind.
import { createHmac, timingSafeEqual } from "node:crypto";
export function verifyWeeshSignature(rawBody: string, header: string, secret: string) {
// Header-Format: t=1787753892,v1=<hex-signature>
const parts = Object.fromEntries(header.split(",").map((p) => p.split("=")));
const expected = createHmac("sha256", secret)
.update(`${parts.t}.${rawBody}`)
.digest("hex");
const a = Buffer.from(expected);
const b = Buffer.from(parts.v1 ?? "");
if (a.length !== b.length || !timingSafeEqual(a, b)) return false;
// Replay-Schutz: Zeitstempel darf max. 5 Minuten alt sein
return Math.abs(Date.now() / 1000 - Number(parts.t)) < 300;
}event.id kann bei Retries mehrfach eintreffen.Sicherheit & Datenhaltung
Strikte Mandantentrennung
Jede Abfrage ist auf die Organisation des API-Keys begrenzt, durchgesetzt auf Datenbankebene.
Verschlüsselung
TLS 1.3 im Transport, Verschlüsselung im Ruhezustand, Zugangsdaten von Integrationen nur serverseitig lesbar.
Aufbewahrung
Unveränderbare Archivierung mit Audit-Trail über die gesetzliche Aufbewahrungsfrist.
Nachvollziehbarkeit
Jede API-Aktion wird mit Zeitpunkt, Key und Ergebnis protokolliert und ist über /v1/events abrufbar.
Details zur Verarbeitung finden Sie in der Datenschutzerklärung und im Auftragsverarbeitungsvertrag.
Changelog
Die API ist versioniert. Nicht abwärtskompatible Änderungen erscheinen nur in einer neuen Hauptversion; additive Felder können jederzeit hinzukommen.
2026-08-12
Matching-API
GET /v1/matching/:invoiceId liefert 2-Way- und 3-Way-Abgleich inklusive Abweichungsgründen.
2026-06-30
Signierte Dokument-Links
Dokument-Endpunkte geben zeitlich begrenzte Download-URLs statt Base64-Inhalten zurück.
2026-05-04
Idempotency-Key
Alle POST-Endpunkte akzeptieren den Header Idempotency-Key für sichere Wiederholungen.
2026-03-18
Scoped API-Keys
Keys lassen sich pro Scope einschränken und einzeln widerrufen.
Glossar
- EN 16931
- Europäische Norm für das semantische Datenmodell der elektronischen Rechnung.
- XRechnung
- Deutsche CIUS der EN 16931, verpflichtend im Rechnungsverkehr mit öffentlichen Auftraggebern.
- ZUGFeRD
- Hybrides Format: PDF/A-3 mit eingebettetem CII-XML.
- Peppol BIS
- Business Interoperability Specification für den Austausch im Peppol-Netzwerk.
- Access Point
- Zertifizierter Zugangspunkt, der Dokumente ins Peppol-Netzwerk übergibt.
- SMP
- Service Metadata Publisher: hinterlegt, welche Dokumenttypen ein Teilnehmer empfangen kann.
- MLR
- Message Level Response: technische Empfangs- oder Fehlerquittung.
- CIUS
- Core Invoice Usage Specification: nationale Einschränkung der EN 16931.
Support
Keys und Endpunkte verwalten Sie im API-Bereich Ihres Workspace. Bei Rückfragen zu einer konkreten Anfrage nennen Sie bitte immer die requestId aus der Fehlerantwort.
In wenigen Minuten integriert.
Konto erstellen, API-Key generieren und die erste Rechnung per API versenden.