MailerSend
Email API

Templates

Use the MailerSend Templates API endpoint to easily manage your transactional email templates. Create, fetch, update, and delete single templates or a list of templates.

Create and manage email templates via the MailerSend API.

Get templates

Retrieve the account templates using this GET request:

GET  https://api.mailersend.com/v1/templates

Request parameters

Query parameterTypeRequiredLimitationsDetails
domain_idstringnoExisting hashed domain ID.
pageintnoMin: 1
limitintnoMin: 10, Max: 100Default: 25
use MailerSend\MailerSend;

$mailersend = new MailerSend(['api_key' => 'key']);

// Get all templates of an account
$mailersend->template->getAll();

// Get all templates of a domain
$mailersend->template->getAll('domain_id');

// Get page 2 of templates with 20 records per page
$mailersend->template->getAll('domain_id', 2, 20);

More examples

import 'dotenv/config';
import { MailerSend} from "mailersend";

const mailerSend = new MailerSend({
  apiKey: process.env.API_KEY,
});

mailerSend.email.template.list({
    domain_id: "domain_id"
})
  .then((response) => console.log(response.body))
  .catch((error) => console.log(error.body));

More examples

from mailersend import MailerSendClient, TemplatesBuilder

ms = MailerSendClient()

request = (TemplatesBuilder()
          .domain_id("domain-id")
          .page(1)
          .limit(25)
          .build_templates_list_request())

response = ms.templates.list_templates(request)

More examples

package main

import (
	"context"
	"log"
	"time"
	
	"github.com/mailersend/mailersend-go"
)

var APIKey = "Api Key Here"

func main() {
	// Create an instance of the mailersend client
	ms := mailersend.NewMailersend(APIKey)

	ctx := context.Background()
	ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
	defer cancel()
	
	options := &mailersend.ListTemplateOptions{
		Page:  1,
		Limit: 25,
	}
	
	_, _, err := ms.Template.List(ctx, options)
	if err != nil {
		log.Fatal(err)
	}
}

More examples

import com.mailersend.sdk.MailerSend;
import com.mailersend.sdk.exceptions.MailerSendException;
import com.mailersend.sdk.templates.TemplateItem;
import com.mailersend.sdk.templates.TemplatesList;

public void getTemplatesList() {
    
    MailerSend ms = new MailerSend();
    ms.setToken("mailersend token");
    
    try {
        
            TemplatesList list = ms.templates().domainId("domain-id").page(1).limit(25).getTemplates();
            
            for (TemplateItem item : list.templates) {
                
                System.out.println(item.id);
                System.out.println(item.name);
            }
        
    } catch (MailerSendException e) {
        
        e.printStackTrace();
    }
}

More examples

require "mailersend-ruby"

ms_client = Mailersend::Client.new('your_mailersend_token')

ms_templates = Mailersend::Templates.new(ms_client)
ms_templates.list(domain_id: "aax455lll", page: 1, limit: 10)

More examples

Responses

Valid

Response Code: 200 OK
Response Headers:
	content-type: application/json
{
  "data": [
    {
      "id": "x8emy5o5world01w",
      "name": "Signup email",
      "description": null,
      "type": "html",
      "image_path": "https://link.com/images/image.jpg",
      "variables": {
        "variables": {},
        "personalization": {
          "name": "",
          "company": ""
        }
      },
      "created_at": "2020-06-10 10:09:56",
      "updated_at": "2020-06-10 10:09:56",
      "category": {
        "id": "5genxmqlgozlyvk7",
        "name": "Newsletters"
      },
      "categories": [
        {
          "id": "5genxmqlgozlyvk7",
          "name": "Newsletters"
        }
      ],
      "translations": [
        {
          "language": "es",
          "language_name": "Spanish",
          "status": "published",
          "total_email_sent": 25,
          "last_email_sent_at": "2021-06-22T16:00:00.000000Z",
          "translated_at": "2021-06-22T15:45:00.000000Z",
          "created_at": "2021-06-22T15:40:00.000000Z",
          "updated_at": "2021-06-22T15:45:00.000000Z"
        }
      ]
    },
    {
      "id": "x8emy5o5world01x",
      "name": "Premium subscription",
      "description": null,
      "type": "html",
      "image_path": "https://link.com/images/image.jpg",
      "variables": {
        "variables": {},
        "personalization": {
          "name": "",
          "company": ""
        }
      },
      "created_at": "2020-06-10 10:09:56",
      "updated_at": "2020-06-10 10:09:56",
      "category": {
        "id": "5genxmqlgozlyvk7",
        "name": "Newsletters"
      },
      "categories": [
        {
          "id": "5genxmqlgozlyvk7",
          "name": "Newsletters"
        }
      ],
      "translations": [
        {
          "language": "es",
          "language_name": "Spanish",
          "status": "published",
          "total_email_sent": 25,
          "last_email_sent_at": "2021-06-22T16:00:00.000000Z",
          "translated_at": "2021-06-22T15:45:00.000000Z",
          "created_at": "2021-06-22T15:40:00.000000Z",
          "updated_at": "2021-06-22T15:45:00.000000Z"
        }
      ]
    },
    {
      "id": "x8emy5o5world01y",
      "name": "Newsletter",
      "description": null,
      "type": "html",
      "image_path": "https://link.com/images/image.jpg",
      "variables": {
        "variables": {},
        "personalization": {
          "name": "",
          "company": ""
        }
      },
      "created_at": "2020-06-10 10:09:56",
      "updated_at": "2020-06-10 10:09:56",
      "category": {
        "id": "5genxmqlgozlyvk7",
        "name": "Newsletters"
      },
      "categories": [
        {
          "id": "5genxmqlgozlyvk7",
          "name": "Newsletters"
        }
      ],
      "translations": [
        {
          "language": "es",
          "language_name": "Spanish",
          "status": "published",
          "total_email_sent": 25,
          "last_email_sent_at": "2021-06-22T16:00:00.000000Z",
          "translated_at": "2021-06-22T15:45:00.000000Z",
          "created_at": "2021-06-22T15:40:00.000000Z",
          "updated_at": "2021-06-22T15:45:00.000000Z"
        }
      ]
    }
  ],
  "links": {
    "first": "https:\/\/www.mailersend.io\/api\/v1\/templates?page=1",
    "last": null,
    "prev": null,
    "next": null
  },
  "meta": {
    "current_page": 1,
    "current_page_url": "https:\/\/www.mailersend.io\/api\/v1\/templates?page=1",
    "from": 1,
    "path": "https:\/\/www.mailersend.io\/api\/v1\/templates",
    "per_page": 25,
    "to": 3
  }
}

Get a single template

Retrieve the information of a single template, its category, domain, and stats using this GET request:

GET https://api.mailersend.com/v1/templates/{template_id}

Request parameters

URL parameterTypeRequiredLimitationsDetails
template_idstringyes
use MailerSend\MailerSend;

$mailersend = new MailerSend(['api_key' => 'key']);

$mailersend->template->find('template_id');

More examples

import 'dotenv/config';
import { MailerSend} from "mailersend";

const mailerSend = new MailerSend({
  apiKey: process.env.API_KEY,
});

mailerSend.email.template.single("template_id")
  .then((response) => console.log(response.body))
  .catch((error) => console.log(error.body));

More examples

from mailersend import MailerSendClient, TemplatesBuilder

ms = MailerSendClient()

request = (TemplatesBuilder()
          .template_id("template-id")
          .build_template_get_request())

response = ms.templates.get_template(request)

More examples

package main

import (
	"context"
	"log"
	"time"
	
	"github.com/mailersend/mailersend-go"
)

var APIKey = "Api Key Here"

func main() {
	// Create an instance of the mailersend client
	ms := mailersend.NewMailersend(APIKey)

	ctx := context.Background()
	ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
	defer cancel()
	
	templateID := "template-id"
	
	_, _, err := ms.Template.Get(ctx, templateID)
	if err != nil {
		log.Fatal(err)
	}
}

More examples

import com.mailersend.sdk.MailerSend;
import com.mailersend.sdk.MailerSendResponse;
import com.mailersend.sdk.exceptions.MailerSendException;
import com.mailersend.sdk.templates.Template;
import com.mailersend.sdk.templates.TemplateItem;
import com.mailersend.sdk.templates.TemplatesList;

public void getTemplate() {
    
    MailerSend ms = new MailerSend();
    ms.setToken("mailersend token");
    
    try {
        
            Template template = ms.templates().getTemplate("template id");
            
            System.out.println(template.id);
            System.out.println(template.name);
            System.out.println(template.imagePath);
        
    } catch (MailerSendException e) {
        
        e.printStackTrace();
    }
}

More examples

require "mailersend-ruby"

ms_client = Mailersend::Client.new('your_mailersend_token')

ms_templates = Mailersend::Templates.new(ms_client)
ms_templates.single(template_id: "id124")

More examples

Responses

Valid

{
  "data": {
    "id": "x8emy5o5world01w",
    "name": "libero",
    "description": null,
    "type": "html",
    "image_path": "http://mailersend.com/images/templates/placeholder.png",
    "variables": {
      "variables": {},
      "personalization": {
        "name": "",
        "elements": [
          {
            "name": "",
            "price": ""
          }
        ],
        "license_key": "",
        "account_name": "",
        "product_name": "",
        "renew_button": "",
        "expiration_date": ""
      }
    },
    "created_at": "2021-06-22T15:38:51.000000Z",
    "updated_at": "2021-06-22T16:00:00.000000Z",
    "category": {
      "id": "5genxmqlgozlyvk7",
      "name": "aut"
    },
    "categories": [
      {
        "id": "5genxmqlgozlyvk7",
        "name": "aut"
      }
    ],
    "domain": {
      "id": "1jreeo",
      "name": "domain.com",
      "dkim": true,
      "spf": true,
      "tracking": false,
      "is_verified": true,
      "is_cname_verified": false,
      "is_dns_active": true,
      "is_cname_active": false,
      "is_tracking_allowed": false,
      "has_not_queued_messages": false,
      "not_queued_messages_count": 0,
      "domain_settings": {
        "send_paused": false,
        "track_clicks": true,
        "track_opens": true,
        "track_opens_pixel_on_top": false,
        "track_unsubscribe": true,
        "track_unsubscribe_html": "<p>Click here to <a href=\"{{unsubscribe}}\">unsubscribe</a></p>",
        "track_unsubscribe_html_enabled": false,
        "track_unsubscribe_plain": "Click here to unsubscribe: {{unsubscribe}}",
        "track_unsubscribe_plain_enabled": false,
        "track_content": true,
        "custom_tracking_enabled": false,
        "custom_tracking_subdomain": "email",
        "return_path_subdomain": "mta",
        "inbound_routing_enabled": false,
        "inbound_routing_subdomain": "inbound",
        "precedence_bulk": false,
        "ignore_duplicated_recipients": false
      },
      "is_sending_paused": false,
      "created_at": "2020-06-10 10:09:50",
      "updated_at": "2020-06-10 10:09:50",
      "totals": []
    },
    "translations": [
      {
        "language": "es",
        "language_name": "Spanish",
        "status": "published",
        "total_email_sent": 25,
        "last_email_sent_at": "2021-06-22T16:00:00.000000Z",
        "translated_at": "2021-06-22T15:45:00.000000Z",
        "created_at": "2021-06-22T15:40:00.000000Z",
        "updated_at": "2021-06-22T15:45:00.000000Z"
      }
    ],
    "html": "<p>Hi {{ name }}, your license key is {{ license_key }}.</p>",
    "text": "Hi {{ name }}, your license key is {{ license_key }}.",
    "template_stats": {
      "total": 1200,
      "queued": 0,
      "sent": 4,
      "rejected": 16,
      "delivered": 1180,
      "delivery_rate": "98",
      "opened": 590,
      "open_rate": "50",
      "clicked": 118,
      "click_rate": "10",
      "unsubscribed": 2,
      "unsubscribe_rate": "0",
      "complained": 0,
      "complain_rate": "0",
      "last_email_sent_at": "2026-10-13T09:30:00.000000Z"
    }
  }
}

Error

Response Code: 404 Not Found

Template stats

template_stats holds the sending stats for the template.

Note

Template stats are all-time totals for the template and can't be filtered by date. They aren't real-time, so a recent send may not show yet. For stats over a date range, tag your emails and use Activity data by date filtered by tag.

FieldTypeDetails
totalintegerAll emails sent with this template, in any status.
queuedintegerEmails waiting to be sent.
sentintegerEmails sent and waiting for a delivery result.
rejectedintegerEmails that could not be delivered.
deliveredintegerEmails delivered.
delivery_ratestring|integerdelivered as a whole-number percentage of total, e.g. "98". 0 when total is 0.
openedintegerDelivered emails opened at least once. Each email counts once.
open_ratestring|integeropened as a whole-number percentage of delivered, e.g. "50". 0 when delivered is 0.
clickedintegerDelivered emails clicked at least once. Each email counts once.
click_ratestring|integerclicked as a whole-number percentage of delivered. 0 when delivered is 0.
unsubscribedintegerEmails whose recipient unsubscribed.
unsubscribe_ratestring|integerunsubscribed as a whole-number percentage of delivered. 0 when delivered is 0.
complainedintegerEmails the recipient marked as spam.
complain_ratestring|integercomplained as a whole-number percentage of delivered. 0 when delivered is 0.
last_email_sent_atstring|nullWhen an email with this template was last sent. null if none has been sent.

Create a template

Create a new template using this POST request:

POST https://api.mailersend.com/v1/templates
use MailerSend\MailerSend;
use MailerSend\Helpers\Builder\TemplateParams;

$mailersend = new MailerSend(['api_key' => 'key']);

$params = (new TemplateParams())
    ->setName('My Template')
    ->setHtml('<p>Hello {{name}}</p>')
    ->setText('Hello {{name}}')
    ->setDomainId('domain_id')
    ->setCategories(['category_id'])
    ->setTags(['transactional', 'welcome']);

$mailersend->template->create($params);

More examples

import 'dotenv/config';
import { MailerSend } from "mailersend";

const mailerSend = new MailerSend({
  apiKey: process.env.API_KEY,
});

mailerSend.email.template.create({
  name: "My Template",
  html: "<p>Hello {{name}}</p>",
  text: "Hello {{name}}",
  domain_id: "domain_id",
  categories: ["category_id"],
  tags: ["transactional", "welcome"],
})
  .then((response) => console.log(response.body))
  .catch((error) => console.log(error.body));

More examples

import com.mailersend.sdk.MailerSend;
import com.mailersend.sdk.exceptions.MailerSendException;
import com.mailersend.sdk.templates.Template;

public void createTemplate() {

    MailerSend ms = new MailerSend();
    ms.setToken("mailersend token");

    try {

        Template template = ms.templates().builder()
            .name("My Template")
            .html("<p>Hello {{name}}</p>")
            .text("Hello {{name}}")
            .domainId("domain-id")
            .categories(new String[]{"category-id"})
            .tags(new String[]{"transactional", "welcome"})
            .createTemplate();

        System.out.println(template.id);
        System.out.println(template.name);

    } catch (MailerSendException e) {

        e.printStackTrace();
    }
}

More examples

Request parameters

