Edit File

The Edit endpoint allows you to programmatically edit PDF documents by detecting form fields and filling them with provided data. This endpoint is ideal for:

  • Automatically filling out PDF forms
  • Pre-populating documents with customer data
  • Generating filled documents at scale

Tutorial and explanation video

Quick Start

const editDocument = async () => {
const response = await fetch("https://api.extend.ai/edit", {
method: "POST",
headers: {
Authorization: "Bearer <API_TOKEN>",
"Content-Type": "application/json",
"x-extend-api-version": "2025-04-21",
},
body: JSON.stringify({
file: {
fileUrl: "https://example.com/documents/form.pdf",
},
config: {
engineVersion: "1.0.0",
instructions: "Fill out the form with the provided data",
advancedOptions: {
flattenPdf: true,
},
},
}),
});
if (!response.ok) {
const error = await response.json();
console.error("Error:", error);
return;
}
const data = await response.json();
console.log("Document edited successfully:", data);
};
editDocument();

Endpoints

POST /edit

Edit a PDF document synchronously. The request will wait for the edit operation to complete (up to 5 minutes) before returning results.

Request Body

FieldTypeRequiredDescription
fileobjectYesFile to edit
file.fileNamestringNoName of the file
file.fileUrlstringYes*URL to download the file
file.fileIdstringYes*Existing Extend file ID
configobjectYesConfiguration for the edit operation
config.engineVersionstringNoEdit engine version. Use an exact version for reproducible results, or latest for the latest stable version. Defaults to 1.0.0.

*One of fileUrl or fileId must be provided.

Response

{
"editRun": {
"object": "edit_run",
"id": "edit_run_xK9mLPqRtN3vS8wF5hB2cQ",
"fileId": "file_Zk9mNP12Qw4yTv8BdR3H",
"editedFile": {
"fileId": "file_Ab3cDE45Fg6hIj7KlM8nO",
"downloadUrl": "https://extend-ai-files.s3.amazonaws.com/..."
},
"status": "PROCESSED",
"config": {
"engineVersion": "1.0.0",
"instructions": "Fill out the form with the provided data"
},
"output": {},
"metrics": {
"processingTimeMs": 1234
},
"usage": {
"credits": 1
}
}
}

POST /editor_runs

Edit a PDF document. Returns immediately with an editor run ID that can be used to poll for results.

Request Body

Same as POST /edit.

Response

{
"object": "edit_run_status",
"id": "editor_run_xK9mLPqRtN3vS8wF5hB2cQ",
"status": "PROCESSING"
}

GET /editor_runs/{id}

Retrieve the status and results of an editor run.

Path Parameters

ParameterTypeDescription
idstringThe editor run ID

Response (Processing)

{
"editRun": {
"object": "edit_run_status",
"id": "editor_run_xK9mLPqRtN3vS8wF5hB2cQ",
"status": "PROCESSING"
}
}

Response (Completed)

{
"editRun": {
"object": "edit_run",
"id": "editor_run_xK9mLPqRtN3vS8wF5hB2cQ",
"fileId": "file_Zk9mNP12Qw4yTv8BdR3H",
"editedFile": {
"fileId": "file_Ab3cDE45Fg6hIj7KlM8nO",
"downloadUrl": "https://extend-ai-files.s3.amazonaws.com/..."
},
"status": "PROCESSED",
"config": { ... },
"output": { ... },
"metrics": { "processingTimeMs": 1234 },
"usage": { "credits": 1 }
}
}

DELETE /editor_runs/{id}

Delete an edit run and all associated data. This operation is permanent and cannot be undone.

Path Parameters

ParameterTypeDescription
idstringThe edit run ID

Response

{
"editorRunId": "editor_run_xK9mLPqRtN3vS8wF5hB2cQ",
"message": "Editor run data has been successfully deleted."
}

Configuration Options

The config object controls how documents are edited.

Instructions

instructions string

