Message tracking
The Nylas API offers several ways to track different types of actions that may happen to a message or thread. You can track:
- Links clicked
- Message opened
- Thread replied
Nylas sends a webhook notification to your server when these actions occur. If you haven't set up webhooks yet, review our webhooks documentation. Make sure you enable the triggers you want to be notified about from your developer dashboard before you send a message with tracking enabled.
Nylas detects an email has been read by embedding an image pixel into the message HTML. The image pixel needs to be downloaded for Nylas to detect that the message was opened. Only the initial download is tracked.
There are three different ways you can track a message or thread, and you can use any combination of these tracking features. All you have to do is include a tracking attribute when you send a message through the /send
endpoint.
How message tracking works
Once a user acts on a message that you've enabled tracking for (e.g., opening the message), Nylas will make a POST
request to your webhook endpoint, with delta information about the action that occurred.
The object_data
will contain a metadata
sub-attribute that has information about the action. To see the more general structure of the webhook notification, see Webhooks
Enabling tracking
To enable tracking for a message, include a tracking
attribute with the other attributes when you send a message. You can include the tracking object when you send a draft or when you send a message directly.
The Tracking object
Attribute | Type | Description |
---|---|---|
links | boolean | True enables link tracking. |
opens | boolean | True enables message open tracking. |
thread_replies | boolean | True enables thread reply tracking. |
payload | string | An optional string that allows you to keep track of additional information. This string will be included in the webhook notification. |
curl -X POST -H "Authorization: Basic <access_token>" -d '{
"reply_to_message_id": "84umizq7c4jtrew491brpa6iu",
"body" : "Please click this: <a href='https://nylas.com/'>click</a>",
"subject": "New Site",
"to": [
{
"name": "Nylas",
"email": "[email protected]"
}
],
"tracking": {
"links": true,
"opens": true,
"thread_replies": false,
"payload": "Any string you want!!"
}
}' "https://api.nylas.com/send"
from nylas import APIClient
# Initialize and connect to the Nylas client
nylas = APIClient(
CLIENT_ID,
CLIENT_SECRET,
ACCESS_TOKEN
)
# If the draft has not been created
# Create a draft with a tracking object
draft = nylas.drafts.create()
draft.subject = "With Love, from Nylas"
draft.body = "This email was sent using the Nylas Email API. Visit https://nylas.com for details."
draft.to = [{'name': 'Me', 'email': '[email protected]'}]
draft.tracking = {"links": 'true', "opens": 'true', "thread_replies": 'true', "payload": "payload"}
# Send the draft
draft.send()
# Or, if the draft already exists
# Just add the tracking object to the existing draft object
draft = nylas.drafts.get(draft.id)
draft.tracking = {"links": 'true', "opens": 'true', "thread_replies": 'true', "payload": "payload"}
# Send the draft
draft.send()
import com.nylas.NylasClient;
import com.nylas.NylasAccount;
import com.nylas.Tracking;
import com.nylas.Draft;
import com.nylas.NameEmail;
import java.util.Arrays;
public class NylasExamples {
public static void messageTrackingExample() throws Exception {
// Initialize and connect to the Nylas client
NylasClient nylas = new NylasClient();
NylasAccount account = nylas.account("ACCESS_TOKEN");
// If the draft has not been created
Draft draft = new Draft();
draft.setSubject("With Love, From Nylas");
draft.setTo(Arrays.asList(new NameEmail("Nylas", "[email protected]")));
draft.setBody("This email was sent using the Nylas email API. Visit https://nylas.com for details.");
// Create the tracking object and add it to the draft
Tracking tracking = new Tracking();
tracking.setOpens(true);
tracking.setLinks(true);
tracking.setThreadReplies(true);
tracking.setPayload("payload");
draft.setTracking(tracking);
// Send the draft
account.drafts().send(draft);
// Or, if the draft already exists
// Just add the tracking object to the existing draft object
Draft draft = account.drafts().get("draft-id");
draft.setTracking(tracking);
// Send the draft
account.drafts().send(draft);
}
}
const Nylas = require('nylas');
const { default: Draft } = require('nylas/lib/models/draft');
// Initialize and connect to the Nylas client
Nylas.config({
clientId: CLIENT_ID,
clientSecret: CLIENT_SECRET
});
const nylas = Nylas.with(ACCESS_TOKEN);
// If the draft has not been created
let draft = new Draft(nylas, {
subject: 'With Love, from Nylas',
to: [{ name: 'Nylas', email: '[email protected]' }],
body: 'This email was sent using the Nylas email API. Visit https://nylas.com for details.'
});
// Create the tracking object
const tracking = { "links": true, "opens": true, "thread_replies": true, "payload": "payload" };
// Send the new draft with the tracking object passed in as an argument
draft.send(tracking).then(message => {
console.log(`${message.id} was sent`);
});
// Or, if the draft already exists
draft = nylas.drafts.find('draft-id');
// Send the existing draft with the tracking object passed in as an argument
draft.send(tracking).then(message => {
console.log(`${message.id} was sent`);
});
#!/usr/bin/env ruby
require 'nylas'
# Initialize and connect to the Nylas client
nylas = Nylas::API.new(
app_id: CLIENT_ID,
app_secret: CLIENT_SECRET,
access_token: ACCESS_TOKEN
)
# If the draft has not been created
# Create a draft with a tracking object
draft = nylas.drafts.create(
to: [{ email: '[email protected]', name: "Nylas" }],
subject: 'With Love, from Nylas',
body: 'This email was sent using the Nylas email API. Visit https://nylas.com for details.',
tracking: { "links": true, "opens": true, "thread_replies": true }
)
# Send the draft
draft.send!
# Or, if the draft already exists
# Just add the tracking object to the existing draft object
draft = nylas.drafts.find('draft-id')
draft.tracking = { "links": true, "opens": true, "thread_replies": true, "payload": "payload" }
# Send the draft
draft.send!
Link clicked
When you send a message with link tracking enabled, Nylas notifies you when a recipient clicks on tracked links in that message.
To enable link tracking for a message, set links
to true
in the tracking
attribute, when sending the message through the /send
endpoint.
Link formatting
To set up a link so Nylas can track it, you must use a valid URI scheme and wrap the link in HTML <a></a>
tags.
Nylas supports the following URI schemes:
http
https
mailto
tel
The link must also be wrapped in HTML <a></a>
tags so that Nylas can detect the links to track. Most email clients automatically detect items that look like links, such as 10.0.0.1
, tel:5402502334
, or apple.com
, and render them as clickable, so it's easy to get out of the habit of writing correct HTML. However, links must be formatted with the correct HTML <a></a>
tags before you make a request to /send
.
The following are examples of valid links that Nylas can detect and track.
<a href="https://www.google.com">google.com</a>
<a href="mailto:[email protected]">Mailto Nyla!</a>
The examples below are malformed or invalid links that cannot be tracked
<a>www.google.com</a>
<a href="zoommtg://zoom.us/join?confno=12345">Join a zoom conference</a>
Invalid and malformed links are not replaced with a tracking link, and are left as written.
Link tracking best practices
When link tracking is enabled, Nylas rewrites all valid HTML links with a new URL that allows tracking. This rewrite process prevents tracking links with embedded login credentials, because the destination servers don't recognize the rewritten credentials.
Nylas ignores links that contain credentials. This means that the links still work as expected, however this means that link tracking does not work for these links.
For example, private Google Form URLs contain login credentials, so Nylas ignores the link and it cannot be tracked.
Link Clicked send example
...
"to": [
{
"email": "[email protected]",
"name": "Nylas personal"
}
],
"tracking": {
"links": true,
"opens": true,
"thread_replies": true,
"payload": "Tracking enabled"
},
"subject": "email index"
...
Link Clicked Response Example
{
"deltas": [
{
"date": 1471630848,
"type": "message.link_clicked",
"object": "metadata",
"object_data": {
"object": "metadata",
"id": "NYLAS_METADATA_ID",
"account_id": "EMAIL_ACCOUNT_ID",
"metadata": {
"sender_app_id": "SENDER_APP_ID",
"link_data": [
{"url": "apple.com", "count": 2},
{"url": "apple.com", "count": 0},
{"url": "nylas.com", "count": 10},
],
"payload": "hello world",
"message_id": "NYLAS_MESSAGE_ID",
"recents": [{
"id:" 0,
"ip": "0.0.0.0",
"user_agent": "chrome",
"link_index": 2
}, ...]
}
}
}
]
}
Learn More
Link tracking metadata.
Recents Array
The recents
field contains the last 50 events. These have IDs in order to help parse which events have already been processed. The IDs are only unique within a particular recents
array, and there is a separate recents
array for each message/trigger pair. For example, opening message A, clicking on a link in message A, and opening message B will all have an id
of 0. Opening message A again will have an id
of 1.
Errors in Message Tracking
A message with link tracking enabled that has too many links tracked in it may fail to send. If this occurs, disable link tracking to send the message.
The error message returned is:
The message has not been sent. Link tracking cannot be supported for this number of links and/or size of payload. Please try resending with link tracking disabled.
If a message with either Open or Reply tracking cannot handle the metadata object's size in the message, for example, the payload
value is too big. If this occurs, disable tracking to send the message. One of the following error messages will be returned:
The message has not been sent. Please try resending with open tracking disabled.
The message has not been sent. Please try resending with reply tracking disabled.
Open Tracking
When you send a message with open tracking enabled, you will be notified whenever any of the recipients open that message. Opened messages are tracked by embedding 1x1 pixel image in the email. The message.opened
webhook is triggered when the image is loaded.
To enable open tracking for a message, set opens
to true
in the tracking
attribute when sending the message through the /send
endpoint.
See the webhook information about the Message Opened endpoint
Tip: CDN and caching behavior can change how Message Opened webhooks behave. See Troubleshooting immediate webhook notifications for more information.
Open Tracking Send Example
...
"to": [
{
"email": "[email protected]",
"name": "Nylas personal"
}
],
"tracking": {
"links": true,
"opens": true,
"thread_replies": true,
"payload": "Tracking enabled"
},
"subject": "email index"
...
Open Tracking Response Example
{
"deltas": [
{
"date": 1471630848,
"type": "message.opened",
"object": "metadata",
"object_data": {
"object": "metadata",
"id": "NYLAS_METADATA_ID",
"account_id": "EMAIL_ACCOUNT_ID",
"metadata": {
"sender_app_id": "SENDER_APP_ID",
"count": "OPEN_COUNT",
"payload": "{myCustom: 'data'}",
"message_id": "NYLAS_MESSAGE_ID",
"recents": [{
"id:" 0,
"ip": "0.0.0.0",
"user_agent": "chrome"
}, ...]
},
}
}
]
}
Thread Replied
When you send a message with reply tracking enabled, you will be notified whenever any corresponding thread participant responds to that thread. To enable reply tracking for a thread, set thread_replies
to true
in the tracking
attribute when sending the message through the /send
endpoint.
Thread Replied Send Example
...
"to": [
{
"email": "[email protected]",
"name": "Nylas personal"
}
],
"tracking": {
"links": true,
"opens": true,
"thread_replies": true,
"payload": "Tracking enabled"
},
"subject": "email index"
...
Thread Replied Response Example
{
"deltas": [
{
"date": 1471630848,
"type": "thread.replied",
"object": "metadata",
"object_data": {
"object": "metadata",
"id": "NYLAS_METADATA_ID",
"account_id": "EMAIL_ACCOUNT_ID",
"metadata": {
"sender_app_id": "SENDER_APP_ID",
"payload": "{myCustom: 'data'}",
"message_id": "NYLAS_MESSAGE_ID",
"reply_to_message_id": "NYLAS_REPLY_TO_MESSAGE_ID",
"thread_id": "NYLAS_THREAD_ID",
"from_self": true,
"timestamp": 1471630848,
},
}
}
]
}
Scopes
You need to enable the email.metadata
, as it relies on tracking new messages coming in. Reply tracking cannot be implemented with send-only scope.
View the Nylas Scopes for the complete collection and the Authentication Scopes section for specific dependencies.
Learn More