REST API
API Dokumentation
Alle Verarbeitungs-Endpunkte folgen dem gleichen asynchronen Muster: Job einreichen → jobId erhalten → Status pollen bis DONE.
https://datawork.devAuthentifizierung
Alle Endpunkte (ausser /auth/register und /login) erfordern einen JWT Bearer Token.
1. Token holen
POST /login Content-Type: application/x-www-form-urlencoded username=ihre@email.ch&password=IhrPasswort
→ Antwort: {"access_token":"eyJ..."}
2. Token in allen Requests mitschicken
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9...
Beispiel mit curl
TOKEN=$(curl -s -X POST https://datawork.dev/login \ -d "username=ihre@email.ch&password=IhrPasswort" \ | python3 -c "import sys,json; print(json.load(sys.stdin)['access_token'])") echo $TOKEN
Asynchrones Verarbeitungsmuster
Alle Verarbeitungs-Endpunkte sind asynchron. Es gibt zwei Varianten:
Variante A — Polling (ohne Webhook)
Job einreichen
POST mit Datei → sofort 202 Accepted + jobId
Status pollen
GET /jobs/{jobId} alle 2–3s bis status = DONE oder FAILED
Ergebnis lesen
Das fertige Ergebnis steht im Status-Response
Polling-Beispiel (Python)
import requests, time
BASE = "https://datawork.dev"
HEADERS = {"Authorization": f"Bearer {TOKEN}"}
# 1. Job einreichen
res = requests.post(f"{BASE}/extract/analyze/async",
headers=HEADERS,
data={"fields": "betrag,iban,datum"},
files={"file": open("rechnung.pdf", "rb")})
job_id = res.json()["jobId"]
# 2. Pollen bis fertig
while True:
r = requests.get(f"{BASE}/extract/jobs/{job_id}", headers=HEADERS).json()
if r["status"] in ("DONE", "FAILED"):
break
time.sleep(2)
# 3. Ergebnis
print(r["result"]["fields"])Variante B — Webhook (kein Polling nötig)
Job einreichen
POST mit Datei + webhookUrl → sofort 202 Accepted + jobId
Callback empfangen
Server sendet POST an deine webhookUrl sobald der Job DONE oder FAILED ist
Webhook-Beispiel (curl)
curl -X POST "https://datawork.dev/extract/analyze/async?webhookUrl=https://ihre-app.ch/webhook" \ -H "Authorization: Bearer $TOKEN" \ -F "file=@rechnung.pdf" \ -F "fields=betrag,iban,datum"
→ Sobald der Job abgeschlossen ist, sendet der Server automatisch:
POST https://ihre-app.ch/webhook
Content-Type: application/json
{"jobId":"abc123","status":"DONE","timestamp":"2025-01-15T10:30:00Z"} Das vollständige Ergebnis kann anschliessend per GET /jobs/{jobId} abgerufen werden.
Job-Status
Feldextraktion POST /extract/analyze/async
Extrahiert definierte Felder (Key/Value) aus einem Dokument — mit Konfidenzwert, Bounding Box und optionalem Bildausschnitt.
Request
| Parameter | Typ | Pflicht | Beschreibung |
|---|---|---|---|
file | binary | ja | PDF, PNG, JPEG |
fields | string | ja | Kommagetrennte Feldnamen, z.B. betrag,iban,datum |
includeImages | string | nein | true (default) — Bildausschnitte als base64 JPEG |
webhookUrl | query | nein | HTTPS-Callback-URL |
curl
curl -X POST https://datawork.dev/extract/analyze/async \ -H "Authorization: Bearer $TOKEN" \ -F "file=@rechnung.pdf" \ -F "fields=betrag,iban,datum,lieferant"
Antwort (DONE)
{
"jobId": "abc123",
"status": "DONE",
"result": {
"documentType": "Rechnung",
"processedPages": 1,
"fields": [
{
"key": "betrag",
"label": "Rechnungsbetrag",
"value": "CHF 1'234.50",
"confidence": 0.97,
"boundingBox": { "page": 1, "x": 120, "y": 340, "width": 180, "height": 22, "unit": "px" },
"image": "data:image/jpeg;base64,/9j/4AAQ..."
}
]
}
}Downloads
/extract/jobs/{jobId}/result — JSON-Datei/extract/jobs/{jobId}/result/csv — CSV-Export/extract/jobs/{jobId}/file — OriginaldateiMarkdown / Word Extraktion POST /structure/analyze/async
Konvertiert ein Dokument in strukturiertes GFM-Markdown und Word (.docx) — mit Überschriften, Listen, Tabellen und eingebetteten Bildern.
Request
| Parameter | Typ | Pflicht | Beschreibung |
|---|---|---|---|
file | binary | ja | PDF, PNG, JPEG |
webhookUrl | query | nein | HTTPS-Callback-URL |
curl
curl -X POST https://datawork.dev/structure/analyze/async \ -H "Authorization: Bearer $TOKEN" \ -F "file=@dokument.pdf"
Antwort (DONE)
{
"jobId": "abc123",
"status": "DONE",
"markdown": "# Protokoll Sitzung
## Traktanden
1. Begrüssung
2. ..."
}Downloads
/structure/jobs/{jobId}/result/docx — Word-Datei/structure/jobs/{jobId}/file — OriginaldateiKlassifizierung POST /classify/analyze/async
Ordnet ein Dokument automatisch einer Kategorie zu — mit Konfidenzwerten pro Klasse.
Request
| Parameter | Typ | Pflicht | Beschreibung |
|---|---|---|---|
file | binary | ja | PDF, PNG, JPEG |
classes | query | nein | Kommagetrennte Klassen, z.B. Rechnung,Vertrag,Lieferschein |
threshold | query | nein | Mindestkonfidenz 0.0–1.0 (default: 0.0) |
webhookUrl | query | nein | HTTPS-Callback-URL |
curl
curl -X POST "https://datawork.dev/classify/analyze/async?classes=Rechnung,Vertrag,Lieferschein&threshold=0.7" \ -H "Authorization: Bearer $TOKEN" \ -F "file=@dokument.pdf"
Antwort (DONE)
{
"jobId": "abc123",
"status": "DONE",
"topClass": "Rechnung",
"topConfidence": 0.94,
"belowThreshold": false,
"predictions": [
{ "className": "Rechnung", "confidence": 0.94 },
{ "className": "Lieferschein","confidence": 0.04 },
{ "className": "Vertrag", "confidence": 0.02 }
]
}Textkorrektur POST /correction/analyze/async
Erkennt Rechtschreib- und Grammatikfehler in handgeschriebenem oder gescanntem Text. Korrekturen werden direkt ins Bild eingezeichnet.
Request
| Parameter | Typ | Pflicht | Beschreibung |
|---|---|---|---|
file | binary | ja | PNG, JPEG, PDF |
webhookUrl | query | nein | HTTPS-Callback-URL |
curl
curl -X POST https://datawork.dev/correction/analyze/async \ -H "Authorization: Bearer $TOKEN" \ -F "file=@aufsatz.jpg"
Antwort (DONE)
{
"jobId": "abc123",
"status": "DONE",
"correctionCount": 3,
"originalText": "Ich gehe gerne in den Wald und suche Pilze.",
"correctedText": "Ich gehe gerne in den Wald und suche Pilze.",
"corrections": [
{ "wordIndex": 4, "original": "gerne", "corrected": "gern", "type": "grammar" }
]
}Download — korrigiertes Bild
/correction/jobs/{jobId}/result — PNG (1 Seite) oder ZIP (mehrere Seiten)Dokument befragen POST /ask/analyze/async
Stellt eine Freitextfrage an ein Dokument. Die Antwort basiert ausschliesslich auf dem Dokumentinhalt — kein Halluzinieren.
Request
| Parameter | Typ | Pflicht | Beschreibung |
|---|---|---|---|
file | binary | ja | PDF, PNG, JPEG |
question | string | ja | Frage auf Deutsch/Englisch (max. 500 Zeichen) |
webhookUrl | query | nein | HTTPS-Callback-URL |
curl
curl -X POST https://datawork.dev/ask/analyze/async \ -H "Authorization: Bearer $TOKEN" \ -F "file=@vertrag.pdf" \ -F "question=Bis wann kann der Vertrag gekündigt werden?"
Antwort (DONE)
{
"jobId": "abc123",
"status": "DONE",
"question": "Bis wann kann der Vertrag gekündigt werden?",
"answer": "Gemäss Abschnitt 8.2 kann der Vertrag mit einer Frist von 3 Monaten auf Ende eines Quartals schriftlich gekündigt werden."
}Fehler & HTTP-Status
| HTTP Status | Bedeutung |
|---|---|
202 Accepted | Job erfolgreich eingereiht — jobId im Body |
400 Bad Request | Ungültige Parameter (fehlende Pflichtfelder, ungültige webhookUrl etc.) |
401 Unauthorized | Kein oder ungültiger Bearer Token |
402 Payment Required | Guthaben nicht ausreichend |
404 Not Found | Job-ID nicht gefunden |
403 Forbidden | Job gehört einem anderen Benutzer |
502 Bad Gateway | Fehler im KI-Backend — Job wird als FAILED markiert |
Fehlerformat
{ "message": "Unzureichendes Guthaben (0.00 CHF, benötigt 0.15 CHF)" }Kosten: CHF 0.15 pro verarbeitete Seite — bei FAILED werden keine Kosten verrechnet. Neues Konto startet mit CHF 10.00 Startguthaben — keine Kreditkarte nötig. Kostenloses Konto erstellen →