AI Extract for Documents: PDFs, Filings and Tenders to Typed JSON
A pdf to json api turns a public PDF into typed JSON. See a real IRS W-9 call over API or MCP, what it costs (5 points, empty results billed) and its limits.
By the NeuralVerge team · 14 min read · Updated October 2026
▸On this page
A pdf to json api takes the address of a public PDF and returns the fields you asked for as typed JSON, so nobody has to read the document and no parser has to guess where the number sits on page 14. NeuralVerge's AI Extract does this for annual reports, filings, tenders and forms, over REST or MCP. This article shows a real call on the IRS Form W-9, what it cost and where it stops.
The short version
- —What it is: AI Extract reads a document you point it at, maps the content to fields you describe or pin with a JSON Schema, and returns JSON. With a schema the typed object comes back in
machine. - —Who it is for: teams that process the same kind of document hundreds of times (filings, tenders, data sheets, forms) and want rows, not text. For web pages, see AI extraction in the product.
- —What it costs: a flat 5 points per call, as the product and pricing pages state it. A call on a dead URL returned null and was still billed 5 points.
- —What it takes: a public URL. The product pages describe no file-upload route and make no claim about scans or handwriting, so test your own.
What a pdf to json api does
A PDF is a layout format. It records where glyphs go on a page, not what they mean. A pdf to json api reads that layout and returns meaning: instead of lines of text, you get contract_value, deadline and issuing_authority as named fields with types. Three adjacent tools are often used for the same job, and each leaves a different gap.
Versus a PDF text extractor
A text extractor gives you the characters from the file, usually in reading order. That is a good first step, but the result is still prose. Somebody has to write the rules that find the total in a table, and those rules break when the next publisher lays out the same kind of document differently. Extraction by meaning asks for "the total contract value" and looks for it wherever it is.
Versus asking a chat model to read the file
Pasting a document into a general-purpose chat model is useful for one-off reading. For a pipeline it is awkward: the answer comes back as prose, the shape varies between runs, and you own the splitting, retrying and validating. An extraction call turns the same reading step into a repeatable request, and with a schema it returns a typed object.
Versus a research pipeline
Extraction reads a document you already point it at. It does not decide which document to read. A research run starts from a question and chooses its sources. The two work together: AI research when you have a question, AI extraction when you have a link.
How extraction reads a document
What goes in: URLs, not file uploads
The AI Extract request takes a url, plain-language instructions and an optional settings object. The product description says to point it at "any public page or PDF". It does not describe an upload route for files, so this article does not assume one.
- —The document has to be reachable at a public address.
- —Private documents are a different question. A PDF in your own storage, behind a login or only available as an email attachment is not covered by what the product pages describe. Check the documentation for what is supported rather than designing around a feature you have not seen.
- —Public does not mean unrestricted. Check the terms of whoever publishes the document before you process it at volume, the same way you would for any other public source.
1. Read the document
The file is read as a document, with its pages and tables, not rendered as a web page. The product page does not detail how long or complex files are handled, so test your longest one.
2. Clean out what is not content
The product describes stripping boilerplate before extraction. For documents that should mean running headers and footers do not become field values. I have not measured how well it does that, so check it on your own files.
3. Map the content to your fields
This is the step that makes it worth more than a text extractor. You describe the fields in plain language, or pin them with a JSON Schema, and the model fills them from wherever they appear. The contract value might be in a summary box on page one in one tender and in a pricing table on page nine in the next. The field name stays the same.
4. Return JSON
With a schema, the typed object comes back in machine. Without one, the result arrives as JSON text in human. The next section shows both.
Documents people extract
The more regular the layout, the easier validation is. Where a registry already offers structured data, a ready-made data source is usually the cleaner route; extraction is for documents that stay documents.
| Document type | Typical fields | Note |
|---|---|---|
| Corporate filings and annual reports | Names, addresses, officers, revenue, financial year end | Where a registry already offers structured data, a ready-made data source is usually the cleaner route. Extraction is for documents that stay documents. |
| Procurement and tender notices | Authority, subject, deadline, value | Dates are everywhere in a notice, so name the deadline field precisely. |
| Product data sheets and price lists | Model, specification, price | Long lists need a check that every line item came back. |
| Invoices and purchase orders | Supplier, number, date, line items, totals | Has its own concerns, such as arithmetic checks (see the invoice article below). |
| Regulatory forms and licences | Holder, number, validity dates | Fixed layouts make validation easy. The W-9 below is this kind of document. |
For the invoice case in particular, there is a separate article on invoice extraction.
A real call on the IRS Form W-9
Everything below is a real call, made on 2026-10-29 through the run_extract tool on the hosted MCP server, against a public document: the IRS Form W-9, a three-page US government form at https://www.irs.gov/pub/irs-pdf/fw9.pdf. It is a modest test: a short form with a fixed layout. Treat it as proof that the mechanism works on a real PDF, not as a measure of how it copes with yours.
The request had three parts: the url, plain-language instructions, and a JSON Schema passed as a string in settings.extract_schema_json.
{
"url": "https://www.irs.gov/pub/irs-pdf/fw9.pdf",
"instructions": "Extract the form identity and the entries a filer provides in Part I.",
"settings": {
"extract_schema_json": "{\"type\":\"object\",\"properties\":{\"form_number\":{\"type\":\"string\"},\"form_title\":{\"type\":\"string\"},\"revision_date\":{\"type\":\"string\"},\"issuing_agency\":{\"type\":\"string\"},\"part_one_line_labels\":{\"type\":\"array\",\"items\":{\"type\":\"string\"}}},\"required\":[\"form_number\",\"form_title\",\"revision_date\",\"issuing_agency\",\"part_one_line_labels\"]}"
}
}
The response, with the human field shortened where marked:
{
"session_id": "1638d1b3-3ec2-4574-a3e5-c73f1476fa95",
"kind": "extract",
"url": "https://www.irs.gov/pub/irs-pdf/fw9.pdf",
"used_url": "https://www.irs.gov/pub/irs-pdf/fw9.pdf",
"instructions": "Extract the form identity and the entries a filer provides in Part I.",
"settings": { "has_schema": true, "extract_schema_json": { "...": "the schema above, expanded" } },
"human": "# Form W-9: Request for Taxpayer Identification Number and Certification\n\nForm W-9 is used to request a U.S. person's correct Taxpayer Identification Number (TIN) and to certify certain information. ... [shortened: the field continues with lines 2, 3a, 3b, 4, 5, 6, 7 and the TIN entry as a markdown list]",
"machine": {
"form_number": "W-9",
"form_title": "Request for Taxpayer Identification Number and Certification",
"revision_date": "March 2024",
"issuing_agency": "Internal Revenue Service",
"part_one_line_labels": [
"Name of entity/individual.",
"Business name/disregarded entity name, if different from above.",
"Check the appropriate box for federal tax classification of the entity/individual whose name is entered on line 1. Check only one of the following seven boxes.",
"If on line 3a you checked “Partnership” or “Trust/estate,” ... See instructions . . . . . . . . .",
"Exemptions (codes apply only to certain entities, not individuals; see instructions on page 3):",
"Address (number, street, and apt. or suite no.). See instructions.",
"City, state, and ZIP code",
"List account number(s) here (optional)",
"Social security number",
"Employer identification number"
]
},
"total_points": 5
}
Reading the response:
- —
kindisextract;session_ididentifies the call;urlandused_urlare the address you sent and the one that was read, which you store as provenance. - —
machineis the typed object. Its keys are the ones in the schema, and the strings are values from the form: the form number, the title, the March 2024 revision date, the agency, and a list of labels. - —
humanis a markdown rendering for a person skimming the result, andtotal_pointsis the cost: 5.
One observation matters more than the rest. The schema asked for line "labels", and ten strings came back, as printed on the form, including the long instruction fragments attached to lines 3a and 3b. The extraction was faithful; it was not tidy. If your code needs a short name for each line, ask for one as a separate field, and plan to validate and clean what comes back. Typed does not mean normalised.
The same call without a schema
To see what the schema does, the same document was sent with instructions only: ask for the form name, number, revision date, issuing agency, the numbered fields a person fills in (label and short description), and the page count, with null for anything not in the document. No extract_schema_json.
The call also cost 5 points. The shape differed in a way that matters for integration:
- —
settings.has_schemawasfalse. - —
machinewasnull. - —The whole result arrived as JSON text inside the
humanstring, which parses to an object withform_name,form_number,revision_date,issuing_agency, afieldsarray of label and description pairs (twelve entries), andpages: 3. Where the form gave no description for a line, the value was null rather than invented.
So without a schema the model chooses the structure from your instructions, and you parse it out of text. With a schema, machine carries the typed object. Use a schema whenever downstream code depends on the shape.
Designing a schema for documents
A document type, say tender notices or tax forms, will be processed hundreds of times, and you will want to compare the output across all of them. A few habits help.
- —Name the fields for the document type, not for the model.
submission_deadlineis better thandate, because a notice contains many dates. - —Allow null. Make it explicit that a field can be empty. A document that does not state a value should give you an empty value, not a guess. This is the single most important property to test.
- —Ask for evidence. Add a short supporting quote and a page reference as fields next to each important value. They make review fast and they are the start of a provenance trail.
- —Keep dates and amounts separable. Ask for a number and a currency as two fields, and for dates in a fixed format, so downstream code can compare them.
- —Separate the label from the explanation. The W-9 run showed what happens when you ask for a label and the form's label is a paragraph. Name the short form and the long form as two fields.
- —Start small. Run five or ten real documents, read the output next to the originals and add fields only when a real question demands them. Every field is another place the extractor can be wrong.
A worked example, illustrative
Suppose a procurement analyst at Acme Oy, a fictional Finnish company, wants every public tender notice from a set of authorities turned into a spreadsheet row. This part is a narrative, not a captured call: there is no real notice and there are no values in it.
In outline: build the list of notice addresses elsewhere (a feed, a sitemap or a research step); request each address first and drop the ones that do not load, since a dead link still costs a call; queue one job per document with the URL and a schema version; extract with a schema shaped like the W-9 one; validate that the deadline parses and the value is a number or null; store the URL, fetch time and schema version with every row; and have a person compare a sample of rows to the originals.
REST and MCP
The W-9 call above is the MCP path: an agent sends exactly those arguments to the run_extract tool on the hosted MCP server. The same capability is available over REST, a POST to https://api.neuralverge.ai/functions/v1/run-extract with a bearer API key and the same JSON body, as the product page documents it. Only the MCP response was captured here, so no REST response is shown. Endpoint and parameter details live in the documentation.
The inputs, outputs and price are the same either way, so the choice is about who makes the call. Use REST from a batch job or a queue. Use MCP when an agent meets a PDF link while doing something else: a company page links to its annual report, a registry entry links to a filing, a search result is a notice. The agent asks for exactly the fields the current task needs and receives JSON, and its context window is not spent on forty pages of text. Setup is in the guide to connecting the MCP server. AI research is REST-only; extraction is on both.
Cost and limits
AI Extract is a flat 5 points per call. The product page puts it as "regardless of page size", and the pricing page lists it in the action costs next to Search, also 5 points. Both W-9 calls cost 5, with and without a schema. Agents pay the same: the MCP tool is priced as the equivalent REST call.
- —You can budget from counts. Number of documents multiplied by 5 points, plus any retries. Check the pricing page for the current point value in money before you plan a large backlog.
- —A null result is billed too. To check, the same kind of call was made on a PDF address that no longer exists (it returns HTTP 404). The result was
"human": "null"and"machine": null, andtotal_pointswas still 5. A URL that does not load is not free. Check that every address loads before a batch run, for example with a quick HEAD or GET request from your own side, and count null results as billed.
The edges:
- —It reads what is there. If a value is not in the document, the right answer is an empty field. The no-schema W-9 run returned null for lines with no description, which is the right behaviour, but one form is not a guarantee. Test it with a document that lacks a field.
- —Typed is not tidy. The W-9 labels came back as printed, long fragments included. Plan to validate and clean.
- —It does not tell you whether the document is true. Extraction reports what a filing or notice says. A figure in an annual report is the company's claim. Where a claim matters, corroborate it with a second source, which is the kind of question a research step is for.
- —Long documents mean choices. One call returns one result for one document. The W-9 is three pages. Size limits are not stated, so if you want every line item of a long price list, confirm the output includes all of them.
- —Scans and unusual files are untested here. The W-9 was a text PDF. The product pages make no claim about OCR, scanned images or handwriting.
- —No accuracy or speed figure. No measured numbers exist to quote, so none are given. Measure on your own documents.
How to decide
- —Do you process one document type repeatedly? That is where a schema pays off. For a one-off read, a chat model is enough.
- —Is the document public and reachable by URL? If it sits in private storage, check the documentation first.
- —Does it return empty rather than guess? Give it a document that lacks a field you ask for.
- —Does one schema hold across publishers? Test at least ten documents from different sources.
- —Does it cope with your longest file and your scans? Run the biggest and the worst you have.
- —Is the price predictable? Multiply your document count by 5 points, verify every URL loads first, and compare against a small real run.
- —Does an agent need it mid-task? Then call it as a tool over MCP.
Frequently asked questions
Can I upload a PDF file directly?
The request takes a URL, so the document needs to be reachable at a public address. The product description says to point extraction at a public page or PDF, and it does not describe a file-upload route. If your documents sit in private storage, check the documentation for what is supported before you design around it, rather than assuming an upload endpoint exists.
Do I have to define a schema before I extract a document?
No, but it changes the result. Without a schema, the output arrives as JSON text in the human field and machine is null. With a JSON Schema in settings.extract_schema_json, machine holds the typed object. For documents you plan to store and query, a schema is worth the effort.
What does extracting one PDF cost?
AI Extract is a flat 5 points per call, regardless of page size, per the product page and the pricing page. A real test call on a PDF address that no longer loaded returned null and was still billed 5 points, so check URLs before a batch run.
Does it work on scanned PDFs?
The product pages do not make a claim about scanned images or handwriting, so this article does not either. Test a handful of your own scans. If a field is unreadable the right behaviour is an empty value, so check that unreadable pages come back empty instead of filled with a plausible guess.
Can I use this over MCP from an AI agent?
Yes. The same capability is exposed on the hosted MCP server as the run_extract tool, with the same inputs and outputs as the REST endpoint and the same price. An agent that meets a document link mid-task can request typed fields instead of reading the whole document itself.
How do I know the extracted value is correct?
Extraction reports what the document says, not whether it is right. Ask for a supporting quote and a page reference as fields in your schema, store the source URL with every record, and sample outputs against the original document before you trust an aggregate.
Related articles
What is intelligent document processing? How IDP works, how it differs from OCR and RPA, and a real no-schema W-9 extraction call over REST or MCP.
An invoice extraction api turns a PDF invoice into typed JSON you can check. A real AI Extract run on a sample invoice, the gap the checks caught, and the cost.
How to extract structured data from news articles over API or MCP: an event schema, dedup, paywalls and provenance, at a flat 5 points per page.
About NeuralVerge
Give your agents structured, cited, real-world data from 300+ sources and the open web — through one API or MCP server.
AI Extraction on the NeuralVerge blog.