Email templates allow you to create reusable email designs with dynamic variables. This guide covers the complete template workflow.
Create a Template
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 )
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
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}}} \n You 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:
String Variables
Number Variables
Optional Variables
{
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:
By Template ID
By Template Alias
With Field Overrides
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 )
// If your template has an alias (e.g., "welcome")
emailParams := & resend . SendEmailRequest {
To : [] string { "[email protected] " },
Template : & resend . EmailTemplate {
Id : "welcome" , // Using alias instead of ID
Variables : map [ string ] any {
"NAME" : "Bob Smith" ,
"companyName" : "Tech Startup Inc" ,
"messageCount" : 3 ,
},
},
}
sent , err := client . Emails . SendWithContext ( ctx , emailParams )
// Override template fields for specific sends
emailParams := & resend . SendEmailRequest {
From : "[email protected] " , // Override template's From
To : [] string { "[email protected] " },
Subject : "Custom Subject Override" , // Override template's Subject
Bcc : [] string { "[email protected] " },
ReplyTo : "[email protected] " ,
Template : & resend . EmailTemplate {
Id : templateId ,
Variables : map [ string ] any {
"NAME" : "Charlie Brown" ,
"companyName" : "Example LLC" ,
"messageCount" : 7 ,
},
},
}
sent , err := client . Emails . SendWithContext ( ctx , emailParams )
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