WeeshWeesh

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. 1

    Workspace anlegen

    Konto erstellen und Firmenprofil inkl. USt-IdNr. und Bankdaten vervollständigen.

  2. 2

    API-Key erzeugen

    Im Bereich API einen Key mit den benötigten Scopes anlegen und serverseitig hinterlegen.

  3. 3

    Rechnung senden

    POST /v1/invoices mit dem kanonischen Payload, Format und Kanal wählt Weesh automatisch.

  4. 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"
ScopeBerechtigung
invoices:readRechnungen, Positionen, Status und Dokumente lesen.
invoices:writeRechnungen anlegen, ändern, validieren und versenden.
contacts:readGeschäftspartner und Netzwerkdaten lesen.
contacts:writeGeschäftspartner anlegen und pflegen.
p2p:readBestellungen, Matching, Freigaben und Zahlungen lesen.
p2p:writeFreigaben entscheiden und Bestellungen pflegen.
webhooks:manageWebhook-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.

FeldTypBeschreibung
invoiceNumberstringEindeutige Rechnungsnummer der Organisation.
issueDatedateRechnungsdatum (ISO 8601).
dueDatedate?Fälligkeitsdatum; optional, wenn Zahlungsbedingungen gesetzt sind.
currencystringISO-4217-Code, z. B. EUR.
buyerobjectEmpfänger inkl. Adresse, USt-IdNr., Peppol-ID und Leitweg-ID.
sellerobject?Überschreibt das Firmenprofil der Organisation.
lineItems[]arrayPositionen mit Menge, Einheit, Einzelpreis und Steuersatz.
allowances[]array?Nachlässe und Zuschläge auf Dokumentebene.
paymentTermsobject?Zahlungsziel, Skonto, Bankverbindung.
attachments[]array?Zusätzliche Anlagen (PDF, CSV) bis 10 MB je Dokument.
deliveryobjectKanal 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. 1

    Syntax: Wohlgeformtheit und XSD-Konformität des erzeugten XML.

  2. 2

    Schematron: EN-16931-Regeln sowie nationale CIUS-Regeln (z. B. BR-DE-*).

  3. 3

    Geschäftsregeln: Summenprüfung, Steuerlogik, Pflichtfelder je Empfängerprofil.

  4. 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.

draftErfasst, noch nicht validiert oder versendet.
validatingValidierung läuft (Syntax, Schematron, Geschäftsregeln).
invalidValidierung fehlgeschlagen, Fehlerliste liegt im Status-Objekt.
queuedValidiert und für die Zustellung eingeplant.
sentAn den Zustellkanal übergeben.
deliveredEmpfang bestätigt (Peppol MLR / Kanalquittung).
rejectedVom Empfänger inhaltlich abgelehnt.
archivedRevisionssicher abgelegt, unveränderbar.

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.

email

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

POST/v1/invoicesRechnung aus dem kanonischen Modell erzeugen
GET/v1/invoicesRechnungen filtern, suchen und paginieren
GET/v1/invoices/:idEinzelne Rechnung inkl. Positionen laden
PATCH/v1/invoices/:idEntwurf aktualisieren
POST/v1/invoices/:id/validateValidierung ohne Versand ausführen
POST/v1/invoices/:id/sendRechnung über einen Kanal zustellen
GET/v1/invoices/:id/statusValidierungs- und Zustellstatus lesen
GET/v1/invoices/:id/documentsXML- und PDF-Artefakte als signierte Links
POST/v1/invoices/importBestehendes UBL/CII-XML importieren

Netzwerk

GET/v1/contactsKunden und Lieferanten auflisten
POST/v1/contactsGeschäftspartner anlegen
GET/v1/network/lookupPeppol-Teilnehmer nach ID oder USt-IdNr. suchen
GET/v1/network/capabilitiesUnterstützte Dokumenttypen eines Empfängers

Procure-to-Pay

GET/v1/purchase-ordersBestellungen abrufen
POST/v1/purchase-ordersBestellung für den Abgleich anlegen
GET/v1/matching/:invoiceId2-Way-/3-Way-Match-Ergebnis lesen
POST/v1/approvals/:id/decideFreigabe erteilen oder ablehnen
GET/v1/paymentsZahlungen und Zuordnungen abrufen

Plattform

POST/v1/webhooksSignierten Webhook-Endpunkt registrieren
GET/v1/webhooks/deliveriesZustellversuche und Antworten einsehen
GET/v1/eventsAudit-Trail der Organisation lesen

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/…" }
  ]
}

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.

HTTPCodeBedeutung
400invalid_requestPayload ist syntaktisch oder semantisch fehlerhaft.
401unauthorizedAPI-Key fehlt, ist widerrufen oder abgelaufen.
403forbidden_scopeDer Key besitzt den benötigten Scope nicht.
404not_foundRessource existiert nicht in dieser Organisation.
409duplicate_invoiceRechnungsnummer wurde in dieser Organisation bereits verwendet.
422validation_failedFormatregeln (EN 16931, XRechnung, Peppol BIS) verletzt.
429rate_limitedRatenlimit überschritten, siehe Retry-After-Header.
500internal_errorUnerwarteter Fehler. Anfrage kann idempotent wiederholt werden.
503channel_unavailableZustellkanal 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.

TarifAnfragen/Min.BurstWebhooks
Starter601203 Endpunkte
Business30060010 Endpunkte
Professional1.2002.40025 Endpunkte
Enterpriseindividuellindividuellunbegrenzt
Für Massenimporte nutzen Sie Batch-Uploads statt paralleler Einzelanfragen.

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;
}
Behandeln Sie Ereignisse idempotent: 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.