# Templates and Merging

> Fix 400 Bad Request, templates that aren't found, empty merge fields, missing blocks and images, wrong culture formats and mergeHtml in merged documents.

- **Product:** ReportingCloud
- **Section:** Documentation
- **Kind:** Topic
- **Path:** ReportingCloud > Troubleshooting > Templates and Merging
- **3374 words**
- **Web URL:** https://docs.textcontrol.com/reporting-cloud/troubleshooting/mail-merge/
- **LLMs URL:** https://docs.textcontrol.com/reporting-cloud/troubleshooting/mail-merge/llms.txt
- **LLMs-Full URL:** https://docs.textcontrol.com/reporting-cloud/troubleshooting/mail-merge/llms-full.txt

---

A merge request goes wrong in one of two ways. The Web API refuses it with 400 Bad Request because the template or the data is missing, or it returns a document that isn't what you expected: values are missing, a table is gone, an amount shows the wrong currency or HTML tags aren't applied. In both cases the cause lies in the request, in the template name, the JSON data or the `mergeSettings`. Most problems below can be traced by comparing the template with the data, so start there.

### Compare the Template With Your Data

A merge field gets its value from the key of the same name in a record of `mergeData`, and a merge block repeats once for each item of the array of the same name. [GET /v1/templates/info](https://docs.textcontrol.com/reporting-cloud/reference/web-api/templates/info/get/llms-full.txt) lists the fields and blocks of a stored template, with their nesting and formats:

```bash
curl -H "Authorization: ReportingCloud-APIKey $REPORTINGCLOUD_API_KEY" \
  "https://api.reporting.cloud/v1/templates/info?templateName=sample_invoice.tx"
```

The response holds the top-level fields in `mergeFields` and the blocks in `mergeBlocks`, each block with its own fields and nested blocks. Compare these names with the keys of your JSON: [Check the Field Names of a Template](https://docs.textcontrol.com/reporting-cloud/mail-merge/fields/#check-the-field-names-of-a-template) shows the response for the demo template, and [The Structure of the Data](https://docs.textcontrol.com/reporting-cloud/mail-merge/data-sources/#the-structure-of-the-data) the data that matches it.

### The Request Returns 400 Bad Request

A document or template request returns `400 Bad Request`. The reference names three kinds of causes: a template that isn't in the template storage, a body without data and a document or template that isn't valid. [Bad Request](https://docs.textcontrol.com/reporting-cloud/document-processing/errors/#bad-request) lists the causes of each endpoint.

The sections below cover the three cases you meet most often: a template name the storage doesn't know, a body without data and an upload that is refused.

### The Template Isn't Found

A merge request with `templateName`, or a request to `GET /v1/templates/info` or another template endpoint, returns 400, and the template name looks right.

The name has to match the file name in the template storage, extension included, such as `sample_invoice.tx`. Only the letter case may differ: `Sample_Invoice.TX` names the same template. The template may also have been deleted, or never uploaded to this account. A new trial account has the demo template `sample_invoice.tx` in its storage.

1. Check whether the storage has a template of this name with [GET /v1/templates/exists](https://docs.textcontrol.com/reporting-cloud/reference/web-api/templates/exists/get/llms-full.txt). It returns `true` or `false`:

    ```bash
    curl -H "Authorization: ReportingCloud-APIKey $REPORTINGCLOUD_API_KEY" \
      "https://api.reporting.cloud/v1/templates/exists?templateName=sample_invoice.tx"
    ```
2. If it returns `false`, list the names in the storage with [GET /v1/templates/list](https://docs.textcontrol.com/reporting-cloud/reference/web-api/templates/list/get/llms-full.txt) or under **My Templates** in the portal. Correct the name in your request.
3. If the template isn't in the list, upload it under that name with [POST /v1/templates/upload](https://docs.textcontrol.com/reporting-cloud/reference/web-api/templates/upload/post/llms-full.txt), or send it with the request in the `template` field of the `MergeBody`, as a Base64 string.

### The Request Has No Data

A merge request returns 400 although the template exists.

The service found no data in the `MergeBody`, or no template. The body is a JSON object whose `mergeData` holds the records as a JSON array, and the template comes from the query parameter `templateName` or from the `template` field of the body.

1. Send the body as JSON, with the header `Content-Type: application/json`.
2. Check the structure of the body. Save it as *merge.json*, for example:

    ```json
    {
      "mergeData": [
        {
          "invoice_no": "778723",
          "billto_name": "Joey Montana",
          "item": [
            {
              "qty": "1",
              "item_no": "1",
              "item_description": "Item description 1",
              "item_total": "2130.40"
            }
          ]
        }
      ]
    }
    ```
3. Send it with the template name and the return format in the query string:

    ```bash
    curl -i -X POST "https://api.reporting.cloud/v1/document/merge?templateName=sample_invoice.tx&returnFormat=PDF" \
      -H "Authorization: ReportingCloud-APIKey $REPORTINGCLOUD_API_KEY" \
      -H "Content-Type: application/json" \
      --data @merge.json
    ```

The option `--data @merge.json` reads the body from the file. [Merge Data](https://docs.textcontrol.com/reporting-cloud/mail-merge/data-sources/llms-full.txt) describes the format of `mergeData` in full.

### A Template Upload Returns 400

[POST /v1/templates/upload](https://docs.textcontrol.com/reporting-cloud/reference/web-api/templates/upload/post/llms-full.txt) returns 400.

The service couldn't read the template: its format isn't supported, or the file arrived damaged. The endpoint accepts DOC, DOCX, RTF and TX files, sent as a Base64 string in a JSON string.

1. Check that the file is a DOC, DOCX, RTF or TX document.
2. Encode the whole file as one Base64 string without line breaks, for example with `base64 -w 0 invoice.docx`.
3. Send the string in quotes as the body, as [Upload a Template](https://docs.textcontrol.com/reporting-cloud/document-processing/templates/#upload-a-template) shows.

### Fields Are Empty in the Document

The merged document lacks values where the template has merge fields, and the text of the fields is gone.

A field without data is removed, because `removeEmptyFields` is `true` unless you set it to `false`. A field has no data when the record has no key of its name: the name is spelled differently, the key is on another level or the value is missing. The merge matches names regardless of letter case, so only a different spelling counts: `invoice_no` and `invoiceNo` are different names.

1. Get the field names with `GET /v1/templates/info`, as [Compare the Template With Your Data](#compare-the-template-with-your-data) shows, and compare them with the keys of your JSON.
2. Put the keys of top-level fields into the record itself, and the keys of fields inside a block into the objects of the array that carries the block's name.
3. When an SDK creates the JSON from your objects, compare the names it sends. The .NET SDK writes property names in camel case, so a property `InvoiceNumber` becomes the key `invoiceNumber`, which still fills a field `InvoiceNumber`; a property `InvoiceNo` doesn't fill a field `invoice_no`. [Name Fields After the Data](https://docs.textcontrol.com/reporting-cloud/mail-merge/fields/#name-fields-after-the-data) describes the rules.

### Empty Lines Remain Where Fields Had No Data

The document has blank lines where a line of the template held only merge fields without data, such as a second address line.

`removeEmptyLines` is `false` unless you set it, so a line that held only empty fields stays as an empty line. Remove such lines with the setting:

1. Add `removeEmptyLines` to the `mergeSettings` of the request:

    ```json
    {
      "mergeData": [
        { "invoice_no": "778723" }
      ],
      "mergeSettings": {
        "removeEmptyLines": true
      }
    }
    ```
2. Merge again. Lines with other content besides the empty fields stay.

Of the SDKs, only the .NET SDK offers the setting, as the `RemoveEmptyLines` property of `MergeSettings`. With the PHP, Java or Ruby SDK, send the request to the Web API directly. [Merge Settings](https://docs.textcontrol.com/reporting-cloud/mail-merge/settings/#set-merge-settings-in-the-sdks) lists the settings of each SDK.

### A Merge Block Is Missing

A table row or a section that should repeat for each item is missing from the document.

A block without data is removed, because `removeEmptyBlocks` is `true` unless you set it to `false`. This is also how conditional blocks work. A block has no data when the record has no array with the block's name, when the array is empty or when the array of a nested block isn't inside the items of the outer block.

1. Get the block names and their nesting with `GET /v1/templates/info`, in `mergeBlocks`.
2. Name the array exactly like the block, on the level of the block: a top-level block is a key of the record, and a nested block is a key of each item of the outer block's array.
3. To keep a block in the document when it has no data, set `removeEmptyBlocks` to `false` in the `mergeSettings`.

[Merge Blocks](https://docs.textcontrol.com/reporting-cloud/mail-merge/blocks/llms-full.txt), [Nested Blocks](https://docs.textcontrol.com/reporting-cloud/mail-merge/nested-blocks/llms-full.txt) and [Conditional Blocks](https://docs.textcontrol.com/reporting-cloud/mail-merge/conditional-content/llms-full.txt) describe the data each kind of block needs.

### A Merged Image Is Missing

An image placeholder of the template doesn't show the image from your data.

The record has no value under the name of the column the placeholder is bound to, or the value isn't the Base64 string of a JPG, PNG, BMP or GIF image. `removeEmptyImages` is `false` unless you set it, so a placeholder without data stays in the document.

1. In the template editor, right-click the image and check under **Select Object Data Source** which column it is bound to.
2. Check that the record has a key of that name, and that its value is the Base64 string of a JPG, PNG, BMP or GIF image.
3. To remove placeholders that have no data, set `removeEmptyImages` to `true`.

[Images](https://docs.textcontrol.com/reporting-cloud/mail-merge/images/llms-full.txt) walks through a template with an image placeholder.

### Dates and Currency Values Have the Wrong Format

A price shows the dollar sign where you expect the euro, or a long date appears in English.

The merge formats dates and currency values for a culture, and the culture is `en-US` unless you set another one. The culture shows in the fields that the template formats: with a numeric format such as `C` for currency, or with a date format.

1. Set the culture in the `mergeSettings` to a language culture name, such as `de-DE` for German or `fr-FR` for French:

    ```json
    {
      "mergeSettings": {
        "culture": "de-DE"
      }
    }
    ```
2. Check the formats of the fields: `GET /v1/templates/info` returns them in `numericFormat` and `dateTimeFormat`. An empty value means that the template sets no format for the field. Set one in the template editor, in the options of the merge field.

The Java and Ruby SDKs have no culture setting; send a merge with another culture to the Web API directly. [Culture](https://docs.textcontrol.com/reporting-cloud/mail-merge/culture/llms-full.txt) shows the field options and the effect of each culture.

### HTML Formatting Isn't Applied

Field data that contains HTML, such as `<strong>` or `<em>`, isn't merged as formatted text.

HTML in field data is only interpreted when `mergeHtml` is `true` in the `mergeSettings`, the complete value is enclosed in an `<html>` element and the request goes to `POST /v1/document/merge`. `mergeHtml` is `false` unless you set it, and the font name, size and colors come from the field in the template, not from the HTML.

1. Set `mergeHtml` to `true` and enclose the value in `<html>` and `</html>`:

    ```json
    {
      "mergeData": [
        {
          "comments": "<html><strong>Delivery</strong> within <em>five</em> business days</html>"
        }
      ],
      "mergeSettings": {
        "mergeHtml": true
      }
    }
    ```
2. Send the request to `document/merge`.
3. Set the font, size and color of the text on the merge field in the template, not in the HTML.

[HTML Content](https://docs.textcontrol.com/reporting-cloud/mail-merge/html-content/llms-full.txt) shows a template with a comments field and the merged result.

### The Number of Documents Isn't What You Expect

You get one document for several records, or several documents where you expected one.

The merge creates one document for each record of `mergeData` when the request sends `append=false`. With `append=true`, or with no `append` at all, it appends them to one document instead. The SDKs don't share a default: `MergeDocument` of the .NET SDK appends unless you pass `false`, `mergeDocument` of the Java SDK and `merge_document` of the Ruby gem send `false` unless you pass `true`, and `mergeDocument` of the PHP SDK sends `append` only when it is `true`, so the service appends whatever you pass.

1. Pass `append` with every request, so that the result doesn't depend on a default: `append=true` or `append=false` in the query string, or the `append` argument of the SDK method. With the PHP SDK, which can't send `false`, merge one record per request.
2. Read every element of the result: the response is an array with one document per element.

### The Saved Document Doesn't Open

You saved the response of a merge request as *invoice.pdf*, and the file doesn't open as a PDF.

The Web API doesn't return the PDF itself. The response body is a JSON array that holds each created document as a Base64 string. The .NET, Java and PHP SDKs decode it for you; the Ruby SDK returns the Base64 strings, which you decode yourself.

1. Save the response to a file:

    ```bash
    curl -s -X POST "https://api.reporting.cloud/v1/document/merge?templateName=sample_invoice.tx&returnFormat=PDF" \
      -H "Authorization: ReportingCloud-APIKey $REPORTINGCLOUD_API_KEY" \
      -H "Content-Type: application/json" \
      --data @merge.json \
      -o response.json
    ```
2. Take the first element of the array and decode it, for example with jq:

    ```bash
    jq -r '.[0]' response.json | base64 -d > invoice.pdf
    ```

[Web API](https://docs.textcontrol.com/reporting-cloud/getting-started/web-api/llms-full.txt) in Getting Started walks through this request from the start.

### Related Pages

- [Overview](https://docs.textcontrol.com/reporting-cloud/mail-merge/overview/llms-full.txt): how templates, merge data and the merge request fit together.
- [Merge Settings](https://docs.textcontrol.com/reporting-cloud/mail-merge/settings/llms-full.txt): every setting of `mergeSettings` with its default.
- [Managing Templates](https://docs.textcontrol.com/reporting-cloud/document-processing/templates/llms-full.txt): the endpoints of the template storage.
- [Errors and Status Codes](https://docs.textcontrol.com/reporting-cloud/document-processing/errors/llms-full.txt): the status codes of the Web API.
- [Quotas and Limits](https://docs.textcontrol.com/reporting-cloud/troubleshooting/quotas-limits/llms-full.txt): 403 responses, the 60-second limit and watermarks.

---

## Nearby

- **Previous:** [Quotas and Limits](https://docs.textcontrol.com/reporting-cloud/troubleshooting/quotas-limits/llms-full.txt)
- **Next:** [Getting Support](https://docs.textcontrol.com/reporting-cloud/troubleshooting/support/llms-full.txt)
