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

1const axios = require("axios");
2
3const editDocument = async () => {
4 try {
5 const response = await axios.post(
6 "https://api.extend.ai/edit",
7 {
8 file: {
9 fileUrl: "https://example.com/documents/form.pdf",
10 },
11 config: {
12 instructions: "Fill out the form with the provided data",
13 advancedOptions: {
14 flattenPdf: true
15 }
16 },
17 },
18 {
19 headers: {
20 Authorization: "Bearer <API_TOKEN>",
21 "Content-Type": "application/json",
22 "x-extend-api-version": "2025-04-21"
23 },
24 }
25 );
26
27 console.log("Document edited successfully:", response.data);
28 } catch (error) {
29 console.error("Error:", error.response?.data || error.message);
30 }
31};
32
33editDocument();

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

*One of fileUrl or fileId must be provided.

Response

1{
2 "success": true,
3 "editRun": {
4 "object": "edit_run",
5 "id": "edit_run_xK9mLPqRtN3vS8wF5hB2cQ",
6 "fileId": "file_Zk9mNP12Qw4yTv8BdR3H",
7 "editedFile": {
8 "fileId": "file_Ab3cDE45Fg6hIj7KlM8nO",
9 "downloadUrl": "https://extend-ai-files.s3.amazonaws.com/..."
10 },
11 "status": "PROCESSED",
12 "config": {
13 "instructions": "Fill out the form with the provided data"
14 },
15 "output": {},
16 "metrics": {
17 "processingTimeMs": 1234
18 },
19 "usage": {
20 "credits": 1
21 }
22 }
23}

POST /edit/async

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

This is useful for:

  • Large files that may take longer to process
  • Avoiding timeout issues with synchronous editing
  • Processing multiple files in parallel

Request Body

Same as POST /edit.

Response

1{
2 "object": "edit_run_status",
3 "id": "edit_run_xK9mLPqRtN3vS8wF5hB2cQ",
4 "status": "PROCESSING"
5}

GET /edit_runs/{id}

Retrieve the status and results of an edit run.

Path Parameters

ParameterTypeDescription
idstringThe edit run ID

Response (Processing)

1{
2 "success": true,
3 "editRun": {
4 "object": "edit_run_status",
5 "id": "edit_run_xK9mLPqRtN3vS8wF5hB2cQ",
6 "status": "PROCESSING"
7 }
8}

Response (Completed)

1{
2 "success": true,
3 "editRun": {
4 "object": "edit_run",
5 "id": "edit_run_xK9mLPqRtN3vS8wF5hB2cQ",
6 "fileId": "file_Zk9mNP12Qw4yTv8BdR3H",
7 "editedFile": {
8 "fileId": "file_Ab3cDE45Fg6hIj7KlM8nO",
9 "downloadUrl": "https://extend-ai-files.s3.amazonaws.com/..."
10 },
11 "status": "PROCESSED",
12 "config": { ... },
13 "output": { ... },
14 "metrics": { "processingTimeMs": 1234 },
15 "usage": { "credits": 1 }
16 }
17}

DELETE /edit_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

1{
2 "success": true,
3 "editRunId": "edit_run_xK9mLPqRtN3vS8wF5hB2cQ",
4 "message": "Edit run data has been successfully deleted."
5}

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.

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

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, and values to fill.

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:page_indexintegerZero-based page index
extend_edit:valueanyThe value to fill into this field
extend_edit:text_edit_optionsobjectText styling: combing, maxLength, fontSize, fontColor, font
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)
itemsobjectSchema for array items (when type is “array”)
enumarrayAllowed values for enum/dropdown/radio fields
maxItemsintegerMaximum number of rows for array/table fields

Example Schema

1{
2 "config": {
3 "schema": {
4 "type": "object",
5 "required": ["policy_number", "policyholder_information_first_name"],
6 "properties": {
7 "policy_number": {
8 "type": ["string", "null"],
9 "description": "The policyholder's unique identification number.",
10 "extend_edit:bbox": {
11 "left": 0.250,
12 "top": 0.242,
13 "right": 0.454,
14 "bottom": 0.267
15 },
16 "extend_edit:field_type": "text",
17 "extend_edit:page_index": 0,
18 "extend_edit:value": "12345678",
19 "extend_edit:text_edit_options": {
20 "combing": true,
21 "maxLength": 8
22 }
23 },
24 "policyholder_information_first_name": {
25 "type": ["string", "null"],
26 "description": "The first name of the policyholder.",
27 "extend_edit:bbox": {
28 "left": 0.608,
29 "top": 0.313,
30 "right": 0.880,
31 "bottom": 0.338
32 },
33 "extend_edit:field_type": "text",
34 "extend_edit:page_index": 0,
35 "extend_edit:value": "John",
36 "extend_edit:text_edit_options": {
37 "combing": true,
38 "maxLength": 9
39 }
40 },
41 "is_permanent_address_change": {
42 "type": ["boolean", "null"],
43 "description": "Check this box if the address provided is a permanent change.",
44 "extend_edit:bbox": {
45 "left": 0.088,
46 "top": 0.480,
47 "right": 0.107,
48 "bottom": 0.494
49 },
50 "extend_edit:field_type": "checkbox",
51 "extend_edit:page_index": 0,
52 "extend_edit:value": true
53 },
54 "patient_information_sex_male": {
55 "type": ["boolean", "null"],
56 "description": "A checkbox to indicate if the patient's sex is Male.",
57 "extend_edit:bbox": {
58 "left": 0.137,
59 "top": 0.570,
60 "right": 0.156,
61 "bottom": 0.585
62 },
63 "extend_edit:field_type": "checkbox",
64 "extend_edit:page_index": 0,
65 "extend_edit:value": false
66 }
67 },
68 "additionalProperties": false
69 }
70 }
71}

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

