---
title: "Introducing Templates"
slug: introducing-templates
description: "Create, edit, and send emails with Templates."
created_at: "2025-11-04"
updated_at: "2025-11-04"
image: "https://cdn.resend.com/posts/introducing-templates.jpg"
humans: ["carolina-josephik", "giovana-yahiro", "isabella-aquino", "joao-melo", "vitor-capretz"]
category: "product"
featured: true
---

Today, we're launching **Templates**: a new way for your team to personalize emails.

Anyone on your team, from designers to marketers to developers, can create templates with our modern email builder.

Define a structure and style of your template to communicate your brand. Then, add variables to personalize the email.

<video
  src="https://cdn.resend.com/posts/introducing-templates.mp4"
  poster="https://cdn.resend.com/posts/templates-cover.png"
  controls
  className="extraWidth"
/>

## Creating a new Template

One way to create a new Template is through the dashboard.

<video
  src="https://cdn.resend.com/posts/templates-post-create-template.mp4"
  autoPlay
  loop
  muted
  playsInline
  className="extraWidth"
/>

You can also import your existing HTML or React Email code. Alternatively, [create a Template via the API](/docs/api-reference/templates/create-template).

All Templates are stored in your Resend account on the [Templates](/templates) page.

## Template variables

You can create **template variables** to personalize email content. When you send the email, Resend will replace the variables with the actual values you've attached to your Contacts.


Variables can be `strings` or `numbers`. You can set a fallback value, which will be used if a value is not provided.

Use these variables in your Template's body, subject, reply to, and preview text fields.

<video
  src="https://cdn.resend.com/posts/template-video-variable.mp4"
  autoPlay
  loop
  muted
  playsInline
  className="extraWidth"
/>

When creating a Template using the API, use the `variables` parameter to define the template variables.

<CodeTabs codeHeight={310}>

```nodejs
import { Resend } from 'resend';

const resend = new Resend('re_xxxxxxxxx');

await resend.templates.create({
  --highlight-start
  name: 'order-confirmation',
  --highlight-end
  from: 'Wayback Store <hi@orders.waybackstore.com>',
  subject: 'Thanks for your order!',
  html: "<p>Name: {{{PRODUCT}}}</p><p>Total: {{{PRICE}}}</p>",
  --highlight-start
  variables: [
    {
      key: 'PRODUCT',
      type: 'string',
      fallbackValue: 'item'
    },
    {
      key: 'PRICE',
      type: 'number',
      fallbackValue: 20
    }
  ]
  --highlight-end
});
```

```ruby
require "resend"

Resend.api_key = "re_xxxxxxxxx"

params = {
  --highlight-start
  "name": 'order-confirmation',
  --highlight-end
  "from": 'Wayback Store <hi@orders.waybackstore.com>',
  "subject": 'Thanks for your order!',
  "html": "<p>Name: #{{{PRODUCT}}}</p><p>Total: #{{{PRICE}}}</p>",
  --highlight-start
  "variables": [
    {
      "key": 'PRODUCT',
      "type": 'string',
      "fallbackValue": 'item'
    },
    {
      "key": 'PRICE',
      "type": 'number',
      "fallbackValue": 20
    }
  ]
  --highlight-end
}

Resend::Templates.create(params)
```

```php
$resend = Resend::client('re_xxxxxxxxx');

$resend->templates->create([
  --highlight-start
  'name' => 'order-confirmation',
  --highlight-end
  'from' => 'Wayback Store <hi@orders.waybackstore.com>',
  'subject' => 'Thanks for your order!',
    'html' => "<p>Name: {{{PRODUCT}}}</p><p>Total: {{{PRICE}}}</p>",
  --highlight-start
  'variables' => [
    [
      'key' => 'PRODUCT',
      'type' => 'string',
      'fallbackValue' => 'item'
    ],
    [
      'key' => 'PRICE',
      'type' => 'number',
      'fallbackValue' => 49.99
    ]
  ]
  --highlight-end
]);
```

```python
import resend

resend.api_key = "re_xxxxxxxxx"

params: resend.Templates.CreateParams = {
  --highlight-start
  "name": "order-confirmation",
  --highlight-end
  "from": "Wayback Store <hi@orders.waybackstore.com>",
  "subject": "Thanks for your order!",
  "html": "<p>Name: {{{PRODUCT}}}</p><p>Total: {{{PRICE}}}</p>",
  --highlight-start
  "variables": [
    {
      "key": "PRODUCT",
      "type": "string",
      "fallbackValue": "item"
    },
    {
      "key": "PRICE",
      "type": "number",
      "fallbackValue": 20
    },
  ]
  --highlight-end
}

resend.Templates.create(params)
```