Natural language instructions for the edit operation. Use this to provide context or specific guidance on how to fill the form.

{
"config": {
"instructions": "Fill out all fields on the form. For the signature field, use 'John Doe'. Leave optional fields blank if no data is provided."
}
}

Schema Generation Instructions

schemaGenerationInstructions string

Additional instructions used when Extend needs to generate a schema from the PDF. This is useful when you want to bias field detection or naming without providing a full schema yourself.

{
"config": {
"schemaGenerationInstructions": "Detect signature fields, preserve table structure, and use customer-friendly field names."
}
}

Schema

schema object

A JSON Schema defining the structure of fields to edit. The schema uses extend_edit:* properties to specify PDF field types, bounding box positions, text styling options, values to fill, and optional signature image fills.

Schema Types

The type property supports the following formats:

Type FormatDescription
["string", "null"]Nullable string field (for text, signature)
["number", "null"]Nullable number field (for text)
["integer", "null"]Nullable integer field (for text)
["boolean", "null"]Nullable boolean field (for checkbox, radio)
"array"Array field (for tables)
"object"Object field (for signatures)
(no type, use enum)Enum field (for radio, optionList, dropdown)

Schema Properties

Each field in the schema can include:

PropertyTypeDescription
typestring or arrayJSON type (see table above)
descriptionstringDescription of the field
extend_edit:field_typestringPDF field type: "text", "checkbox", "radio", "dropdown", "optionList", "signature", "table"
extend_edit:bboxobjectBounding box with left, top, right, bottom (pixel coordinates)
extend_edit:bboxesarrayAn array of bounding boxes used for radio enums only. Enums are matched on index to a bounding box in this array.
extend_edit:page_indexintegerZero-based page index
extend_edit:valueanyThe value to fill into this field
extend_edit:imageobjectImage fill for signature fields. Use { "image_url": "https://..." } with a PNG or JPEG URL.
extend_edit:text_edit_optionsobjectText styling: combing, maxLength, multiLine, fontSize, color (RGB 0–255), opacity (0–1), and font. fontColor is a deprecated alias for color.
extend_edit:column_widthnumberWidth of the column as a percentage (for table fields)
extend_edit:row_heightsarrayArray of row height percentages (for array/table fields)
extend_edit:source_acroformobjectDetails about the original PDF form field. When Detect Form returns this property, include it unchanged in Edit requests.
itemsobjectSchema for array items (when type is “array”)
enumarrayAllowed values for enum/dropdown/radio fields
extend:descriptionsarrayHuman-readable labels for the values in enum, in the same order.
maxItemsintegerMaximum number of rows for array/table fields

Example Schema

{
"config": {
"schema": {
"type": "object",
"required": ["policy_number", "policyholder_information_first_name"],
"properties": {
"policy_number": {
"type": ["string", "null"],
"description": "The policyholder's unique identification number.",
"extend_edit:bbox": {
"left": 0.250,
"top": 0.242,
"right": 0.454,
"bottom": 0.267
},
"extend_edit:field_type": "text",
"extend_edit:page_index": 0,
"extend_edit:value": "12345678",
"extend_edit:text_edit_options": {
"combing": true,
"maxLength": 8
}
},
"policyholder_information_first_name": {
"type": ["string", "null"],
"description": "The first name of the policyholder.",
"extend_edit:bbox": {
"left": 0.608,
"top": 0.313,
"right": 0.880,
"bottom": 0.338
},
"extend_edit:field_type": "text",
"extend_edit:page_index": 0,
"extend_edit:value": "John",
"extend_edit:text_edit_options": {
"combing": true,
"maxLength": 9
}
},
"is_permanent_address_change": {
"type": ["boolean", "null"],
"description": "Check this box if the address provided is a permanent change.",
"extend_edit:bbox": {
"left": 0.088,
"top": 0.480,
"right": 0.107,
"bottom": 0.494
},
"extend_edit:field_type": "checkbox",
"extend_edit:page_index": 0,
"extend_edit:value": true
},
"patient_information_sex_male": {
"type": ["boolean", "null"],
"description": "A checkbox to indicate if the patient's sex is Male.",
"extend_edit:bbox": {
"left": 0.137,
"top": 0.570,
"right": 0.156,
"bottom": 0.585
},
"extend_edit:field_type": "checkbox",
"extend_edit:page_index": 0,
"extend_edit:value": false
}
},
"additionalProperties": false
}
}
}

