PDF to JSON with a schema you define
PdfParse converts any PDF or scan into JSON your code can read without regex. You get every block with its type, text, bounding box and confidence, and on Growth and above you can add a schema that returns exactly the fields you name, typed and traced to a page.
See the JSON for your own file
The drop zone below opens on the JSON tab, so you can inspect the real structure of page one before you write a line of code.
What one call returns
Page one rendered with every block outlined, next to the JSON your code receives.
- Reading text layer
- Detecting layout
- Extracting tables
- Building JSON
Headings, paragraphs, tables and totals detected
Portsmouth, NH 03801
| Description | Qty | Unit | Amount |
|---|---|---|---|
| Oak countertop, 2.4 m | 2 | 640.00 | 1,280.00 |
| Cabinet doors, shaker | 12 | 85.00 | 1,020.00 |
| On site fitting | 1 | 450.00 | 450.00 |
Quote the invoice number with your transfer.
Goods remain ours until paid in full.
Pages 2 and later are parsed after you create an account.
{ "document": { "pages": 2, "parsed_pages": 1, "language": "en" }, "pages": [ { "number": 1, "blocks": [ { "type": "heading", "text": "Invoice", "bbox": [48, 52, 132, 84] }, { "type": "paragraph", "text": "Harbor Street Joinery, 14 Dock Lane, Portsmouth" }, { "type": "key_value", "pairs": { "Invoice no.": "INV-2026-0418", "Issued": "Oct 14, 2026", "Due": "Nov 13, 2026" } }, { "type": "table", "columns": ["Description", "Qty", "Unit", "Amount"], "rows": [ ["Oak countertop, 2.4 m", 2, 640.00, 1280.00], ["Cabinet doors, shaker", 12, 85.00, 1020.00], ["On site fitting", 1, 450.00, 450.00] ] }, { "type": "total", "label": "Total due", "value": 2983.75, "currency": "USD", "confidence": 0.98 } ] } ], "fields": { "invoice_number": { "value": "INV-2026-0418", "confidence": 0.99, "page": 1 }, "total": { "value": 2983.75, "confidence": 0.98, "page": 1 }, "due_date": { "value": "2026-11-13", "confidence": 0.97, "page": 1 } } }
Downloads from the demo include a watermark field and cover page one only.
Page one is parsed in your browser, so your file never reaches our servers.
One demo per day from this network. Create an account to parse more pages.
$ curl https://api.pdfparse.ai/v1/parse \ -H "Authorization: Bearer $PDFPARSE_API_KEY" \ -F file[email protected] \ -F outputs=json,markdown,csv
Two layers of JSON in one response
The first layer describes the document as it is printed. Each page lists its width, height and blocks, and each block says whether it is a heading, paragraph, table, list, form field, checkbox or image. The second layer is optional and describes what you need from it, through the fields object filled by your schema.
- pages, with number, width, height and an ordered list of blocks
- blocks, with type, text, bbox as [x0, y0, x1, y1] and a confidence value
- tables, with page, rows, columns and a CSV copy of each table
- fields, with your schema values, a per field confidence and the source page
- usage, with the number of pages billed for the call
{
"id": "prs_8f2c41",
"status": "completed",
"pages": [{
"number": 1, "width": 612, "height": 792,
"blocks": [
{"type": "heading", "text": "Invoice 2024-118", "bbox": [72, 64, 310, 88], "confidence": 0.99},
{"type": "table", "text": "Item | Qty | Total", "bbox": [72, 300, 540, 420], "confidence": 0.97}
]
}],
"fields": {
"invoice_number": {"value": "2024-118", "confidence": 0.99, "page": 1},
"total_due": {"value": "6000.00", "confidence": 0.98, "page": 1}
},
"usage": {"pages": 1}
}
How a PDF becomes typed JSON
-
1
Send the file to /v1/parse, or upload it in the web app if you prefer no code.
-
2
Text is read from the text layer, and OCR fills in any page that is only an image.
-
3
Layout analysis groups characters into blocks, assigns a type and orders them for reading.
-
4
If you pass a schema_id or an inline schema, the fields are located, typed and normalized.
-
5
The response returns synchronously for small files, or as a job you fetch from /v1/jobs/{id}.
Structure that survives messy layouts
JSON is only useful when the structure is right. A table split across two pages has to arrive as one table, and a total printed in a footer must not be mistaken for a line item.
- On multi column layouts every block gets its correct position in reading order, so arrays follow the logic of the page.
- Merged cells keep their row span and column span in the table object instead of being duplicated or dropped.
- Scanned and faxed pages produce the same block types as digital ones, each with its own confidence.
- Rotated pages are normalized, and coordinates are reported for the upright page.
- Header and footer blocks are typed separately, so a page number never leaks into a schema field.
Request JSON with a schema
Define the fields once with POST /v1/schemas, then reference them by schema_id, or send the schema inline while you iterate.
curl https://api.pdfparse.ai/v1/parse \
-H "Authorization: Bearer pp_live_your_key" \
-H "Content-Type: application/json" \
-d '{
"url": "https://files.example.com/invoice-118.pdf",
"outputs": ["json"],
"schema": {
"fields": [
{"name": "invoice_number", "type": "string", "description": "Number printed after Invoice"},
{"name": "issue_date", "type": "date"},
{"name": "total_due", "type": "money"}
]
}
}'
import os
from pdfparse_ai import PdfParse
client = PdfParse(api_key=os.environ["PDFPARSE_API_KEY"])
result = client.parse("invoice-118.pdf", outputs=["json"], schema_id="sch_invoices")
for name, field in result.fields.items():
print(name, field["value"], field["confidence"], field["page"])
Who converts PDFs to JSON with PdfParse
- Backend engineers who load supplier documents into a database and need typed values, not strings.
- Fintech and lending teams reading bank statements, pay stubs and tax forms into underwriting systems.
- Product teams that let their own users upload documents and show the parsed fields for review.
- Data engineers building pipelines where low confidence fields are routed to a person before import.
The plan you need for JSON output
Block level JSON with coordinates, tables and OCR comes with Starter, $49 a month or $24 a month on yearly billing. Custom extraction schemas start on Growth at $149 a month, with up to 10 schemas, webhooks and batch jobs. Scale at $499 a month removes the schema limit and adds form field and checkbox detection, which most form heavy pipelines need. All limits sit on pdf extraction api pricing.
- Starter 2,000 pages, 1 API key, 1 seat $49 per month $24 per month, $288 billed yearly
- Growth 7,000 pages, 5 API keys, 3 seats $149 per month $74 per month, $888 billed yearly
- Scale 24,000 pages, 20 API keys, 10 seats $499 per month $249 per month, $2,988 billed yearly
- Enterprise 72,000 pages, unlimited API keys with per key limits, 25 seats $1,499 per month $749 per month, $8,988 billed yearly
FAQ
Is the JSON shape stable between documents?
Yes. Every response follows the same top level shape with id, status, pages, tables, fields, chunks and usage. Keys you did not request come back empty rather than missing.
Which field types can a schema use?
String, number, date, money, boolean and array. Dates are returned in ISO format and money as a decimal string, so you never parse currency symbols yourself.
What happens when a field is not in the document?
The field returns a null value with low confidence. Nothing is invented to fill the gap, which lets your code decide whether to ask a person.
Can I see where a value came from?
Each schema field carries its source page, and each block carries a bounding box, so you can highlight the value on the rendered page in your own interface.
Do I need a schema to get JSON?
No. Without a schema you still receive the full block and table structure. A schema only adds the fields object on top of it.
Get JSON from your PDFs today
Sign up, create a key and send the first document with a schema of your own.