PDF, scan or photo in → typed JSON out. Presets for invoices, receipts, bank statements, contracts, tables, or your own field list. Every field comes with a confidence; nothing is guessed. Try it on the demo page.
Header X-API-Key: dx_…. Limit 500 calls per key per day. Keys are issued by the service owner.
curl -X POST https://extract.skakalkin.fyi/v1/extract -H "X-API-Key: dx_…" \
-F "file=@invoice.pdf" -F "preset=invoice"
{"id": "job_…", "status": "done", "preset": "invoice", "pages": 1, "language": "de",
"fields": {"supplier_name": "Muster GmbH", "invoice_number": "RE-2026-0142", "invoice_date": "2026-10-03",
"currency": "EUR", "total": 1190.0, "items": [{"description": "Consulting", "quantity": 10, "unit_price": 100.0, "amount": 1000.0}]},
"confidence": {"supplier_name": 0.95, "total": 0.95, "due_date": 0}, "uncertain": [], "notes": "", "ms": 6400}
-F "preset=generic" -F 'schema={"fields": {
"policy_number": "insurance policy number",
"insured": "insured person, full name",
"valid_from": {"type": "date"}, "valid_to": {"type": "date"},
"premium": {"type": "number", "description": "annual premium"},
"covers": {"type": "array", "fields": {"risk": "", "limit": {"type": "number"}}}
}}' -F "hint=amounts in UAH"
Types: string (default), number, integer, date (ISO), boolean, array of flat objects. Up to 60 fields, 10 pages, 20 MB.
-F "async=1" -F "callback_url=https://your.app/hook"
→ {"id": "job_…", "status": "queued", "pages": 8, "poll": "https://extract.skakalkin.fyi/v1/jobs/job_…"}
GET https://extract.skakalkin.fyi/v1/jobs/job_… → the same result object when done; the callback receives it as JSON POST
GET https://extract.skakalkin.fyi/v1/presets field lists of all presets
GET https://extract.skakalkin.fyi/v1/jobs your last 50 jobs
POST https://extract.skakalkin.fyi/v1/keys (X-Admin-Key, form name=…) issue a client key · DELETE /v1/keys/{key}
| Code | Meaning |
|---|---|
| 401 | missing or revoked key |
| 413 | file over the size limit |
| 422 | unreadable file or invalid schema |
| 429 | daily limit reached |
| 502 | model error, retry |
Files are not stored (only a SHA-256 of the upload and the result JSON, so a job can be polled). Stack: Python, FastAPI, OpenAI vision with strict JSON schema, PyMuPDF.