MailerSend
Email API

Analytics

Track the performance of your transactional emails with MailerSend's Analytics API endpoint. Discover opens by country, email activity and more.

With these requests, get analytics on the activity of your emails like open rate, CTR, bounce rate, and other data for a dedicated list of recipients, domain names, or even tags.

Note on data retention

Analytics data is stored for up to 6 months.

Activity data by date

Retrieve data grouped by date, based on activity, with this GET request:

GET https://api.mailersend.com/v1/analytics/date

Request parameters

Query parameterTypeRequiredLimitationsDetails
domain_idstringno
recipient_id[]stringnoMax number of recipients: 50 TBDNot yet implemented
date_fromintyesTimestamp is assumed to be UTC. Must be lower than date_to.Format: 1443651141
date_tointyesTimestamp is assumed to be UTC. Must be higher than date_from.Format: 1443661141
group_bystringnoPossible options: days, weeks, months, yearsDefault: days
tags[]string[]no
event[]string[]noPossible types: queued,sent,delivered,soft_bounced,
hard_bounced,deferred,opened,clicked,unsubscribed,
spam_complaints,survey_opened, survey_submitted,opened_unique,clicked_unique
use MailerSend\MailerSend;
use MailerSend\Helpers\Builder\ActivityAnalyticsParams;
use MailerSend\Common\Constants;

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

$activityAnalyticsParams = (new ActivityAnalyticsParams(100, 101))
                    ->setDomainId('domain_id')
                    ->setGroupBy(Constants::GROUP_BY_DAYS)
                    ->setTags(['tag'])
                    ->setEvent(['sent', 'delivered']);

$mailersend->analytics->activityDataByDate($activityAnalyticsParams);

More examples

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

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

mailerSend.email.analytics.byDate({
  date_from: 1443651141,
  date_to: 2443651141,
  event: [ActivityEventType.CLICKED, ActivityEventType.OPENED],
}).then(response => {
  console.log(response.body);
}).catch(error => {
  console.log(error.body);
});

More examples

from mailersend import MailerSendClient, AnalyticsBuilder
from datetime import datetime, timedelta

ms = MailerSendClient()

date_from = int((datetime.now() - timedelta(days=30)).timestamp())
date_to = int(datetime.now().timestamp())

request = (AnalyticsBuilder()
          .date_from(date_from)
          .date_to(date_to)
          .events("sent", "delivered", "opened")
          .domain_id("domain-id")
          .group_by("days")
          .build())

response = ms.analytics.get_activity_by_date(request)
for stat in response.data:
    print(f"Date: {stat.date}, Sent: {stat.sent}, Delivered: {stat.delivered}")

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()

	from := time.Now().Add(-24 * time.Hour).Unix()
	to := time.Now().Unix()
	domainID := "domain-id"
	events := []string{"sent", "queued", "delivered"}

	options := &mailersend.AnalyticsOptions{
		DomainID:    domainID,
		DateFrom:    from,
		DateTo:      to,
		Event:       events,
	}

	_, _, err := ms.Analytics.GetActivityByDate(ctx, options)
	if err != nil {
		log.Fatal(err)
	}
}

More examples

import java.util.Date;
import com.mailersend.sdk.MailerSend;
import com.mailersend.sdk.analytics.AnalyticsByDate;
import com.mailersend.sdk.analytics.AnalyticsByDateList;
import com.mailersend.sdk.analytics.AnalyticsList;
import com.mailersend.sdk.analytics.AnalyticsStatistic;
import com.mailersend.sdk.exceptions.MailerSendException;
import com.mailersend.sdk.util.EventTypes;

public void getAnalyticsByDate() {

    MailerSend ms = new MailerSend();
    ms.setToken(TestHelper.validToken);
    
    try {
        
        Date dateFrom = new Date(); // set your from date normally
        
        AnalyticsByDateList list = ms.analytics()
                .dateFrom(dateFrom)
                .dateTo(new Date())
                .domainId(TestHelper.domainId)
                .getByDate(new String[] {EventTypes.DELIVERED, EventTypes.OPENED, EventTypes.CLICKED});
        
        System.out.println("\n\nAnalytics by date for domain:");
        for (AnalyticsByDate dayStat : list.statistics) {
            
            System.out.println(dayStat.statDate.toString());
            System.out.println(dayStat.delivered);
            System.out.println(dayStat.opened);
            System.out.println(dayStat.clicked);
                            
        }
        
    } catch (MailerSendException e) {
        
        e.printStackTrace();
    }
}

