# Templates

> Send a saved email template through the Reggio Digital API and fill in its variables from your own data.

Source: https://reggiodigital.com/developers/templates

A template keeps the wording and design of a message in the dashboard, so the business can change a receipt without anyone touching code. Your application sends the template's identifier and the values to fill in.

## Creating one

Templates are built and published in [Email templates](https://reggiodigital.com/email/templates) in the dashboard. Each template has an identifier, a UUID, which you copy from its page. Only the published version sends: saving a draft changes nothing for live sends until someone chooses Publish.

## Sending a template

Send `template_id` and `variables` in place of `subject`, `html` and `text`:

cURL:

```bash
curl -X POST https://reggiodigital.com/api/v1/emails \
  -H "Authorization: Bearer $REGGIO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
      "from": "hello@yourdomain.com",
      "to": [
          "success@simulator.amazonses.com"
      ],
      "template_id": "COPY_YOUR_TEMPLATE_IDENTIFIER",
      "variables": {
          "customer_name": "Alex",
          "order_number": "1042",
          "total": "$42.00"
      }
  }'
```

Laravel:

```php
use Illuminate\Support\Facades\Http;

$response = Http::withToken(config('services.reggio.key'))
    ->acceptJson()
    ->post('https://reggiodigital.com/api/v1/emails', [
        'from' => 'hello@yourdomain.com',
        'to' => [
            'success@simulator.amazonses.com',
        ],
        'template_id' => 'COPY_YOUR_TEMPLATE_IDENTIFIER',
        'variables' => [
            'customer_name' => 'Alex',
            'order_number' => '1042',
            'total' => '$42.00',
        ],
    ]);

if ($response->failed()) {
    throw new RuntimeException($response->json('error.message'));
}

$body = $response->json();
```

PHP:

```php
$payload = [
    'from' => 'hello@yourdomain.com',
    'to' => [
        'success@simulator.amazonses.com',
    ],
    'template_id' => 'COPY_YOUR_TEMPLATE_IDENTIFIER',
    'variables' => [
        'customer_name' => 'Alex',
        'order_number' => '1042',
        'total' => '$42.00',
    ],
];

$ch = curl_init('https://reggiodigital.com/api/v1/emails');

curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer '.getenv('REGGIO_API_KEY'),
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode($payload),
]);

$body = json_decode((string) curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);

if ($status >= 400) {
    throw new RuntimeException($body['error']['message']);
}
```

Node.js:

```js
const response = await fetch("https://reggiodigital.com/api/v1/emails", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.REGGIO_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
      "from": "hello@yourdomain.com",
      "to": [
          "success@simulator.amazonses.com"
      ],
      "template_id": "COPY_YOUR_TEMPLATE_IDENTIFIER",
      "variables": {
          "customer_name": "Alex",
          "order_number": "1042",
          "total": "$42.00"
      }
  }),
});

const body = await response.json();

if (!response.ok) {
  throw new Error(body.error.message);
}
```

The template supplies the subject and both bodies. Sending `subject`, `html` or `text` alongside `template_id` is refused with a `422`, and so is sending `variables` without a template.

Templates work in [batches](https://reggiodigital.com/developers/email#sending-a-batch) and [scheduled sends](https://reggiodigital.com/developers/email#sending-later) too. When we accept a scheduled or batch send, we fill the template in and keep that finished message, so publishing a new version afterwards does not change mail you have already handed us.

## Variables

In the template, a variable is written as `{{ customer_name }}`. In the request, it is a key in `variables`:

```json
"variables": { "customer_name": "Alex", "order_number": "1042", "total": "$42.00" }
```

- Names are case sensitive. Up to 50 per message.
- Each variable has a type set in the template. **Text** takes text or a number, **Number** takes a number, and **Web address** takes a complete `http://` or `https://` address.
- A variable can be required, or optional with a default. A missing optional value uses its default. The preview values in the editor are never used for real sends.
- Values are always treated as text, never as markup, so a value cannot inject HTML into the message.
- The finished subject is limited to 255 characters and cannot contain a line break.

A missing required value, a name the template does not define, or a value of the wrong type is refused with a `422`. `error.fields` names the variable, as in `variables.order_number`, or `emails.0.variables.order_number` in a batch.

## Errors you are likely to see

| Status | Why |
| --- | --- |
| `422` | The template does not exist on this account, has never been published, or a variable is missing or invalid. |
| `402` | The account no longer has a transactional email plan. |

Everything else behaves as for any send. See [errors, limits and headers](https://reggiodigital.com/developers/conventions).
