Parse files into structured content.
One call turns a PDF, a scan, an office file, or a recording into clean markdown and structured JSON — with a bounding box on every block it emits, not only the tables and the pictures.
Look at the page before you pay for it.
Most parsing APIs run the same model over every page and bill you for all of them. We route first. Three pages in four never reach a model at all.
- 01
Send the file. That is the whole configuration.
No schema, no template, no saved config to set up first. Parse takes a URL or a file id and decides how to read it. Override the decision with one field when you already know — force OCR on a bad fax, force transcription on a recording that arrived as a PDF.
- 02
Read it with the smallest thing that works
A born-digital PDF has a text layer already. A single-column letter has no layout to solve. Those go through a rule-based pipeline with no GPU and no charge. Only the hard quarter — scans, dense tables, multi-column filings — reaches OCR and rakedoc-nano.
- 03
Markdown for people. JSON for everything else.
You get two artifacts from one read. Markdown that a person can open and a model can chunk, and structured JSON that carries the blocks, their page, and their position. Audio skips the markdown and returns the transcript instead, with a detected language and timed segments.
- 04
Every element keeps its box
Paragraphs, headings, list items, table cells, figures, footnotes — each one comes back with the rectangle it occupied. Most parsing services box the pictures and the tables and leave the text as a stream. Boxing the text is what lets a later step redact a clause, sign at an anchor, cite a source region, or show an auditor the exact cell a number came from.
- 05
Wait, or don't
A small file comes back finished on the same call. A long recording or a 300-page scan comes back with a run id to poll, or a webhook if you would rather be told. Either way the read is kept: hand the same file id to extract, redact, or sign and nothing is parsed twice.
One endpoint. Everything that arrives.
The mail room does not sort itself before it reaches you, so Parse does not ask you to sort it first either.
The parser is ours. So are the weights.
rakedoc-nano is the model that reads the hard quarter. It is first among all vision-language models on ParseBench — proprietary frontier models included — and it is published on Hugging Face under AGPL-3.0, so you can check that yourself.
- 77.2 ParseBench overall First among all VLMs, fifth overall
- 1.2 B Parameters Runs on any GPU with 8 GB, ~6 pages/s on one H100
- $0.60 Per 1,000 pages At enterprise volume; $2 rack rate, and only on pages that need a model
- AGPL-3.0 Open weights Run it, inspect it, fine-tune it, keep documents inside your perimeter
ParseBench overall score — leaderboard, including our submitted run
- LlamaParse Cost Effective 80.6
- rakedoc-nano ours, open weights 77.2
- florin-parser-nano open 76.7
- Gemini 3 Flash 75.1
- Reducto (Agentic) 73.0
- Fable 5 70.8
- Datalab Accurate 70.0
- Opus 4.8 63.7
- Azure Document Intelligence 59.6
- Google Document AI 50.4
- AWS Textract 47.9
rakedoc-nano, per dimension
- 86.4 Tables Ahead of every dedicated parsing API but one
- 88.8 Content faithfulness Within 3.5 points of the best on the bench
- 71.7 Semantic formatting Sixth overall, third among VLMs
- 74.3 Grounding The boxes, scored
- 64.9 Charts The dimension we are least proud of
Every number here comes from the public ParseBench leaderboard, including our own submitted run. Our score is the mean of three full runs on a single H100; run-to-run spread stayed within ±0.2 on every dimension. Models with no published price are on the chart anyway. We would rather you check the numbers than take our word for them.
A parser you can take with you.
We publish the weights, the lineage, the exact benchmark commit, and the run-to-run noise we measured. Serve rakedoc-nano yourself with vLLM on any card with 8 GB and no document ever leaves your network. That is a strange thing to give away, and we did it on purpose — a parser is the floor of every workflow above it, and a floor nobody can inspect is a floor nobody should stand on.
Used as a pre-processing step in front of a larger model, a small parser also earns its keep twice. It cuts the token count the model downstream has to read, and its boxes let that model point at a word on a page instead of paraphrasing one. Send us the documents that break it. That is how the next version gets trained.
You are probably paying to read pages that read themselves.
Parsing is sold per page because per page is easy to bill, not because every page costs the same to read.
- BillingWhat everyone charges One rate per page, whatever is on it.What we charge Nothing for the pages a rule can read, which on our own traffic is three in four. The model bills only on the quarter that needs it.
- BoxesWhat everyone charges Layout and table structure as paid add-ons.What we charge Included, on every element, including the text. There is no version of Parse that returns a stream of words with no coordinates.
- Lock-inWhat everyone charges A closed model, and a bill that follows your volume forever.What we charge The weights are on Hugging Face under AGPL-3.0. Self-host at high utilization and the marginal cost drops below $0.30 per 1,000 pages — on your hardware, with our blessing.
- ProofWhat everyone charges A marketing number from an internal eval.What we charge A public leaderboard, a submitted pull request, the commit we ran, and the ±0.2 spread across three runs. Reproduce it if you want to.
One call. Markdown, JSON, and boxes.
No schema to define first and nothing to configure. The second call below is extract, reusing the same file id — the page is already read, so it is not read again.
import { CloudRakerClient } from "@cloudraker/api";
const client = new CloudRakerClient({ token: "YOUR_API_KEY" });
// 1 - Read the file. Routing is automatic; override it when you know better.
const run = await client.parse({
body: { file: { url: "https://example.com/rate-filing.pdf" } },
});
console.log(run.output?.markdownUrl); // rendered markdown, time-limited URL
console.log(run.output?.jsonUrl); // blocks, page, and position
// 2 - Every block carries the rectangle it came from
const parsed = await client.fetch(run.output!.jsonUrl);
for (const block of parsed.blocks) {
console.log(block.type, block.page, block.bbox, block.text.slice(0, 60));
}
// 3 - The read is attached to the file, not the call. No second parse.
const data = await client.extract({
body: {
files: [{ id: run.file.id }],
schema: {
type: "object",
properties: { effective_date: { type: ["string", "null"] } },
},
citations: true,
},
});
console.log(data.output?.value);from cloudraker.client import CloudRaker
client = CloudRaker(token="YOUR_API_KEY")
# 1 - Read the file. Routing is automatic; override it when you know better.
run = client.parse(file={"url": "https://example.com/rate-filing.pdf"})
print(run.output.markdown_url) # rendered markdown, time-limited URL
print(run.output.json_url) # blocks, page, and position
# 2 - Every block carries the rectangle it came from
for block in client.fetch(run.output.json_url)["blocks"]:
print(block["type"], block["page"], block["bbox"], block["text"][:60])
# 3 - The read is attached to the file, not the call. No second parse.
data = client.extract(
files=[{"id": run.file.id}],
schema={
"type": "object",
"properties": {"effective_date": {"type": ["string", "null"]}},
},
citations=True,
)
print(data.output.value)Same read. Different day job.
The three paths differ in who makes the call. What comes back is the same markdown, the same JSON, and the same boxes.
Parse is the first step of most of the others.
Extract, redact, fill, compose, redline, and sign all start by reading the page. Same foundation, one read.
Send us the page that breaks it.
The free tier covers thousands of pages a month, and the pages a rule can read never count against it. Point Parse at your worst filing and read what comes back.