Email templates allow you to create reusable email designs with dynamic variables that can be populated at send time.
Quick Start
Here’s how to create a template and send an email using it:
package main
import (
"context"
"fmt"
"os"
"github.com/resend/resend-go/v3"
)
func main() {
ctx := context.Background()
apiKey := os.Getenv("RESEND_API_KEY")
client := resend.NewClient(apiKey)
// Create a template
template, err := client.Templates.Create(&resend.CreateTemplateRequest{
Name: "welcome-email",
Alias: "welcome",
Subject: "Welcome {{{userName}}}!",
Html: "<h1>Hello {{{userName}}}!</h1><p>Welcome to {{{companyName}}}.</p>",
Variables: []*resend.TemplateVariable{
{
Key: "userName",
Type: resend.VariableTypeString,
FallbackValue: "User",
},
{
Key: "companyName",
Type: resend.VariableTypeString,
FallbackValue: "Our Company",
},
},
})
if err != nil {
panic(err)
}
// Publish the template
_, err = client.Templates.Publish(template.Id)
if err != nil {
panic(err)
}
// Send email using the template
sent, err := client.Emails.Send(&resend.SendEmailRequest{
To: []string{"[email protected]"},
Template: &resend.EmailTemplate{
Id: template.Id,
Variables: map[string]any{
"userName": "Alice Johnson",
"companyName": "Acme Corp",
},
},
})
if err != nil {
panic(err)
}
fmt.Printf("Email sent: %s\n", sent.Id)
}
EmailTemplate Struct
When sending emails with templates, use the EmailTemplate struct:
The template ID or alias to use for this email.
Key-value pairs to populate the template placeholders. Values can be strings, numbers, or other JSON-serializable types.
Source: emails.go:17
Creating Templates
Basic Template Creation
ctx := context.Background()
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)
Source: examples/send_email_with_template.go:17
CreateTemplateRequest Fields
The name of the template.
A unique alias for the template. Use this to reference the template instead of its ID.
Default sender email address for this template.
Default subject line. Can include template variables like {{{variableName}}}.
Default reply-to address. Can be a string or array of strings.
HTML content with template variables. Use triple braces {{{variableName}}} for variables.
Plain text version with template variables.
Array of variable definitions used in the template.
All variables referenced in Html or Subject (e.g., {{{userName}}}) must be declared in the Variables array, or the API will return a validation error.
Source: templates.go:28
Template Variables
Each variable in a template must be defined with the TemplateVariable struct:
The variable name (without braces). Must match the placeholder in HTML/subject.
Variable type: VariableTypeString or VariableTypeNumber.
Default value used if no value is provided when sending the email.
Source: templates.go:19
Variable Types
String Variables
Number Variables
{
Key: "userName",
Type: resend.VariableTypeString,
FallbackValue: "Guest",
}
Use for: names, email addresses, text content, URLs{
Key: "messageCount",
Type: resend.VariableTypeNumber,
FallbackValue: 0,
}
Use for: counts, prices, quantities, IDs
Publishing Templates
Templates must be published before they can be used:
ctx := context.Background()
// Publish by template ID
publishResp, err := client.Templates.PublishWithContext(ctx, template.Id)
if err != nil {
panic(err)
}
fmt.Printf("Published template: %s\n", publishResp.Id)
Only published templates can be used to send emails. Unpublished templates are in draft state.
Source: examples/send_email_with_template.go:58
Sending Emails with Templates
Using Template ID
ctx := context.Background()
emailParams := &resend.SendEmailRequest{
To: []string{"[email protected]"},
Template: &resend.EmailTemplate{
Id: "3a76bde0-8f64-4b48-a92f-5f650cc0319d",
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)
Source: examples/send_email_with_template.go:65
Using Template Alias
You can use the template’s alias instead of its ID:
emailParams := &resend.SendEmailRequest{
To: []string{"[email protected]"},
Template: &resend.EmailTemplate{
Id: "welcome", // Using alias instead of ID
Variables: map[string]any{
"userName": "Bob Smith",
"companyName": "Tech Startup Inc",
"messageCount": 3,
},
},
}
sent, err := client.Emails.Send(emailParams)
Using aliases makes your code more maintainable since you don’t need to update IDs when recreating templates.
Source: examples/send_email_with_template.go:84
Overriding Template Fields
You can override template defaults when sending:
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: template.Id,
Variables: map[string]any{
"userName": "Charlie Brown",
"companyName": "Example LLC",
"messageCount": 7,
},
},
}
sent, err := client.Emails.Send(emailParams)
Source: examples/send_email_with_template.go:103
Fields specified in SendEmailRequest take precedence over template defaults.
Managing Templates
Retrieving a Template
ctx := context.Background()
// Get by ID
template, err := client.Templates.GetWithContext(ctx, "3a76bde0-8f64-4b48-a92f-5f650cc0319d")
if err != nil {
panic(err)
}
// Or get by alias
template, err = client.Templates.Get("welcome")
if err != nil {
panic(err)
}
fmt.Printf("Template: %s (Status: %s)\n", template.Name, template.Status)
fmt.Printf("Variables: %d\n", len(template.Variables))
Listing Templates
ctx := context.Background()
// List all templates
listResp, err := client.Templates.ListWithContext(ctx, nil)
if err != nil {
panic(err)
}
fmt.Printf("Found %d templates\n", len(listResp.Data))
for _, tmpl := range listResp.Data {
fmt.Printf("- %s (alias: %s, status: %s)\n", tmpl.Name, tmpl.Alias, tmpl.Status)
}
// List with pagination
limit := 10
paginatedResp, err := client.Templates.List(&resend.ListOptions{
Limit: &limit,
})
Updating a Template
ctx := context.Background()
updateParams := &resend.UpdateTemplateRequest{
Name: "Updated Welcome Template",
Subject: "Welcome {{{userName}}} to {{{companyName}}}!",
Html: "<h1>Hello {{{userName}}}!</h1><p>Updated content</p>",
Variables: []*resend.TemplateVariable{
{
Key: "userName",
Type: resend.VariableTypeString,
FallbackValue: "User",
},
{
Key: "companyName",
Type: resend.VariableTypeString,
FallbackValue: "Our Company",
},
},
}
updated, err := client.Templates.UpdateWithContext(ctx, "welcome", updateParams)
if err != nil {
panic(err)
}
fmt.Printf("Updated template: %s\n", updated.Id)
After updating a template, you must publish it again for changes to take effect in sent emails.
Duplicating a Template
ctx := context.Background()
duplicateResp, err := client.Templates.DuplicateWithContext(ctx, "welcome")
if err != nil {
panic(err)
}
fmt.Printf("Duplicated template ID: %s\n", duplicateResp.Id)
Deleting a Template
ctx := context.Background()
removeResp, err := client.Templates.RemoveWithContext(ctx, template.Id)
if err != nil {
panic(err)
}
if removeResp.Deleted {
fmt.Printf("Deleted template: %s\n", removeResp.Id)
}
Source: examples/send_email_with_template.go:126
Common Use Cases
templateParams := &resend.CreateTemplateRequest{
Name: "welcome-email",
Alias: "welcome",
Subject: "Welcome to {{{appName}}}, {{{userName}}}!",
Html: `
<h1>Welcome {{{userName}}}!</h1>
<p>Thanks for joining {{{appName}}}.</p>
<p>Get started by <a href="{{{loginUrl}}}">logging in</a>.</p>
`,
Variables: []*resend.TemplateVariable{
{Key: "userName", Type: resend.VariableTypeString, FallbackValue: "there"},
{Key: "appName", Type: resend.VariableTypeString, FallbackValue: "our app"},
{Key: "loginUrl", Type: resend.VariableTypeString},
},
}
templateParams := &resend.CreateTemplateRequest{
Name: "order-confirmation",
Alias: "order-confirmed",
Subject: "Order #{{{orderNumber}}} Confirmed",
Html: `
<h1>Thank you for your order!</h1>
<p>Order Number: {{{orderNumber}}}</p>
<p>Total: ${{{orderTotal}}}</p>
<p>Items: {{{itemCount}}}</p>
<p><a href="{{{trackingUrl}}}">Track your order</a></p>
`,
Variables: []*resend.TemplateVariable{
{Key: "orderNumber", Type: resend.VariableTypeString},
{Key: "orderTotal", Type: resend.VariableTypeNumber},
{Key: "itemCount", Type: resend.VariableTypeNumber},
{Key: "trackingUrl", Type: resend.VariableTypeString},
},
}
templateParams := &resend.CreateTemplateRequest{
Name: "password-reset",
Alias: "reset-password",
Subject: "Reset your password",
Html: `
<h1>Password Reset Request</h1>
<p>Hi {{{userName}}},</p>
<p>Click the link below to reset your password:</p>
<p><a href="{{{resetUrl}}}">Reset Password</a></p>
<p>This link expires in {{{expiryMinutes}}} minutes.</p>
`,
Variables: []*resend.TemplateVariable{
{Key: "userName", Type: resend.VariableTypeString},
{Key: "resetUrl", Type: resend.VariableTypeString},
{Key: "expiryMinutes", Type: resend.VariableTypeNumber, FallbackValue: 60},
},
}
Best Practices
Declare All Variables
Always declare variables in the Variables array before using them in HTML:// ✅ Correct - variable is declared
Html: "<p>Hello {{{userName}}}</p>",
Variables: []*resend.TemplateVariable{
{Key: "userName", Type: resend.VariableTypeString},
}
// ❌ Wrong - will cause validation error
Html: "<p>Hello {{{userName}}}</p>",
Variables: []*resend.TemplateVariable{},
Use Aliases for Stability
Use template aliases instead of IDs for better code maintainability:Template: &resend.EmailTemplate{
Id: "welcome", // Use alias, not "3a76bde0-8f64-4b48-a92f-5f650cc0319d"
Variables: map[string]any{...},
}
Provide Fallback Values
Always provide sensible fallback values for optional variables:{
Key: "userName",
Type: resend.VariableTypeString,
FallbackValue: "Valued Customer", // Good default
}
Use Triple Braces
Use triple braces {{{variable}}} for template variables to prevent HTML escaping:Html: "<h1>Hello {{{userName}}}!</h1>" // Correct
// Not: "<h1>Hello {{userName}}!</h1>" // Wrong
Publish After Updates
Remember to publish templates after creating or updating them:template, _ := client.Templates.Create(params)
client.Templates.Publish(template.Id) // Required!
Next Steps
Sending Emails
Learn the basics of sending emails
Attachments
Add attachments to template emails
Batch Emails
Send templated emails in bulk
Scheduled Emails
Schedule template emails for later