Zum Inhalt springen

Ergebnisse abrufen

Ergebnisse werden nicht gepusht, sondern über den Auslieferungs-Feed abgeholt. Der Feed ist eine geordnete Sicht auf abgeschlossene Läufe. Der Server merkt sich nichts als „konsumiert“ – ihr speichert den zurückgegebenen nextCursor und schickt ihn beim nächsten Poll wieder mit.

Terminal-Fenster
curl "https://api.legentio.com/v1/scans?cursor=$CURSOR" \
-H "Authorization: Bearer $SCAN_PORTAL_API_KEY"

Antwort:

{
"items": [
{
"scanId": "k17c9c8f2a1b3d4e5f6a7b8c9d0e1f2",
"revision": 1,
"status": "completed",
"environment": "prod",
"documentType": { "slug": "rechnung", "name": "Rechnung" },
"fileName": "rechnung.pdf",
"partnerName": "Muster GmbH",
"partnerTestMode": false,
"ocrConfidence": 0.98,
"data": { "Rechnungsnummer": "", "Partner": "Muster GmbH" },
"submittedAt": "2026-07-08T09:00:00.000Z",
"completedAt": "2026-07-08T09:00:12.000Z",
"deliveredAt": "2026-07-08T09:00:12.000Z",
"resultTruncated": false
}
],
"nextCursor": "eyJ2IjoxLCJ0IjoxNzUyMH0"
}

partnerTestMode ist true, wenn der erkannte Partner für den Dokumenttyp im Testmodus steht. Solche Läufe werden normal verarbeitet und ausgeliefert, sollten aber nicht produktiv übernommen, sondern nur zur Kontrolle abgelegt werden (siehe Partner).

Parameter Beschreibung
cursor Position aus dem nextCursor der letzten Antwort. Schließt since aus.
since Startpunkt in der Vergangenheit (ISO 8601 oder Millisekunden). Für Backfill/Recovery. Schließt cursor aus.
status Komma-Liste aus completed,failed. Standard: nur completed.
environment prod (Standard), test oder all.
documentType Auf einen Dokumenttyp-Slug einschränken.
limit Seitengröße 1–200 (Standard 50).
markdown true/1/yes hängt das erkannte markdown an jeden Eintrag an.

Ohne cursor und ohne since beginnt der Feed am Anfang der Historie. status, environment und documentType sind Lesezeit-Filter – der Cursor läuft auch über übersprungene Läufe weiter, und ihr dürft Filter zwischen zwei Polls wechseln (bereits passierte Einträge werden dadurch aber nicht rückwirkend sichtbar).

cursor ← gespeicherte Position (oder leer beim ersten Mal)
wiederhole in Intervallen:
antwort ← GET /v1/scans?cursor={cursor}
für jeden eintrag in antwort.items:
verarbeite(eintrag) # idempotent! upsert nach scanId
cursor ← antwort.nextCursor
speichere(cursor) # NACH dem Verarbeiten persistieren

Speichert den Cursor erst nach dem Verarbeiten der Einträge. Stürzt der Client dazwischen ab, seht ihr dieselben Einträge erneut – das ist beabsichtigt (at-least-once).

Jeder Eintrag trägt eine revision. Ein Retry oder eine Korrektur erhöht sie und liefert den Lauf erneut im Feed aus, vor jedem gespeicherten Cursor. Führt euren Speicher deshalb als Upsert nach scanId und behaltet die höchste revision.

data und markdown werden im Feed nur als Inline-Kopie mitgeliefert. War ein Wert zu groß, ist resultTruncated: true und der Wert fehlt. Ladet ihn dann über die Einzelabfrage nach.

Liefert einen einzelnen Lauf in derselben Form wie ein Feed-Eintrag – zusätzlich aber:

  • die nicht-terminalen Status (processing, solange der Lauf noch läuft),
  • für abgeschlossene Läufe das vollständige data (bei Bedarf aus dem ausgelagerten Speicher nachgeladen) sowie rawOcrResult (OCR-Rohergebnis).
Terminal-Fenster
curl "https://api.legentio.com/v1/scans/$SCAN_ID?markdown=true" \
-H "Authorization: Bearer $SCAN_PORTAL_API_KEY"

Der Parameter markdown=true hängt das vollständige erkannte Markdown an. Unbekannte IDs (und interne Schema-Tests) sind ein 404.

Bei status = failed tragen die Einträge failureReason (maschinenlesbar) und error (deutsche Meldung) statt data. Nimm failed über status=completed,failed in den Feed auf, wenn ihr Fehlschläge automatisch auswerten wollt.