Self-serve API
Document to JSON API
Copy a curl, send a file, get schema-shaped JSON. No sales call. Free playground first. Default cloud path is an OpenRouter-compatible endpoint with free model ids — paid OpenAI or Anthropic keys are optional.
POST /v1/extract
Accepts multipart form-data (`file` + `schema`) or a JSON body (`file_base64` + `schema`). Optionally pass `preset` as invoice | packing_list | bank_statement | bol. When AUTH_SECRET is set and DEMO_MODE is not true, send Authorization: Bearer sk_live_…
Async jobs (slow models / Cloudflare 524)
trycloudflare.com and similar proxies often close an idle POST around 100 seconds. Local Ollama extracts commonly take 2–5 minutes. Enqueue a job, then poll. Quota is checked on enqueue and counted only if the job succeeds. File bytes stay in RAM and are dropped when the job finishes — they are not written to the account store.
Success body
{
"ok": true,
"data": { "vendor": "Acme Industrial Supply Co.", "total": 4820.75 },
"meta": {
"model": "mock",
"pages": 2,
"preset": "invoice",
"filename": "invoice-acme.pdf",
"mode": "mock",
"warnings": [],
"plan": "free",
"quota_remaining": 19
}
}Error body
{
"ok": false,
"error": { "code": "INVALID_SCHEMA", "message": "Schema root must be a JSON object, not an array." }
}Limits
- File: PDF / PNG / JPG / WebP, max 10 MB, first 3 pages.
- Schema: object root, max 50 top-level keys, depth 8, 200 total keys, 64 KB.
- Burst rate limit: 60 requests / 10 minutes per client →
429 RATE_LIMITEDwithX-RateLimit-*. - Monthly quotas: Free 20 · Starter 500 · Pro 5000 →
402 QUOTA_EXCEEDED. - Auth: when
AUTH_SECRETis set andDEMO_MODEis not true, sendAuthorization: Bearer sk_live_…. - Files stay in memory for the request (sync) or until the async job finishes. Nothing is written to disk except account metadata in the JSON/KV store.
Presets
Other endpoints
POST /v1/extract— sync extract (short cloud-LLM runs)POST /v1/extract/jobs·GET /v1/extract/jobs/:id— async extract (Ollama / long runs)GET /health— liveness + feature flagsPOST /v1/auth/magic-link— passwordless sign-inGET/POST /v1/keys·DELETE /v1/keys/:idPOST /v1/billing/checkout·/v1/billing/portal·/v1/billing/webhook
Error codes
- BAD_REQUEST
- INVALID_JSON
- INVALID_SCHEMA
- SCHEMA_TOO_LARGE
- INVALID_PRESET
- MISSING_FILE
- UNSUPPORTED_FILE
- FILE_TOO_LARGE
- MODEL_FAILURE
- RATE_LIMITED
- UNAUTHORIZED
- PAYMENT_REQUIRED
- QUOTA_EXCEEDED