Skip to main content
Email templates allow you to create reusable email designs with dynamic variables. This guide covers the complete template workflow.

Create a Template

1

Create a basic template

Start by creating a simple template without variables:
ctx := context.TODO()
client := resend.NewClient(apiKey)

template, err := client.Templates.CreateWithContext(ctx, &resend.CreateTemplateRequest{
	Name: "welcome-email",
	Html: "<strong>Welcome to our service!</strong>",
})
if err != nil {
	panic(err)
}
fmt.Printf("Created template: %s\n", template.Id)
2

Add dynamic variables

Create a template with variables for personalization:
template, err := client.Templates.Create(&resend.CreateTemplateRequest{
	Name:    "user-notification",
	From:    "[email protected]",
	Subject: "Hello {{{NAME}}}",
	Html:    "<strong>Hey, {{{NAME}}}, you are {{{AGE}}} years old.</strong>",
	Variables: []*resend.TemplateVariable{
		{
			Key:           "NAME",
			Type:          resend.VariableTypeString,
			FallbackValue: "user",
		},
		{
			Key:           "AGE",
			Type:          resend.VariableTypeNumber,
			FallbackValue: 25,
		},
	},
})
if err != nil {
	panic(err)
}
fmt.Printf("Created template: %s\n", template.Id)
All variables used in your HTML (e.g., {{{NAME}}}, {{{AGE}}}) must be declared in the Variables array. Otherwise, the API will return an error:Variable 'NAME' is used in the template but not defined in the variables list
3

Create with all options

Use all available template fields:
template, err := client.Templates.Create(&resend.CreateTemplateRequest{
	Name:    "full-template-example",
	Alias:   "full-example",
	From:    "Team <[email protected]>",
	Subject: "Important Update for {{{NAME}}}",
	ReplyTo: []string{"[email protected]", "[email protected]"},
	Html:    "<h1>Hello {{{NAME}}}</h1><p>You have {{{COUNT}}} new messages.</p>",
	Text:    "Hello {{{NAME}}}\nYou have {{{COUNT}}} new messages.",
	Variables: []*resend.TemplateVariable{
		{
			Key:           "NAME",
			Type:          resend.VariableTypeString,
			FallbackValue: "Guest",
		},
		{
			Key:           "COUNT",
			Type:          resend.VariableTypeNumber,
			FallbackValue: 0,
		},
	},
})

Variable Types

Resend supports two variable types:
{
	Key:           "USERNAME",
	Type:          resend.VariableTypeString,
	FallbackValue: "Guest", // Optional default value
}

Update a Template

Modify an existing template:
updatedTemplate, err := client.Templates.UpdateWithContext(ctx, templateId, &resend.UpdateTemplateRequest{
	Name:    "welcome-email-updated",
	Html:    "<strong>Welcome to our updated service, {{{NAME}}}!</strong>",
	Subject: "Welcome {{{NAME}}}!",
	Variables: []*resend.TemplateVariable{
		{
			Key:           "NAME",
			Type:          resend.VariableTypeString,
			FallbackValue: "Guest",
		},
	},
})
if err != nil {
	panic(err)
}
fmt.Printf("Updated template: %s\n", updatedTemplate.Id)

Publish a Template

Templates must be published before they can be used to send emails:
publishedTemplate, err := client.Templates.PublishWithContext(ctx, templateId)
if err != nil {
	panic(err)
}
fmt.Printf("Published template: %s\n", publishedTemplate.Id)

// Verify the template is published
publishedCheck, err := client.Templates.Get(publishedTemplate.Id)
if err != nil {
	panic(err)
}
fmt.Printf("Status: %s\n", publishedCheck.Status)
fmt.Printf("Published at: %s\n", publishedCheck.PublishedAt)
Only published templates can be used to send emails. Draft templates will result in an error.

Send Email with Template

Once published, use your template to send emails:
emailParams := &resend.SendEmailRequest{
	To: []string{"[email protected]"},
	Template: &resend.EmailTemplate{
		Id: templateId,
		Variables: map[string]any{
			"NAME":         "Alice Johnson",
			"companyName":  "Acme Corporation",
			"messageCount": 12,
		},
	},
}

sent, err := client.Emails.SendWithContext(ctx, emailParams)
if err != nil {
	panic(err)
}
fmt.Printf("Sent email: %s\n", sent.Id)

Retrieve Template Details

