# PDF Form Fields

> Extract the values of text boxes, check boxes and combo boxes from the AcroForm fields of a PDF form with pdf/acroforms/fields or GetFields, and flatten fields.

- **Product:** DS Server
- **Section:** Documentation
- **Kind:** Topic
- **Path:** DS Server > Document Processing > PDF Form Fields
- **2270 words**
- **Web URL:** https://docs.textcontrol.com/ds-server/document-processing/pdf-forms/
- **LLMs URL:** https://docs.textcontrol.com/ds-server/document-processing/pdf-forms/llms.txt
- **LLMs-Full URL:** https://docs.textcontrol.com/ds-server/document-processing/pdf-forms/llms-full.txt

---

When users return a filled-in PDF form, such as an application or an order form, your application needs the values they entered. The DocumentProcessing Web API reads the AcroForm fields of a PDF document, the interactive form fields of the PDF format, and returns each field with its name, its type, its value and its position on the page. For the opposite direction, a form that must no longer be edited, the convert endpoint replaces form fields with their current values.

### How Reading Form Fields Works

The endpoint is [POST /documentprocessing/pdf/acroforms/fields](https://docs.textcontrol.com/ds-server/reference/web-api/documentprocessing/pdf-acroforms-fields/post/llms-full.txt):

| Part of the request | Content |
|---|---|
| Body | The PDF document as a Base64 string in a JSON string, with the content type `application/json` |
| Response | A JSON array with one object per form field |

Every field has these properties:

| Property | Content |
|---|---|
| `fieldName` | The name of the field |
| `alternateFieldName` | The alternate name of the field |
| `fieldType` | The type of the field, such as `FormTextField` or `FormCheckBox` |
| `bounds` | The position and size of the field, an object with `x`, `y`, `width` and `height` |

Depending on `fieldType`, a field has more properties:

| Field type | Properties |
|---|---|
| `FormTextField` | `value`, the text of the field |
| `FormCheckBox`, `FormRadioButton` | `isChecked`, whether the box or button is selected |
| `FormComboBox`, `FormListBox`, `FormChoiceField` | `value`, the selected value, and `options`, the entries of the list, besides `canEdit`, `sort`, `multiSelect`, `doNotSpellCheck` and `commitOnSelChange` |
| `FormButton` | No properties of its own |

A PDF without form fields is answered with `400 Bad Request`, not with an empty array. Every request needs an access token, as [Authentication](https://docs.textcontrol.com/ds-server/document-processing/authentication/llms-full.txt) describes.

### Read the Form Fields With curl

The following commands read the fields of *invoice.pdf* and print the name, the type and the value of each:

```bash
DS=http://localhost:5000
TOKEN="<access_token>"

# Wrap the Base64 string of the PDF in a JSON string
base64 -w 0 invoice.pdf | jq -Rs . > invoice.json

curl --request POST "$DS/documentprocessing/pdf/acroforms/fields" \
  --header "Authorization: Bearer $TOKEN" \
  --header "Content-Type: application/json" \
  --data-binary @invoice.json \
  --output fields.json

jq '.[] | {fieldName, fieldType, value, isChecked}' fields.json
```

The commands work as follows:

- The body is the PDF as a Base64 string in a JSON string, which `base64 -w 0` and `jq -Rs .` create.
- The response is JSON, not Base64, so *fields.json* can be read as it is.
- The last `jq` command prints four properties of each field. `value` is null for a check box, and `isChecked` is null for a text field.

### Read the Form Fields With .NET

The package `TXTextControl.DocumentServices.DocumentProcessing` returns each field as an object of a class derived from `FormField`, in the namespace `TXTextControl.DocumentServices.DocumentProcessing.PDF.AcroForms`:

```csharp
using TXTextControl.DocumentServices.DocumentProcessing;
using TXTextControl.DocumentServices.DocumentProcessing.OAuth;
using TXTextControl.DocumentServices.DocumentProcessing.PDF.AcroForms;

var oauthSettings = new OAuthSettings("<client ID>", "<client secret>");
var documentProcessing = new DocumentProcessing("http://localhost:5000", oauthSettings);

byte[] pdf = File.ReadAllBytes("invoice.pdf");
FormField[] fields = await documentProcessing.PDF.AcroForms.GetFields(pdf);

foreach (FormField field in fields)
{
    // Read the value from the class of the field type
    string value = field switch
    {
        FormTextField textField => textField.Value,
        FormCheckBox checkBox => checkBox.IsChecked ? "checked" : "not checked",
        FormComboBox comboBox => comboBox.Value,
        _ => ""
    };

    Console.WriteLine($"{field.FieldName} ({field.FieldType}): {value}");
}
```

The code works as follows:

- The `DocumentProcessing` constructor takes the service URL and the credentials of a security profile, and requests an access token.
- `PDF.AcroForms.GetFields` takes the PDF as a byte array and returns a `FormField` array.
- `FormField` has the common properties `FieldName`, `AlternateFieldName`, `FieldType` and `Bounds`. The `switch` expression reads the value from the derived classes: `FormTextField.Value`, `FormCheckBox.IsChecked` and `FormComboBox.Value`, which also has `Options`. `FormListBox` derives from `FormComboBox` and `FormRadioButton` from `FormCheckBox`, so the `switch` reads list boxes and radio buttons as well.

The reference of the package names the element type of the result `AcroFormField`; in version 5.0.0 of the package, the class is `FormField`. The classes are listed in the [DocumentProcessing namespace](https://docs.textcontrol.com/ds-server/reference/dotnet-api/txtextcontrol-documentservices-documentprocessing/llms-full.txt) of the .NET API.

### Flatten Form Fields

Flattening replaces every form field of a document with its current content, so the values become ordinary text of the document instead of fields. The convert endpoint does this when you add `flattenFormFields=true`, as [Converting Documents](https://docs.textcontrol.com/ds-server/document-processing/converting/#flatten-form-fields) shows:

```bash
base64 -w 0 document.docx | jq -Rs . > document.json

curl --request POST "$DS/documentprocessing/document/convert?returnFormat=PDF&flattenFormFields=true" \
  --header "Authorization: Bearer $TOKEN" \
  --header "Content-Type: application/json" \
  --data-binary @document.json \
  --output converted.json

jq -r . converted.json | base64 -d > flattened.pdf
```

In C#, the third argument of `Convert` flattens the form fields:

```csharp
byte[] document = File.ReadAllBytes("document.docx");
byte[] flattened = await documentProcessing.Convert(document, ReturnFormat.PDF, true);
```

The parameter was added in version 3.4.0. Its default is `false`, and a value that isn't a Boolean, such as `maybe`, is refused with `400` and a validation error.

### Fill Form Fields With Data

Form fields in a template can also receive values from JSON data when the template is merged. The merge setting `formFieldMergeType` decides whether form fields are left alone, preselected with the data or replaced by it, as [Set Merge Options](https://docs.textcontrol.com/ds-server/document-processing/mail-merge/#set-merge-options) describes.

### Next Steps

- [PDF Documents](https://docs.textcontrol.com/ds-server/document-processing/pdf/llms-full.txt): create PDF and PDF/A documents with passwords, permissions and a signature.
- [Converting Documents](https://docs.textcontrol.com/ds-server/document-processing/converting/llms-full.txt): convert documents with or without form fields.
- [Document Information](https://docs.textcontrol.com/ds-server/document-processing/document-info/llms-full.txt): read the merge fields and blocks of a template.
- [Errors and Status Codes](https://docs.textcontrol.com/ds-server/document-processing/errors/llms-full.txt): what a refused request means.

---

## Nearby

- **Previous:** [PDF Documents](https://docs.textcontrol.com/ds-server/document-processing/pdf/llms-full.txt)
- **Next:** [Barcodes](https://docs.textcontrol.com/ds-server/document-processing/barcodes/llms-full.txt)