```go
import "github.com/resend/resend-go/v2"

client := resend.NewClient("re_xxxxxxxxx")

params := &resend.CreateTemplateRequest{
  --highlight-start
  Name: "order-confirmation",
  --highlight-end
  From: "Wayback Store <hi@orders.waybackstore.com>",
  Subject: "Thanks for your order!",
  Html: "<p>Name: {{{PRODUCT}}}</p><p>Total: {{{PRICE}}}</p>",
  --highlight-start
  Variables: []resend.TemplateVariable{
    {
      Key: "PRODUCT",
      Type: "string",
      FallbackValue: "item",
    },
    {
      Key: "PRICE",
      Type: "number",
      FallbackValue: 20,
    },
  },
  --highlight-end
}

template, _ := client.Templates.Create(params)
```

```rust
use resend_rs::{types::CreateTemplateOptions, Resend, Result};

#[tokio::main]
async fn main() -> Result<()> {
  let resend = Resend::new("re_xxxxxxxxx");

  --highlight-start
  let name = "order-confirmation";
  --highlight-end
  let from = "Wayback Store <hi@orders.waybackstore.com>";
  let subject = "Thanks for your order!";
  let html = "<p>Name: {{{PRODUCT}}}</p><p>Total: {{{PRICE}}}</p>";
  --highlight-start
  let variables = vec![
    TemplateVariable {
      key: "PRODUCT",
      type_: "string",
      fallback_value: Some("item"),
    },
    TemplateVariable {
      key: "PRICE",
      type_: "number",
      fallback_value: Some(20),
    },
  ];
  --highlight-end

  let opts = CreateTemplateOptions::new(name, from, subject)
    .with_html(html)
    .with_variables(variables);

  let _template = resend.templates.create(opts).await?;

  Ok(())
}
```

```java
Resend resend = new Resend("re_xxxxxxxxx");

--highlight-start
List<TemplateVariable> variables = Arrays.asList(
  new TemplateVariable("PRODUCT", "string", "item"),
  new TemplateVariable("PRICE", "number", 20),
);
--highlight-end

CreateTemplateOptions params = CreateTemplateOptions.builder()
  --highlight-start
  .name("order-confirmation")
  --highlight-end
  .from("Wayback Store <hi@orders.waybackstore.com>")
  .subject("Thanks for your order!")
    .html("<p>Name: {{{PRODUCT}}}</p><p>Total: {{{PRICE}}}</p>")
  .variables(variables)
  .build();

CreateTemplateResponseSuccess data = resend.templates().create(params);
```

```dotnet
using Resend;

IResend resend = ResendClient.Create("re_xxxxxxxxx");

--highlight-start
var variables = new List<TemplateVariable>
{
  new TemplateVariable("PRODUCT", "string", "item"),
  new TemplateVariable("PRICE", "number", 20),
};
--highlight-end

var resp = await resend.TemplateAddAsync(
  new TemplateData()
  {
    --highlight-start
    Name = "order-confirmation",
    --highlight-end
    From = "Wayback Store <hi@orders.waybackstore.com>",
    Subject = "Thanks for your order!",
    HtmlBody = @"
      <p>Name: {{{PRODUCT}}}</p>
      <p>Total: {{{PRICE}}}</p>
    ",
    Variables = variables
  }
);

Console.WriteLine($"Template Id={resp.Content}");
```

```curl
curl -X POST 'https://api.resend.com/templates' \\
 -H 'Authorization: Bearer re_xxxxxxxxx' \\
 -H 'Content-Type: application/json' \\
 -d $'{
  --highlight-start
  "name": "order-confirmation",
  --highlight-end
  "from": "Wayback Store <hi@orders.waybackstore.com>",
  "subject": "Thanks for your order!",
  "html": "<p>Name: {{{PRODUCT}}}</p><p>Total: {{{PRICE}}}</p>",
  --highlight-start
  "variables": [
    {
      "key": "PRODUCT",
      "type": "string",
      "fallbackValue": "item"
    }, 
    {
      "key": "PRICE",
      "type": "number",
      "fallbackValue": 20
    }
  ]
  --highlight-end
}'
```
</CodeTabs>

## Collaboration

Your entire team can collaborate in realtime to craft the perfect email template together. Anyone can create variables and use them in the visual editor. 

<video
  src="https://cdn.resend.com/posts/templates-video-collab.mp4"
  autoPlay
  loop
  muted
  playsInline
  className="extraWidth"
/>

When you send a test email, you can add example values to see how the email will look to a real user.

## Versioning

Templates are living documents, so we've introduced a versioning system. As you refine your voice, update your design, or tweak your copy, you can freely iterate and collaborate with your team with confidence.

We track changes and keep previous versions, in case you need them.

<video
  src="https://cdn.resend.com/posts/templates-video-versioning.mp4"
  autoPlay
  loop
  muted
  playsInline
  className="extraWidth"
/>

Once you've finalized your Template, publish it to make it available for sending.

This publishing experience puts you in control. Let's imagine your team is going through a rebrand. You can make edits to your Templates in production without the risk of leaking your new logo. When you're ready, publish the new version without any additional code changes.

## Send emails with Templates

Now that your Template is stored on Resend, just pass the template ID and variables. We'll handle the rest.

The `template` parameter replaces the `html` or `react` parameters that you'd normally use for sending. 