Combed Fields

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

1{
2 "extend_edit:text_edit_options": {
3 "combing": true,
4 "maxLength": 9
5 }
6}

Advanced Options

When enabled, automatically detects form fields in the document. Default: true.

advancedOptions.flattenPdf boolean

When enabled, flattens the PDF after editing, making form fields non-editable. This is useful for generating final documents. Default: false.

advancedOptions.tableParsingEnabled boolean

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

1{
2 "config": {
3 "advancedOptions": {
4 "flattenPdf": true,
5 "tableParsingEnabled": false
6 }
7 }
8}

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:

1{
2 "code": "FILE_TYPE_NOT_SUPPORTED",
3 "message": "Only PDF files are supported for editing",
4 "requestId": "req_abc123",
5 "retryable": false
6}

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

1const response = await axios.post("https://api.extend.ai/edit", {
2 file: {
3 fileUrl: "https://example.com/application-form.pdf"
4 },
5 config: {
6 schema: {
7 type: "object",
8 properties: {
9 applicant_name: {
10 type: ["string", "null"],
11 "extend_edit:field_type": "text",
12 "extend_edit:page_index": 0,
13 "extend_edit:bbox": { left: 0.1, top: 0.2, right: 0.4, bottom: 0.23 },
14 "extend_edit:value": "Jane Smith"
15 },
16 application_date: {
17 type: ["string", "null"],
18 "extend_edit:field_type": "text",
19 "extend_edit:page_index": 0,
20 "extend_edit:bbox": { left: 0.5, top: 0.2, right: 0.8, bottom: 0.23 },
21 "extend_edit:value": "2024-03-21"
22 },
23 email_address: {
24 type: ["string", "null"],
25 "extend_edit:field_type": "text",
26 "extend_edit:page_index": 0,
27 "extend_edit:bbox": { left: 0.1, top: 0.3, right: 0.4, bottom: 0.33 },
28 "extend_edit:value": "jane@example.com"
29 }
30 },
31 required: ["applicant_name"],
32 additionalProperties: false
33 },
34 advancedOptions: {
35 flattenPdf: true
36 }
37 }
38}, {
39 headers: {
40 Authorization: "Bearer <API_TOKEN>",
41 "x-extend-api-version": "2025-04-21"
42 }
43});
44
45// Download the filled PDF
46const downloadUrl = response.data.editRun.editedFile.downloadUrl;

Async Processing with Polling

1// Start async edit
2const startResponse = await axios.post("https://api.extend.ai/edit/async", {
3 file: { fileUrl: "https://example.com/large-form.pdf" },
4 config: {
5 schema: {
6 type: "object",
7 properties: {
8 name: {
9 type: ["string", "null"],
10 "extend_edit:field_type": "text",
11 "extend_edit:page_index": 0,
12 "extend_edit:bbox": { left: 0.1, top: 0.1, right: 0.5, bottom: 0.13 },
13 "extend_edit:value": "John Doe"
14 }
15 },
16 additionalProperties: false
17 }
18 }
19}, {
20 headers: {
21 Authorization: "Bearer <API_TOKEN>",
22 "x-extend-api-version": "2025-04-21"
23 }
24});
25
26const editRunId = startResponse.data.id;
27
28// Poll for completion
29let result;
30while (true) {
31 const statusResponse = await axios.get(
32 `https://api.extend.ai/edit_runs/${editRunId}`,
33 {
34 headers: {
35 Authorization: "Bearer <API_TOKEN>",
36 "x-extend-api-version": "2025-04-21"
37 }
38 }
39 );
40
41 result = statusResponse.data.editRun;
42
43 if (result.status === "PROCESSED" || result.status === "FAILED") {
44 break;
45 }
46
47 // Wait before polling again
48 await new Promise(resolve => setTimeout(resolve, 1000));
49}
50
51if (result.status === "PROCESSED") {
52 console.log("Output file:", result.editedFile.downloadUrl);
53} else {
54 console.error("Edit failed:", result.failureReason);
55}

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).