More examples

require "mailersend-ruby"

ms_analytics = Mailersend::Analytics.new
ms_analytics.date(date_from: 1620643567, date_to: 1623321967, events: %w[sent queued])

More examples

Responses

Response keyTypeDetails
data.stats.*.datetimestampThe date will be at the start of the group_by unit (so start of day/week/month/year). Every date in the date range will be present, even if there are no events for that day.
data.stats.*.[event]intEvery queried event[] will be present in the response with a default value - 0

Valid

Response Code: 200 OK
Response Headers:
	content-type: application/json
{
  "data": {
    "date_from": "1591228800",
    "date_to": "1591401599",
    "group_by": "days",
    "stats": [
      {
        "date": "1591228800",
        "queued": 0,
        "sent": 0,
        "delivered": 0,
        "opened": 0,
        "clicked": 0,
        "soft_bounced": 0,
        "hard_bounced": 0,
        "unsubscribed": 0,
        "spam_complaints": 0,
        "opened_unique": 0,
        "clicked_unique": 0,
	"survey_opened":0,
	"survey_submitted":0
      },
      {
        "date": "1591315200",
        "queued": 0,
        "sent": 0,
        "delivered": 0,
        "opened": 0,
        "clicked": 0,
        "soft_bounced": 0,
        "hard_bounced": 0,
        "unsubscribed": 0,
        "spam_complaints": 0,
        "opened_unique": 0,
        "clicked_unique": 0,
	"survey_opened":0,
	"survey_submitted":0
      }
    ]
  }
}

Error

Response Code: 422 Unprocessable Entity

See - Validation errors

Opens by country

Retrieve data grouped by country, based on activity, with this GET request:

GET https://api.mailersend.com/v1/analytics/country

Request parameters

Query parameterTypeRequiredLimitationsDetails
domain_idstringno
recipient_id[]stringnoMax number of recipients: 50 TBDNot yet implemented
date_fromintyesTimestamp is assumed to be UTC. Must be lower than date_to.Format: 1443651141
date_tointyesTimestamp is assumed to be UTC. Must be higher than date_from.Format: 1443661141
tags[]string[]no
use MailerSend\MailerSend;
use MailerSend\Helpers\Builder\OpensAnalyticsParams;

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

$opensAnalyticsParams = (new OpensAnalyticsParams(100, 101))
                    ->setDomainId('domain_id')
                    ->setTags(['tag']);

$mailersend->analytics->opensByCountry($opensAnalyticsParams);

More examples

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

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

mailerSend.email.analytics.byCountry({
  date_from: 1443651141,
  date_to: 2443651141,
}).then(response => {
  console.log(response.body);
}).catch(error => {
  console.log(error.body);
});

More examples

from mailersend import MailerSendClient, AnalyticsBuilder
from datetime import datetime, timedelta

ms = MailerSendClient()

date_from = int((datetime.now() - timedelta(days=30)).timestamp())
date_to = int(datetime.now().timestamp())

request = (AnalyticsBuilder()
          .date_from(date_from)
          .date_to(date_to)
          .domain_id("domain-id")
          .build())

response = ms.analytics.get_opens_by_country(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()

	from := time.Now().Add(-24 * time.Hour).Unix()
	to := time.Now().Unix()
	domainID := "domain-id"

	options := &mailersend.AnalyticsOptions{
		DomainID: domainID,
		DateFrom: from,
		DateTo:   to,
	}

	_, _, err := ms.Analytics.GetOpensByCountry(ctx, options)
	if err != nil {
		log.Fatal(err)
	}
}

More examples

import java.util.Date;
import com.mailersend.sdk.MailerSend;
import com.mailersend.sdk.analytics.AnalyticsList;
import com.mailersend.sdk.analytics.AnalyticsStatistic;
import com.mailersend.sdk.exceptions.MailerSendException;

