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

# Form Filling

> Automatically fill PDF and image forms with structured data.

The form filling API fills PDF and image forms with your structured data. It works with native PDF form fields and scanned/image forms.

**Before you begin**, make sure you have:

1. A [Datalab account](https://www.datalab.to/auth/sign_up) with an [API key](https://www.datalab.to/app/keys) (new accounts include \$5 in free credits)
2. Python 3.10+ installed
3. The Datalab SDK: `pip install datalab-python-sdk`
4. Your `DATALAB_API_KEY` environment variable set

## Quick Start

<CodeGroup>
  ```python Python SDK theme={null}
  from datalab_sdk import DatalabClient, FormFillingOptions

  client = DatalabClient()

  options = FormFillingOptions(
      field_data={
          "name": {"value": "John Doe", "description": "Full name"},
          "email": {"value": "john@example.com", "description": "Email address"},
          "date": {"value": "12/15/2024", "description": "Today's date"},
      }
  )

  result = client.fill("form.pdf", options=options)
  result.save_output("filled_form.pdf")

  print(f"Fields filled: {result.fields_filled}")
  print(f"Fields not found: {result.fields_not_found}")
  ```

  ```bash cURL theme={null}
  curl -X POST https://www.datalab.to/api/v1/fill \
    -H "X-API-Key: $DATALAB_API_KEY" \
    -F "file=@form.pdf" \
    -F 'field_data={"name": {"value": "John Doe", "description": "Full name"}, "email": {"value": "john@example.com", "description": "Email address"}}'

  # Poll request_check_url from response until status is "complete"
  # Response includes output_base64 with the filled form
  ```

  ```python Python (requests) theme={null}
  import requests, json, time, base64, os

  headers = {"X-API-Key": os.getenv("DATALAB_API_KEY")}

  field_data = {
      "name": {"value": "John Doe", "description": "Full name"},
      "email": {"value": "john@example.com", "description": "Email"},
      "date": {"value": "12/15/2024", "description": "Date"}
  }

  with open("form.pdf", "rb") as f:
      response = requests.post(
          "https://www.datalab.to/api/v1/fill",
          files={"file": ("form.pdf", f, "application/pdf")},
          data={"field_data": json.dumps(field_data), "confidence_threshold": "0.5"},
          headers=headers
      )

  check_url = response.json()["request_check_url"]

  while True:
      result = requests.get(check_url, headers=headers).json()
      if result["status"] == "complete":
          pdf_bytes = base64.b64decode(result["output_base64"])
          with open("filled_form.pdf", "wb") as f:
              f.write(pdf_bytes)
          print(f"Fields filled: {result['fields_filled']}")
          break
      elif result["status"] == "failed":
          print(f"Error: {result.get('error')}")
          break
      time.sleep(2)
  ```
</CodeGroup>

See [SDK Form Filling](/docs/welcome/sdk/form-filling) for complete SDK documentation.

## How It Works

1. Upload your form (PDF or image) with field data
2. The API detects form fields and matches them to your data
3. Fields are filled and the form is returned as PDF or PNG

## Field Data Format

Provide field names with values and descriptions:

```python theme={null}
field_data = {
    "field_key": {
        "value": "The value to fill",
        "description": "Description to help match the field"
    }
}
```

### Examples

**Basic fields:**

```python theme={null}
field_data = {
    "first_name": {"value": "John", "description": "First name"},
    "last_name": {"value": "Doe", "description": "Last name"},
    "ssn": {"value": "123-45-6789", "description": "Social Security Number"}
}
```

**Checkboxes:**

```python theme={null}
field_data = {
    "is_citizen": {"value": "yes", "description": "US citizenship status"},
    "agree_terms": {"value": "checked", "description": "Terms agreement"}
}
```

Values like `"yes"`, `"true"`, `"1"`, `"checked"`, `"x"` will check boxes.

**Compound data:**

```python theme={null}
field_data = {
    "full_address": {
        "value": "123 Main St, New York, NY, 10001",
        "description": "Complete address"
    }
}
```

The API can split compound data across multiple form fields.

## Options

| Option                 | Type   | Default  | Description                                                                                                                                                                              |
| ---------------------- | ------ | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `field_data`           | dict   | Required | Field names mapped to values and descriptions                                                                                                                                            |
| `context`              | str    | None     | Additional context to help match fields                                                                                                                                                  |
| `confidence_threshold` | float  | `0.5`    | Minimum confidence for field matching (0.0-1.0)                                                                                                                                          |
| `max_pages`            | int    | None     | Maximum pages to process                                                                                                                                                                 |
| `page_range`           | str    | None     | Specific pages to process                                                                                                                                                                |
| `skip_cache`           | bool   | `False`  | Skip cached results                                                                                                                                                                      |
| `processing_location`  | string | -        | Data residency region: `"eu"` or `"us"`. When set, use `file_url` or a pre-uploaded `datalab://` reference — multipart uploads are not supported. EU carries a regional pricing premium. |

### Context Parameter

Use `context` to improve matching for specific form types:

```python theme={null}
options = FormFillingOptions(
    field_data={...},
    context="W-4 Employee's Withholding Certificate for new hire"
)
```

## Response

| Field              | Type  | Description                           |
| ------------------ | ----- | ------------------------------------- |
| `status`           | str   | `processing`, `complete`, or `failed` |
| `success`          | bool  | Whether filling succeeded             |
| `output_format`    | str   | `pdf` or `png`                        |
| `output_base64`    | str   | Base64-encoded filled form            |
| `fields_filled`    | list  | Field names that were filled          |
| `fields_not_found` | list  | Field names that couldn't be matched  |
| `page_count`       | int   | Pages processed                       |
| `runtime`          | float | Processing time in seconds            |
| `cost_breakdown`   | dict  | Cost details                          |

## Supported Form Types

* **PDF with native AcroForm fields** - Uses PDF form fields directly
* **PDF with visual fields** - Detects field locations and adds text overlays
* **Images** (PNG, JPG) - Detects field locations and draws text on image

The API automatically detects the input type and uses the appropriate method.

<Warning>
  Results are deleted from Datalab servers one hour after processing completes.
</Warning>

## Next Steps

<CardGroup cols={2}>
  <Card title="SDK Form Filling" icon="code" href="/docs/welcome/sdk/form-filling">
    Complete SDK reference for form filling
  </Card>

  <Card title="File Upload" icon="upload" href="/docs/recipes/file-management/file-upload-api">
    Upload forms for reuse across requests
  </Card>

  <Card title="Pipelines" icon="workflow" href="/docs/recipes/pipelines/pipeline-overview">
    Chain processors into versioned, reusable pipelines.
  </Card>

  <Card title="Webhooks" icon="bell" href="/platform/webhooks">
    Get notified when form filling completes
  </Card>
</CardGroup>
