Thresh

Concepts

Specs

A spec names what you want back: fields (scalar values), tables (a name plus its columns; Thresh returns every row), and questions (plain language, answered only from the document). Results always conform to your spec's shape, so your code can rely on the structure.

Value conventions

Every value is a string. Numbers come back as plain digits (no currency symbols or thousands separators), checkbox and option states as "true" or "false", and missing values as the string "null", never silently dropped. Answers are terse values quoted from the document, or "not stated".

Auto-extraction

Upload with no spec and the engine discovers the schema: every meaningful labeled field and every table, named in snake_case from the document's own labels. Output is still structurally guaranteed JSON. Use it to explore a new document family, then pin down a spec or template for production runs.

Templates

A template is a saved spec with a name, scoped to your workspace. Reference it at upload time (template=invoices) instead of repeating the spec. Uploads snapshot the resolved spec, so editing or deleting a template never changes past extractions.

Verification pass

Opt in with verify=true (a checkbox in the console, verify=True in the SDK) and the engine reads the document a second time, checking every extracted value against the pages character for character, as written. Fields the verifier cannot confirm come back with verification: "suspect" in field_meta, along with the as-written value it observed, including cases where the same field appears differently on different pages. Confirmed fields are marked verified in the result view. Verification never edits values; it only flags them for review. It roughly doubles the processing per document, so reserve it for documents where a wrong field is expensive.

Review

Open any completed result and press Review to work through the fields with the source page alongside: flagged fields come first (verification suspects, then low confidence), and each is a click to accept or a quick edit to correct. Click the page to zoom; the Original PDF button opens the source document any time. Corrections never modify the extraction result; they are stored next to it (reviews on the API, reviews() in the SDK) with who decided what, and every decision lands in the audit log. Your integration can read the reviews to apply corrected values downstream.

Deletion

Delete a document from its result page (or DELETE /v1/documents/id, or delete_document() in the SDK) and the stored file and every extracted or corrected value are erased. What remains is a tombstone: the document's status, page count, and cost stay visible so usage history and billing stay honest, and the deletion itself is recorded in the audit log. Documents still processing finish first.

Webhooks

Register an https endpoint and Thresh signs every delivery Stripe-style: the Thresh-Signature header carries a timestamp and an HMAC-SHA256 of the payload using your endpoint secret. Verify with the SDK helper or a few lines of your own; reject stale timestamps to prevent replays. Events fire on document.completed, document.failed, deal.completed (with the synthesized summary, discrepancy references resolved), and deal.failed.

Workspace roles

Console accounts carry a role. Members are the non-technical seat: they upload against saved templates (or auto-extraction), review results with the source page alongside, and read deals. Key and webhook management refuses member sessions outright, the console shows them no raw JSON, and spend figures are left out of their responses entirely. Admins additionally manage templates and workspace settings, and developers get the full technical surface. API keys themselves are workspace-level and unaffected by roles, so integrations keep working regardless of who is signed in.

Idempotency

Send an Idempotency-Key header (or idempotency_key= in the SDK) on uploads. Retries with the same key return the original document instead of creating a duplicate.

Limits

PDFs up to 32MB. Long documents are handled automatically: pages are windowed and large field sets are split across model calls, then merged, so a 60-field, 40-page document just works. Failed extractions are never billed.