openapi: 3.1.0 info: title: Templates version: 2.0.0 description: Create and manage reusable email templates with dynamic content. contact: name: Mailtrap Support url: 'https://docs.mailtrap.io' email: support@mailtrap.io license: name: Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) url: 'https://creativecommons.org/licenses/by-sa/4.0/' x-logo: url: 'https://mailtrap.io/wp-content/uploads/2021/04/mailtrap-logo.svg' servers: - description: Mailtrap API url: 'https://mailtrap.io' security: - HeaderAuth: [] - BearerAuth: [] tags: - name: templates x-page-title: Templates x-page-description: Manage email templates description: |- Create and manage reusable email templates with dynamic content. The number of templates you can hold is set by your subscription plan and counted across every account in your organization. paths: /api/email_templates: get: description: |- Get all email templates existing in your account, as a single unpaginated array. If your account holds enough templates for the response size to matter, see the experimental `GET /api/templates`, which returns the same templates one page at a time. operationId: emailTemplates summary: Get all Email Templates tags: - templates x-codeSamples: - lang: shell label: 'cURL' source: | curl -X GET "https://mailtrap.io/api/email_templates" \ -H "Api-Token: YOUR_API_KEY" - lang: javascript label: Node.js source: | const { MailtrapClient } = require("mailtrap"); const client = new MailtrapClient({ token: "YOUR_API_KEY", accountId: YOUR_ACCOUNT_ID }); async function getTemplates() { const templates = await client.emailTemplates.getList(); console.log("Templates:", templates); } getTemplates(); - lang: php label: PHP source: | emailTemplates($accountId); $response = $emailTemplates->getAllEmailTemplates(); var_dump(ResponseHelper::toArray($response)); - lang: python label: Python source: | import mailtrap as mt client = mt.MailtrapClient(token="YOUR_API_KEY", account_id="YOUR_ACCOUNT_ID") templates = client.email_templates_api.templates.get_list() for tpl in templates: print(f"{tpl.name}: {tpl.uuid}") - lang: ruby label: Ruby source: | require 'mailtrap' client = Mailtrap::Client.new(api_key: 'YOUR_API_KEY') templates = Mailtrap::EmailTemplatesAPI.new(YOUR_ACCOUNT_ID, client) puts templates.list - lang: csharp label: .NET source: | using Mailtrap; using var mailtrapFactory = new MailtrapClientFactory("YOUR_API_KEY"); var client = mailtrapFactory.CreateClient(); var templates = await client.Account(YOUR_ACCOUNT_ID).EmailTemplates().GetAll(); foreach (var template in templates) { Console.WriteLine($"Template: {template.Name}, ID: {template.Uuid}"); } - lang: java label: Java source: | import io.mailtrap.config.MailtrapConfig; import io.mailtrap.factory.MailtrapClientFactory; var config = new MailtrapConfig.Builder().token("YOUR_API_KEY").build(); var client = MailtrapClientFactory.createMailtrapClient(config); var response = client.emailTemplatesApi().emailTemplates().getAllTemplates(accountId); - lang: go label: Go source: | package main import ( "context" "fmt" "log" "os" "github.com/mailtrap/mailtrap-go" ) func main() { client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) if err != nil { log.Fatal(err) } templates, _, err := client.EmailTemplates.List(context.Background()) if err != nil { log.Fatal(err) } for _, template := range templates { fmt.Printf("%d %s (%s)\n", template.ID, template.Name, template.Category) } } responses: '200': description: OK. content: application/json: schema: type: array items: $ref: '#/components/schemas/EmailTemplateResponse' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '429': $ref: '#/components/responses/RateLimited' post: description: Create a new email template operationId: createEmailTemplate summary: Create Email Template tags: - templates x-codeSamples: - lang: shell label: 'cURL' source: | curl -X POST "https://mailtrap.io/api/email_templates" \ -H "Api-Token: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "email_template": { "name": "Welcome Email", "subject": "Welcome to {{company_name}}!", "category": "onboarding", "body_html": "

Welcome {{user_name}}!

", "body_text": "Welcome {{user_name}}!" } }' - lang: javascript label: Node.js source: | import { MailtrapClient } from "mailtrap"; const client = new MailtrapClient({ token: "YOUR_API_KEY", accountId: YOUR_ACCOUNT_ID }); async function createTemplate() { const template = await client.emailTemplates.create({ name: "Welcome Email", subject: "Welcome to {{company_name}}!", category: "onboarding", body_html: "

Welcome {{user_name}}!

", body_text: "Welcome {{user_name}}!" }); console.log(`Template created: ${template.uuid}`); } createTemplate(); - lang: php label: PHP source: | emailTemplates($accountId); $response = $emailTemplates->createEmailTemplate( EmailTemplate::init( 'Welcome Email', 'Welcome to {{company_name}}!', 'onboarding', 'Welcome {{user_name}}!', '

Welcome {{user_name}}!

' ) ); var_dump(ResponseHelper::toArray($response)); - lang: python label: Python source: | import mailtrap as mt client = mt.MailtrapClient(token="YOUR_API_KEY", account_id="YOUR_ACCOUNT_ID") template = client.email_templates_api.templates.create( mt.CreateEmailTemplateParams( name="Welcome Email", subject="Welcome to {{company_name}}!", category="onboarding", body_html="

Welcome {{user_name}}!

", body_text="Welcome {{user_name}}!" ) ) - lang: ruby label: Ruby source: | require 'mailtrap' client = Mailtrap::Client.new(api_key: 'YOUR_API_KEY') templates = Mailtrap::EmailTemplatesAPI.new(YOUR_ACCOUNT_ID, client) template = templates.create( name: 'Welcome Email', subject: 'Welcome to {{company_name}}!', category: 'onboarding', body_html: '

Welcome {{user_name}}!

