Turn documents into typed
objects

Define a Zod or Pydantic schema. Get back a typed object with bounding-box grounding and calibrated confidence on every field.

Extraction

A schema in. Typed data out.

Describe the shape you want, send a document, and get back a typed object. Every value grounded to its source and scored for confidence.
document
INVOICE
ACME Inc
Invoice no.
INV-2026-0142
Issued
May 31, 2026
Total due $4,210.00 USD
typed object
{
vendor : 0.99
number : 0.98
issued : 0.97
total : 0.96
currency : 0.99
}

schema

const Invoice = object({
  vendor: string(),  number: string(),  issued: date(),  total: number(),  currency: enum(["USD", "EUR"]),})

document

INVOICE
ACME Inc
Invoice no.
INV-2026-0142
Issued
May 31, 2026
Design retainer $3,000.00
Asset licensing $1,210.00
Total due $4,210.00 USD

typed object

{
vendor :
0.99
number :
0.98
issued :
0.97
total :
0.96
currency :
0.99
}
Review
Every value comes back with a confidence score. Set your own threshold: anything below it is flagged, never silently accepted.
confidence review
threshold 0.90
merchant "Blue Bottle"
0.99
date "2026-05-29"
0.98
subtotal 38.00
0.96
tax 3.42
0.82
total 41.42
0.99
4 auto-accepted 1 to review
Grounding
The anchor rides the response: the page and the words each value came from. A reviewer checks the flagged span, not the whole document.
source anchor
receipt_4821.jpg · 1 page
BLUE BOTTLE COFFEE p.1
05/29/2026 14:12 p.1
SUBTOTAL $38.00 p.1
TAX 8.875% $3.42 p.1
TOTAL $41.42 p.1
5 anchored
Evals as code

Know your accuracy
before you commit.

mean field accuracy
97.8 %
1 field below your 95% bar· review →
Golden set in, per-field accuracy out. The eval runs in your own repo, as a CI gate, before you pay for a page.
SDKs

One object.
Your types.

The same result, validated into your own Zod or Pydantic types. No JSON to map, no any to wrangle. Plain JSON Schema works everywhere: in both SDKs and over raw HTTP.

import { z } from "zod"
import { VelrimClient } from "@velrim/sdk"
const Invoice = z.object({
vendor: z.string(),
number: z.string(),
issued: z.coerce.date(),
total: z.number(),
currency: z.enum(["USD", "EUR"]),
})
const velrim = new VelrimClient({ apiKey })
const { data } = await velrim.extract(Invoice, { bytes })
field value type
vendor "ACME Inc" string
number "INV-2026-0142" string
issued "2026-05-31" Date
total 4210.0 number
currency "USD" "USD" | "EUR"
Pricing

Priced in the open. And you set the ceiling
on your worst day.

500
Free pages to start
No credit card. One-time, on the house.
$0
Over your cap, ever
You set the ceiling; overage is opt-in, off by default.

See exactly how pages are priced on the pricing page.

Ready when you are.

Define a schema, send a document, get a typed object back. Your first extraction is a curl away.