Using the Nylas Email API
💡 Looking for the Email API references? You can find them here!
This page explains how to use the Nylas Email API. You'll learn how to do the following tasks:
- Read email messages from an account's inbox.
- Search for email messages.
- Update an email message's labels, file attachments, unread status, stars, folders, and more.
- Delete drafts, files, and folders.
How the Email API works
The Nylas Email API interacts with users' providers using their original SMTP/ActiveSync gateways. This means that when you make a Send Message request, for example, Nylas connects to the provider to send an email message as the user. Because of this, providers see the activity as the user sending a message, rather than an external platform making the request on the user's behalf.
Email messages sent through Nylas have very high deliverability, but might be subject to rate-limiting and abuse detection from the provider. See Improve email deliverability for more information and a list of best practices.
Provider IDs for messages
Nylas v3 uses an object's provider ID to refer to the object, and different providers return differently formatted IDs. For IMAP messages, Nylas extracts the ID from the message-id
header. For Google and Microsoft, the object ID comes from the provider's internal ID.
Before you begin
To follow along with the samples on this page, you first need to sign up for a Nylas developer account, which gets you a free Nylas application and API key.
For a guided introduction, you can follow the Getting started guide to set up a Nylas account and Sandbox application. When you have those, you can connect an account from a calendar provider (such as Google, Microsoft, or iCloud) and use your API key with the sample API calls on this page to access that account's data.
One-click unsubscribe requirements for Google messages
As of February 2024, Google requires that users who send more than 5,000 email messages per day to Gmail email addresses include one-click unsubscribe headers in each of their marketing and subscribed emails (see Google’s official Email sender guidelines). This is along with the visible unsubscribe links that must be in the body content of all marketing and subscribed email messages.
To set up one-click unsubscribe headers using Nylas, include the custom_headers
object in your Send Message or Create Draft request. This object accepts a set of key-value pairs, each of which represents the header’s name
and its value
. You must include the following headers:
List-Unsubscribe-Post
:List-Unsubscribe=One-Click
List-Unsubscribe
: The unsubscribe link (for example, amailto
link that uses the end user’s email address, or a link to your list management software).
"custom_headers":[
{
"name": "List-Unsubscribe-Post",
"value": "List-Unsubscribe=One-Click"
},
{
"name": "List-Unsubscribe",
"value": "<mailto: nyla@example.com?subject=unsubscribe>, <https://mailinglist.example.com/unsubscribe.html>"
}
]
Read email messages from inboxes
Messages are the fundamental object in the Nylas platform, and the core building block for most email applications. They contain several pieces of information, such as the message's timestamp, the sender's address, the recipients, and the body of the message. They can also contain file attachments, calendar invites, and more.
By default, the Messages endpoint returns the 50 most recent messages, but the following examples use the limit
parameter to reduce the number of results to five.
The following examples show how to return the five most recent email messages from an account's inbox by making a request to the Nylas Email API.
curl --request GET \
--url "https://api.us.nylas.com/v3/grants/<NYLAS_GRANT_ID>/messages?limit=5" \
--header 'Accept: application/json, application/gzip' \
--header 'Authorization: Bearer <NYLAS_API_KEY>' \
--header 'Content-Type: application/json'
{
"request_id": "d0c951b9-61db-4daa-ab19-cd44afeeabac",
"data": [
{
"starred": false,
"unread": true,
"folders": [
"UNREAD",
"CATEGORY_PERSONAL",
"INBOX"
],
"grant_id": "1",
"date": 1706811644,
"attachments": [
{
"id": "1",
"grant_id": "1",
"filename": "invite.ics",
"size": 2504,
"content_type": "text/calendar; charset=\"UTF-8\"; method=REQUEST"
},
{
"id": "2",
"grant_id": "1",
"filename": "invite.ics",
"size": 2504,
"content_type": "application/ics; name=\"invite.ics\"",
"is_inline": false,
"content_disposition": "attachment; filename=\"invite.ics\""
}
],
"from": [
{
"name": "Nylas DevRel",
"email": "nylasdev@nylas.com"
}
],
"id": "1",
"object": "message",
"snippet": "Send Email with Nylas APIs",
"subject": "Learn how to Send Email with Nylas APIs",
"thread_id": "1",
"to": [
{
"name": "Nyla",
"email": "nyla@nylas.com"
}
],
"created_at": 1706811644,
"body": "Learn how to send emails using the Nylas APIs!"
}
],
"next_cursor": "123"
}
Your users get a lot of email. If you encounter 429 errors or provider rate limits when listing all messages, try lowering your limit
and adding other parameters to reduce the number of messages returned.
You can also get email messages from your end users' inboxes using the Nylas SDKs.
from dotenv import load_dotenv
load_dotenv()
import os
import sys
from nylas import Client
nylas = Client(
os.environ.get('NYLAS_API_KEY'),
os.environ.get('NYLAS_API_URI')
)
grant_id = os.environ.get("NYLAS_GRANT_ID")
messages = nylas.messages.list(
grant_id,
query_params={
"limit": 5
}
)
print(messages)
app.get("/nylas/recent-emails", async (req, res) => {
try {
const identifier = process.env.USER_GRANT_ID;
const messages = await nylas.messages.list({
identifier,
queryParams: {
limit: 5,
},
});
res.json(messages);
} catch (error) {
console.error("Error fetching emails:", error);
}
});
require 'nylas'
nylas = Nylas::Client.new(api_key: '<NYLAS_API_KEY>')
query_params = { limit: 5 }
messages, _ = nylas.messages.list(identifier: '<NYLAS_GRANT_ID>', query_params: query_params)
messages.each {|message|
puts "[#{Time.at(message[:date]).strftime("%d/%m/%Y at %H:%M:%S")}] \
#{message[:subject]}"
}
import com.nylas.NylasClient;
import com.nylas.models.*;
import java.text.SimpleDateFormat;
public class ReadInbox {
public static void main(String[] args) throws NylasSdkTimeoutError, NylasApiError {
NylasClient nylas = new NylasClient.Builder("<NYLAS_API_KEY>").build();
ListMessagesQueryParams queryParams = new ListMessagesQueryParams.Builder().limit(5).build();
ListResponse<Message> message = nylas.messages().list("<NYLAS_GRANT_ID>", queryParams);
for(Message email : message.getData()) {
String date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").
format(new java.util.Date((email.getDate() * 1000L)));
System.out.println("[" + date + "] | " + email.getSubject());
}
}
}
import com.nylas.NylasClient
import com.nylas.models.*
import java.text.SimpleDateFormat
import java.util.*
fun dateFormatter(milliseconds: String): String {
return SimpleDateFormat("dd/MM/yyyy HH:mm:ss").format(Date(milliseconds.toLong() * 1000)).toString()
}
fun main(args: Array<String>) {
val nylas: NylasClient = NylasClient(apiKey = "<NYLAS_API_KEY>")
val queryParams = ListMessagesQueryParams(limit = 5, inFolder = listOf("Inbox"))
val messages : List<Message> = nylas.messages().list("<NYLAS_GRANT_ID>", queryParams).data
for(message in messages) {
println("[" + dateFormatter(message.date.toString()) + "] |" + message.subject + " | " + message.folders)
}
}
Search an inbox for email messages
In Nylas v3, you add query parameters to a Return all Messages request to search for email messages. For more information, see the Messages reference documentation.
⚠️ If you're using the in
query parameter on a Google account to filter for email messages with a specific folder ("label" in the Google UI), you must reference the folder ID. Nylas does not support filtering by folders using their name.
The following examples show how to search an end user's inbox for email messages using the Nylas SDKs.
import 'dotenv/config'
import Nylas from 'nylas'
const NylasConfig = {
apiKey: process.env.NYLAS_API_KEY,
apiUri: process.env.NYLAS_API_URI,
}
const nylas = new Nylas(NylasConfig)
async function searchInbox() {
try {
const result = await nylas.messages.list({
identifier: process.env.NYLAS_GRANT_ID,
queryParams: {
search_query_native: 'nylas',
limit: 5
}
})
console.log('search results:', result)
} catch (error) {
console.error('Error to complete search:', error)
}
}
searchInbox()
from dotenv import load_dotenv
load_dotenv()
import os
import sys
from nylas import Client
nylas = Client(
os.environ.get('NYLAS_API_KEY'),
os.environ.get('NYLAS_API_URI')
)
grant_id = os.environ.get("NYLAS_GRANT_ID")
messages = nylas.messages.list(
grant_id,
query_params={
"limit": 5,
"search_query_native": 'nylas'
}
)
print(messages)
require 'nylas'
nylas = Nylas::Client.new(api_key: '<NYLAS_API_KEY>')
query_params = {limit: 5, search_query_native: "subject: hello"}
messages, _ = nylas.messages.list(identifier: '<NYLAS_GRANT_ID>', query_params: query_params)
messages.each {|message|
puts "[#{Time.at(message[:date]).strftime("%d/%m/%Y at %H:%M:%S")}] \
#{message[:subject]}"
}
import com.nylas.NylasClient;
import com.nylas.models.*;
import java.text.SimpleDateFormat;
import com.nylas.models.Thread;
import java.util.List;
public class SearchInbox {
public static void main(String[] args) throws NylasSdkTimeoutError, NylasApiError {
NylasClient nylas = new NylasClient.Builder("<NYLAS_API_KEY>").build();
ListMessagesQueryParams queryParams = new ListMessagesQueryParams.Builder().
searchQueryNative("subject: hello").
limit(5).
build();
ListResponse<Message> message = nylas.messages().list("<NYLAS_GRANT_ID>", queryParams);
for(Message email : message.getData()) {
String date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").
format(new java.util.Date((email.getDate() * 1000L)));
System.out.println("[" + date + "] | " + email.getSubject());
}
}
}
import com.nylas.NylasClient
import com.nylas.models.*
import java.text.SimpleDateFormat
import java.util.*
fun dateFormatter(milliseconds: String): String {
return SimpleDateFormat("dd/MM/yyyy HH:mm:ss").format(Date(milliseconds.toLong() * 1000)).toString()
}
fun main(args: Array<String>) {
val nylas: NylasClient = NylasClient(apiKey = "<NYLAS_API_KEY>")
val queryParams = ListMessagesQueryParams(limit = 5, searchQueryNative = "subject: hello")
val messages : List<Message> = nylas.messages().list("<NYLAS_GRANT_ID>", queryParams).data
for(message in messages) {
println("[" + dateFormatter(message.date.toString()) + "] |" + message.subject)
}
}
Modify and delete inbox content
Most Nylas Email API endpoints allow you to modify objects using PUT
and POST
requests. You can make the following changes:
- Threads and Messages: Modify labels, unread status, stars, and folders. See the Threads and Messages references for more information.
- Folders and Labels: Update folder and label names. See the Folders references for more information.
- Files: Upload files to use as attachments. See the Attachments references for more information.
You can also make DELETE
requests to certain endpoints. This allows you to delete existing objects, such as Folders.
What's next?
Now that you've learned the basics of working with the Nylas Email API, browse the following documentation to learn more: