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.

Pracujesz z agentem kodującym zamiast z kodem aplikacji? DocSolved MCP łączy Codex, Claude Code, Gemini CLI i inne agenty zgodne z MCP z tym samym API.

Odczytaj pierwszy dokument w mniej niż 3 minuty

  1. Utwórz klucz API w Ustawieniach dewelopera. Zakres extract wystarczy do tej pętli; klucz jest pokazywany tylko raz.
  2. Prześlij dokument jako zadanie asynchroniczne, odpytuj o status do zakończenia, pobierz wynik.
  3. Każde pole w result.extracted_fields[] ma te same klucze: confidence, page, evidence (tekst źródłowy), match_status i bounding_box. Na torze OCR są wypełnione, gdy wartość udało się zlokalizować na stronie (match_status exact, fuzzy lub llm_located); wartość, której OCR nie zakotwiczył, ma not_found i 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:

PoleTypOpis
filefilewymaganePDF, PNG, JPG, HEIC, AVIF, TIFF, BMP lub WEBP (maks. 15 MB)
filenamestringopcjonalneZastą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.

PoleTypOpis
message_idstringwymaganeStabilny identyfikator wiadomości od dostawcy
source_namespacestringwymaganeStabilny zakres dostawcy/konta, na przykład postmark:server-123
filesfile[]wymaganePowtórz dla każdego obsługiwanego załącznika
organization_idstringopcjonalneDocelowa 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

ZdarzenieKiedy jest wywoływane
document.completedEkstrakcja została ukończona, a wynik zapisany
document.review_requiredWalidacja lub kierowanie na podstawie pewności wymaga weryfikacji przez człowieka; wywoływane również wraz z document.completed
document.approvedUpoważniona osoba zatwierdzająca zapisała decyzję o zatwierdzeniu; użyj tego do zapisów księgowych
document.failedPrzetwarzanie nie powiodło się; zadania przyjęte przez e-mail zawierają informacje o możliwości ponowienia i metadane prób
Użyj 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:

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.