Get information about a template:
template, err := client.Templates.GetWithContext(ctx, templateId)
if err != nil {
	panic(err)
}

fmt.Printf("Id: %s\n", template.Id)
fmt.Printf("Name: %s\n", template.Name)
fmt.Printf("Status: %s\n", template.Status)
fmt.Printf("Variables: %d\n", len(template.Variables))

List Templates

Retrieve all templates with pagination:
listResponse, err := client.Templates.ListWithContext(ctx, nil)
if err != nil {
	panic(err)
}

fmt.Printf("HasMore: %t\n", listResponse.HasMore)
fmt.Printf("Templates count: %d\n", len(listResponse.Data))

for _, tmpl := range listResponse.Data {
	fmt.Printf("- %s (%s) - Status: %s\n",
		tmpl.Name, tmpl.Id, tmpl.Status)
}

Duplicate a Template

Create a copy of an existing template:
duplicatedTemplate, err := client.Templates.DuplicateWithContext(ctx, templateId)
if err != nil {
	panic(err)
}
fmt.Printf("Duplicated template: %s\n", duplicatedTemplate.Id)

// The duplicate is a separate template with its own ID
duplicateCheck, err := client.Templates.Get(duplicatedTemplate.Id)
if err != nil {
	panic(err)
}
fmt.Printf("Duplicate details: %s (Status: %s)\n",
	duplicateCheck.Name, duplicateCheck.Status)

Delete a Template

Permanently remove a template:
removedTemplate, err := client.Templates.RemoveWithContext(ctx, templateId)
if err != nil {
	panic(err)
}
fmt.Printf("Removed template: %s\n", removedTemplate.Id)
fmt.Printf("Deleted: %t\n", removedTemplate.Deleted)
Deleting a template is permanent and cannot be undone. Any emails currently using this template will fail.

Complete Example

Here’s a complete workflow from examples/send_email_with_template.go:
examples/send_email_with_template.go
package main

import (
	"context"
	"fmt"
	"os"

	"github.com/resend/resend-go/v3"
)

func main() {
	ctx := context.TODO()
	apiKey := os.Getenv("RESEND_API_KEY")
	client := resend.NewClient(apiKey)

	// Step 1: Create template with variables
	templateParams := &resend.CreateTemplateRequest{
		Name:    "user-welcome-template",
		Alias:   "welcome",
		From:    "[email protected]",
		Subject: "Welcome to {{{companyName}}}, {{{userName}}}!",
		Html: `
		<html>
			<body>
				<h1>Hello {{{userName}}}!</h1>
				<p>Welcome to {{{companyName}}}. We're excited to have you on board.</p>
				<p>You currently have {{{messageCount}}} unread messages waiting for you.</p>
			</body>
		</html>
		`,
		Text: "Hello {{{userName}}}! Welcome to {{{companyName}}}.",
		Variables: []*resend.TemplateVariable{
			{
				Key:           "userName",
				Type:          resend.VariableTypeString,
				FallbackValue: "User",
			},
			{
				Key:           "companyName",
				Type:          resend.VariableTypeString,
				FallbackValue: "Our Company",
			},
			{
				Key:           "messageCount",
				Type:          resend.VariableTypeNumber,
				FallbackValue: 0,
			},
		},
	}

	template, err := client.Templates.CreateWithContext(ctx, templateParams)
	if err != nil {
		panic(err)
	}
	fmt.Printf("Created template: %s\n", template.Id)

	// Step 2: Publish the template
	_, err = client.Templates.PublishWithContext(ctx, template.Id)
	if err != nil {
		panic(err)
	}
	fmt.Printf("Published template: %s\n", template.Id)

	// Step 3: Send email using the template
	emailParams := &resend.SendEmailRequest{
		To: []string{"[email protected]"},
		Template: &resend.EmailTemplate{
			Id: template.Id,
			Variables: map[string]any{
				"userName":     "Alice Johnson",
				"companyName":  "Acme Corporation",
				"messageCount": 12,
			},
		},
	}

	sent, err := client.Emails.SendWithContext(ctx, emailParams)
	if err != nil {
		panic(err)
	}
	fmt.Printf("Sent email: %s\n", sent.Id)
}

Next Steps

Basic Usage

Learn the fundamentals of sending emails

Error Handling

Handle rate limits and validation errors

Templates API

View complete Templates API reference

Batch Emails

Send multiple emails efficiently

Build docs developers (and LLMs) love