', body_text: 'Welcome {{user_name}}!' ) puts "Template: #{template}" - lang: csharp label: .NET source: | using Mailtrap; using Mailtrap.EmailTemplates.Requests; using var mailtrapFactory = new MailtrapClientFactory("YOUR_API_KEY"); var client = mailtrapFactory.CreateClient(); var request = new CreateEmailTemplateRequest( "Welcome Email", // Name "onboarding", // Category "Welcome to {{company_name}}!") // Subject { BodyHtml = "

Welcome {{user_name}}!

", BodyText = "Welcome {{user_name}}!" }; var template = await client.Account(YOUR_ACCOUNT_ID).EmailTemplates().Create(request); - lang: java label: Java source: | import io.mailtrap.config.MailtrapConfig; import io.mailtrap.factory.MailtrapClientFactory; var config = new MailtrapConfig.Builder().token("YOUR_API_KEY").build(); var client = MailtrapClientFactory.createMailtrapClient(config); var request = new CreateEmailTemplateRequest( new EmailTemplate( "Welcome Email", "onboarding", "Welcome to {{company_name}}!", "Welcome {{user_name}}!", "

Welcome {{user_name}}!

") ); var template = client.emailTemplatesApi().emailTemplates().createEmailTemplate(accountId, request); - lang: go label: Go source: | package main import ( "context" "fmt" "log" "os" "github.com/mailtrap/mailtrap-go" ) func main() { client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) if err != nil { log.Fatal(err) } template, _, err := client.EmailTemplates.Create(context.Background(), &mailtrap.EmailTemplateRequest{ Name: "Welcome email", Category: "Onboarding", Subject: "Welcome to Mailtrap", BodyHTML: "

Welcome, {{name}}!

", BodyText: "Welcome, {{name}}!", }) if err != nil { log.Fatal(err) } fmt.Printf("created template %d (uuid %s)\n", template.ID, template.UUID) } - lang: hcl label: Terraform source: | # terraform apply creates the template: POST /api/email_templates # Provider docs: https://registry.terraform.io/providers/mailtrap/mailtrap/latest/docs terraform { required_providers { mailtrap = { source = "mailtrap/mailtrap" } } } # The token is read from the MAILTRAP_API_TOKEN environment variable. provider "mailtrap" {} resource "mailtrap_email_template" "welcome" { name = "Welcome email" category = "Onboarding" subject = "Welcome to Mailtrap" body_html = "

Welcome, {{name}}!

" body_text = "Welcome, {{name}}!" } requestBody: content: application/json: schema: $ref: '#/components/schemas/EmailTemplateRequest' responses: '201': description: Email template created successfully. content: application/json: schema: $ref: '#/components/schemas/EmailTemplateResponse' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '422': description: Validation errors, or the account has reached its plan's template limit. content: application/json: schema: $ref: '#/components/schemas/UnprocessableEntity' examples: validation_error: summary: Required attributes are missing value: errors: name: - can't be blank category: - can't be blank subject: - can't be blank template_limit_reached: summary: The plan's template limit is reached value: errors: base: - You've reached the maximum number of templates allowed. Please upgrade your plan to add more. '429': $ref: '#/components/responses/RateLimited' /api/email_templates/{email_template_id}: get: description: Get an email template by ID operationId: getEmailTemplate summary: Get Email Template tags: - templates x-codeSamples: - lang: shell label: 'cURL' source: | curl -X GET "https://mailtrap.io/api/email_templates/{email_template_id}" \ -H "Api-Token: YOUR_API_KEY" - lang: javascript label: Node.js source: | const { MailtrapClient } = require("mailtrap"); const client = new MailtrapClient({ token: "YOUR_API_KEY", accountId: YOUR_ACCOUNT_ID }); async function getTemplate() { const templateId = 12345; const template = await client.emailTemplates.get(templateId); console.log(`Template: ${template.name} (UUID: ${template.uuid})`); } getTemplate(); - lang: php label: PHP source: | emailTemplates($accountId); $templateId = $_ENV['MAILTRAP_TEMPLATE_ID']; $response = $emailTemplates->getEmailTemplate($templateId); var_dump(ResponseHelper::toArray($response)); - lang: python label: Python source: | import mailtrap as mt client = mt.MailtrapClient(token="YOUR_API_KEY", account_id="YOUR_ACCOUNT_ID") template_id = 12345 template = client.email_templates_api.templates.get_by_id(template_id) print(f"Template: {template.name} (ID: {template.id})") - lang: ruby label: Ruby source: | require 'mailtrap' client = Mailtrap::Client.new(api_key: 'YOUR_API_KEY') templates = Mailtrap::EmailTemplatesAPI.new( YOUR_ACCOUNT_ID, client ) template = templates.get(template_id) puts "Template: #{template}" - lang: csharp label: .NET source: | using Mailtrap; using var mailtrapFactory = new MailtrapClientFactory("YOUR_API_KEY"); var client = mailtrapFactory.CreateClient(); var accountId = 1000001; var templateId = 12345; var template = await client.Account(accountId).EmailTemplate(templateId).GetDetails(); Console.WriteLine(template.Name); - lang: java label: Java source: | import io.mailtrap.config.MailtrapConfig; import io.mailtrap.factory.MailtrapClientFactory; var config = new MailtrapConfig.Builder().token("YOUR_API_KEY").build(); var client = MailtrapClientFactory.createMailtrapClient(config); long accountId = 1000001L; long templateId = 12345L; var template = client.emailTemplatesApi().emailTemplates() .getEmailTemplate(accountId, templateId); System.out.println(template); - lang: go label: Go source: | package main import ( "context" "fmt" "log" "os" "github.com/mailtrap/mailtrap-go" ) func main() { client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) if err != nil { log.Fatal(err) } template, _, err := client.EmailTemplates.Get(context.Background(), 1000001) if err != nil { log.Fatal(err) } fmt.Printf("%s: %s\n", template.Name, template.Subject) } responses: '200': description: Returns attributes of the email template. content: application/json: schema: $ref: '#/components/schemas/EmailTemplateResponse' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' '429': $ref: '#/components/responses/RateLimited' patch: description: Update an email template operationId: updateEmailTemplate summary: Update Email Template tags: - templates x-codeSamples: - lang: shell label: 'cURL' source: | curl -X PATCH "https://mailtrap.io/api/email_templates/{email_template_id}" \ -H "Api-Token: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "email_template": { "name": "Updated Template", "subject": "New Subject" } }' - lang: javascript label: Node.js source: | const { MailtrapClient } = require("mailtrap"); const client = new MailtrapClient({ token: "YOUR_API_KEY", accountId: YOUR_ACCOUNT_ID }); async function updateTemplate() { const templateId = 12345; const template = await client.emailTemplates.update(templateId, { name: "Updated Template", subject: "New Subject" }); console.log(`Template updated: ${template.name} (UUID: ${template.uuid})`); } updateTemplate(); - lang: php label: PHP source: | emailTemplates($accountId); $templateId = $_ENV['MAILTRAP_TEMPLATE_ID']; $response = $emailTemplates->updateEmailTemplate( $templateId, EmailTemplate::init( 'Updated Welcome Email', 'Updated Subject', 'Transactional', 'Updated Text Body', '
Updated HTML Body
' ) ); var_dump(ResponseHelper::toArray($response)); - lang: python label: Python source: | import mailtrap as mt email_template_id = "YOUR_TEMPLATE_ID" client = mt.MailtrapClient(token="YOUR_API_KEY", account_id="YOUR_ACCOUNT_ID") template = client.email_templates_api.templates.update( template_id=email_template_id, template_params=mt.UpdateEmailTemplateParams( name="Edited Welcome Email", subject="Edited Welcome to {{company_name}}!", category="onboarding", body_html="

Edited Welcome {{user_name}}!

", body_text="Edited Welcome {{user_name}}!" ) ) - lang: ruby label: Ruby source: | require 'mailtrap' client = Mailtrap::Client.new(api_key: 'YOUR_API_KEY') templates = Mailtrap::EmailTemplatesAPI.new( YOUR_ACCOUNT_ID, client ) templates.update(EMAIL_TEMPLATE_ID, name: 'Welcome Updated') - lang: csharp label: .NET source: | using Mailtrap; using Mailtrap.EmailTemplates.Requests; using var mailtrapFactory = new MailtrapClientFactory("YOUR_API_KEY"); var client = mailtrapFactory.CreateClient(); var accountId = 1000001; var templateId = 12345; var request = new UpdateEmailTemplateRequest("Updated Welcome Email", "Transactional", "Updated Subject") { BodyHtml = "
Updated HTML Body
", BodyText = "Updated Text Body", }; var template = await client.Account(accountId).EmailTemplate(templateId).Update(request); Console.WriteLine(template.Name); - lang: java label: Java source: | import io.mailtrap.config.MailtrapConfig; import io.mailtrap.factory.MailtrapClientFactory; import io.mailtrap.model.request.emailtemplates.EmailTemplate; import io.mailtrap.model.request.emailtemplates.UpdateEmailTemplateRequest; var config = new MailtrapConfig.Builder().token("YOUR_API_KEY").build(); var client = MailtrapClientFactory.createMailtrapClient(config); long accountId = 1000001L; long templateId = 12345L; var request = new UpdateEmailTemplateRequest( new EmailTemplate("Updated Welcome Email", "Transactional", "Updated Subject", "Updated Text Body", "
Updated HTML Body
")); var template = client.emailTemplatesApi().emailTemplates() .updateEmailTemplate(accountId, templateId, request); System.out.println(template); - lang: go label: Go source: | package main import ( "context" "fmt" "log" "os" "github.com/mailtrap/mailtrap-go" ) func main() { client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) if err != nil { log.Fatal(err) } // Only the fields you set are changed. A body that has been set cannot be // cleared, only replaced. template, _, err := client.EmailTemplates.Update(context.Background(), 1000001, &mailtrap.EmailTemplateRequest{ Subject: "Welcome aboard", BodyHTML: "

Welcome aboard, {{name}}!

", }) if err != nil { log.Fatal(err) } fmt.Printf("updated template %d: %s\n", template.ID, template.Subject) } requestBody: content: application/json: schema: $ref: '#/components/schemas/EmailTemplateRequest' responses: '200': description: Email template updated successfully. content: application/json: schema: $ref: '#/components/schemas/EmailTemplateResponse' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' '422': $ref: '#/components/responses/UnprocessableEntity' '429': $ref: '#/components/responses/RateLimited' delete: description: Delete an email template operationId: deleteEmailTemplate summary: Delete Email Template tags: - templates x-codeSamples: - lang: shell label: 'cURL' source: | curl -X DELETE "https://mailtrap.io/api/email_templates/{email_template_id}" \ -H "Api-Token: YOUR_API_KEY" - lang: javascript label: Node.js source: | const { MailtrapClient } = require("mailtrap"); const client = new MailtrapClient({ token: "YOUR_API_KEY", accountId: YOUR_ACCOUNT_ID }); async function deleteTemplate() { const templateId = 12345; await client.emailTemplates.delete(templateId); console.log("Template deleted successfully"); } deleteTemplate(); - lang: php label: PHP source: | emailTemplates($accountId); $templateId = $_ENV['MAILTRAP_TEMPLATE_ID']; $response = $emailTemplates->deleteEmailTemplate($templateId); var_dump($response->getStatusCode()); - lang: python label: Python source: | import mailtrap as mt email_template_id = "YOUR_TEMPLATE_ID" client = mt.MailtrapClient(token="YOUR_API_KEY", account_id="YOUR_ACCOUNT_ID") deleted_template = client.email_templates_api.templates.delete( template_id=email_template_id ) - lang: ruby label: Ruby source: | require 'mailtrap' client = Mailtrap::Client.new(api_key: 'YOUR_API_KEY') templates = Mailtrap::EmailTemplatesAPI.new( YOUR_ACCOUNT_ID, client ) templates.delete(EMAIL_TEMPLATE_ID) - lang: csharp label: .NET source: | using Mailtrap; using var mailtrapFactory = new MailtrapClientFactory("YOUR_API_KEY"); var client = mailtrapFactory.CreateClient(); var accountId = 1000001; var templateId = 12345; await client.Account(accountId).EmailTemplate(templateId).Delete(); - lang: java label: Java source: | import io.mailtrap.config.MailtrapConfig; import io.mailtrap.factory.MailtrapClientFactory; var config = new MailtrapConfig.Builder().token("YOUR_API_KEY").build(); var client = MailtrapClientFactory.createMailtrapClient(config); long accountId = 1000001L; long templateId = 12345L; client.emailTemplatesApi().emailTemplates().deleteEmailTemplate(accountId, templateId); - lang: go label: Go source: | package main import ( "context" "fmt" "log" "os" "github.com/mailtrap/mailtrap-go" ) func main() { client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) if err != nil { log.Fatal(err) } if _, err := client.EmailTemplates.Delete(context.Background(), 1000001); err != nil { log.Fatal(err) } fmt.Println("template deleted") } responses: '204': description: No Content '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' '429': $ref: '#/components/responses/RateLimited' parameters: - $ref: '#/components/parameters/email_template_id' /api/templates: get: description: |- Returns a paginated list of the email templates in your account. {% hint style="warning" %} This endpoint is experimental. Its parameters and response shape may change before it is generally available. `GET /api/email_templates` remains the stable way to list templates. {% endhint %} `/api/templates` is the conventions-compliant replacement for `/api/email_templates`: it wraps every response in a `data` envelope, takes a flat request body on writes, and paginates this list, where `GET /api/email_templates` returns every template as a single unpaginated array. `/api/email_templates` keeps its published shapes and is unaffected. Pagination is page-token based: pass the `token` query parameter and follow the `next_token` and `prev_token` values returned in the `pagination` object to walk between pages. A `per_page` above `100` is clamped to `100` rather than rejected. A `token` past the last page returns an empty `data` array rather than an error: the `pagination` object echoes the `token` you asked for, and `prev_token` points at the last page that has data. Follow the tokens returned by a previous response rather than constructing them by hand — a `token` whose offset (`(token - 1) * per_page`) overflows a 64-bit integer is rejected with `422`. operationId: getTemplates summary: Get a paginated list of Email Templates (Experimental) tags: - templates parameters: - $ref: '#/components/parameters/token' - $ref: '#/components/parameters/per_page' x-codeSamples: - lang: shell label: 'cURL' source: | curl -X GET "https://mailtrap.io/api/templates?per_page=50&token=1" \ -H "Api-Token: YOUR_API_KEY" - lang: javascript label: Node.js source: | import { MailtrapClient } from "mailtrap"; const client = new MailtrapClient({ token: "YOUR_API_KEY", accountId: YOUR_ACCOUNT_ID }); const page = await client.templates.getList({ per_page: 50, token: 1 }); console.log(`Templates: ${page.data.length}`, page.pagination); - lang: php label: PHP source: | templates($accountId); $response = $templates->getTemplates(perPage: 50, token: 1); var_dump(ResponseHelper::toArray($response)); - lang: python label: Python source: | import mailtrap as mt client = mt.MailtrapClient(token="YOUR_API_KEY", account_id="YOUR_ACCOUNT_ID") templates = client.templates_api.templates page = templates.get_list(mt.TemplateListParams(per_page=50, token=1)) for template in page.data: print(f"{template.name}: {template.uuid}") print(page.pagination) - lang: ruby label: Ruby source: | require 'mailtrap' client = Mailtrap::Client.new(api_key: 'YOUR_API_KEY') templates = Mailtrap::TemplatesAPI.new(YOUR_ACCOUNT_ID, client) page = templates.list(per_page: 50, token: 1) puts page.data puts page.pagination - lang: csharp label: .NET source: | using Mailtrap; using Mailtrap.Templates.Models; using var mailtrapFactory = new MailtrapClientFactory("YOUR_API_KEY"); var client = mailtrapFactory.CreateClient(); var filter = new TemplateListFilter { PerPage = 50, Token = 1 }; var page = await client.Account(YOUR_ACCOUNT_ID).Templates().GetAll(filter); foreach (var template in page.Data) { Console.WriteLine($"Template: {template.Name}, ID: {template.Id}"); } Console.WriteLine($"Next page token: {page.Pagination?.NextToken}"); - lang: java label: Java source: | import io.mailtrap.api.templates.TemplateListFilter; import io.mailtrap.config.MailtrapConfig; import io.mailtrap.factory.MailtrapClientFactory; var config = new MailtrapConfig.Builder().token("YOUR_API_KEY").build(); var client = MailtrapClientFactory.createMailtrapClient(config); var templates = client.templatesApi().templates(); long accountId = YOUR_ACCOUNT_ID; var filter = TemplateListFilter.builder().perPage(50).token(1).build(); var page = templates.getTemplates(accountId, filter); System.out.println(page.getData()); System.out.println(page.getPagination()); - lang: go label: Go source: | package main import ( "context" "fmt" "log" "os" "github.com/mailtrap/mailtrap-go" ) func main() { client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) if err != nil { log.Fatal(err) } page, _, err := client.Templates.List(context.Background(), &mailtrap.TemplateListOptions{PerPage: 50, Token: 1}) if err != nil { log.Fatal(err) } for _, template := range page.Data { fmt.Printf("%d %s (%s)\n", template.ID, template.Name, template.Category) } if next := page.Pagination.NextToken; next != nil { fmt.Printf("next token: %d\n", *next) } } responses: '200': description: OK. content: application/json: schema: type: object required: - data - pagination properties: data: type: array items: $ref: '#/components/schemas/EmailTemplateResponse' pagination: $ref: '#/components/schemas/Pagination' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '422': description: The `token` is too large to paginate with — its offset overflows a 64-bit integer. content: application/json: schema: type: object properties: errors: type: string example: errors: token is out of range '429': $ref: '#/components/responses/TemplatesRateLimited' post: description: |- Creates an email template and returns it in a `data` envelope. {% hint style="warning" %} This endpoint is experimental. Its request and response shapes may change before it is generally available. `POST /api/email_templates` remains the stable way to create a template. {% endhint %} The request body is flat, where `POST /api/email_templates` expects the attributes wrapped in `email_template`. That wrapper is still accepted here, so you can switch the path first and flatten the body afterwards. operationId: createTemplate summary: Create Email Template (Experimental) tags: - templates x-codeSamples: - lang: shell label: 'cURL' source: | curl -X POST "https://mailtrap.io/api/templates" \ -H "Api-Token: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "Welcome Email", "subject": "Welcome to {{company_name}}!", "category": "onboarding", "body_html": "

