Detect Form

Detect Form detects the fields in a PDF form and returns a form_detection_run whose output.schema you can pass straight to /edit or /edit_runs. The returned schema has field positions annotated, so you don’t have to write extend_edit:bbox coordinates by hand. Optionally, supply your own schema and Extend maps it onto the detected fields.

Reach for it when you:

  • Need a starter schema for a new PDF form.
  • Want to map an existing schema onto a vendor-specific layout.
  • Need annotated field locations before running edits at scale.
  • Want to add conditional form logic on top of detected fields.

Use POST /detect_form for synchronous testing. For production workloads, use POST /form_detection_runs and poll GET /form_detection_runs/{id} to avoid request timeout issues.

Quick start

We’ll detect the fields in a PDF form. Grab a key from the Developers page and store it as the EXTEND_API_KEY environment variable. If you’re using an SDK, see the installation instructions.

$export EXTEND_API_KEY="your_api_key_here"
1from extend_ai import Extend
2
3client = Extend()
4
5run = client.detect_form(
6 file={"url": "https://example.com/form.pdf"},
7 config={
8 "instructions": "Detect the form fields and use human-readable field names.",
9 "advancedOptions": {"radioEnumsEnabled": True},
10 },
11)
12
13print(run.output.schema)

Response

The response is a form_detection_run. A successful synchronous request returns after the run reaches PROCESSED; the asynchronous endpoint usually returns it with status: "PROCESSING".

FieldTypeDescription
object"form_detection_run"The resource type.
idstringThe form detection run ID. Use it with GET /form_detection_runs/{id}.
statusstringPROCESSING, PROCESSED, or FAILED.
outputobject | nullPresent when processing succeeds. Contains schema, annotatedSchema, and mappingResult.
output.schemaobjectThe final generated schema after mapping. If no inputSchema was provided, this is the same as output.annotatedSchema. Pass it to /edit or /edit_runs.
output.annotatedSchemaobject | nullThe original schema detected from the file, annotated with field locations.
output.mappingResultobject | nullPresent when you provide an inputSchema. Contains matches, unmatchedInputPaths, and unusedFormFieldKeys.
metricsobject | nullPage, field, and processing-time metrics. Present when processing succeeds.
usageobject | nullCredits consumed by the run when usage data is available.

Asynchronous processing

For production workloads, create a form detection run and poll it by ID:

$curl -X POST https://api.extend.ai/form_detection_runs \
> -H "Authorization: Bearer $EXTEND_API_KEY" \
> -H "x-extend-api-version: 2026-02-09" \
> -H "Content-Type: application/json" \
> -d '{
> "file": { "url": "https://example.com/form.pdf" },
> "config": {
> "instructions": "Detect the form fields and use human-readable field names."
> }
> }'
$
$curl https://api.extend.ai/form_detection_runs/sgr_xK9mLPqRtN3vS8wF5hB2cQ \
> -H "Authorization: Bearer $EXTEND_API_KEY" \
> -H "x-extend-api-version: 2026-02-09"

Poll until status is PROCESSED or FAILED. See Async Processing for retry and polling guidance.

Request configuration

The config object is shared by the sync and async form detection endpoints:

FieldTypeDescription
inputSchemaobjectAn existing edit schema to map onto the detected form fields. When provided, the response includes a mappingResult.
instructionsstringCustom instructions for field detection and naming.
advancedOptions.tableParsingEnabledbooleanParse table regions as arrays of objects. Defaults to false.
advancedOptions.radioEnumsEnabledbooleanModel radio fields as enums so only one widget in a group is selected. Defaults to false.
advancedOptions.nativeFieldsOnlybooleanOnly use native AcroForm fields from the PDF and skip object detection. Defaults to false.

A common workflow

The generated schema uses the same format as edit runs, including support for root-level JSON Schema conditionals. A common workflow is:

  1. Generate a base schema from the PDF form.
  2. Add conditional requirements for follow-up fields.
  3. Use the refined schema with /edit or /edit_runs.

For the exact request and response schemas, see Detect Form (Sync), Detect Form (Async), and Get Form Detection Run.