Field values are specified directly on each field using extend_edit:value. This replaces the legacy input object approach.

Signature Image Fills

For signature fields, you can provide an image instead of a text value:

{
"type": "object",
"extend_edit:field_type": "signature",
"extend_edit:image": {
"image_url": "https://example.com/signature.png"
}
}

Combed Fields

For fields that require character-by-character input (like SSN, phone numbers, or policy numbers), use combing: true with a maxLength:

{
"extend_edit:text_edit_options": {
"combing": true,
"maxLength": 9
}
}

For fields that should wrap across multiple lines, set multiLine: true:

{
"extend_edit:text_edit_options": {
"multiLine": true
}
}

Native AcroForm metadata

Detect Form may return extend_edit:source_acroform for PDF form fields. Keep it unchanged when adding extend_edit:value and sending the schema to Edit. fieldName and fieldType describe the field, optionMap lists its supported choices, and optionValue identifies the value for a selected option.

Text appearance

Use color for an RGB text color and opacity for text opacity. RGB channels are integers from 0 to 255; opacity ranges from 0 to 1. fontColor remains accepted as a deprecated alias for color.

Advanced Options

advancedOptions.flattenPdf boolean

When enabled, flattens the PDF after editing, making form fields non-editable. This is useful for generating final documents. The default is true for Edit 1.0.0 and 0.0.1, and false for 1.0.0-beta.

advancedOptions.tableParsingEnabled boolean

When enabled, parses table structures in the document. Default: false.

{
"config": {
"advancedOptions": {
"flattenPdf": true,
"tableParsingEnabled": false
}
}
}

advancedOptions.radioEnumsEnabled boolean

When enabled, radio groups are represented as enums so only one option can be selected.

The default is true for Edit 1.0.0 and 1.0.0-beta, and false for 0.0.1.

advancedOptions.nativeFieldsOnly boolean

When enabled, only native AcroForm fields from the PDF are used in the schema.

advancedOptions.conditionalGenerationEnabled boolean

When enabled, Extend reads requirements explicitly stated in the form and adds root-level JSON Schema conditional validation rules to a generated edit schema. The rules validate generated field values when the schema is used for an edit; they do not add interactive UI behavior. Default: false.

If an Edit run cannot generate values that satisfy the generated conditionals, the run fails with SCHEMA_VALIDATION_ERROR.

This option applies only when Extend generates the schema. If you provide config.schema, include any conditional rules directly in that schema.

To learn more about conditional keywords, see Conditional schema validation in the JSON Schema documentation.


Status Values

StatusDescription
PROCESSINGThe file is being edited
PROCESSEDThe edit completed successfully
FAILEDThe edit failed (see failureReason)

Error Handling

When an error occurs, the API returns a structured error response:

{
"code": "FILE_TYPE_NOT_SUPPORTED",
"message": "Only PDF files are supported for editing",
"requestId": "req_abc123",
"retryable": false
}

Error Codes

Error CodeDescriptionRetryable
INVALID_CONFIG_OPTIONSInvalid configuration options
UNABLE_TO_DOWNLOAD_FILECould not download the file from the URL
FILE_TYPE_NOT_SUPPORTEDFile type not supported (only PDFs)
FILE_SIZE_TOO_LARGEFile exceeds maximum size
CORRUPT_FILEFile is corrupt
OCR_ERROROCR processing error
PASSWORD_PROTECTED_FILEFile is password protected
FAILED_TO_CONVERT_TO_PDFPDF conversion failed
SCHEMA_VALIDATION_FAILEDSchema validation error
INTERNAL_ERRORInternal server error

