# Find and Replace

> Replace text placeholders such as %%CustomerName%% in DOCX, DOC or RTF documents with the findandreplace endpoint and FindAndReplaceBody instead of a merge.

- **Product:** DS Server
- **Section:** Documentation
- **Kind:** Topic
- **Path:** DS Server > Document Processing > Find and Replace
- **1895 words**
- **Web URL:** https://docs.textcontrol.com/ds-server/document-processing/find-replace/
- **LLMs URL:** https://docs.textcontrol.com/ds-server/document-processing/find-replace/llms.txt
- **LLMs-Full URL:** https://docs.textcontrol.com/ds-server/document-processing/find-replace/llms-full.txt

---

Not every template has merge fields. A contract written in Word with placeholders such as `%%CustomerName%%` in plain text, or a document in which one product name has to be replaced by another, can be filled with the findandreplace endpoint of the DocumentProcessing Web API. You send the document with a list of text pairs, and DS Server replaces each search text with its replacement and returns the result in the format you choose.

### How Find and Replace Works

The endpoint is [POST /documentprocessing/document/findandreplace](https://docs.textcontrol.com/ds-server/reference/web-api/documentprocessing/document-findandreplace/post/llms-full.txt). Its JSON body, the `FindAndReplaceBody`, has three properties:

| Property | Content |
|---|---|
| `findAndReplaceData` | An array of pairs, each an array of two strings: the text to find and the text that replaces it. Required |
| `template` | The document as a Base64 string, in the format RTF, DOC, DOCX or TX |
| `mergeSettings` | Optional. The same settings as for the merge endpoint, for example the document properties of the result |

The query parameter `returnFormat` sets the format of the result: `PDF`, `PDFA`, `DOCX`, `DOC`, `RTF`, `HTML`, `TX` or `TXT`, with `PDF` as the default. The response is the changed document as a Base64 string in a JSON string.

Every request needs an access token, as [Authentication](https://docs.textcontrol.com/ds-server/document-processing/authentication/llms-full.txt) describes. The samples use the service URL `http://localhost:5000` and the token in the variable `TOKEN`.

### Find and Replace or Merge

Both endpoints fill a template with data. Which one fits depends on the template:

|  | findandreplace | merge |
|---|---|---|
| Placeholders in the template | Any text | Merge fields and merge blocks |
| Data | Pairs of strings | JSON records with nested arrays |
| Repeating sections, such as table rows | No | Merge blocks |
| Documents per request | One | One, or one per record |

Use find and replace for existing documents with text placeholders, and [Merging Templates](https://docs.textcontrol.com/ds-server/document-processing/mail-merge/llms-full.txt) for templates designed with merge fields.

### Replace Text With curl

*template.docx* contains the placeholders `%%CustomerName%%` and `%%Date%%`. The following commands replace them and create a DOCX document:

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

# Build the FindAndReplaceBody from the document and the text pairs
jq -n \
  --rawfile template <(base64 -w 0 template.docx) \
  '{
    template: $template,
    findAndReplaceData: [
      ["%%CustomerName%%", "Peter Jackson"],
      ["%%Date%%", "September 29, 2026"]
    ]
  }' > replace.json

curl --request POST "$DS/documentprocessing/document/findandreplace?returnFormat=DOCX" \
  --header "Authorization: Bearer $TOKEN" \
  --header "Content-Type: application/json" \
  --data-binary @replace.json \
  --output replaced.json

# Decode the Base64 string of the response
jq -r . replaced.json | base64 -d > contract.docx
```

The commands work as follows:

- `--rawfile template` reads the Base64 string of the document into the variable `$template`.
- `findAndReplaceData` lists the pairs. The first string of each pair is the text to find, and the second is its replacement.
- `jq -r .` removes the quotes of the response, and `base64 -d` decodes the DOCX document.

The pairs must be arrays of two strings. An object such as `{"%%Date%%": "September 29, 2026"}` is refused with `400` "One or more validation errors occurred.", with an error for `$.findAndReplaceData`.

### Replace Text With .NET

In the package `TXTextControl.DocumentServices.DocumentProcessing`, the pairs are a list of `KeyValuePair<string, string>` in a `FindAndReplaceBody`:

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

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

var findAndReplaceBody = new FindAndReplaceBody
{
    Template = await File.ReadAllBytesAsync("template.docx"),
    FindAndReplaceData = new List<KeyValuePair<string, string>>
    {
        new("%%CustomerName%%", "Peter Jackson"),
        new("%%Date%%", "September 29, 2026")
    }
};

byte[] document = await documentProcessing.FindAndReplace(findAndReplaceBody, ReturnFormat.DOCX);
await File.WriteAllBytesAsync("contract.docx", document);
```

The code works as follows:

- `Template` takes the document as a byte array; the package encodes it.
- `FindAndReplaceData` holds the pairs: the `Key` is the text to find and the `Value` its replacement.
- `FindAndReplace` returns the changed document as a byte array. The overload without a `ReturnFormat` takes the `FindAndReplaceBody` alone and creates PDF.

### Set the Document Properties

`mergeSettings` takes the object described in [Set Merge Options](https://docs.textcontrol.com/ds-server/document-processing/mail-merge/#set-merge-options). Its document properties set the properties of the result: `documentTitle`, `documentSubject`, `author`, `creatorApplication`, `creationDate`, `lastModificationDate` and `userPassword`. The `mergeHtml` setting works only with the merge endpoint.

The following body creates a PDF document with a title and a password that is needed to open it:

```bash
jq -n \
  --rawfile template <(base64 -w 0 template.docx) \
  '{
    template: $template,
    findAndReplaceData: [["%%CustomerName%%", "Peter Jackson"]],
    mergeSettings: {documentTitle: "Contract", userPassword: "<password>"}
  }' > replace.json
```

In C#, set the `MergeSettings` property of the `FindAndReplaceBody`:

```csharp
findAndReplaceBody.MergeSettings = new MergeSettings
{
    DocumentTitle = "Contract",
    UserPassword = "<password>"
};
```

### Next Steps

- [Merging Templates](https://docs.textcontrol.com/ds-server/document-processing/mail-merge/llms-full.txt): fill templates with merge fields and repeating blocks.
- [Converting Documents](https://docs.textcontrol.com/ds-server/document-processing/converting/llms-full.txt): convert a document without changing its text.
- [Appending Documents](https://docs.textcontrol.com/ds-server/document-processing/appending/llms-full.txt): add the filled document to other documents.
- [Errors and Status Codes](https://docs.textcontrol.com/ds-server/document-processing/errors/llms-full.txt): what to do when a request is refused.

---

## Nearby

- **Previous:** [Appending Documents](https://docs.textcontrol.com/ds-server/document-processing/appending/llms-full.txt)
- **Next:** [Document Information](https://docs.textcontrol.com/ds-server/document-processing/document-info/llms-full.txt)