public void getOpensByCountry() {

    MailerSend ms = new MailerSend();
    ms.setToken(TestHelper.validToken);
    
    try {
        
        Date dateFrom = new Date(); // set your from date normally
        
        AnalyticsList list = ms.analytics()
                .dateFrom(dateFrom)
                .dateTo(new Date())
                .domainId(TestHelper.domainId)
                .getOpensByCountry();
        
        System.out.println("\n\nOpens by country:");
        
        for (AnalyticsStatistic stat : list.statistics) {
            
            System.out.println(stat.name + " - " + stat.count);
        }
                
    } catch (MailerSendException e) {
        
        e.printStackTrace();
    }
}

More examples

require "mailersend-ruby"

ms_analytics = Mailersend::Analytics.new
ms_analytics.country(date_from: 1620643567, date_to: 1623321967)

More examples

Responses

Response keyTypeDetails
data.stats.*.namestring2 Letter code of the country. Will not be present if there's no data.
data.stats.*.countint

Valid

Response Code: 200 OK
Response Headers:
	content-type: application/json
{
  "data": {
    "date_from": 1591228800,
    "date_to": 1591401599,
    "stats": [
      {
        "name": "LT",
        "count": 2
      }
    ]
  }
}

Error

Response Code: 422 Unprocessable Entity

See - Validation errors

Opens by user-agent name

Retrieve data grouped by user-agent name (browser and operating system), based on activity, with this GET request:

GET https://api.mailersend.com/v1/analytics/ua-name

Request parameters

Query parameterTypeRequiredLimitationsDetails
domain_idstringno
recipient_id[]stringnoMax number of recipients: 50 TBDNot yet implemented
date_fromintyesTimestamp is assumed to be UTC. Must be lower than date_to.Format: 1443651141
date_tointyesTimestamp is assumed to be UTC. Must be higher than date_from.Format: 1443661141
tags[]string[]no
use MailerSend\MailerSend;
use MailerSend\Helpers\Builder\OpensAnalyticsParams;

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

$opensAnalyticsParams = (new OpensAnalyticsParams(100, 101))
                    ->setDomainId('domain_id')
                    ->setTags(['tag']);

$mailersend->analytics->opensByUserAgentName($opensAnalyticsParams);

More examples

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

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

mailerSend.email.analytics.byUserAgent({
  date_from: 1443651141,
  date_to: 2443651141,
}).then(response => {
  console.log(response.body);
}).catch(error => {
  console.log(error.body);
});

More examples

from mailersend import MailerSendClient, AnalyticsBuilder
from datetime import datetime, timedelta

ms = MailerSendClient()

date_from = int((datetime.now() - timedelta(days=30)).timestamp())
date_to = int(datetime.now().timestamp())

request = (AnalyticsBuilder()
          .date_from(date_from)
          .date_to(date_to)
          .domain_id("domain-id")
          .build())

response = ms.analytics.get_opens_by_user_agent(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()

	from := time.Now().Add(-24 * time.Hour).Unix()
	to := time.Now().Unix()
	domainID := "domain-id"

	options := &mailersend.AnalyticsOptions{
		DomainID: domainID,
		DateFrom: from,
		DateTo:   to,
	}

	_, _, err := ms.Analytics.GetOpensByUserAgent(ctx, options)
	if err != nil {
		log.Fatal(err)
	}
}

More examples

import java.util.Date;
import com.mailersend.sdk.MailerSend;
import com.mailersend.sdk.analytics.AnalyticsList;
import com.mailersend.sdk.analytics.AnalyticsStatistic;
import com.mailersend.sdk.exceptions.MailerSendException;

public void getOpensByUserAgentName() {

    MailerSend ms = new MailerSend();
    ms.setToken(TestHelper.validToken);
    
    try {
        
        Date dateFrom = new Date(); // set your from date normally
        
        AnalyticsList list = ms.analytics()
                .dateFrom(dateFrom)
                .dateTo(new Date())
                .getOpensByUserAgent();
        
        System.out.println("\n\nOpens by user agent:");
        
        for (AnalyticsStatistic stat : list.statistics) {
            
            System.out.println(stat.name + " - " + stat.count);
        }
                
    } catch (MailerSendException e) {
        
        e.printStackTrace();
    }
}

More examples

from mailersend import analytics

api_key = "API key here"

mailer = analytics.NewAnalytics(api_key)

date_from = 1623073576
date_to = 1623074976

# optional arguments
domain_id = "domain-id"

mailer.get_opens_by_user_agent(date_from, date_to, domain_id)

