Kontrakt API
Sancho rozpoznaje dokumenty przez wymienny backend OCR. Domyślnie jest to Parseur, ale wdrożenie self-hosted może wskazać własną usługę — wystarczy, że wystawi dwa endpointy HTTP opisane poniżej.
Jeśli dopiero zaczynasz implementację, zacznij od przewodnika Jak zbudować backend OCR, a tutaj wracaj po szczegóły.
Konfiguracja
Section titled “Konfiguracja”Zmienne środowiskowe API:
| Zmienna | Opis |
|---|---|
OCR_PROVIDER |
parseur (domyślnie) albo custom. |
OCR_CUSTOM_BASE_URL |
Adres bazowy usługi, np. https://ocr.firma.local. Wymagany dla custom. |
OCR_CUSTOM_SUBMIT_PATH |
Ścieżka endpointu przyjmującego dokument. Domyślnie /ocr/documents. |
OCR_CUSTOM_STATUS_PATH |
Ścieżka endpointu statusu; identyfikator zlecenia doklejany jest na końcu. Domyślnie /ocr/documents. |
OCR_CUSTOM_API_KEY |
Opcjonalny token. Gdy ustawiony, Sancho wysyła nagłówek Authorization: Bearer <token>. |
OCR_POLL_INTERVAL_MS |
Odstęp między odpytaniami. Domyślnie 3000. |
OCR_POLL_MAX_ATTEMPTS |
Maksymalna liczba odpytań. Domyślnie 60 (czyli 3 minuty przy domyślnym odstępie). |
Adres jest sklejany dosłownie: OCR_CUSTOM_BASE_URL + ścieżka. Baza może więc zawierać własny prefiks (https://ocr.firma.local/api) i nie zostanie on utracony.
Niepoprawna konfiguracja zatrzymuje start API: custom bez OCR_CUSTOM_BASE_URL, parseur bez PARSEUR_API_KEY, a także budżet odpytywania (OCR_POLL_INTERVAL_MS × OCR_POLL_MAX_ATTEMPTS) równy lub dłuższy niż 10 minut.
Endpoint 1 — przyjęcie dokumentu
Section titled “Endpoint 1 — przyjęcie dokumentu”POST {OCR_CUSTOM_BASE_URL}{OCR_CUSTOM_SUBMIT_PATH}
Żądanie multipart/form-data:
| Pole | Opis |
|---|---|
file |
Zawartość dokumentu (PDF lub obraz); nazwa pliku i typ MIME są zachowane. |
documentType |
purchase_order albo goods_received_source. |
Odpowiedź 202 (dowolny kod 2xx jest akceptowany):
{ "id": "3f1c8b12-9d4e-4a51-8b0c-1f2e3d4a5b6c", "status": "pending" }id to dowolny identyfikator unikalny w obrębie usługi — najlepiej UUID. Musi być nieprzezroczysty i bezpieczny w URL: trafia do ścieżki endpointu statusu, więc znaki takie jak / czy spacja zostaną zakodowane procentowo (%2F, %20), a wiele serwerów odrzuca %2F w segmencie ścieżki. Nie używaj numerów dokumentów.
status przyjmuje wartości pending, processing, queued, ready lub error; pominięcie pola oznacza pending. Zwrócenie ready już tutaj jest dozwolone — Sancho i tak wykona jedno odpytanie, bo odpowiedź na przyjęcie nie zawiera pola data.
Sancho nigdy nie ponawia tego żądania automatycznie — powtórka oznaczałaby drugie zlecenie dla tego samego dokumentu.
Endpoint 2 — odpytanie o wynik
Section titled “Endpoint 2 — odpytanie o wynik”GET {OCR_CUSTOM_BASE_URL}{OCR_CUSTOM_STATUS_PATH}/{id}
W trakcie przetwarzania:
{ "id": "3f1c8b12-9d4e-4a51-8b0c-1f2e3d4a5b6c", "status": "processing" }Po zakończeniu:
{ "id": "3f1c8b12-9d4e-4a51-8b0c-1f2e3d4a5b6c", "status": "ready", "data": { "documentNumber": "ZAM/1/2026", "items": [] }}Przy błędzie:
{ "id": "3f1c8b12-9d4e-4a51-8b0c-1f2e3d4a5b6c", "status": "error", "message": "Nie udało się odczytać dokumentu" }Odpowiedź spoza zakresu 2xx (w tym 404 dla nieznanego id) jest traktowana jak awaria połączenia: Sancho ponawia odpytanie w ramach pozostałego budżetu, a gdy ten się wyczerpie — oznacza dokument jako błędny.
Format wyniku
Section titled “Format wyniku”Pole data musi być zgodne ze schematem JSON odpowiadającym przesłanemu documentType:
purchase-order.schema.json—documentType: purchase_ordergoods-received-source.schema.json—documentType: goods_received_source— dowolny dokument źródłowy przyjęcia: WZ, faktura zakupu, dowód dostawy. Oprócz nagłówka i pozycji schemat zawiera klasyfikacjękind(invoice/goodsIssuedNote/other), ceny pozycji (priceNet,valueNet,vatRate) orazdeliveryCostNet— koszt transportu, zwracany zamiast pozycji usługowej witems
Zasady wspólne dla obu schematów:
- Wszystkie pola są opcjonalne — pomiń to, czego parser nie odczytał.
- Pominięta wartość skalarna jest traktowana jak
null, pominięteitemsjak[]. - Nieznane klucze są ignorowane.
- Daty to napisy w formacie
YYYY-MM-DD. - Liczby to liczby JSON, nie napisy.
- NIP-y najlepiej podawać jako same cyfry — Sancho i tak usuwa spacje oraz myślniki.
Dokument, którego wynik nie przejdzie walidacji, otrzymuje status błędu (SchemaValidationError) i nie trafia do dalszego przetwarzania.