JSON parameters are provided in dot notation

JSON ParameterTypeRequiredLimitationsDetails
htmlstringyesMax size of 2 MB.The HTML body of the template.
textstringyesMax size of 2 MB.Plain text version.
namestringnoMax: 50Defaults to "Template" if not provided.
domain_idstringnoExisting hashed domain ID. Must belong to the account.
categoriesarraynoArray of hashed category IDs. Each must belong to the account.
tagsarraynoMax: 5 items, each max 191 chars. Tags can't contain URLs, HTML tags or template syntax such as {{Array of tag strings to attach to the template.

Responses

Valid

Response Code: 201 CREATED
Response Headers:
	content-type: application/json
{
  "data": {
    "id": "x8emy5o5world01w",
    "name": "My Template",
    "description": null,
    "type": "html",
    "image_path": "http://mailersend.com/images/templates/placeholder.png",
    "variables": {
      "variables": {},
      "personalization": {}
    },
    "created_at": "2021-06-22T15:38:51.000000Z",
    "updated_at": "2021-06-22T15:38:51.000000Z",
    "category": {
      "id": "5genxmqlgozlyvk7",
      "name": "aut"
    },
    "categories": [
      {
        "id": "5genxmqlgozlyvk7",
        "name": "aut"
      }
    ],
    "domain": {
      "id": "yjm4ej",
      "name": "example.org",
      "dkim": true,
      "spf": true,
      "tracking": false,
      "is_verified": true,
      "is_cname_verified": false,
      "is_dns_active": true,
      "is_cname_active": false,
      "is_tracking_allowed": false,
      "has_not_queued_messages": false,
      "not_queued_messages_count": 0,
      "domain_settings": {
        "send_paused": false,
        "track_clicks": true,
        "track_opens": true,
        "track_opens_pixel_on_top": false,
        "track_unsubscribe": true,
        "track_unsubscribe_html": "<p>Click here to <a href=\"{{unsubscribe}}\">unsubscribe</a></p>",
        "track_unsubscribe_html_enabled": false,
        "track_unsubscribe_plain": "Click here to unsubscribe: {{unsubscribe}}",
        "track_unsubscribe_plain_enabled": false,
        "track_content": true,
        "custom_tracking_enabled": false,
        "custom_tracking_subdomain": "email",
        "return_path_subdomain": "mta",
        "inbound_routing_enabled": false,
        "inbound_routing_subdomain": "inbound",
        "precedence_bulk": false,
        "ignore_duplicated_recipients": false
      },
      "is_sending_paused": false,
      "created_at": "2020-06-10 10:09:50",
      "updated_at": "2020-06-10 10:09:50",
      "totals": []
    }
  }
}

Invalid

Response Code: 422 Unprocessable Entity

See - Validation errors

Update a template

Update an existing template using this PUT request. Only templates created via API (origin=api) can be updated — templates created in the MailerSend app return 404.

PUT https://api.mailersend.com/v1/templates/{template_id}
use MailerSend\MailerSend;
use MailerSend\Helpers\Builder\TemplateParams;

$mailersend = new MailerSend(['api_key' => 'key']);

$params = (new TemplateParams())
    ->setName('Updated Template Name')
    ->setHtml('<p>Hello {{name}}, your updated content here.</p>')
    ->setText('Hello {{name}}, your updated content here.')
    ->setTags(['transactional']);

$mailersend->template->update('template_id', $params);

More examples

import 'dotenv/config';
import { MailerSend } from "mailersend";

const mailerSend = new MailerSend({
  apiKey: process.env.API_KEY,
});

mailerSend.email.template.update("template_id", {
  name: "Updated Template Name",
  html: "<p>Hello {{name}}, your updated content here.</p>",
  text: "Hello {{name}}, your updated content here.",
  tags: ["transactional"],
})
  .then((response) => console.log(response.body))
  .catch((error) => console.log(error.body));

More examples

import com.mailersend.sdk.MailerSend;
import com.mailersend.sdk.exceptions.MailerSendException;
import com.mailersend.sdk.templates.Template;

public void updateTemplate() {

    MailerSend ms = new MailerSend();
    ms.setToken("mailersend token");

    try {

        Template template = ms.templates().builder()
            .name("Updated Template Name")
            .html("<p>Hello {{name}}, your updated content here.</p>")
            .text("Hello {{name}}, your updated content here.")
            .tags(new String[]{"transactional"})
            .updateTemplate("template-id");

        System.out.println(template.id);
        System.out.println(template.name);

    } catch (MailerSendException e) {

        e.printStackTrace();
    }
}

More examples

Request parameters

URL parameterTypeRequiredLimitationsDetails
template_idstringyes

JSON parameters are provided in dot notation

JSON ParameterTypeRequiredLimitationsDetails
htmlstringnoMax size of 2 MB.The HTML body of the template.
textstringnoMax size of 2 MB.Plain text version. Auto-generated from HTML if auto_generate is true.
namestringnoMax: 50
domain_idstringnoExisting hashed domain ID. Must belong to the account.
categoriesarraynoArray of hashed category IDs. Pass an empty array to remove all categories.
tagsarraynoMax: 5 items, each max 191 chars. Tags can't contain URLs, HTML tags or template syntax such as {{Array of tag strings to attach to the template.
auto_generatebooleannoIf true, plain text is auto-generated from the HTML content.

Responses

Valid

Response Code: 200 OK
Response Headers:
	content-type: application/json
{
  "data": {
    "id": "x8emy5o5world01w",
    "name": "Updated Template Name",
    "description": null,
    "type": "html",
    "image_path": "http://mailersend.com/images/templates/placeholder.png",
    "variables": {
      "variables": {},
      "personalization": {}
    },
    "created_at": "2021-06-22T15:38:51.000000Z",
    "updated_at": "2021-06-22T16:00:00.000000Z",
    "category": {
      "id": "5genxmqlgozlyvk7",
      "name": "aut"
    },
    "categories": [
      {
        "id": "5genxmqlgozlyvk7",
        "name": "aut"
      }
    ],
    "domain": {
      "id": "yjm4ej",
      "name": "example.org",
      "dkim": true,
      "spf": true,
      "tracking": false,
      "is_verified": true,
      "is_cname_verified": false,
      "is_dns_active": true,
      "is_cname_active": false,
      "is_tracking_allowed": false,
      "has_not_queued_messages": false,
      "not_queued_messages_count": 0,
      "domain_settings": {
        "send_paused": false,
        "track_clicks": true,
        "track_opens": true,
        "track_opens_pixel_on_top": false,
        "track_unsubscribe": true,
        "track_unsubscribe_html": "<p>Click here to <a href=\"{{unsubscribe}}\">unsubscribe</a></p>",
        "track_unsubscribe_html_enabled": false,
        "track_unsubscribe_plain": "Click here to unsubscribe: {{unsubscribe}}",
        "track_unsubscribe_plain_enabled": false,
        "track_content": true,
        "custom_tracking_enabled": false,
        "custom_tracking_subdomain": "email",
        "return_path_subdomain": "mta",
        "inbound_routing_enabled": false,
        "inbound_routing_subdomain": "inbound",
        "precedence_bulk": false,
        "ignore_duplicated_recipients": false
      },
      "is_sending_paused": false,
      "created_at": "2020-06-10 10:09:50",
      "updated_at": "2020-06-10 10:09:50",
      "totals": []
    }
  }
}

Invalid

Response Code: 422 Unprocessable Entity

See - Validation errors

Error

Response Code: 404 Not Found

Delete a template

Delete a template with this DELETE request:

DELETE  https://api.mailersend.com/v1/templates/{template_id}

Request parameters

URL parameterTypeRequiredLimitationsDetails
template_idstringyes
use MailerSend\MailerSend;

$mailersend = new MailerSend(['api_key' => 'key']);

$mailersend->template->delete('template_id');

More examples

import 'dotenv/config';
import { MailerSend} from "mailersend";

const mailerSend = new MailerSend({
  apiKey: process.env.API_KEY,
});

mailerSend.email.template.delete("template_id")
  .then((response) => console.log(response.body))
  .catch((error) => console.log(error.body));

More examples

from mailersend import MailerSendClient, TemplatesBuilder

ms = MailerSendClient()

request = (TemplatesBuilder()
          .template_id("template-id")
          .build_template_delete_request())

response = ms.templates.delete_template(request)

More examples

package main

import (
	"context"
	"log"
	"time"
	
	"github.com/mailersend/mailersend-go"
)

var APIKey = "Api Key Here"

func main() {
	// Create an instance of the mailersend client
	ms := mailersend.NewMailersend(APIKey)

	ctx := context.Background()
	ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
	defer cancel()

	templateID := "template-id"
	
	_, err := ms.Template.Delete(ctx, templateID)
	if err != nil {
		log.Fatal(err)
	}
}

More examples

import com.mailersend.sdk.MailerSend;
import com.mailersend.sdk.MailerSendResponse;
import com.mailersend.sdk.exceptions.MailerSendException;
import com.mailersend.sdk.templates.Template;
import com.mailersend.sdk.templates.TemplateItem;
import com.mailersend.sdk.templates.TemplatesList;

public void deleteTemplate() {
    
    MailerSend ms = new MailerSend();
    ms.setToken("mailersend token");
    
    try {
        
            MailerSendResponse response = ms.templates().deleteTemplate("template id");
            
            System.out.println(response.responseStatusCode);
        
    } catch (MailerSendException e) {
        
        e.printStackTrace();
    }
}

More examples

require "mailersend-ruby"

ms_client = Mailersend::Client.new('your_mailersend_token')

ms_templates = Mailersend::Templates.new(ms_client)
ms_templates.delete(template_id: "id124")

More examples

Responses

Valid

Response Code: 200 OK
Response Body: [EMPTY]

Error

Response Code: 404 Not Found

Email Survey Templates

Using our drag-and-drop email builder, you may create email templates with a survey block to ask questions and reviews to your recipients. When your recipient receives an email with a survey, they can preview the email and answer your survey questions. Then the responses are sent to your webhook if available.

When a recipient answers all available survey questions the responses are immediately sent to your webhook(if available). However, when a recipient doesn't completely answer all available questions, after an idle time of 30 minutes, the responses would be sent.

Rules and steps for sending an email with a survey include:

  • You cannot use the following variables {{url}}, {{survey}}, {{survey_last_question}}, as they are reserved.
  • You must enable content_tracking on your domain by selecting your domain and enabling the setting under tracking details. Content tracking is a feature available on Starter plans and above.
  • Add a webhook with the activity.survey_submitted event to receive the survey answers.
  • You can also include the activity.survey_opened event in your webhook to know when a recipient has opened an email containing a survey at least once.

Payloads

Example of activity.survey_submitted data sent to your webhook:

{
    "type": "activity.survey_submitted",
    "created_at": "2025-08-06T00:20:36.589903Z",
    "data": {
        "id": "68929fd47f916891ef12eba9",
        "domain_id": "7nxe3yjmeq28vp0k",
        "message_id": "68929fd402fd7079a02cf858",
        "email_id": "68929fd47f916891ef12eba9",
        "type": "survey_submitted",
        "subject": "Test email",
        "from": "test@domain.com",
        "tags": [
            "test2",
            "test3"
        ],
        "meta": {
            "surveys": [
                {
                    "question_id": 1,
                    "survey_id": 1,
                    "answer": "test",
                    "is_last_question": true
                }
            ]
        }
    }
}

On this page