Read PDF form fields
A fillable PDF hides a form beneath the page: text boxes, checkboxes, radio groups, and dropdowns, each with its own internal name and current value. This read PDF form fields API opens that layer and hands you back a complete inventory in JSON, so you know exactly what a form contains before you try to fill it, validate it, or route it anywhere.
Run it online
Run this on our servers with your account. Free tools run in your browser; this one bills your KIT balance per the price above.
The problem this solves
Anyone who has tried to auto-fill a government form, an intake questionnaire, or a vendor's contract template knows the first obstacle: you cannot fill fields you cannot see. Field names are often cryptic, inconsistent, or duplicated across a document, and PDF authoring tools rarely export a clean schema alongside the file. This endpoint exists for developers who receive PDFs from third parties — clients, agencies, partners — and need to programmatically discover the form's shape before writing a single line of fill logic.
What comes back
You call POST /pdf/form-read and get a task_id immediately. The result lists every field on every page: its internal name, its type (text, checkbox, radio button, choice list, or signature placeholder), its current value, and, where present, the list of allowed choices for dropdowns and radio groups. Nothing is inferred or guessed — this is a direct read of what the document's AcroForm dictionary actually declares, so the output matches what a viewer like Acrobat would show you field by field.
A short history of the fillable PDF
Interactive forms have been part of the PDF specification since the mid-1990s, built on the AcroForm technology Adobe carried over from its earlier FDF format. Decades later, a large share of government, HR, insurance, and legal paperwork still circulates as these form-bearing PDFs, precisely because the layout is fixed and the data model is standardized. That stability is also why reading them programmatically is worthwhile: the field structure of a well-built form rarely changes, so a mapping you build once tends to keep working.
Where it fits your pipeline
Treat this as the discovery step before any fill or validation logic runs. Read a template once to build a field map, cache that map, and then use it to drive downstream automation — populating the same form thousands of times, checking that a submitted PDF has all required fields completed, or reconciling values against a database record. Because each call is a small, self-contained task, it fits naturally at the start of an intake or onboarding workflow.
Delivery and retention
Results are delivered to a signed webhook, the recommended path for automation, or through a signed link valid for 24 hours. Documents and extracted data are held only for the retention window, then deleted, and nothing you submit is ever used to train a model. A failed task — a corrupt file, a form with no AcroForm at all — is retried three times and, if it still cannot be read, returns a clear error at no charge.
What you can do with it
Map an unfamiliar third-party template
A partner sends a new intake form you have never seen. Read its fields once to discover the internal names and types, then wire your fill logic without opening the PDF in a desktop tool.
Validate completeness before submission
Before accepting a filled-out application, read its fields back and check that every required text box, checkbox, and signature field actually carries a value.
Build a dynamic form-filling service
Support many different client PDF templates in one pipeline by reading each form's field map on first upload and caching it, instead of hardcoding field names per template.
Audit which fields a form actually exposes
Confirm that a generated or downloaded PDF template still exposes the expected fields after an update, catching silently broken form fields before they reach end users.
FAQ
How do I read the fields of a PDF form with an API?
Send the document to POST /pdf/form-read, which returns a task_id right away. The full list of field names, types, and current values is then delivered as JSON to your signed webhook or a signed link.
Is the read PDF form fields API free?
There's no free tier — free tiers get abused and slow everyone down. Access runs on a prepaid ForHosting KIT balance: top up from $10.00 (it never expires) and each request is charged at its published price, so a call with no balance returns HTTP 402. No subscription, no tokens, no invented credits, and a failed task is never charged.
What field types does it detect?
Text fields, checkboxes, radio button groups, choice lists (dropdowns and list boxes), and signature field placeholders — everything declared in the document's AcroForm, along with each field's current value.
What if the PDF has no fillable form?
If the document carries no AcroForm dictionary at all, the response simply reports an empty field list rather than an error, since a form-less PDF is a valid — if uninteresting — result.
Does it return the values people already typed in?
Yes. Each field's current value is included alongside its name and type, so you can read an already partially or fully filled form, not just its empty structure.
Can I read many PDFs in bulk?
Yes. Every call is an independent asynchronous task, so you can submit large batches in parallel and collect each field list by webhook as it completes.
Does reading fields also let me fill them through this endpoint?
No, this capability is read-only: it inventories the form. Filling and writing values is handled through a separate write operation once you know the field names.
What happens with a scanned PDF that only looks like a form?
A scanned image has no real AcroForm fields to read, only flat pixels, so the field list comes back empty. This endpoint reads the form layer, not the visual layout.
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, and soon from our app, email and Telegram.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/pdf/form-read \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"pdf":"https://ejemplo.com/documento.pdf"}'const res = await fetch("https://api.kit.forhosting.com/pdf/form-read", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"pdf": "https://ejemplo.com/documento.pdf"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/pdf/form-read",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"pdf": "https://ejemplo.com/documento.pdf"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/pdf/form-read", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"pdf":"https://ejemplo.com/documento.pdf"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"pdf":"https://ejemplo.com/documento.pdf"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/pdf/form-read", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"pdf": "https://ejemplo.com/documento.pdf"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "pdf.form_read",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Limits
max_mb | 25 |
max_pages | 200 |
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |
413 | input_too_large | The file exceeds the size limit. |