# Merge Data

> Structure the JSON mergeData array of a merge: records, values, arrays for merge blocks, nested objects and the serialization by the .NET and PHP SDKs.

- **Product:** ReportingCloud
- **Section:** Documentation
- **Kind:** Topic
- **Path:** ReportingCloud > Mail Merge > Merge Data
- **3536 words**
- **Web URL:** https://docs.textcontrol.com/reporting-cloud/mail-merge/data-sources/
- **LLMs URL:** https://docs.textcontrol.com/reporting-cloud/mail-merge/data-sources/llms.txt
- **LLMs-Full URL:** https://docs.textcontrol.com/reporting-cloud/mail-merge/data-sources/llms-full.txt

---

The data of a merge is the `mergeData` property of the request: a JSON array of records, whose names are the names of the merge fields and merge blocks in the template. Its structure decides how many documents a merge creates, which fields receive which values and how often a block is repeated. You build it by hand, with any JSON library or with an SDK, which turns your objects into this array.

How the array travels in a request, with the template and the settings, is shown in [Overview](https://docs.textcontrol.com/reporting-cloud/mail-merge/overview/#the-merge-request). The samples here belong to *sample\_invoice.tx*, the demo template of every trial account.

### The Structure of the Data

The demo template contains merge fields outside of any block, called *top-level fields*, and a merge block named `item` with fields of its own:

![Sample invoice template marking top-level merge fields and the item block](https://docs.textcontrol.com/assets/img/reporting-cloud/top-level-fields-item-block.69d3b5e8.webp)

The data for this template is an array with one object per invoice. Save the following data as *data.json*, the file the requests of [Overview](https://docs.textcontrol.com/reporting-cloud/mail-merge/overview/llms-full.txt) send:

```json
[
  {
    "yourcompany_companyname": "Text Control, LLC",
    "invoice_no": "778723",
    "billto_name": "Joey Montana",
    "billto_companyname": "Montana, LLC",
    "item": [
      {
        "qty": "1",
        "item_no": "1",
        "item_description": "Item description 1",
        "item_unitprice": "2663",
        "item_discount": "20",
        "item_total": "2130.40"
      },
      {
        "qty": "1",
        "item_no": "2",
        "item_description": "Item description 2",
        "item_unitprice": "5543",
        "item_discount": "0",
        "item_total": "5543"
      }
    ],
    "total_discount": "532.60",
    "total_sub": "7673.4",
    "total_tax": "537.138",
    "total": "8210.538"
  }
]
```

Each part of the data has its counterpart in the template:

| In the data | In the template |
|---|---|
| A value of a record, such as `"invoice_no": "778723"` | A top-level field with the same name, `invoice_no` |
| An array of objects, such as `"item": [...]` | The merge block with the name of the array, `item`. It is repeated for each object, and its fields, such as `qty` and `item_total`, take the values of that object |
| An object inside a record or an array element, such as `"product": { "name": "..." }` | A field with dot notation, `product.name`, as [Nested Blocks](https://docs.textcontrol.com/reporting-cloud/mail-merge/nested-blocks/#shape-the-data) shows |
| An image as a Base64 string | An image placeholder, as [Images](https://docs.textcontrol.com/reporting-cloud/mail-merge/images/llms-full.txt) describes |

A field that finds no value in the data is removed by default, as [Merge Fields](https://docs.textcontrol.com/reporting-cloud/mail-merge/fields/#remove-or-keep-empty-fields) explains. The demo template has more fields than the sample above, such as `billto_city` and `payment_due`; the [Web API](https://docs.textcontrol.com/reporting-cloud/getting-started/web-api/llms-full.txt) tutorial has the complete invoice data.

### One Record per Document

Each object at the top level of the array is a record, and the whole template is merged once for each record. Fields inside a block are repeated once for each element of the block's array, and blocks can be nested in any number of levels, as [Nested Blocks](https://docs.textcontrol.com/reporting-cloud/mail-merge/nested-blocks/llms-full.txt) shows.

The following data contains two records, so a merge creates two invoices:

```json
[
  {
    "yourcompany_companyname": "Text Control, LLC",
    "yourcompany_zip": "28226"
  },
  {
    "yourcompany_companyname": "Text Control GmbH",
    "yourcompany_zip": "28217"
  }
]
```

With `append=false`, the response contains two documents. With `append=true`, or without `append`, both invoices are appended to one document. [Create One Document or One per Record](https://docs.textcontrol.com/reporting-cloud/mail-merge/overview/#create-one-document-or-one-per-record) shows both requests.

A single record can also be sent as a JSON object instead of an array with one element: the `MergeBody` of [POST /v1/document/merge](https://docs.textcontrol.com/reporting-cloud/reference/web-api/document/merge/post/#request-payload) accepts both. An array keeps the same form for one record and for many.

### Values

The values of the official samples are JSON strings, such as `"2663"` in *data.json*, and numbers, such as `"item_total": 234.56` in the Java sample of the [merge reference](https://docs.textcontrol.com/reporting-cloud/reference/web-api/document/merge/post/#examples). How a number or a date appears in the document is decided by the field and the culture:

- **Formats** of numbers and dates are properties of a merge field, set in the template, as [Merge Fields](https://docs.textcontrol.com/reporting-cloud/mail-merge/fields/#format-values) describes.
- **The culture** of the merge, such as `de-DE`, decides currency symbols and the language of long date formats, as [Culture](https://docs.textcontrol.com/reporting-cloud/mail-merge/culture/llms-full.txt) explains.
- **Formatted text** in a value, enclosed in an `<html>` element, keeps its bold, italic and underline formatting when the `mergeHtml` setting is `true`, as [HTML Content](https://docs.textcontrol.com/reporting-cloud/mail-merge/html-content/llms-full.txt) shows.

### Merge Objects With the .NET SDK

The .NET SDK takes your objects and serializes them into the `mergeData` array. The following console application merges one invoice into the demo template, with classes whose properties are named like the fields of *sample\_invoice.tx*. It needs the NuGet package `TXTextControl.ReportingCloud`, as [Installing an SDK](https://docs.textcontrol.com/reporting-cloud/installation/sdks/llms-full.txt) describes:

```csharp
using TXTextControl.ReportingCloud;

// One record: the template is merged once, and item fills the merge block
List<Invoice> invoices = new List<Invoice>
{
    new Invoice
    {
        invoice_no = "778723",
        billto_name = "Joey Montana",
        item = new List<Item>
        {
            new Item { qty = "1", item_no = "1", item_description = "Item description 1", item_total = "2130.40" },
            new Item { qty = "1", item_no = "2", item_description = "Item description 2", item_total = "5543" }
        },
        total = "8210.538"
    }
};

ReportingCloud rc = new ReportingCloud(Environment.GetEnvironmentVariable("REPORTINGCLOUD_API_KEY"));

// The SDK serializes the list into the mergeData array
MergeBody mergeBody = new MergeBody { MergeData = invoices };

List<byte[]> documents = rc.MergeDocument(mergeBody, "sample_invoice.tx", ReturnFormat.PDF, false);
File.WriteAllBytes("invoice.pdf", documents[0]);

public class Invoice
{
    public string invoice_no { get; set; } = "";
    public string billto_name { get; set; } = "";
    public List<Item> item { get; set; } = new List<Item>();
    public string total { get; set; } = "";
}

public class Item
{
    public string qty { get; set; } = "";
    public string item_no { get; set; } = "";
    public string item_description { get; set; } = "";
    public string item_total { get; set; } = "";
}
```

The code works as follows:

- The `ReportingCloud` constructor with one string authenticates with an API key; the class sends its requests to `https://api.reporting.cloud`.
- `MergeData` of `MergeBody` takes any object. A list becomes the JSON array of records, so the request body contains the same structure as *data.json*, with `template` and `mergeSettings` set to `null`.
- The SDK writes names in camel case: a property `InvoiceNumber` is sent as `invoiceNumber`, and the keys of a dictionary are changed the same way. Names that start with a lowercase letter, such as `invoice_no`, are sent unchanged, which is why the classes use the names of the template's fields.
- `MergeDocument` sends the request with the template name, the return format and `append`, and returns the created documents as a list of byte arrays, already decoded from Base64.

When the names are known only at run time, such as the fields of a web form, pass a `Dictionary<string, string>` or a list of them, as the blog article [Creating Dynamic HTML Forms Using ReportingCloud](https://www.textcontrol.com/blog/2016/09/28/creating-dynamic-html-forms-using-reportingcloud/) does. A single object instead of a list is sent as a JSON object rather than an array, which the Web API merges as one record, as [ReportingCloud: The MergeData JSON Object Format Explained](https://www.textcontrol.com/blog/2016/10/04/reportingcloud-the-mergedata-json-object-format-explained/) shows.

### Merge Arrays With the PHP SDK

The PHP SDK takes the records as an array of associative arrays, and it sends their keys unchanged. The following script merges the same invoice; it needs the Composer package `textcontrol/textcontrol-reportingcloud`:

```php
<?php

require_once __DIR__ . '/vendor/autoload.php';

use TextControl\ReportingCloud\ReportingCloud;

$reportingCloud = new ReportingCloud([
    'api_key' => (string) getenv('REPORTINGCLOUD_API_KEY'),
]);

// One record: an array of associative arrays, item fills the merge block
$mergeData = [
    [
        'invoice_no'  => '778723',
        'billto_name' => 'Joey Montana',
        'item'        => [
            ['qty' => '1', 'item_no' => '1', 'item_description' => 'Item description 1', 'item_total' => '2130.40'],
            ['qty' => '1', 'item_no' => '2', 'item_description' => 'Item description 2', 'item_total' => '5543'],
        ],
        'total'       => '8210.538',
    ],
];

$documents = $reportingCloud->mergeDocument($mergeData, 'PDF', 'sample_invoice.tx');

file_put_contents('invoice.pdf', $documents[0]);
```

`mergeDocument` returns an array with the binary data of each created document. Its fifth parameter, `$append`, is `false` by default, and the SDK then leaves `append` out of the request, which the service answers with one document of all the records: the array holds one element. The SDK has no way to send `append=false`; to get one document per record, merge one record per request.

### Java and Ruby

- **Java.** The `MergeBody` constructor takes the records as an array or an `Iterable` of objects, and the SDK serializes their fields with their declared names, such as `recipient_name` and `item` in the Java sample of the reference.
- **Ruby.** `MergeBody.new` takes the records as an array of hashes and raises an `ArgumentError` when the array is empty or its first element isn't a hash.

The [SDKs](https://docs.textcontrol.com/reporting-cloud/sdks/llms-full.txt) section describes each SDK, and the [merge reference](https://docs.textcontrol.com/reporting-cloud/reference/web-api/document/merge/post/#examples) has a sample in each language.

### Next Steps

- [Merge Fields](https://docs.textcontrol.com/reporting-cloud/mail-merge/fields/llms-full.txt): name the fields of a template after the data.
- [Merge Blocks](https://docs.textcontrol.com/reporting-cloud/mail-merge/blocks/llms-full.txt): repeat parts of a template for each element of an array.
- [Nested Blocks](https://docs.textcontrol.com/reporting-cloud/mail-merge/nested-blocks/llms-full.txt): merge data with several levels.
- [Datasource Excerpts](https://docs.textcontrol.com/reporting-cloud/portal/datasource-excerpts/llms-full.txt): load sample data of the same structure into the template editor.

---

## Nearby

- **Previous:** [Overview](https://docs.textcontrol.com/reporting-cloud/mail-merge/overview/llms-full.txt)
- **Next:** [Merge Fields](https://docs.textcontrol.com/reporting-cloud/mail-merge/fields/llms-full.txt)