Welcome {{user_name}}!

", "body_text": "Welcome {{user_name}}!" }' - lang: javascript label: Node.js source: | import { MailtrapClient } from "mailtrap"; const client = new MailtrapClient({ token: "YOUR_API_KEY", accountId: YOUR_ACCOUNT_ID }); const template = await client.templates.create({ name: "Welcome Email", subject: "Welcome to {{company_name}}!", category: "onboarding", body_html: "

Welcome {{user_name}}!

", body_text: "Welcome {{user_name}}!" }); console.log(`Template created: ${template.data.uuid}`); - lang: php label: PHP source: | templates($accountId); $response = $templates->createTemplate(new CreateTemplate( name: 'Welcome Email', subject: 'Welcome to {{company_name}}!', category: 'onboarding', bodyHtml: '

Welcome {{user_name}}!

', bodyText: 'Welcome {{user_name}}!', )); var_dump(ResponseHelper::toArray($response)); - lang: python label: Python source: | import mailtrap as mt client = mt.MailtrapClient(token="YOUR_API_KEY", account_id="YOUR_ACCOUNT_ID") templates = client.templates_api.templates template = templates.create( mt.CreateTemplateParams( name="Welcome Email", subject="Welcome to {{company_name}}!", category="onboarding", body_html="

Welcome {{user_name}}!

", body_text="Welcome {{user_name}}!", ) ) print(f"Template created: {template.uuid}") - lang: ruby label: Ruby source: | require 'mailtrap' client = Mailtrap::Client.new(api_key: 'YOUR_API_KEY') templates = Mailtrap::TemplatesAPI.new(YOUR_ACCOUNT_ID, client) template = templates.create( name: 'Welcome Email', subject: 'Welcome to {{company_name}}!', category: 'onboarding', body_html: '

Welcome {{user_name}}!

', body_text: 'Welcome {{user_name}}!' ) puts "Template created: #{template.uuid}" - lang: csharp label: .NET source: | using Mailtrap; using Mailtrap.Templates.Requests; using var mailtrapFactory = new MailtrapClientFactory("YOUR_API_KEY"); var client = mailtrapFactory.CreateClient(); var request = new CreateTemplateRequest { Name = "Welcome Email", Category = "onboarding", Subject = "Welcome to {{company_name}}!", BodyHtml = "

Welcome {{user_name}}!

", BodyText = "Welcome {{user_name}}!" }; var template = await client.Account(YOUR_ACCOUNT_ID).Templates().Create(request); Console.WriteLine($"Template created: {template.Uuid}"); - lang: java label: Java source: | import io.mailtrap.model.request.templates.CreateTemplateRequest; import io.mailtrap.config.MailtrapConfig; import io.mailtrap.factory.MailtrapClientFactory; var config = new MailtrapConfig.Builder().token("YOUR_API_KEY").build(); var client = MailtrapClientFactory.createMailtrapClient(config); var templates = client.templatesApi().templates(); long accountId = YOUR_ACCOUNT_ID; var request = CreateTemplateRequest.builder() .name("Welcome Email") .category("onboarding") .subject("Welcome to {{company_name}}!") .bodyHtml("

Welcome {{user_name}}!

") .bodyText("Welcome {{user_name}}!") .build(); var template = templates.createTemplate(accountId, request).getData(); System.out.println(template.getUuid()); - lang: go label: Go source: | package main import ( "context" "fmt" "log" "os" "github.com/mailtrap/mailtrap-go" ) func main() { client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) if err != nil { log.Fatal(err) } template, _, err := client.Templates.Create(context.Background(), &mailtrap.CreateTemplateRequest{ Name: "Welcome Email", Category: "onboarding", Subject: "Welcome to {{company_name}}!", BodyHTML: "

Welcome {{user_name}}!

", BodyText: "Welcome {{user_name}}!", }) if err != nil { log.Fatal(err) } fmt.Printf("created template %d (uuid %s)\n", template.ID, template.UUID) } requestBody: content: application/json: schema: $ref: '#/components/schemas/TemplateRequest' responses: '201': description: Email template created successfully. content: application/json: schema: $ref: '#/components/schemas/TemplateResponse' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '422': description: Validation errors, or the account has reached its plan's template limit. content: application/json: schema: $ref: '#/components/schemas/UnprocessableEntity' examples: validation_error: summary: Required attributes are missing value: errors: name: - can't be blank category: - can't be blank subject: - can't be blank template_limit_reached: summary: The plan's template limit is reached value: errors: base: - You've reached the maximum number of templates allowed. Please upgrade your plan to add more. '429': $ref: '#/components/responses/TemplatesRateLimited' /api/templates/{template_id}: get: description: |- Returns a single email template in a `data` envelope. {% hint style="warning" %} This endpoint is experimental. Its parameters and response shape may change before it is generally available. `GET /api/email_templates/{email_template_id}` remains the stable way to read a template. {% endhint %} operationId: getTemplate summary: Get Email Template (Experimental) tags: - templates x-codeSamples: - lang: shell label: 'cURL' source: | curl -X GET "https://mailtrap.io/api/templates/{template_id}" \ -H "Api-Token: YOUR_API_KEY" - lang: javascript label: Node.js source: | import { MailtrapClient } from "mailtrap"; const client = new MailtrapClient({ token: "YOUR_API_KEY", accountId: YOUR_ACCOUNT_ID }); const template = await client.templates.get(YOUR_TEMPLATE_ID); console.log(`Template: ${template.data.name} (UUID: ${template.data.uuid})`); - lang: php label: PHP source: | templates($accountId); $templateId = (int) $_ENV['MAILTRAP_TEMPLATE_ID']; $response = $templates->getTemplate($templateId); var_dump(ResponseHelper::toArray($response)); - lang: python label: Python source: | import mailtrap as mt client = mt.MailtrapClient(token="YOUR_API_KEY", account_id="YOUR_ACCOUNT_ID") templates = client.templates_api.templates template = templates.get_by_id(YOUR_TEMPLATE_ID) print(f"Template: {template.name} (UUID: {template.uuid})") - lang: ruby label: Ruby source: | require 'mailtrap' client = Mailtrap::Client.new(api_key: 'YOUR_API_KEY') templates = Mailtrap::TemplatesAPI.new(YOUR_ACCOUNT_ID, client) template = templates.get(YOUR_TEMPLATE_ID) puts "Template: #{template.name} (UUID: #{template.uuid})" - lang: csharp label: .NET source: | using Mailtrap; using var mailtrapFactory = new MailtrapClientFactory("YOUR_API_KEY"); var client = mailtrapFactory.CreateClient(); var template = await client.Account(YOUR_ACCOUNT_ID).Template(YOUR_TEMPLATE_ID).GetDetails(); Console.WriteLine($"Template: {template.Name} (UUID: {template.Uuid})"); - lang: java label: Java source: | import io.mailtrap.config.MailtrapConfig; import io.mailtrap.factory.MailtrapClientFactory; var config = new MailtrapConfig.Builder().token("YOUR_API_KEY").build(); var client = MailtrapClientFactory.createMailtrapClient(config); var templates = client.templatesApi().templates(); long accountId = YOUR_ACCOUNT_ID; long templateId = YOUR_TEMPLATE_ID; var template = templates.getTemplate(accountId, templateId).getData(); System.out.println(template.getName() + " (" + template.getUuid() + ")"); - lang: go label: Go source: | package main import ( "context" "fmt" "log" "os" "github.com/mailtrap/mailtrap-go" ) func main() { client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) if err != nil { log.Fatal(err) } template, _, err := client.Templates.Get(context.Background(), 12345) if err != nil { log.Fatal(err) } fmt.Printf("%s (uuid %s)\n", template.Name, template.UUID) } responses: '200': description: OK. content: application/json: schema: $ref: '#/components/schemas/TemplateResponse' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' '429': $ref: '#/components/responses/RateLimited' patch: description: |- Updates an email template and returns it in a `data` envelope. `PUT` is accepted on the same path and behaves identically. {% hint style="warning" %} This endpoint is experimental. Its request and response shapes may change before it is generally available. `PATCH /api/email_templates/{email_template_id}` remains the stable way to update a template. {% endhint %} The request body is flat, where `PATCH /api/email_templates/{email_template_id}` expects the attributes wrapped in `email_template`. That wrapper is still accepted here, so you can switch the path first and flatten the body afterwards. Every attribute is optional. A request carrying none of them returns `200` with the template unchanged. operationId: updateTemplate summary: Update Email Template (Experimental) tags: - templates x-codeSamples: - lang: shell label: 'cURL' source: | curl -X PATCH "https://mailtrap.io/api/templates/{template_id}" \ -H "Api-Token: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "Welcome Email v2", "subject": "Welcome aboard, {{user_name}}!" }' - lang: javascript label: Node.js source: | import { MailtrapClient } from "mailtrap"; const client = new MailtrapClient({ token: "YOUR_API_KEY", accountId: YOUR_ACCOUNT_ID }); const template = await client.templates.update(YOUR_TEMPLATE_ID, { name: "Welcome Email v2", subject: "Welcome aboard, {{user_name}}!" }); console.log(`Template updated: ${template.data.name}`); - lang: php label: PHP source: | templates($accountId); $templateId = (int) $_ENV['MAILTRAP_TEMPLATE_ID']; $response = $templates->updateTemplate($templateId, new UpdateTemplate( name: 'Welcome Email v2', subject: 'Welcome aboard, {{user_name}}!', )); var_dump(ResponseHelper::toArray($response)); - lang: python label: Python source: | import mailtrap as mt client = mt.MailtrapClient(token="YOUR_API_KEY", account_id="YOUR_ACCOUNT_ID") templates = client.templates_api.templates template = templates.update( YOUR_TEMPLATE_ID, mt.UpdateTemplateParams( name="Welcome Email v2", subject="Welcome aboard, {{user_name}}!", ), ) print(f"Template updated: {template.name}") - lang: ruby label: Ruby source: | require 'mailtrap' client = Mailtrap::Client.new(api_key: 'YOUR_API_KEY') templates = Mailtrap::TemplatesAPI.new(YOUR_ACCOUNT_ID, client) template = templates.update( YOUR_TEMPLATE_ID, name: 'Welcome Email v2', subject: 'Welcome aboard, {{user_name}}!' ) puts "Template updated: #{template.name}" - lang: csharp label: .NET source: | using Mailtrap; using Mailtrap.Templates.Requests; using var mailtrapFactory = new MailtrapClientFactory("YOUR_API_KEY"); var client = mailtrapFactory.CreateClient(); var request = new UpdateTemplateRequest { Name = "Welcome Email v2", Subject = "Welcome aboard, {{user_name}}!" }; var template = await client.Account(YOUR_ACCOUNT_ID).Template(YOUR_TEMPLATE_ID).Update(request); Console.WriteLine($"Template updated: {template.Name}"); - lang: java label: Java source: | import io.mailtrap.model.request.templates.UpdateTemplateRequest; import io.mailtrap.config.MailtrapConfig; import io.mailtrap.factory.MailtrapClientFactory; var config = new MailtrapConfig.Builder().token("YOUR_API_KEY").build(); var client = MailtrapClientFactory.createMailtrapClient(config); var templates = client.templatesApi().templates(); long accountId = YOUR_ACCOUNT_ID; long templateId = YOUR_TEMPLATE_ID; var request = UpdateTemplateRequest.builder() .name("Welcome Email v2") .subject("Welcome aboard, {{user_name}}!") .build(); var template = templates.updateTemplate(accountId, templateId, request).getData(); System.out.println(template.getName()); - lang: go label: Go source: | package main import ( "context" "fmt" "log" "os" "github.com/mailtrap/mailtrap-go" ) func main() { client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) if err != nil { log.Fatal(err) } template, _, err := client.Templates.Update(context.Background(), 12345, &mailtrap.UpdateTemplateRequest{ Name: "Welcome Email v2", Subject: "Welcome aboard, {{user_name}}!", }) if err != nil { log.Fatal(err) } fmt.Printf("updated template %d: %s\n", template.ID, template.Name) } requestBody: content: application/json: schema: $ref: '#/components/schemas/TemplateUpdateRequest' responses: '200': description: OK. content: application/json: schema: $ref: '#/components/schemas/TemplateResponse' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' '422': description: Validation errors. content: application/json: schema: $ref: '#/components/schemas/UnprocessableEntity' examples: validation_error: summary: An attribute was blanked out value: errors: name: - can't be blank category: - can't be blank subject: - can't be blank drag_and_drop_template: summary: The template was built in the drag-and-drop editor value: errors: body_html: - cannot update body_html of template created within UI editor body_text: - cannot update body_text of template created within UI editor '429': $ref: '#/components/responses/RateLimited' delete: description: |- Deletes an email template. {% hint style="warning" %} This endpoint is experimental. `DELETE /api/email_templates/{email_template_id}` remains the stable way to delete a template. {% endhint %} operationId: deleteTemplate summary: Delete Email Template (Experimental) tags: - templates x-codeSamples: - lang: shell label: 'cURL' source: | curl -X DELETE "https://mailtrap.io/api/templates/{template_id}" \ -H "Api-Token: YOUR_API_KEY" - lang: javascript label: Node.js source: | import { MailtrapClient } from "mailtrap"; const client = new MailtrapClient({ token: "YOUR_API_KEY", accountId: YOUR_ACCOUNT_ID }); await client.templates.delete(YOUR_TEMPLATE_ID); console.log("Template deleted successfully"); - lang: php label: PHP source: | templates($accountId); $templateId = (int) $_ENV['MAILTRAP_TEMPLATE_ID']; $response = $templates->deleteTemplate($templateId); var_dump($response->getStatusCode()); // 204 - lang: python label: Python source: | import mailtrap as mt client = mt.MailtrapClient(token="YOUR_API_KEY", account_id="YOUR_ACCOUNT_ID") templates = client.templates_api.templates templates.delete(YOUR_TEMPLATE_ID) print("Template deleted successfully") - lang: ruby label: Ruby source: | require 'mailtrap' client = Mailtrap::Client.new(api_key: 'YOUR_API_KEY') templates = Mailtrap::TemplatesAPI.new(YOUR_ACCOUNT_ID, client) templates.delete(YOUR_TEMPLATE_ID) puts 'Template deleted successfully' - lang: csharp label: .NET source: | using Mailtrap; using var mailtrapFactory = new MailtrapClientFactory("YOUR_API_KEY"); var client = mailtrapFactory.CreateClient(); await client.Account(YOUR_ACCOUNT_ID).Template(YOUR_TEMPLATE_ID).Delete(); Console.WriteLine("Template deleted successfully"); - lang: java label: Java source: | import io.mailtrap.config.MailtrapConfig; import io.mailtrap.factory.MailtrapClientFactory; var config = new MailtrapConfig.Builder().token("YOUR_API_KEY").build(); var client = MailtrapClientFactory.createMailtrapClient(config); var templates = client.templatesApi().templates(); long accountId = YOUR_ACCOUNT_ID; long templateId = YOUR_TEMPLATE_ID; templates.deleteTemplate(accountId, templateId); System.out.println("Template deleted successfully"); - lang: go label: Go source: | package main import ( "context" "fmt" "log" "os" "github.com/mailtrap/mailtrap-go" ) func main() { client, err := mailtrap.NewClient(os.Getenv("MAILTRAP_API_TOKEN")) if err != nil { log.Fatal(err) } if _, err := client.Templates.Delete(context.Background(), 12345); err != nil { log.Fatal(err) } fmt.Println("deleted template") } responses: '204': description: No Content '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' '429': $ref: '#/components/responses/RateLimited' parameters: - $ref: '#/components/parameters/template_id' components: securitySchemes: HeaderAuth: type: apiKey description: API token in Api-Token header in: header name: Api-Token BearerAuth: type: http scheme: bearer bearerFormat: JWT description: Bearer token authentication parameters: email_template_id: name: email_template_id in: path required: true description: Email template ID schema: type: integer format: int64 example: 60927 template_id: name: template_id in: path required: true description: Email template ID schema: type: integer format: int64 example: 60927 token: name: token description: Page number to retrieve (page-token pagination). Defaults to `1`. in: query required: false schema: type: integer format: int64 minimum: 1 default: 1 example: 1 per_page: name: per_page description: Number of templates per page. Defaults to `50`, maximum `100`. Larger values are clamped to `100`. in: query required: false schema: type: integer minimum: 1 default: 50 example: 50 schemas: UnprocessableEntity: type: object properties: errors: type: object additionalProperties: type: array items: type: string example: errors: category: - can't be blank subject: - can't be blank UnauthenticatedResponse: title: UnauthenticatedResponse type: object properties: error: type: string description: Error message example: Incorrect API token example: error: Incorrect API token PermissionsDeniedResponse: title: PermissionsDeniedResponse type: object properties: errors: type: string example: Account access forbidden example: errors: Account access forbidden NotFoundResponse: title: NotFoundResponse type: object properties: error: type: string description: Error message example: Not Found example: error: Not Found EmailTemplateRequest: title: EmailTemplateRequest type: object required: - email_template properties: email_template: type: object required: - name - subject - category properties: name: type: string maxLength: 255 category: type: string maxLength: 255 subject: type: string maxLength: 255 body_text: type: string maxLength: 10000000 body_html: type: string maxLength: 10000000 example: email_template: name: My Email Template subject: Promotional Email category: Promotional body_html:
Template Body
body_text: Template Body EmailTemplateResponse: title: EmailTemplateResponse type: object properties: id: type: integer uuid: type: string format: uuid name: type: string maxLength: 255 category: type: string maxLength: 255 subject: type: string maxLength: 255 body_text: type: string maxLength: 10000000 body_html: type: string maxLength: 10000000 created_at: type: string format: date-time updated_at: type: string format: date-time example: id: 26730 uuid: '018dd5e3-f6d2-7c00-8f9b-e5c3f2d8a132' name: My Email Template subject: Promotional Email category: Promotional body_html:
Template Body
body_text: Template Body created_at: '2021-01-01T00:00:00Z' updated_at: '2021-01-01T00:00:00Z' Pagination: title: Pagination type: object description: Page-token pagination metadata. properties: token: type: integer description: Current page number. example: 1 prev_token: type: [integer, "null"] description: Previous page number, or `null` on the first page. example: null next_token: type: [integer, "null"] description: Next page number, or `null` on the last page. example: 2 first_url: type: string format: uri example: 'https://mailtrap.io/api/templates?per_page=50&token=1' prev_url: type: [string, "null"] format: uri example: null current_url: type: string format: uri example: 'https://mailtrap.io/api/templates?per_page=50&token=1' next_url: type: [string, "null"] format: uri example: 'https://mailtrap.io/api/templates?per_page=50&token=2' TemplateRequest: title: TemplateRequest type: object required: - name - subject - category properties: name: type: string maxLength: 255 category: type: string maxLength: 255 subject: type: string maxLength: 255 body_text: type: string maxLength: 10000000 body_html: type: string maxLength: 10000000 example: name: My Email Template subject: Promotional Email category: Promotional body_html:
Template Body
body_text: Template Body TemplateUpdateRequest: title: TemplateUpdateRequest type: object properties: name: type: string maxLength: 255 category: type: string maxLength: 255 subject: type: string maxLength: 255 body_text: type: string maxLength: 10000000 body_html: type: string maxLength: 10000000 example: name: My Email Template subject: Promotional Email TemplateResponse: title: TemplateResponse type: object required: - data properties: data: $ref: '#/components/schemas/EmailTemplateResponse' EndpointRateLimitedResponse: title: EndpointRateLimitedResponse type: object required: - errors properties: errors: type: string example: Rate limit exceeded RateLimitedResponse: title: RateLimitedResponse type: object # NOTE: the shared global throttle (Rack::Attack) returns the legacy singular `error` key. # This diverges from the plural-`errors` convention; kept here to match the real response. required: - error properties: error: type: string example: Throttled responses: Unauthorized: description: Returns unauthorized error message. Check your credentials. content: application/json: schema: $ref: '#/components/schemas/UnauthenticatedResponse' example: error: Incorrect API token Forbidden: description: Returns forbidden error message. Check your permissions. content: application/json: schema: $ref: '#/components/schemas/PermissionsDeniedResponse' example: errors: Account access forbidden NotFound: description: Resource not found content: application/json: schema: $ref: '#/components/schemas/NotFoundResponse' example: error: Not Found UnprocessableEntity: description: Validation errors content: application/json: schema: $ref: '#/components/schemas/UnprocessableEntity' example: errors: category: - can't be blank subject: - can't be blank RateLimited: description: |- Too many requests. The public API is rate limited to 150 requests per 10 seconds per API token. Retry after the window resets (see the `x-ratelimit-reset` header). headers: x-ratelimit-limit: description: Maximum number of requests allowed within the window. schema: type: integer example: 150 x-ratelimit-remaining: description: Requests remaining in the current window. schema: type: integer example: 0 x-ratelimit-reset: description: ISO 8601 timestamp when the current rate-limit window resets. schema: type: string format: date-time example: '2026-06-15T10:00:10.000000Z' content: application/json: schema: $ref: '#/components/schemas/RateLimitedResponse' TemplatesRateLimited: description: |- Too many requests. Two limits apply: 150 requests per minute per account on this endpoint, counted in separate allowances for listing and for creating, and the global 150 requests per 10 seconds per API token. The response body tells them apart, and only the global throttle sets the `x-ratelimit-*` headers. headers: x-ratelimit-limit: description: Maximum number of requests allowed within the window. Sent by the global throttle only. schema: type: integer example: 150 x-ratelimit-remaining: description: Requests remaining in the current window. Sent by the global throttle only. schema: type: integer example: 0 x-ratelimit-reset: description: ISO 8601 timestamp when the current rate-limit window resets. Sent by the global throttle only. schema: type: string format: date-time example: '2026-06-15T10:00:10.000000Z' content: application/json: schema: oneOf: - $ref: '#/components/schemas/EndpointRateLimitedResponse' - $ref: '#/components/schemas/RateLimitedResponse' examples: endpoint_rate_limit: summary: The per-account limit on this endpoint is reached value: errors: Rate limit exceeded global_rate_limit: summary: The global per-token throttle is reached value: error: Throttled