Dokumentacja API DocSolved
DocSolved udostępnia REST API do wyodrębniania ustrukturyzowanych danych z przesłanych dokumentów lub znormalizowanych załączników e-mail. Trwałe zadania, zatwierdzanie przez człowieka, podpisane webhooki i eksporty księgowe wspierają automatyzacje w Make, n8n, Zapier oraz integracjach niestandardowych.
Odczytaj pierwszy dokument w mniej niż 3 minuty
- Utwórz klucz API w Ustawieniach dewelopera. Zakres
extractwystarczy do tej pętli; klucz jest pokazywany tylko raz. - Prześlij dokument jako zadanie asynchroniczne, odpytuj o status do zakończenia, pobierz wynik.
- Każde pole w
result.extracted_fields[]ma te same klucze:confidence,page,evidence(tekst źródłowy),match_statusibounding_box. Na torze OCR są wypełnione, gdy wartość udało się zlokalizować na stronie (match_statusexact,fuzzylubllm_located); wartość, której OCR nie zakotwiczył, manot_foundi pustą ramkę. Ustrukturyzowane e-faktury są parsowane z XML, więc ich pola nie niosą strony ani ramki.
cURL
export DOCAI_API_KEY="sk_docai_YOUR_KEY" # 1. submit (a retried submit with the same Idempotency-Key returns the same job) JOB_ID=$(curl -s -X POST https://docsolved.ai/api/v1/jobs \ -H "Authorization: Bearer $DOCAI_API_KEY" \ -H "Idempotency-Key: invoice-2026-0847" \ -F "[email protected]" | python3 -c 'import json,sys; print(json.load(sys.stdin)["job_id"])') # 2. poll until status is completed / review_required / failed until curl -s https://docsolved.ai/api/v1/jobs/$JOB_ID \ -H "Authorization: Bearer $DOCAI_API_KEY" | grep -qE '"status": ?"(completed|review_required|failed)"'; do sleep 2; done # 3. result curl -s https://docsolved.ai/api/v1/jobs/$JOB_ID/result \ -H "Authorization: Bearer $DOCAI_API_KEY"
Python
import os, time, requests
BASE = "https://docsolved.ai/api/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['DOCAI_API_KEY']}"}
with open("invoice.pdf", "rb") as f:
submit = requests.post(f"{BASE}/jobs", headers={**HEADERS, "Idempotency-Key": "invoice-2026-0847"},
files={"file": ("invoice.pdf", f, "application/pdf")}, timeout=60)
submit.raise_for_status()
job_id = submit.json()["job_id"]
while True:
status = requests.get(f"{BASE}/jobs/{job_id}", headers=HEADERS, timeout=30).json()["status"]
if status in ("completed", "review_required", "failed"):
break
time.sleep(2)
result = requests.get(f"{BASE}/jobs/{job_id}/result", headers=HEADERS, timeout=30).json()["result"]
for field in result["extracted_fields"]:
print(field["field"], field["value"], field["confidence"], field.get("page"), field.get("evidence"))
JavaScript / Node.js 20+
import { readFile } from "node:fs/promises";
const BASE = "https://docsolved.ai/api/v1";
const headers = { Authorization: `Bearer ${process.env.DOCAI_API_KEY}` };
const form = new FormData();
form.append("file", new Blob([await readFile("invoice.pdf")], { type: "application/pdf" }), "invoice.pdf");
const submit = await fetch(`${BASE}/jobs`, { method: "POST", headers: { ...headers, "Idempotency-Key": "invoice-2026-0847" }, body: form });
const { job_id } = await submit.json();
let status;
do {
await new Promise((r) => setTimeout(r, 2000));
({ status } = await (await fetch(`${BASE}/jobs/${job_id}`, { headers })).json());
} while (!["completed", "review_required", "failed"].includes(status));
const { result } = await (await fetch(`${BASE}/jobs/${job_id}/result`, { headers })).json();
for (const f of result.extracted_fields) console.log(f.field, f.value, f.confidence, f.page, f.evidence);
Dalej: webhooki zamiast odpytywania, idempotentne przesyłanie, weryfikacja i zatwierdzanie, eksporty, odbiór z e-maila albo to samo API z agenta kodującego przez MCP.
Uwierzytelnianie
Twórz i zarządzaj kluczami API na stronie Ustawienia dewelopera. Wysyłaj klucz jako token bearer; zakresy (scopes) i miesięczny limit stron klucza są egzekwowane przy każdym żądaniu.
Authorization: Bearer sk_docai_<your_key>
Klucze API zaczynają się od sk_docai_. Zachowaj je w tajemnicy. Są wyświetlane tylko raz, podczas tworzenia.
Użyj zakresu extract, aby przesyłać zadania i odczytywać ich wyniki. Dodaj zakres history, aby listować zapisane rekordy i pobierać eksporty księgowe, oraz zakres webhooks, aby zarządzać punktami końcowymi webhooków. To jedyne obsługiwane zakresy kluczy API. Klucze nie wygasają; unieważnij klucz w Ustawieniach dewelopera, gdy tylko przestanie być potrzebny.
Limity żądań
Wykorzystanie analizy zależy od limitu stron i limitu przechowywania w Twoim planie. Nie ma osobnego limitu na żądanie ani dziennego.
Klucze API dodatkowo rozliczają strony OCR w ramach miesięcznego limitu stron klucza.
Żądania, którym zabrakło stron lub miejsca, zwracają HTTP 402; klucz API po przekroczeniu miesięcznego limitu stron zwraca HTTP 429 ze wskazówką Retry-After.
Punkty pomocnicze (walidacja, tworzenie/test/ponowna wysyłka webhooków, publiczne linki udostępniania) mają limit 60 żądań na minutę na IP, 600 dla uwierzytelnionych; każda odpowiedź 429 zawiera Retry-After w sekundach. Aktualne wartości publikuje GET /api/v1/capabilities w polu rate_limits.
Format błędu
{
"detail": "File too large. Maximum upload size is 15 MB.",
"request_id": "3f1c9d2e8b4a4c0e9a7d1b2c3d4e5f60",
"error": {
"code": "FILE_TOO_LARGE",
"message": "File too large. Maximum upload size is 15 MB.",
"retryable": false,
"request_id": "3f1c9d2e8b4a4c0e9a7d1b2c3d4e5f60"
}
}
Rozgałęziaj po error.code, nigdy po tekście. Kody: INVALID_REQUEST, AUTHENTICATION_REQUIRED, PERMISSION_DENIED, NOT_FOUND, FILE_TOO_LARGE, UNSUPPORTED_DOCUMENT, RATE_LIMITED, QUOTA_EXCEEDED, IDEMPOTENCY_KEY_CONFLICT, PROCESSING_TIMEOUT, INTERNAL_ERROR. Ponawiaj tylko, gdy retryable jest prawdą, respektując Retry-After, i wyślij ponownie ten sam Idempotency-Key. Podaj request_id (wysyłany też w nagłówku X-Request-ID), kontaktując się z pomocą.
Zgodność
W ramach /api/v1 zmiany są wyłącznie dodatkowe: ścieżki, pola, kody błędów i statusy zadań nigdy nie są usuwane ani zmieniane typem. Zmiany łamiące trafiają do /api/v2 z co najmniej 12-miesięcznym okresem przejściowym, ogłaszane w dzienniku zmian i z nagłówkami Deprecation oraz Sunset. Odczytuj GET /api/v1/capabilities przy starcie zamiast wpisywać formaty i limity na stałe.
Synchroniczna ekstrakcja dokumentu
POST/api/v1/analyze
Prześlij dokument i uzyskaj wyniki ekstrakcji synchronicznie. Najlepsze do małych dokumentów (< 2 strony).
Żądanie
Dane formularza multipart:
| Pole | Typ | Opis | |
|---|---|---|---|
file | file | wymagane | PDF, PNG, JPG, HEIC, AVIF, TIFF, BMP lub WEBP (maks. 15 MB) |
filename | string | opcjonalne | Zastąp wyświetlaną nazwę pliku |
Przykład
curl -X POST https://docsolved.ai/api/v1/analyze \ -H "Authorization: Bearer sk_docai_..." \ -F "file=@purchase_order.pdf"
Odpowiedź
{
"request_id": "3fa8...",
"filename": "purchase_order.pdf",
"document_type": "purchase_order",
"document_type_confidence": 0.94,
"summary": "Purchase order from Acme Corp to Widget Co.",
"language": "en",
"extracted_fields": [
{
"field": "po_number",
"value": "PO-2026-0042",
"confidence": 0.97,
"page": 1,
"evidence": "PO-2026-0042"
}
],
"warnings": [],
"ocr": { "pages": 1, "tokens": 312, "language": "eng+pol" },
"llm": { "status": "success", "provider": "openai", "model": "gpt-4o-mini" }
}
Ekstrakcja strumieniowa (SSE)
POST/api/v1/analyze/stream
Tak samo jak synchroniczna, ale przesyła strumieniowo Server-Sent Events pokazujące postęp przetwarzania. Najlepsze do interfejsów działających w czasie rzeczywistym.
Utwórz zadanie asynchroniczne
POST/api/v1/jobs
Prześlij dokument i uzyskaj identyfikator zadania. Przetwarzanie odbywa się w tle.
curl -X POST https://docsolved.ai/api/v1/jobs \ -H "Authorization: Bearer sk_docai_..." \ -F "[email protected]"
{ "job_id": "abc123", "status": "queued", "request_id": "xyz..." }
Przyjmowanie załączników e-mail
POST/api/v1/ingest/email
Niezależny od dostawcy most dla poczty przychodzącej. Postmark, Mailgun, SendGrid, Amazon SES, Make, n8n lub inny adapter musi przeanalizować ładunek dostawcy i wysłać zaakceptowane załączniki jako dane formularza multipart. DocSolved nie hostuje skrzynki pocztowej ani nie wykonuje analizy MIME specyficznej dla dostawcy.
| Pole | Typ | Opis | |
|---|---|---|---|
message_id | string | wymagane | Stabilny identyfikator wiadomości od dostawcy |
source_namespace | string | wymagane | Stabilny zakres dostawcy/konta, na przykład postmark:server-123 |
files | file[] | wymagane | Powtórz dla każdego obsługiwanego załącznika |
organization_id | string | opcjonalne | Docelowa przestrzeń robocza; wywołujący musi mieć uprawnienie do przesyłania |
curl -X POST https://docsolved.ai/api/v1/ingest/email \ -H "Authorization: Bearer sk_docai_..." \ -F "message_id=provider-message-42" \ -F "source_namespace=postmark:server-123" \ -F "organization_id=org_..." \ -F "[email protected];type=application/pdf" \ -F "[email protected];type=image/jpeg"
{
"message_id": "provider-message-42",
"source_namespace": "postmark:server-123",
"accepted_count": 1,
"duplicate_count": 1,
"jobs": [
{"job_id": "job-new", "status": "queued", "filename": "invoice.pdf", "duplicate": false},
{"job_id": "job-old", "status": "completed", "filename": "receipt.jpg", "duplicate": true}
]
}
Idempotencja obejmuje uwierzytelnionego właściciela, przestrzeń nazw dostawcy/konta, miejsce docelowe, identyfikator wiadomości, znormalizowaną nazwę pliku, zawartość pliku i wystąpienie wśród identycznych załączników. Ponowienia dostawcy o zmienionej kolejności zwracają pierwotne identyfikatory zadań. Nieudane przyjęcie może ponownie umieścić to samo zadanie w kolejce ze świeżymi bajtami maksymalnie w trzech łącznych próbach; aktywne i ukończone zadania nigdy nie są przetwarzane dwukrotnie.
Pobierz status zadania
GET/api/v1/jobs/{job_id}
curl https://docsolved.ai/api/v1/jobs/abc123 \ -H "Authorization: Bearer sk_docai_..."
{
"id": "abc123",
"status": "completed",
"progress_pct": 100,
"document_type": "invoice",
"pages_processed": 2
}
Możliwe statusy: queued, processing, review_required, completed, failed, cancelled.
Pobierz wynik zadania
GET/api/v1/jobs/{job_id}/result
Zwraca pełny wynik ekstrakcji, gdy status zadania to completed lub review_required. Akceptuje zakres extract lub history, więc klucz tylko z extract obsługuje całą pętlę: wysłanie, odpytywanie, wynik.
curl https://docsolved.ai/api/v1/jobs/abc123/result \ -H "Authorization: Bearer sk_docai_..."
Eksportuj JSON
POST/api/v1/export/json
Wyślij wynik ekstrakcji jako treść JSON i otrzymaj gotowy plik eksportu.
curl -X POST https://docsolved.ai/api/v1/export/json \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk_docai_..." \
-d '{"request_id":"...","extracted_fields":[...]}' \
-o export.json
Eksportuj CSV
POST/api/v1/export/csv
curl -X POST https://docsolved.ai/api/v1/export/csv \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk_docai_..." \
-d '{"request_id":"...","extracted_fields":[...]}' \
-o fields.csv
Eksportuj XLSX
POST/api/v1/export/xlsx
Zwraca skoroszyt Excel z arkuszami Summary, Fields, Line Items, Warnings i Metadata.
Lista historii
GET/api/v1/history
curl https://docsolved.ai/api/v1/history \ -H "Authorization: Bearer sk_docai_..."
Przepływ przeglądu i zatwierdzania
POST/api/v1/history/{record_id}/workflow
Zastosuj kontrolowane przejście przepływu pracy do zapisanego rekordu. Ta trasa wymaga interaktywnej sesji Clerk: klucze API nie mogą zatwierdzać dokumentów. Członkowie przestrzeni roboczej mogą je weryfikować; administratorzy przestrzeni mogą zatwierdzać, żądać zmian lub odrzucać. Właściciel osobistego rekordu pełni obie role.
{
"action": "approve",
"comment": "Ready to post"
}
Działania: start_review, complete_review, reopen_review, submit_for_approval, approve, request_changes, reject i accept_partial_analysis. Zatwierdzenie zapisuje razem zdarzenie audytu przepływu pracy i zdarzenie skrzynki nadawczej document.approved.
Usuń całą historię
DELETE/api/v1/history
Trwale usuwa wszystkie zapisane analizy z Twojego konta.
Lista kluczy API
GET/api/v1/keys
Utwórz klucz API
POST/api/v1/keys
curl -X POST https://docsolved.ai/api/v1/keys \
-H "Authorization: Bearer <clerk_session_token>" \
-H "Content-Type: application/json" \
-d '{"name": "My automation key", "scopes": "extract,history"}'
{
"id": "...",
"name": "My automation key",
"key": "sk_docai_...", // shown ONCE - save it now
"prefix": "sk_docai_abc",
"scopes": "extract,history",
"created_at": "2026-06-10T12:00:00Z"
}
Odwołaj klucz API
DELETE/api/v1/keys/{key_id}
Utwórz webhook
POST/api/v1/webhooks
curl -X POST https://docsolved.ai/api/v1/webhooks \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"name": "My webhook", "endpoint_url": "https://my.app/hook", "event_types": ["document.completed", "document.review_required", "document.approved", "document.failed"]}'
Odpowiedź zawiera secret do weryfikacji podpisu. Zapisz go teraz, nie zostanie wyświetlony ponownie.
Typy zdarzeń webhooków
| Zdarzenie | Kiedy jest wywoływane |
|---|---|
document.completed | Ekstrakcja została ukończona, a wynik zapisany |
document.review_required | Walidacja lub kierowanie na podstawie pewności wymaga weryfikacji przez człowieka; wywoływane również wraz z document.completed |
document.approved | Upoważniona osoba zatwierdzająca zapisała decyzję o zatwierdzeniu; użyj tego do zapisów księgowych |
document.failed | Przetwarzanie nie powiodło się; zadania przyjęte przez e-mail zawierają informacje o możliwości ponowienia i metadane prób |
document.approved, a nie document.completed, jako punktu kontrolnego do księgowania danych w systemie księgowym. Ekstrakcja może zostać ukończona, gdy pola nadal wymagają korekty.
Testuj webhook
POST/api/v1/webhooks/{webhook_id}/test
Zweryfikuj podpis webhooka
Każda dostawa zawiera następujące nagłówki:
X-DocAI-Event. Typ zdarzenia (np.document.completed)X-DocAI-Timestamp. Znacznik czasu ISO 8601 UTCX-DocAI-Signature.sha256=<hmac>
import hashlib, hmac
def verify(secret, body_str, timestamp, signature_header):
msg = f"{timestamp}.{body_str}"
digest = hmac.new(secret.encode(), msg.encode(), hashlib.sha256).hexdigest()
return hmac.compare_digest(f"sha256={digest}", signature_header)
Nieudane trwałe zdarzenia
DocSolved automatycznie ponawia dostawy wychodzące. Jeśli trwałego zdarzenia skrzynki nadawczej nie można rozwinąć po pięciu próbach, staje się ono nieobsłużonym zdarzeniem. Właściciel może sprawdzić metadane bez ujawniania zapisanego ładunku i ponowić zdarzenie po usunięciu przyczyny.
GET/api/v1/webhook-outbox/failed
curl https://docsolved.ai/api/v1/webhook-outbox/failed \ -H "Authorization: Bearer sk_docai_..."
POST/api/v1/webhook-outbox/{event_id}/replay
curl -X POST https://docsolved.ai/api/v1/webhook-outbox/EVENT_ID/replay \ -H "Authorization: Bearer sk_docai_..."
Te same elementy sterujące są dostępne w Ustawieniach dewelopera → Zdarzenia wymagające uwagi. Rekordy dostaw i zakończone rekordy skrzynki nadawczej są przechowywane przez 30 dni.
Użycie z Make / n8n / Zapier
W przypadku bezpośrednich przesłań wywołaj /api/v1/jobs. W przypadku poczty przychodzącej pozwól dostawcy przetworzyć załączniki i wywołać /api/v1/ingest/email ze stabilnym identyfikatorem wiadomości i przestrzenią nazw źródła. Obie trasy tworzą te same trwałe zadania i korzystają z tego samego przepływu weryfikacji.
Subskrybuj zdarzenia ukończenia i weryfikacji, aby otrzymywać status, a następnie użyj document.approved do uruchamiania kontrolowanych działań księgowych w systemach podrzędnych. Podpisane webhooki eliminują konieczność odpytywania.
Najczęstsze pytania
Jak uwierzytelnić się w API DocSolved?
Utwórz klucz API w /developer — jest wyświetlany tylko raz — a następnie wyślij go jako token Bearer w nagłówku Authorization: Authorization: Bearer sk_docai_your_key.
Jaka jest różnica między /api/v1/analyze a /api/v1/jobs?
/api/v1/analyze zwraca wynik w tym samym żądaniu, co sprawdza się przy interaktywnym użyciu. /api/v1/jobs umieszcza dokument w kolejce, dzięki czemu odpytujesz zadanie lub otrzymujesz podpisany webhook po jego zakończeniu — lepsze rozwiązanie dla wsadów i dużych dokumentów.
Jak otrzymam powiadomienie o zakończeniu przetwarzania dokumentu?
Zarejestruj webhook. DocSolved wysyła metodą POST zdarzenie podpisane HMAC-SHA256 dla document.completed, document.review_required, document.failed i document.approved. Zweryfikuj nagłówek X-DocAI-Signature i zwróć HTTP 2xx w ciągu pięciu sekund.
Czy API zwraca dowody źródłowe dla wyodrębnionych wartości?
W przypadku zeskanowanych dokumentów każde pole zawiera tekst, z którego zostało odczytane, a jeśli OCR zlokalizował wartość — również jej stronę i prostokąt ograniczający. Ustrukturyzowane e-faktury są analizowane na podstawie ich XML i celowo nie mają prostokąta ograniczającego.