Batch send customised transactional emails

When should I use this functionality ?

Let's say you would like to compose a series of transactional messages which use the same transactional template but with dynamic content each. You don't need to call the Send a Transactional Email endpoint multiple times for every version you create, you can instead define up to 1000 message versions within the same single request.

There's two common approaches when it comes to defining the API request to batch send email.


📘

Bulk Sending Limits

  • You can send up to 1000 email messages in one single API call.
  • You can execute the transactional API endpoint making use of the messageVersions parameter up to 6000 times per hour ( or 100 times per minute )

What does this mean?

You can call this endpoint 6000 times per hour. Each time you call it you can define up to 1000 versions to be sent out in a single call.

This means you're allowed to send up to 6 000 000 email versions in one hour.



Use custom HTML for each message version.

Define your base HTML content

You will need to start by defining a base HTML code which you will later modify if necessary.

<!DOCTYPE html>
<html>
<body>

<h1>My First Heading</h1>
<p>My first paragraph.</p>

</body>
</html>

Creating the API Call with HTML content

We will now create the payload for 2 different versions of the base HTML code we just created. Each one of them will be defined in a single API request. It would look like this:


Request

curl --request POST \
  --url https://api.brevo.com/v3/smtp/email \
  --header 'accept: application/json' \
  --header 'api-key: xxxxxxxxxx' \
  --header 'content-type: application/json'
  --data ...



Payload

{
   "sender":{
      "email":"[email protected]",
      "name":"Brevo"
   },
   "subject":"This is my default subject line",
   "htmlContent":"<!DOCTYPE html><html><body><h1>My First Heading</h1><p>My first paragraph.</p></body></html>",
   "messageVersions":[
     //Definition for Message Version 1 
     {
         "to":[
            {
               "email":"[email protected]",
               "name":"Bob Anderson"
            },
            {
               "email":"[email protected]",
               "name":"Anne Smith"
            }
         ],
         "htmlContent":"<!DOCTYPE html><html><body><h1>Modified header!</h1><p>This is still a paragraph</p></body></html>",
         "subject":"We are happy to be working with you"
      },
     
     // Definition for Message Version 2
      {
         "to":[
            {
               "email":"[email protected]",
               "name":"Jim Stevens"
            },
            {
               "email":"[email protected]",
               "name":"Mark Payton"
            },
            {
               "email":"[email protected]",
               "name":"Andrea Wallace"
            }
         ]
      }
   ]
}

📘

Notes

  • Be sure not to pass an outer to parameter. Every recipient (or every set of recipients) should be defined inside each message version.

  • If you look closely, we have set outside the scope of the messageVersions object global values for subject and params . These will be the default if they are not re defined inside a message version.

  • For this example we have overridden the value of these variables in such way that for each node inside messageVersion there's a dynamic definition for them.

In the same way you can re define other common used variables such as:

  • cc
  • bcc
  • replyTo
  • subject
  • params
  • htmlContent

The results

From the previous call, we will get as a result two message versions with different HTML content. They should look like this:




Message Version 1


To: Bob, Anne
From: Brevo
Subject : We are happy to be working with you




Message Version 2


To: Jim, Mark, Andrea
From: Brevo
Subject : This is my default subject line

Embedding variables in HTML

You can also use the params object in each version to dynamically modify your HTML variables. Think of it as an HTML templating language. See the request example below.

{
   "sender":{
      "email":"[email protected]",
      "name":"Brevo"
   },
   "subject":"This is my default subject line",
   "htmlContent":"<!DOCTYPE html><html><body><p>{{params.paragraphText}}</p></body></html>",
   "messageVersions":[
     //Definition for Message Version 1 
     {
         "to":[
            {
               "email":"[email protected]",
               "name":"Bob Anderson"
            },
            {
               "email":"[email protected]",
               "name":"Anne Smith"
            }
         ],
         "params":{
           "paragraphText" :"this is the text for the paragraph section"
         }
         "subject":"We are happy to be working with you"
      },



Check the step-by-step recipe:



Using a customised email template from Brevo.

Creating a transactional template

In order to create multiple message versions we will need in the first place a transactional template which will be later dynamically defined in the API call. Let's overview how to get our template.

  1. Head to your "Templates" under your Transactional tab and hit "New Template" in the upper right corner.
New Template Button

New Template Button



  1. Now we will need to define some default variables for our template. For our purpose, we will just need to add a value to Template Name and Subject Line.



  1. Once we have our template we can work on its design. Here we will set which parts of the template can be dynamic and customizable when building our API call.




We will now change the titles on this template so that we can override them in our API call. The placeholders should also be set to this format: {{ params.<variableName> }}

That's it ! Click on "Save and Activate" in the upper right corner.

You will be redirected to the templates list. Ours should be at the top of the list with an ID (#27). You can copy it, we will need it to build our API call.

📘

Templates using contact attributes.

Please note that the template placeholders using the contact object will always fetch the property value out of your contact database. It can't be defined via API through the {{params}} object.



Creating the API Call with a template id

We will now create the payload for 2 different versions of the template we just created. Each one of them will be defined in a single API request. It would look like this:


Request

curl --request POST \
  --url https://api.brevo.com/v3/smtp/email \
  --header 'accept: application/json' \
  --header 'api-key: xxxxxxxxxx' \
  --header 'content-type: application/json'
  --data ...




Payload

{
   "sender":{
      "email":"[email protected]",
      "name":"Brevo"
   },
   "subject":"This is my default subject line",
   "templateId":27,
   "params":{
      "greeting":"This is my default greeting",
      "headline":"This is my default headline"
   },
   "messageVersions":[
     
     //Definition for Message Version 1 
     {
         "to":[
            {
               "email":"[email protected]",
               "name":"Bob Anderson"
            },
            {
               "email":"[email protected]",
               "name":"Anne Smith"
            }
         ],
         "params":{
            "greeting":"Welcome onboard!",
            "headline":"Be Ready for Takeoff."
         },
         "subject":"We are happy to be working with you"
      },
     
     // Definition for Message Version 2
      {
         "to":[
            {
               "email":"[email protected]",
               "name":"Jim Stevens"
            },
            {
               "email":"[email protected]",
               "name":"Mark Payton"
            },
            {
               "email":"[email protected]",
               "name":"Andrea Wallace"
            }
         ],
         "params":{
            "greeting":"Hello there..."
         }
      }
   ]
}

Be sure not to pass an outer to parameter. Every list of recipients should be defined inside each message version.

If you look closely, we have set outside the scope of the messageVersions object global values for subject and params . These will be the default if they are not re defined inside a message version.

For this example we have overridden the value of these variables in such way that for each node inside messageVersion there's a dynamic definition for them.

In the same way you can re define other common used variables such as:

  • cc
  • bcc
  • replyTo
  • subject
  • params
  • htmlContent

📘

Transactional Attributes

params will always be a custom object where you can define all your transactional attributes. These are the ones which will be later rendered inside the template. For our example we defined as transactional attributes:

  • {{ params.heading }}
  • {{ params.greetings }}

After the call is successfully completed you will get a response containing a list of messageId 's. They match with the number of Message Versions you define in your call.

With these identifiers you can check your transactional logs or webhooks and check the status of your messages.


Response

{
    "messageIds": [
         "[email protected]", // message version 1
         "[email protected]"  // message version 2
    ]
}



The results

From the previous call, we will get as a result two template versions for templateId #27 . They should look like this:




Message Version 1


To: Bob, Anne
From: Brevo
Subject : We are happy to be working with you




Message Version 2


To: Jim, Mark, Andrea
From: Brevo
Subject : This is my default subject line



Check the step-by-step recipe: