> ## Documentation Index
> Fetch the complete documentation index at: https://docs.reducto.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Edit

> Fill forms and modify documents with natural language instructions

Edit fills PDF forms and modifies DOCX documents using natural language instructions. You describe what values should go where, and Edit handles field detection, mapping, and insertion.

While [Parse](/parse/overview) reads documents and [Extract](/extract/overview) pulls specific data out, Edit writes data back in. This completes the document processing loop: parse a document to understand it, extract data from one source, edit that data into a different form.

<Note>
  The Edit endpoint is available in the Python SDK, Node.js SDK, and via cURL. The Go SDK does not yet support Edit.
</Note>

***

## When to Use Edit

Edit solves form filling at scale. Instead of manually clicking through fillable PDFs or templating Word documents, you describe what you want in natural language.

**Common use cases:**

* Filling government and tax forms (W-9, I-9, G-1145) with applicant data
* Completing insurance applications and claim forms
* Populating legal contracts with client information
* Generating customized DOCX reports from extracted data

PDF libraries like PyPDF require knowing exact field names and coordinates. Edit uses AI to understand field context, so "Fill in the applicant name" works even if the PDF field is named `topmostSubform[0].Page1[0].f1_1[0]`.

***

## Quick Start

<CodeGroup>
  ```python Python theme={null}
  from pathlib import Path
  from reducto import Reducto

  client = Reducto()
  upload = client.upload(file=Path("w9_form.pdf"))

  result = client.edit.run(
      document_url=upload.file_id,
      edit_instructions="""
          Fill this W-9 form with:
          - Name: Acme Corporation
          - Business name: Acme Corp LLC
          - Tax classification: LLC
          - Address: 123 Main Street, San Francisco, CA 94102
          - TIN: 12-3456789
      """
  )

  print(result.document_url)  # Download the filled form
  ```

  ```javascript Node.js theme={null}
  import Reducto from 'reductoai';
  import fs from 'fs';

  const client = new Reducto();
  const upload = await client.upload({
    file: fs.createReadStream('w9_form.pdf'),
  });

  const result = await client.edit.run({
    document_url: upload.file_id,
    edit_instructions: `
      Fill this W-9 form with:
      - Name: Acme Corporation
      - Business name: Acme Corp LLC
      - Tax classification: LLC
      - Address: 123 Main Street, San Francisco, CA 94102
      - TIN: 12-3456789
    `
  });

  console.log(result.document_url);  // Download the filled form
  ```

  ```bash cURL theme={null}
  # First upload the file
  FILE_ID=$(curl -s -X POST https://platform.reducto.ai/upload \
    -H "Authorization: Bearer $REDUCTO_API_KEY" \
    -F "file=@w9_form.pdf" | jq -r '.file_id')

  # Then edit
  curl -X POST https://platform.reducto.ai/edit \
    -H "Authorization: Bearer $REDUCTO_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "document_url": "'$FILE_ID'",
      "edit_instructions": "Fill this W-9 form with: Name: Acme Corporation, Business name: Acme Corp LLC, Tax classification: LLC, Address: 123 Main Street, San Francisco, CA 94102, TIN: 12-3456789"
    }'
  ```
</CodeGroup>

**What happens:**

1. Edit detects all fillable fields in the PDF (text boxes, checkboxes, dropdowns)
2. An LLM reads your instructions and field context (labels, surrounding text)
3. Each field gets mapped to the appropriate value
4. The filled PDF is returned as a downloadable URL

***

## PDF vs DOCX

### PDF

PDFs have structured form widgets (text fields, checkboxes, dropdowns). For PDFs without existing form fields, Edit uses vision to detect where fillable areas should be.

| Feature        | Description                            |
| -------------- | -------------------------------------- |
| Text fields    | Fill any text input area               |
| Checkboxes     | Check or uncheck based on instructions |
| Dropdowns      | Choose from available options          |
| Form detection | Finds fields even in scanned forms     |
| Overflow       | Long text can flow to appendix pages   |

### DOCX

DOCX supports richer editing because the format allows inline content modification.

| Feature        | Description                                 |
| -------------- | ------------------------------------------- |
| Form fields    | Modern (2007+) and legacy form controls     |
| Checkboxes     | Both modern and legacy controls             |
| Table cells    | Modify or append to existing cell content   |
| Text insertion | Insert content at paragraph markers         |
| Highlighting   | Edits get highlighted in configurable color |

***

## Request Parameters

<CodeGroup>
  ```python Python theme={null}
  result = client.edit.run(
      document_url="...",           # Required: file to edit
      edit_instructions="...",      # Required: what to fill
      edit_options={
          "color": "#FF0000",                  # Highlight color (DOCX only)
          "enable_overflow_pages": False,      # Appendix for long text (PDF only)
          "llm_provider_preference": "openai"  # LLM provider (optional)
      },
      form_schema=[...]             # Optional: predefined field locations (PDF only)
  )
  ```

  ```javascript Node.js theme={null}
  const result = await client.edit.run({
    document_url: '...',           // Required: file to edit
    edit_instructions: '...',      // Required: what to fill
    edit_options: {
      color: '#FF0000',                   // Highlight color (DOCX only)
      enable_overflow_pages: false,       // Appendix for long text (PDF only)
      llm_provider_preference: 'openai'   // LLM provider (optional)
    },
    form_schema: [...]             // Optional: predefined field locations (PDF only)
  });
  ```

  ```bash cURL theme={null}
  curl -X POST https://platform.reducto.ai/edit \
    -H "Authorization: Bearer $REDUCTO_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "document_url": "...",
      "edit_instructions": "...",
      "edit_options": {
        "color": "#FF0000",
        "enable_overflow_pages": false,
        "llm_provider_preference": "openai"
      },
      "form_schema": [...]
    }'
  ```
</CodeGroup>

### document\_url

The document to edit. Accepts the same formats as Parse: `reducto://` file IDs from upload, public URLs, or presigned S3/GCS URLs.

### edit\_instructions

Natural language instructions describing what to fill. Be explicit about values and which fields they belong to:

```
Fill this form with:
- Full Name: John David Smith
- Date of Birth: March 15, 1985
- SSN: 123-45-6789
- Check "Yes" for US Citizen
- Select "California" for state
```

Vague instructions like "Fill out John's information" perform poorly. Include formatting hints when the form expects specific formats (dates, phone numbers, SSNs).

### edit\_options

| Option                    | Default   | Description                                                                                           |
| ------------------------- | --------- | ----------------------------------------------------------------------------------------------------- |
| `color`                   | `#FF0000` | Hex color for highlighting edits (DOCX only)                                                          |
| `enable_overflow_pages`   | `false`   | Create appendix pages for text exceeding field capacity (PDF only)                                    |
| `llm_provider_preference` | `null`    | LLM provider for form filling: `"openai"`, `"anthropic"`, or `"google"`. If null, defaults to Google. |

### form\_schema

For repeatable form filling, define field locations explicitly. This skips detection, improving speed 3x and consistency. See [Form Schema](/configs/edit/form-schema).

***

## Response

```json theme={null}
{
  "document_url": "https://storage.reducto.ai/filled-form.pdf?...",
  "form_schema": [
    {
      "bbox": {"left": 0.1, "top": 0.2, "width": 0.4, "height": 0.03, "page": 1},
      "description": "Name field in header section",
      "type": "text"
    }
  ],
  "usage": {"num_pages": 2, "credits": 8}
}
```

| Field           | Description                                                                  |
| --------------- | ---------------------------------------------------------------------------- |
| `document_url`  | Presigned URL to download edited document. Valid 24 hours.                   |
| `form_schema`   | Detected field schema (PDF only). Save this to reuse for the same form type. |
| `usage.credits` | Credits charged: 4 per page.                                                 |

***

## Async Processing

For larger documents or webhook delivery, use the async endpoint:

<CodeGroup>
  ```python Python theme={null}
  result = client.edit.run_job(
      document_url=upload.file_id,
      edit_instructions="...",
  )
  print(result.job_id)  # Poll /job/{job_id} or wait for webhook

  # Poll for results
  import time
  while True:
      job = client.job.get(result.job_id)
      if job.status == "Completed":
          print(job.result.document_url)
          break
      time.sleep(2)
  ```

  ```javascript Node.js theme={null}
  const result = await client.edit.runJob({
    document_url: upload.file_id,
    edit_instructions: '...',
  });
  console.log(result.job_id);  // Poll /job/{job_id} or wait for webhook

  // Poll for results
  while (true) {
    const job = await client.job.retrieve(result.job_id);
    if (job.status === 'Completed') {
      console.log(job.result.document_url);
      break;
    }
    await new Promise(r => setTimeout(r, 2000));
  }
  ```

  ```bash cURL theme={null}
  # Submit async job
  JOB_ID=$(curl -s -X POST https://platform.reducto.ai/edit_async \
    -H "Authorization: Bearer $REDUCTO_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "document_url": "reducto://your-file-id",
      "edit_instructions": "..."
    }' | jq -r '.job_id')

  # Poll for results
  while true; do
    STATUS=$(curl -s https://platform.reducto.ai/job/$JOB_ID \
      -H "Authorization: Bearer $REDUCTO_API_KEY" | jq -r '.status')
    echo "Status: $STATUS"
    if [ "$STATUS" = "Completed" ]; then
      curl -s https://platform.reducto.ai/job/$JOB_ID \
        -H "Authorization: Bearer $REDUCTO_API_KEY" | jq '.result.document_url'
      break
    fi
    sleep 2
  done
  ```
</CodeGroup>

Sync requests get priority by default. Async can request priority with `priority=True` if your account has budget available.

***

## How It Works

### PDF

1. **Detect** form widgets (or use vision if none exist)
2. **Analyze** context around each field (labels, headers)
3. **Map** your instructions to fields based on descriptions
4. **Fill** values into the PDF

With a `form_schema`, steps 1-2 are skipped since you've defined field locations and descriptions.

### DOCX

1. **Tag** editable locations (paragraphs, table cells, form controls)
2. **Analyze** document structure against your instructions
3. **Generate** specific edits (insert text, check boxes, update cells)
4. **Apply** edits with optional highlighting

***

## Troubleshooting

<AccordionGroup>
  <Accordion title="Fields remain empty">
    Several things can cause unfilled fields:

    * **Instructions didn't match**: The LLM couldn't map your instructions to that field. Use terms that appear on the form itself.
    * **Dropdown mismatch**: Value must exactly match an option ("CA" vs "California")
    * **Detection missed it**: Use `form_schema` to explicitly define field locations
  </Accordion>

  <Accordion title="No form fields detected">
    The PDF has no widgets and vision couldn't detect fillable areas. Common causes:

    * Scanned image without clear form structure
    * Fields blend into background or lack clear boundaries
    * Document isn't actually a fillable form

    **Solution**: Provide a `form_schema` defining field locations. See [Form Schema](/configs/edit/form-schema).
  </Accordion>

  <Accordion title="Text cut off in PDF fields">
    PDF fields have fixed sizes. When content exceeds capacity, it gets truncated.

    **Solutions:**

    1. Enable overflow: `edit_options={"enable_overflow_pages": True}` creates appendix pages
    2. Abbreviate in your instructions if the form expects short values
  </Accordion>

  <Accordion title="Checkboxes not checking">
    Be explicit: `Check "Yes" for US Citizen` works better than `US Citizen: Yes`. The LLM needs to understand you mean check a box, not fill text.
  </Accordion>

  <Accordion title="Wrong field gets filled">
    When fields have similar labels, the LLM may map incorrectly:

    1. **Be more specific**: "Applicant First Name: John" rather than "Name: John"
    2. **Use form\_schema**: Define exactly which field is which using coordinates
    3. **Reference position**: "The name field in the top-left of page 1"
  </Accordion>

  <Accordion title="Can I use Parse to get field locations?">
    No. Parse finds existing content (labels like "Name:"). Edit finds empty fillable areas (the input box next to "Name:"). Form fields are blank rectangles with nothing for Parse to detect.

    Use Edit once without `form_schema` to detect fields, then save and reuse the returned schema.
  </Accordion>
</AccordionGroup>

***

## Limitations

### Partial Success

Edit returns successfully even when some fields couldn't be filled. These situations don't raise errors:

| Scenario                                | Behavior                    |
| --------------------------------------- | --------------------------- |
| Dropdown value not in options           | Field skipped silently      |
| Instructions don't match any field      | Document returned unchanged |
| Unsupported widget (signatures, images) | Widget skipped              |

### Format-Specific

**PDF:**

* Signature and image fields not supported
* Radio buttons have limited support
* Heavily designed forms may detect incorrectly

**DOCX:**

* Requires structured documents (form controls, tables)
* Very large documents (100+ pages) take longer

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Form Schema" icon="table-cells" href="/form-schema">
    Pre-define field locations for faster, more consistent filling.
  </Card>

  <Card title="API Reference" icon="code" href="/api-reference/edit">
    Complete endpoint specification.
  </Card>
</CardGroup>
