Beispiele mit curl
Die Beispiele setzen https://buero.ihrbetrieb.de als Adresse voraus. Die Schlüssel sind erfunden und funktionieren nirgends; die eigenen entstehen unter Verwaltung → WorkTime Pro (siehe Authentifizierung).
WO=https://buero.ihrbetrieb.de
KEY=wo_test_ab1.NurEinBeispielKeinEchterSchluessel000000000 # allgemeiner Schlüssel
WTKEY=wo_test_wt1.NurEinBeispielKeinEchterSchluessel000000000 # Schlüssel einer WorkTime-Verbindung
Läuft der Server?
curl -s $WO/api/health
curl -s $WO/api/ready
/api/health antwortet, solange der Prozess läuft. /api/ready fragt zusätzlich die Datenbank und meldet, ob die Mandantentrennung greift:
{ "status": "ok", "mandantentrennung": "greift" }
Kunden suchen (Oberflächen-API)
curl -s "$WO/api/v1/customers?q=Meyer&take=20" -H "X-API-Key: $KEY" | jq
Die Antwort enthält kunden und gesamt. Gesucht wird in Firma, Name, Ort und E-Mail; eine reine Zahl findet auch die Kundennummer. Mit rolle=lieferant oder rolle=alle kommen Lieferanten dazu, mit archived=true die archivierten. Der Schlüssel braucht customer:read.
Zur Erinnerung: /api/v1 folgt der Oberfläche und darf sich ändern (siehe Einstieg). Für Dauerhaftes sind die WorkTime- und die Lexware-kompatible Schnittstelle da.
Rechnungsentwurf über die WorkTime-Anbindung
Erst die Verbindung prüfen:
curl -s $WO/api/worktime/v1/verbindung -H "Authorization: Bearer $WTKEY" | jq
Dann den Entwurf schicken. Der Kopf Idempotency-Key sorgt dafür, dass eine Wiederholung nach einem Netzfehler keinen zweiten Beleg anlegt:
curl -s -X POST $WO/api/worktime/v1/belege \
-H "Authorization: Bearer $WTKEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d @entwurf.json | jq
Mit entwurf.json:
{
"art": "rechnung",
"kundeId": "3f1c2b4a-0000-4000-8000-000000000010",
"datum": "2026-10-23",
"leistungVon": "2026-10-20",
"leistungBis": "2026-10-22",
"positionen": [
{ "art": "arbeit", "name": "Arbeitszeit 20.10.2026", "menge": 2.5, "einheit": "Std", "nettoPreis": 58, "steuersatz": 19 },
{ "art": "fahrt", "name": "Anfahrt", "menge": 1, "einheit": "pauschal", "nettoPreis": 35, "steuersatz": 19 },
{ "art": "text", "name": "Vielen Dank für Ihren Auftrag." }
]
}
Die Antwort (201):
{ "id": "9a8b7c6d-0000-4000-8000-000000000020", "nummer": null, "status": "entwurf", "link": "https://buero.ihrbetrieb.de/belege/9a8b7c6d-0000-4000-8000-000000000020" }
Festgeschrieben wird in WorkOffice. Den Stand holt GET /api/worktime/v1/belege/<id> ab.
Beleg einreichen (Lexware-kompatibel)
So schickt ein Shop oder eine Scan-App eine Eingangsrechnung in den Belegeingang. Der Schlüssel braucht die Vorlage „Belege einreichen“:
curl -s -X POST $WO/api/lexware/v1/files \
-H "Authorization: Bearer $KEY" \
-F "file=@rechnung-grosshandel.pdf" \
-F "type=voucher"
Antwort 202 mit id und voucherId. Den Stand der Erkennung zeigt GET /api/lexware/v1/vouchers/<voucherId>.
Die Signatur eines Lexware-Webhooks prüfen
Den öffentlichen Schlüssel einmal holen – ohne Anmeldung:
curl -s $WO/api/v1/webhooks/oeffentlicher-schluessel | jq -r .schluessel > oeffentlich.pem
Dann den empfangenen Leib (leib.json, genau die empfangenen Bytes) gegen den Wert aus X-Lxo-Signature prüfen:
echo "$SIGNATUR" | base64 -d > signatur.bin
openssl dgst -sha512 -verify oeffentlich.pem -signature signatur.bin leib.json
Erwartet: Verified OK.
Die Signatur eines WorkTime-Webhooks nachrechnen
Aus X-WorkOffice-Signatur: t=…,v1=… den Zeitstempel T nehmen und mit dem Geheimnis aus PUT /webhook rechnen:
{ printf '%s.' "$T"; cat leib.json; } | openssl dgst -sha256 -hmac "$GEHEIMNIS"
Der ausgegebene Hexwert muss mit v1 übereinstimmen, und T darf nicht älter als fünf Minuten sein.