> ## Documentation Index
> Fetch the complete documentation index at: https://docs.abbyy.com/llms.txt
> Use this file to discover all available pages before exploring further.

# REST-API

Ingest stellt die API auf Port 8080 des Service `fineparser-ingest` bereit. Senden Sie Dokumente ab, fragen Sie die Jobs wiederholt ab, bis sie abgeschlossen sind, und laden Sie anschließend die Ergebnisse herunter.

Die API verfügt über keine Authentifizierung. Schalten Sie daher eine Komponente vor, die Aufrufer authentifiziert, bevor Sie die API extern zugänglich machen. Siehe [Bereitstellen der API](https://docs.abbyy.com/de/fine-parser/enterprise/best-practices/production-deployment.md#exposing-the-api).

| Endpunkt | Zweck |
| - | - |
| `POST /parse` | Ein oder mehrere Dokumente absenden. |
| `GET /jobs/{jobId}` | Status eines Jobs abrufen. |
| `GET /batch/{batchId}` | Status aller Jobs einer Anfrage abrufen. |
| `GET /jobs/{jobId}/{name}` | Ein Ergebnis herunterladen. |

```bash cURL theme={null}
# Absenden
curl -s -F files=@invoice.pdf -F outputTypes=json http://localhost:8080/parse
# {"jobs":[{"file":"invoice.pdf","jobId":"e08f769f-..."}]}

# Wiederholt abfragen
curl -s http://localhost:8080/jobs/e08f769f-...
# {"status":"successful","files":["e08f769f-.../invoice.json"],...}

# Herunterladen
curl -OJ http://localhost:8080/jobs/e08f769f-.../invoice.json
```

```python Python theme={null}
import pathlib, time

import requests

FP = "http://localhost:8080"

with open("invoice.pdf", "rb") as f:
    r = requests.post(f"{FP}/parse", files={"files": f}, data={"outputTypes": ["json"]})
r.raise_for_status()
job = r.json()["jobs"][0]["jobId"]

while (status := requests.get(f"{FP}/jobs/{job}").json())["status"] in ("pending", "in-progress"):
    time.sleep(3)
if status["status"] != "successful":
    raise RuntimeError(status["failure"])

for entry in status["files"]:
    r = requests.get(f"{FP}/jobs/{entry}")
    r.raise_for_status()
    pathlib.Path(pathlib.Path(entry).name).write_bytes(r.content)
```

## POST /parse

Eine `multipart/form-data`-Anfrage.

| Feld | Erforderlich | Wert |
| - | - | - |
| `files` | Ja | Eine PDF-Datei oder ein Bild, z. B. PNG, JPEG oder TIFF. Wiederholen Sie das Feld, um mehrere Dateien zu senden. |
| `outputTypes` | Ja | `doclang`, `json`, `xml` oder `txt`. Wiederholen Sie das Feld, um mehrere Formate anzufordern. Siehe [Ausgabeformate](https://docs.abbyy.com/de/fine-parser/enterprise/basics/output-formats.md). |
| `baseProfile` | Nein | Ein vordefiniertes Erkennungsprofil. Erfordert `userIni`. |
| `userIni` | Nein | Ein Benutzerprofil, entweder als Feld oder als Datei. Erfordert `baseProfile`. Siehe [Erkennungseinstellungen](https://docs.abbyy.com/de/fine-parser/enterprise/basics/recognition-settings.md#per-request-profiles). |

Als Antwort wird `202 Accepted` mit einer Job-ID pro Datei zurückgegeben. Bei einer Anfrage mit mehreren Dateien wird zusätzlich eine `batchId` zurückgegeben. Dateien, die nicht angenommen werden konnten, werden unter `errors` aufgeführt.

```json theme={null}
{"batchId":"c5a6dd90-...","jobs":[{"file":"a.pdf","jobId":"c2f11bb8-..."},{"file":"b.pdf","jobId":"2ab42551-..."}]}
```

`POST /parse` ist nicht idempotent. Wird die Anfrage nach Überschreitung des Zeitlimits erneut gesendet, können doppelte Jobs entstehen.

## GET /jobs/{jobId}

| Feld | Bedeutung |
| - | - |
| `status` | `pending`, `in-progress`, `successful` oder `failed`. |
| `files` | Bei `successful`: ein Eintrag pro Ergebnis, im Format `{jobId}/{name}`. |
| `durationSeconds` | Bei `successful`: Sekunden von der Übermittlung bis zum Abschluss. |
| `failure` | Bei `failed`: `{"reason": ..., "message": ...}`. |

Der Status eines abgeschlossenen Jobs wird für die in `orchestrator.jobRetentionSeconds` festgelegte Dauer (standardmäßig 24 Stunden) aufbewahrt. Danach gibt dieser Endpunkt `404` zurück, die Ergebnisse lassen sich jedoch weiterhin herunterladen.

| `reason` | Vorgehensweise |
| - | - |
| `profile-rejected` | Korrigieren Sie die in der Meldung genannte Profileinstellung. |
| `ingest-failed` | Prüfen Sie, ob sich die Datei öffnen lässt. Sie ist möglicherweise beschädigt oder liegt in einem nicht unterstützten Format vor. |
| `never-started` | Senden Sie die Datei erneut. |
| `recognition-failed` | Senden Sie die Datei noch einmal. Schlägt die Verarbeitung erneut fehl, ist das Dokument wahrscheinlich nicht lesbar. |
| `finalize-failed` | Prüfen Sie das Ausgabe-Volume und senden Sie die Datei anschließend erneut. |
| `timed-out` | Siehe [Einheitengröße und Leases](https://docs.abbyy.com/de/fine-parser/enterprise/concepts/scaling.md#unit-size-and-leases). |

## GET /batch/{batchId}

Gibt `status` für die gesamte Anfrage sowie `jobs` zurück, wobei jeder Job `jobId`, `file` und `status` in derselben Struktur wie bei `GET /jobs/{jobId}` enthält. Ein Batch ist nur dann `successful`, wenn alle seine Jobs erfolgreich sind.

## GET /jobs/{jobId}/{name}

Lädt ein Ergebnis herunter. Jeder Eintrag in `files` liegt bereits im Format `{jobId}/{name}` vor. Hängen Sie ihn daher einfach an `/jobs/` an. Beim Herunterladen wird nichts gelöscht.

## Fehler

Fehler werden als JSON zurückgegeben: `{"error":{"code":"...","message":"..."}}`. Werten Sie zur Fallunterscheidung `code` aus.

| `code` | HTTP | Bedeutung |
| - | - | - |
| `invalid_request` | 400 | Ein Feld fehlt oder ist ungültig. Die Nachricht gibt an, welches. |
| `no_files_accepted` | 400 | Es konnte keine Datei angenommen werden. `errors` gibt für jede Datei den Grund an. |
| `not_found` | 404 | Der angegebene Job, Batch, die Datei oder der Pfad existiert nicht. |
| `method_not_allowed` | 405 | Falsche HTTP-Methode. |
| `upload_too_large` | 413 | Die Anfrage überschreitet `ingest.maxUploadSize`. |
| `orchestrator_error` | 502 | Ein unerwarteter interner Fehler. |
| `orchestrator_unavailable` | 503 | Vorübergehend nicht verfügbar. Wiederholen Sie die Anfrage nach der in `Retry-After` angegebenen Anzahl Sekunden. |

## Grenzwerte

| Grenzwert | Einstellung |
| - | - |
| Anfragegröße, alle Dateien zusammen | `ingest.maxUploadSize` |
| Multipart-Formularteile pro Anfrage, Dateien und `outputTypes` zusammen | 5.000 |
| Größe von `userIni` | 1 MiB |

## CORS

Um die API aus einem Browser von einem anderen Ursprung aus aufzurufen, geben Sie die Ursprünge kommagetrennt in `ingest.cors.allowedOrigins` an. Standardmäßig sind keine Ursprünge zugelassen.