Examples

Filling a Simple Form with Schema

const response = await fetch("https://api.extend.ai/edit", {
method: "POST",
headers: {
Authorization: "Bearer <API_TOKEN>",
"Content-Type": "application/json",
"x-extend-api-version": "2025-04-21",
},
body: JSON.stringify({
file: {
fileUrl: "https://example.com/application-form.pdf",
},
config: {
schema: {
type: "object",
properties: {
applicant_name: {
type: ["string", "null"],
"extend_edit:field_type": "text",
"extend_edit:page_index": 0,
"extend_edit:bbox": { left: 0.1, top: 0.2, right: 0.4, bottom: 0.23 },
"extend_edit:value": "Jane Smith",
},
application_date: {
type: ["string", "null"],
"extend_edit:field_type": "text",
"extend_edit:page_index": 0,
"extend_edit:bbox": { left: 0.5, top: 0.2, right: 0.8, bottom: 0.23 },
"extend_edit:value": "2024-03-21",
},
email_address: {
type: ["string", "null"],
"extend_edit:field_type": "text",
"extend_edit:page_index": 0,
"extend_edit:bbox": { left: 0.1, top: 0.3, right: 0.4, bottom: 0.33 },
"extend_edit:value": "jane@example.com",
},
},
required: ["applicant_name"],
additionalProperties: false,
},
advancedOptions: {
flattenPdf: true,
},
},
}),
});
const data = await response.json();
// Download the filled PDF
const downloadUrl = data.editRun.editedFile.downloadUrl;

Async Processing with Polling

// Start async edit
const startResponse = await fetch("https://api.extend.ai/editor_runs", {
method: "POST",
headers: {
Authorization: "Bearer <API_TOKEN>",
"Content-Type": "application/json",
"x-extend-api-version": "2025-04-21",
},
body: JSON.stringify({
file: { fileUrl: "https://example.com/large-form.pdf" },
config: {
schema: {
type: "object",
properties: {
name: {
type: ["string", "null"],
"extend_edit:field_type": "text",
"extend_edit:page_index": 0,
"extend_edit:bbox": { left: 0.1, top: 0.1, right: 0.5, bottom: 0.13 },
"extend_edit:value": "John Doe",
},
},
additionalProperties: false,
},
},
}),
});
const startData = await startResponse.json();
const editorRunId = startData.id;
// Poll for completion
let result;
while (true) {
const statusResponse = await fetch(
`https://api.extend.ai/editor_runs/${editorRunId}`,
{
headers: {
Authorization: "Bearer <API_TOKEN>",
"x-extend-api-version": "2025-04-21",
},
}
);
const statusData = await statusResponse.json();
result = statusData.editRun;
if (result.status === "PROCESSED" || result.status === "FAILED") {
break;
}
// Wait before polling again
await new Promise(resolve => setTimeout(resolve, 1000));
}
if (result.status === "PROCESSED") {
console.log("Output file:", result.editedFile.downloadUrl);
} else {
console.error("Edit failed:", result.failureReason);
}

Best Practices

  1. Use async for large files - For files larger than a few MB or complex forms, use the async endpoint to avoid timeouts.

  2. Flatten for final documents - Enable flattenPdf: true when generating final documents to prevent further editing.

  3. Use extend_edit:value on each field - Specify values directly on each field in your schema using the extend_edit:value property.

  4. Use instructions for context - Provide clear instructions when field mapping isn’t straightforward.

  5. Handle errors gracefully - Implement retry logic for retryable errors like OCR_ERROR and INTERNAL_ERROR.

  6. Enable table parsing for forms with tables - Set tableParsingEnabled: true for forms with large regions of empty table cells you want filled.

  7. Use correct bounding box format - Bounding boxes use left, top, right, bottom coordinates (pixel values).