More examples

Responses

Response keyTypeDetails
data.stats.*.namestringUser Agent Name. Will not be present if there's no data.
data.stats.*.countint

Valid

Response Code: 200 OK
Response Headers:
	content-type: application/json
{
  "data": {
    "date_from": 1591228800,
    "date_to": 1591401599,
    "stats": [
      {
        "name": "Chrome",
        "count": 2
      }
    ]
  }
}

Error

Response Code: 422 Unprocessable Entity

See - Validation errors

Opens by reading environment

Retrieve data grouped by the reading environment (webmail, mobile, desktop), based on activity, with this GET request:

GET https://api.mailersend.com/v1/analytics/ua-type

Request parameters

Query parameterTypeRequiredLimitationsDetails
domain_idstringno
recipient_id[]stringnoMax number of recipients: 50 TBDNot yet implemented
date_fromintyesTimestamp is assumed to be UTC. Must be lower than date_to.Format: 1443651141
date_tointyesTimestamp is assumed to be UTC. Must be higher than date_from.Format: 1443661141
tags[]string[]no
use MailerSend\MailerSend;
use MailerSend\Helpers\Builder\OpensAnalyticsParams;

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

$opensAnalyticsParams = (new OpensAnalyticsParams(100, 101))
                    ->setDomainId('domain_id')
                    ->setTags(['tag']);

$mailersend->analytics->opensByReadingEnvironment($opensAnalyticsParams);

More examples

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

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

mailerSend.email.analytics.byReadingEnvironment({
  date_from: 1443651141,
  date_to: 2443651141,
}).then(response => {
  console.log(response.body);
}).catch(error => {
  console.log(error.body);
});

More examples

from mailersend import MailerSendClient, AnalyticsBuilder
from datetime import datetime, timedelta

ms = MailerSendClient()

date_from = int((datetime.now() - timedelta(days=30)).timestamp())
date_to = int(datetime.now().timestamp())

request = (AnalyticsBuilder()
          .date_from(date_from)
          .date_to(date_to)
          .domain_id("domain-id")
          .build())

response = ms.analytics.get_opens_by_reading_environment(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()

	from := time.Now().Add(-24 * time.Hour).Unix()
	to := time.Now().Unix()
	domainID := "domain-id"

	options := &mailersend.AnalyticsOptions{
		DomainID: domainID,
		DateFrom: from,
		DateTo:   to,
	}

	_, _, err := ms.Analytics.GetOpensByReadingEnvironment(ctx, options)
	if err != nil {
		log.Fatal(err)
	}
}

More examples

import java.util.Date;
import com.mailersend.sdk.MailerSend;
import com.mailersend.sdk.analytics.AnalyticsList;
import com.mailersend.sdk.analytics.AnalyticsStatistic;
import com.mailersend.sdk.exceptions.MailerSendException;

public void getOpensByUserAgentType() {

    MailerSend ms = new MailerSend();
    ms.setToken(TestHelper.validToken);
    
    try {
        
        Date dateFrom = new Date(); // set your from date normally
        
        AnalyticsList list = ms.analytics()
                .dateFrom(dateFrom)
                .dateTo(new Date())
                .getOpensByUserAgenType();
        
        System.out.println("\n\nOpens by user agent type:");
        
        for (AnalyticsStatistic stat : list.statistics) {
            
            System.out.println(stat.name + " - " + stat.count);
        }
                
    } catch (MailerSendException e) {
        
        e.printStackTrace();
    }
}

More examples

require "mailersend-ruby"

ms_analytics = Mailersend::Analytics.new
ms_analytics.ua_type(date_from: 1620643567, date_to: 1623321967)

More examples

Responses

Response keyTypeDetails
data.stats.*.namestringOne of webmail, mobile,desktop. Will not be present if there's no data.
data.stats.*.countint

Valid

Response Code: 200 OK
Response Headers:
	content-type: application/json
{
  "data": {
    "date_from": 1591228800,
    "date_to": 1591401599,
    "stats": [
      {
        "name": "webmail",
        "count": 2
      },
      {
        "name": "mobile",
        "count": 2
      },
      {
        "name": "desktop",
        "count": 2
      }
    ]
  }
}

Error

Response Code: 422 Unprocessable Entity

See - Validation errors

On this page