> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sendbaze.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Templates

> Write an email once with placeholders, send it with variables, and keep every version. Edit in the dashboard or through the API.

A template is a subject plus an HTML and/or plain-text body with `{{placeholders}}`. Sending with `templateId` renders the current version with the `variables` you pass.

```html theme={"dark"}
<p>Hi {{name}},</p>
<p>Your order <b>{{order_id}}</b> has shipped and should arrive by {{eta}}.</p>
```

## Placeholders

* Names use letters, digits and underscores and start with a letter or underscore: `{{first_name}}`, `{{ order_id }}` (spaces inside the braces are fine).
* Values may be strings, numbers or booleans.
* In the **HTML part** values are HTML-escaped, so `<script>` from a user becomes harmless text. In the subject and text part they are inserted as-is.
* `{{unsubscribe_url}}` is reserved: Sendbaze fills it in on [marketing email](https://docs.sendbaze.com/get-started/email-types.md).
* Every placeholder the template uses must be supplied at send time. A missing one is a `422 validation_error` with `fields` such as `{ "variables.eta": ["is required by the template"] }`. Extra variables are ignored.

## Send with a template

```ts Node.js theme={"dark"}
await sendbaze.emails.send({
  from: "orders@yourshop.co.za",
  to: "thandi@example.com",
  templateId: "tpl_01j9x7k2r4m8q3v5n6b7c8d9e0",
  variables: { name: "Thandi", order_id: 1042, eta: "Friday" },
});
```

```bash cURL theme={"dark"}
curl https://api.sendbaze.com/v1/emails \
  -H "Authorization: Bearer $SENDBAZE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "from": "orders@yourshop.co.za",
    "to": "thandi@example.com",
    "templateId": "tpl_01j9x7k2r4m8q3v5n6b7c8d9e0",
    "variables": { "name": "Thandi", "order_id": 1042, "eta": "Friday" }
  }'
```

`subject` is optional with a template and overrides the template's subject when given. `html`, `text` and `react` cannot be combined with `templateId`. Prefer components over placeholders? See [React Email](https://docs.sendbaze.com/learn/sending/react-email.md).

## Versions

Every content change (subject, html or text) creates a new version; a rename does not. The message records the template id and the version it rendered, so editing a template never changes what an already-sent email said. The dashboard shows the history with a **Restore** button, which makes an old version current again as a new version. `GET /v1/templates/{id}/versions` returns them with full content.

## Manage templates

> [tab] Dashboard
>
> **Templates** in the dashboard lists your templates, creates new ones and opens an editor with:
>
> * subject, HTML and plain-text fields with the placeholders it finds
> * a live preview with sample values you can change
> * version history with restore
> * **Send a preview to yourself** from any verified domain, which goes through the normal send path and counts as one email

> [tab] API
>
> | Endpoint | Scope | Purpose |
> | - | - | - |
> | `POST /v1/templates` | `emails:send` | Create; the response lists the `variables` found |
> | `GET /v1/templates` | `read` | List, most recently changed first |
> | `GET /v1/templates/{id}` | `read` | Current content and version |
> | `PATCH /v1/templates/{id}` | `emails:send` | Any of `name`, `subject`, `html`, `text`; `null` removes a part |
> | `DELETE /v1/templates/{id}` | `emails:send` | Remove; sent email is unaffected, later sends naming the id fail with 422 |
> | `POST /v1/templates/{id}/render` | `read` | Preview a render; missing placeholders are listed, not thrown |
> | `GET /v1/templates/{id}/versions` | `read` | Every version, newest first |
>
> Names are unique within your organisation; a duplicate is `409 already_exists`.

## Preview a render

`POST /v1/templates/{id}/render` returns what a send would produce. Placeholders you leave out come back under `missing` and stay in the output, so it doubles as a linter for your variables.

```json theme={"dark"}
{
  "version": 1,
  "subject": "Your order 1042 has shipped",
  "html": "<p>Hi Thandi &lt;script&gt;,</p><p>Order <b>1042</b> arrives by {{eta}}.</p>",
  "text": "Hi Thandi <script>, order 1042 arrives by {{eta}}.",
  "missing": ["eta"]
}
```

## React Email and other renderers

If you build email with React Email, MJML or a templating engine of your own, render to HTML in your app and pass `html` (and `text`) to the send request. Sendbaze templates are for teams that want non-developers to edit copy in the dashboard.

```ts theme={"dark"}
import { render } from "@react-email/render";
import { OrderShipped } from "./emails/order-shipped";

await sendbaze.emails.send({
  from: "orders@yourshop.co.za",
  to: "thandi@example.com",
  subject: "Your order #1042 has shipped",
  html: await render(<OrderShipped name="Thandi" orderId={1042} />),
  text: await render(<OrderShipped name="Thandi" orderId={1042} />, { plainText: true }),
});
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.