<CodeTabs codeHeight={290}>
```nodejs
import { Resend } from 'resend';

const resend = new Resend('re_xxxxxxxxx');

await resend.emails.send({
  from: 'Wayback Store <hi@orders.waybackstore.com>',
  to: 'customer@example.com',
  --highlight-start
  template: {
    id: 'order-confirmation',
    variables: {
      PRODUCT: 'Vintage Macintosh',
      PRICE: 499
    }
  }
  --highlight-end
});
```

```ruby
require "resend"

Resend.api_key = "re_xxxxxxxxx"

Resend::Emails.send({
  from: "Wayback Store <hi@orders.waybackstore.com>",
  to: "customer@example.com",
  --highlight-start
  template: {
    id: "order-confirmation",
    variables: {
      PRODUCT: "Vintage Macintosh",
      PRICE: 499
    }
  }
  --highlight-end
})
```

```php
$resend = Resend::client('re_xxxxxxxxx');

$resend->emails->send([
  'from' => 'Wayback Store <hi@orders.waybackstore.com>',
  'to' => 'customer@example.com',
  --highlight-start
  'template' => [
    'id' => 'order-confirmation',
    'variables' => [
      'PRODUCT' => 'Vintage Macintosh',
      'PRICE' => 499
    ]
  ]
  --highlight-end
]);
```

```python
import resend

resend.api_key = "re_xxxxxxxxx"

resend.Emails.send({
  "from": "Wayback Store <hi@orders.waybackstore.com>",
  "to": "customer@example.com",
  --highlight-start
  "template": {
    "id": "order-confirmation",
    "variables": {
      "PRODUCT": "Vintage Macintosh",
      "PRICE": 499
    }
  }
  --highlight-end
})
```

```go
import "github.com/resend/resend-go/v2"

client := resend.NewClient("re_xxxxxxxxx")

params := &resend.SendEmailRequest{
  From: "Wayback Store <hi@orders.waybackstore.com>",
  To: []string{"customer@example.com"},
  --highlight-start
  Template: &resend.Template{
    ID: "order-confirmation",
    Variables: map[string]interface{}{
      "PRODUCT": "Vintage Macintosh",
      "PRICE": 499
    },
  },
  --highlight-end
}

email, err := client.Emails.Send(params)
```

```rust
use resend_rs::{types::SendEmailOptions, Resend, Result};

#[tokio::main]
async fn main() -> Result<()> {
  let resend = Resend::new("re_xxxxxxxxx");

  --highlight-start
  let variables = serde_json::json!({
    "PRODUCT": "Vintage Macintosh",
    "PRICE": 499
  });

  let opts = SendEmailOptions::new("Wayback Store <hi@orders.waybackstore.com>", vec!["customer@example.com"])
    .with_template("order-confirmation", variables);
  --highlight-end

  let _email = resend.emails.send(opts).await?;

  Ok(())
}
```

```java
Resend resend = new Resend("re_xxxxxxxxx");

--highlight-start
Map<String, Object> variables = new HashMap<>();
variables.put("PRODUCT", "Vintage Macintosh");
variables.put("PRICE", 499);
--highlight-end

SendEmailOptions params = SendEmailOptions.builder()
  .from("Wayback Store <hi@orders.waybackstore.com>")
  .to(Arrays.asList("customer@email.com"))
  --highlight-start
  .template(Template.builder()
    .id("order-confirmation")
    .variables(variables)
    .build())
  --highlight-end
  .build();

SendEmailResponseSuccess data = resend.emails().send(params);
```

```dotnet
using Resend;

IResend resend = ResendClient.Create("re_xxxxxxxxx");

--highlight-start
var variables = new Dictionary<string, object>
{
  { "PRODUCT", "Vintage Macintosh" },
  { "PRICE", 499 }
};
--highlight-end

var resp = await resend.EmailSendAsync(
  new EmailMessage()
  {
    From = "Wayback Store <hi@orders.waybackstore.com>",
    To = new[] { "customer@example.com" },
    Template = new Template()
    --highlight-start
    {
      Id = "order-confirmation",
      Variables = variables
    }
    --highlight-end
  }
);

Console.WriteLine($"Email Id={resp.Content}");
```

```curl
curl -X POST 'https://api.resend.com/emails' \
  -H 'Authorization: Bearer re_xxxxxxxxx' \
  -H 'Content-Type: application/json' \
  -d $'{
    "from": "Wayback Store <hi@orders.waybackstore.com>",
    "to": "customer@example.com",
    --highlight-start
    "template": {
      "id": "order-confirmation",
      "variables": {
        "PRODUCT": "Vintage Macintosh",
        "PRICE": 499
      }
    }
    --highlight-end
}'
```
</CodeTabs>

## Get started today

The new Resend templating experience streamlines the handoff between marketing and development. No more waiting for a teammate to pick up a ticket and push a code update.

We can't wait to see how this will enable your team to move faster, together.

Visit the dashboard or [API reference docs](/docs/api-reference/templates) to get started.