Docs

From first file to production job.

REST that prefers boring reliability. Base URL https://api.cupelin.com. SDKs: cupelin (Python) and @cupelin/sdk (TypeScript). Bearer API keys. Idempotency keys on create. Webhooks for long jobs.

Quickstart

from cupelin import Client

client = Client(api_key="ck_live_7f3a91c2e8b04d11")
file = client.files.upload("kiln-invoice.pdf")
parsed = client.parse.create(
    file_id=file.id,
    model="cupel-parse-2026.06",
)
print(parsed.blocks[0].text)
print(parsed.blocks[0].bbox)

Authentication

Send Authorization: Bearer ck_live_... on every call. Live keys start with ck_live_. Test keys start with ck_test_ and only accept files under 8 MB. Rotate a key in Studio. Lost keys are revoked from [email protected]. Idempotency keys are required on POST create. Replay a create with the same key for 24 hours and you get the original object.

Files

Upload with multipart form field file. Maximum 512 MB per file on Foundry and Private fire, 64 MB on Assay. Supported families include PDF, TIFF, PNG, JPEG, DOCX, PPTX, XLSX, HTML, and .eml wrappers. The response is a file_id you pass to parse, split, or extract.

{
  "id": "file_7k2m",
  "filename": "kiln-invoice.pdf",
  "bytes": 241883,
  "page_count": 3,
  "sha256": "e55c72d44b248bd26b74efbb948813bcbdfb1af3bfd3e512885bdd7e0951b943"
}

Parse

POST /v1/parse returns reading-order blocks with bounding boxes. Use model cupel-parse-2026.06 in production. Set tables to reconstruct (default) or as_image.

curl -X POST https://api.cupelin.com/v1/parse \
  -H "Authorization: Bearer ck_live_7f3a91c2e8b04d11" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: parse-18420" \
  -d '{"file_id":"file_7k2m","model":"cupel-parse-2026.06","tables":"reconstruct"}'

Extract

POST /v1/extract pours parse output into a schema. Pass a Studio schema ID or an inline JSON Schema. Confidence below 0.85 is marked needs_review.

curl -X POST https://api.cupelin.com/v1/extract \
  -H "Authorization: Bearer ck_live_7f3a91c2e8b04d11" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: extract-18420" \
  -d '{"file_id":"file_7k2m","schema_id":"schema_invoice_v3","model":"cupel-extract-2026.06"}'
{
  "id": "ext_44ab",
  "fields": {
    "vendor": {
      "value": "Kiln Goods LLC",
      "confidence": 0.98,
      "span": { "page": 1, "bbox": [72, 64, 280, 88] }
    },
    "total": {
      "value": 6805.00,
      "confidence": 0.99,
      "span": { "page": 2, "bbox": [420, 640, 540, 662] }
    }
  }
}

Webhooks

Subscribe to job.completed, job.failed, and review.ready. Cupelin signs the body with HMAC-SHA256 using your endpoint secret. Header Cupelin-Signature is t=timestamp,v1=hex. Replay window is 5 minutes. Retry policy: 8 attempts, exponential backoff, first retry at 15 seconds.

VPC

Foundry VPC add-on runs the same API in your project. Private fire includes air-gap. Endpoints stay /v1/parse, /v1/extract, /v1/jobs. Customer-managed keys are on Private fire. Write [email protected] for a residency map. Training on customer files happens only inside a named eval program you opt into.

Endpoints

POST /v1/parse

POST /v1/extract

POST /v1/split

POST /v1/jobs

GET /v1/jobs/{id}

POST /v1/files

GET /v1/files/{id}

Jobs

Long work goes through POST /v1/jobs. Poll GET /v1/jobs/{id} or wait on job.completed. Status values: queued, firing, cooled, failed, needs_review.

curl -X POST https://api.cupelin.com/v1/jobs \
  -H "Authorization: Bearer ck_live_7f3a91c2e8b04d11" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: job-binder-90" \
  -d '{"type":"split_then_extract","file_id":"file_9q1a","split":{"prompt":"FNOL, medical, photos, coverage letter"},"extract":{"schema_id":"schema_claim_v2"}}'
{
  "id": "job_7809186b",
  "status": "cooled",
  "children": [
    { "label": "FNOL", "pages": [1, 4], "extract_id": "ext_11" },
    { "label": "medical", "pages": [5, 22], "extract_id": "ext_12" }
  ]
}

Recipes

Invoice line items

Parse with tables reconstructed. Extract schema fields vendor, invoice_id, total, line_items[] with description, qty, amount. Route total below 0.85 to Studio. See the home page diagram for Kiln Goods LLC, invoice KG-18420, total 6805.00.

Multi-doc binders

Call split with a plain-language description of the packets. Run extract per child file_id. Keep child IDs stable with the parent idempotency key. The claims example on Split uses FNOL, medical, photos, coverage letter.

Eval sets

In Studio, pin a gold set of 88 rows and a held-out set of 40. Promote a pipeline only when exact field match holds or rises. kiln-ap-88 scored 94.2% on invoice v14 versus v13.

Changelog

  • Parse 2026.06 nested header tables. Merged cells in AP invoices keep a single bbox on the parent header.
  • Extract confidence routing. Fields under 0.85 emit needs_review and a Studio task.
  • Split binder recipes. Plain-language section prompts return stable child file IDs.
  • Studio eval compare. Side-by-side vN and vN-1 on a pinned gold set.
  • Public API v1. Parse, extract, jobs, webhooks. Python and TypeScript SDKs.

Status

All systems firing. Measured 30-day window ending 13 August 2026, Pacific.

Parse99.98% · p95 1.4s digital
Extract99.94% · p95 3.1s
Split99.91% · p95 2.6s
Studio99.99% · US-West, EU-West

Incidents post to kiln notes from [email protected]. Last incident: 11 June 2026, EU-West queue delay, 18 minutes, credited pages on the next invoice.