API-Dokumentation
Mit der DokuScan-API laden Sie Dokumente per Programm hoch, rufen die Ergebnisse ab und lassen sich per Webhook benachrichtigen. Der Zugang gehört zum Business-Paket.
Inhalt
- Überblick
- Authentifizierung
- Dokument hochladen
- Scans abrufen
- Templates auflisten
- Guthaben abfragen
- Webhooks
- Fehlercodes
Überblick
- Basis-URL: https://app.dokuscan.com/api/v1
- Antworten sind JSON. Senden Sie den Header Accept: application/json, damit auch Fehler als JSON kommen.
- Zeitangaben stehen im ISO-8601-Format.
- Der Zugang gehört zum Business-Paket (ab 2.000 Scans).
Authentifizierung
Erstellen Sie API-Schlüssel in der Anwendung unter „API & Webhooks“ (bis zu 5 Schlüssel). Ein Schlüssel wird nur bei der Erstellung vollständig angezeigt. Senden Sie ihn bei jeder Anfrage als Bearer-Token oder im Header X-API-Key.
curl https://app.dokuscan.com/api/v1/account \
-H "Authorization: Bearer dsk_xxxxxxxx" \
-H "Accept: application/json"
Fehlt der Schlüssel oder ist er ungültig, antwortet die API mit 401. Gehört das Konto nicht zum Business-Paket, antwortet sie mit 403.
Dokument hochladen
POST /scans legt einen Scan an. Die Verarbeitung läuft im Hintergrund. Das Ergebnis holen Sie mit GET /scans/{id} ab oder erhalten es per Webhook.
| Parameter | Beschreibung |
|---|---|
| template_id (Pflicht) | ID des Templates, siehe GET /templates. |
| file (Pflicht) | Datei als multipart/form-data. PDF, JPG, JPEG oder PNG, bis 20 MB. |
curl -X POST https://app.dokuscan.com/api/v1/scans \
-H "Authorization: Bearer dsk_xxxxxxxx" \
-H "Accept: application/json" \
-F "template_id=12" \
-F "file=@lieferschein.pdf"
Antwort bei Erfolg (201):
{
"id": 4711,
"status": "uploaded",
"template_id": 12,
"filename": "lieferschein.pdf",
"created_at": "2026-10-18T09:15:00+00:00"
}
Ein Scan verbraucht ein Scan-Guthaben. Mehrseitige PDFs werden über die API nicht aufgeteilt, die Datei zählt als ein Scan.
Scans abrufen
GET /scans/{id} liefert einen Scan. GET /scans liefert eine Liste, neueste zuerst, 25 Einträge pro Seite. Filter: status, template_id. Seite: page.
{
"id": 4711,
"status": "completed",
"filename": "lieferschein.pdf",
"template_id": 12,
"confidence": 92,
"extracted_data": {
"lieferant": "Baustoffe Huber GmbH",
"datum": "12.10.2026",
"rows": [
{ "artikel": "Zement CEM II 25 kg", "menge": 40, "einheit": "Sack" },
{ "artikel": "Kantholz 8x10 cm", "menge": 24, "einheit": "Stk" }
]
},
"reviewed_data": null,
"validation_errors": null,
"is_partial": false,
"error_message": null,
"created_at": "2026-10-18T09:15:00+00:00",
"updated_at": "2026-10-18T09:15:21+00:00"
}
| Status | Bedeutung |
|---|---|
| uploaded | Hochgeladen, wartet auf die Verarbeitung. |
| processing | Wird verarbeitet. |
| completed | Fertig, extracted_data ist gefüllt. |
| validation_failed | Fertig, aber mindestens eine Validierungsregel wurde verletzt. Die Daten sind vorhanden, Details stehen in validation_errors. |
| failed | Fehlgeschlagen, das Guthaben wird gutgeschrieben. error_message nennt die Ursache. |
Die Struktur von extracted_data folgt den Feldern des Templates: Einzelwerte stehen unter dem Feldschlüssel, Tabellenzeilen als Liste unter rows beziehungsweise unter dem Schlüssel des Tabellenfeldes. reviewed_data enthält manuell korrigierte Werte, sofern ein Scan geprüft wurde. confidence ist ein Wert von 0 bis 100, is_partial kennzeichnet ein Teilergebnis.
Templates auflisten
GET /templates liefert die aktiven Templates des Kontos. extraction_mode ist scalar, tabular, mixed oder vision.
{
"data": [
{
"id": 12,
"name": "Lieferschein Huber",
"extraction_mode": "mixed",
"usage_count": 58,
"created_at": "2026-09-20T10:02:11.000000Z"
}
]
}
Guthaben abfragen
GET /account liefert das verbleibende Scan-Guthaben.
{
"remaining_scans": 1842,
"total_scans": 2000,
"used_scans": 158
}
Webhooks
Webhooks benachrichtigen Ihre Anwendung, sobald ein Scan fertig ist oder fehlschlägt. Anlegen können Sie sie in der Anwendung unter „API & Webhooks“ oder per API: GET /webhooks, POST /webhooks (name, url, events), DELETE /webhooks/{id} und GET /webhooks/{id}/logs.
| Ereignis | Wann |
|---|---|
| scan.completed | Ein Scan wurde verarbeitet (Status completed oder validation_failed). |
| scan.failed | Die Verarbeitung ist fehlgeschlagen. |
- Die URL muss eine öffentlich erreichbare HTTPS-Adresse sein.
- DokuScan sendet einen POST mit JSON-Body und wartet bis zu 10 Sekunden. Jeder 2xx-Status gilt als erfolgreich.
- Nach 10 Fehlern in Folge wird der Webhook automatisch deaktiviert.
- Bei der Erstellung wird ein Secret angezeigt. Es wird nur einmal vollständig gezeigt.
Beispiel für den Body bei scan.completed:
{
"event": "scan.completed",
"timestamp": "2026-10-18T09:15:21+00:00",
"data": {
"scan_id": 4711,
"filename": "lieferschein.pdf",
"template_id": 12,
"status": "completed",
"confidence": 92,
"extracted_data": { "lieferant": "Baustoffe Huber GmbH", "rows": [] },
"validation_errors": [],
"is_partial": false
}
}
Signatur prüfen
Jede Anfrage trägt die Header X-DokuScan-Event und X-DokuScan-Signature. Die Signatur ist sha256= plus der HMAC-SHA256 des rohen Request-Bodys mit Ihrem Secret. Prüfen Sie sie, bevor Sie den Inhalt verarbeiten.
// PHP
$raw = file_get_contents('php://input');
$expected = 'sha256=' . hash_hmac('sha256', $raw, $secret);
if (!hash_equals($expected, $_SERVER['HTTP_X_DOKUSCAN_SIGNATURE'] ?? '')) {
http_response_code(401);
exit;
}
// Node.js (Express, raw body)
const crypto = require('crypto');
const expected = 'sha256=' + crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
const valid = crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(req.get('X-DokuScan-Signature') || ''));
Fehlercodes
| Code | Bedeutung |
|---|---|
| 401 | API-Schlüssel fehlt oder ist ungültig. |
| 402 | Kein ausreichendes Scan-Guthaben. |
| 403 | Das Konto hat keinen API-Zugang (Business-Paket). |
| 404 | Scan oder Template nicht gefunden. |
| 409 | Diese Datei wurde mit diesem Template bereits hochgeladen. |
| 422 | Ungültige Parameter. Die Antwort nennt die betroffenen Felder. |
| 429 | Mehr als 200 Scans in der letzten Stunde. |
| 500 | Interner Fehler. Wiederholen Sie die Anfrage später. |
Fehler haben die Form {"error": "…"}. Bei 404 und 422 enthält die Antwort das Feld message, bei 422 zusätzlich errors.