Working with folders and labels
✨ Folders and labels have been combined in Nylas v3. For more information, see Changes to Folders and Labels.
Email providers use either folders or labels to organize and manage messages in an inbox. Nylas determines which method an account uses when it connects, and adjusts its behavior as necessary. This means developers can use the same commands to manage both folders and labels.
This page explains how to work with folders and labels in Nylas v3.
Folder and label behavior
Folders and labels behave similarly across providers, and Nylas v3 simplifies how you work with them by combining their functions into a single Folders API.
Because many providers structure folders differently, Nylas flattens nested folders and adds the parent_id
field to child folders. You can use this data to re-create the folder hierarchy from the provider in your project.
Nylas doesn't support using keywords or attributes to reference folders on the provider (for example, the in:inbox
query returns a 400
error). Instead, you should use id
s in your requests to get the data you need:
- Make a Get all Folders request.
- Inspect the folders Nylas returns, find the one you want to work with, and get its ID.
- Use the folder ID in your requests to work with the specific folder.
Common folder attributes
Nylas automatically maps folder attributes (the folder's name or purpose) to a set of common values: \Archive
, \Drafts
, \Inbox
, \Junk
, \Sent
, and \Trash
. For IMAP providers, Nylas passes the attributes on directly. If a folder doesn't have one of the standard attributes, Nylas returns an empty attributes
array.
You can't filter for folders based on these attributes, but you can use these values to identify the semantically-same folders across providers. For example, to identify the Sent folder...
- Make a Get all Folders request.
- Inspect the
attributes
field for each folder, find the one you want to work with (in this case,/Sent
), and get its ID. - Use the folder ID in your requests to work with the specific folder.
View an account's folders and labels
To get a list of all folders and labels in an account, make a Return all Folders request. Nylas returns, among other things, an id
that you can use later to reference specific folders or labels.
Nylas flattens all folders, including sub-folders, into a single list.
curl --request GET \
--url https://api.us.nylas.com/v3/grants/<NYLAS_GRANT_ID>/folders \
--header 'Accept: application/json, application/gzip' \
--header 'Authorization: Bearer <NYLAS_API_KEY>' \
--header 'Content-Type: application/json'
{
"request_id": "1",
"data": [
{
"id": "CATEGORY_FORUMS",
"grant_id": "2",
"name": "CATEGORY_FORUMS",
"system_folder": true
},
{
"id": "CATEGORY_PERSONAL",
"grant_id": "2",
"name": "CATEGORY_PERSONAL",
"system_folder": true
},
{
"id": "CATEGORY_PROMOTIONS",
"grant_id": "2",
"name": "CATEGORY_PROMOTIONS",
"system_folder": true
},
{
"id": "CATEGORY_SOCIAL",
"grant_id": "2",
"name": "CATEGORY_SOCIAL",
"system_folder": true
},
{
"id": "CATEGORY_UPDATES",
"grant_id": "2",
"name": "CATEGORY_UPDATES",
"system_folder": true
},
{
"id": "CHAT",
"grant_id": "2",
"name": "CHAT",
"system_folder": true
},
{
"id": "DRAFT",
"grant_id": "2",
"name": "DRAFT",
"attributes": [
"\\Drafts"
],
"system_folder": true
},
{
"id": "IMPORTANT",
"grant_id": "2",
"name": "IMPORTANT",
"attributes": [
"\\Important"
],
"system_folder": true
},
{
"id": "INBOX",
"grant_id": "2",
"name": "INBOX",
"attributes": [
"\\Inbox"
],
"system_folder": true
},
{
"id": "SENT",
"grant_id": "2",
"name": "SENT",
"attributes": [
"\\Sent"
],
"system_folder": true
},
{
"id": "SPAM",
"grant_id": "2",
"name": "SPAM",
"attributes": [
"\\Junk"
],
"system_folder": true
},
{
"id": "STARRED",
"grant_id": "2",
"name": "STARRED",
"system_folder": true
},
{
"id": "TRASH",
"grant_id": "2",
"name": "TRASH",
"attributes": [
"\\Trash"
],
"system_folder": true
},
{
"id": "UNREAD",
"grant_id": "2",
"name": "UNREAD",
"system_folder": true
}
]
}
You can also use the v3 Nylas SDKs, as in the examples below.
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 fetchFolders() {
try {
const folders = await nylas.folders.list({
identifier: process.env.NYLAS_GRANT_ID,
})
console.log('folders:', folders)
} catch (error) {
console.error('Error fetching folders:', error)
}
}
fetchFolders()
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")
folder_id = os.environ.get("FOLDER_ID")
folder = nylas.folders.list(
grant_id
)
print(folder)
require 'nylas'
nylas = Nylas::Client.new(api_key: '<NYLAS_API_KEY>')
labels, _ = nylas.folders.list('<NYLAS_GRANT_ID>')
labels.map.with_index { |label, i|
puts("Label #{i}")
puts("#{label[:id]} | #{label[:name]} | #{label[:system_folder]}")
}
import com.nylas.NylasClient;
import com.nylas.models.*;
public class ReadLabels {
public static void main(String[] args) throws NylasSdkTimeoutError, NylasApiError {
NylasClient nylas = new NylasClient.Builder("<NYLAS_API_KEY>").build();
ListResponse<Folder> labels = nylas.folders().list("<NYLAS_GRANT_ID>");
int index=0;
for(Folder label : labels.getData())
System.out.println((index++)+": "+ label.getId() +
" | " + label.getName() + " | " +
" | " + label.getObject());
}
}
import com.nylas.NylasClient
fun main(args: Array<String>) {
val nylas: NylasClient = NylasClient(apiKey = dotenv["NYLAS_API_KEY"])
val labels = nylas.folders().list(dotenv["NYLAS_GRANT_ID"])
var index = 0
for (label in labels.data) println(
index++.toString() + ": " + label.id +
" | " + label.name + " | " +
" | " + label.getObject()
)
}
Create folders and labels
To create a folder or label, make a Create Folder request. Depending on the provider, you can define specific parameters to customize the folder or label:
- Google:
text_color
: Set the text color for the label.background_color
: Set the background color for the label.
- Microsoft and EWS:
parent_id
: Set the parent folder. You can use this to create nested folders.
The following example creates a label for a Google account and defines its text_color
and background_color
.
curl --request POST \
--url 'https://api.us.nylas.com/v3/grants/<NYLAS_GRANT_ID>/folders' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json, application/gzip' \
--header 'Authorization: Bearer <NYLAS_API_KEY>' \
--data '{
"text_color": "#000000",
"name": "new folder",
"background_color": "#73AFFF"
}'
{
"request_id": "1",
"data": {
"id": "Label_10",
"grant_id": "<NYLAS_GRANT_ID>",
"name": "new folder",
"total_count": 0,
"unread_count": 0,
"system_folder": false,
"text_color": "#000000",
"background_color": "#73AFFF"
}
}
You can also create folders and labels 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)
const identifier = process.env.NYLAS_GRANT_ID
const createFolder = async () => {
try {
const folder = await nylas.folders.create({
identifier,
requestBody: {
name: 'New Folder'
}
})
console.log('Folder created:', folder)
} catch (error) {
console.error('Error creating folder:', error)
}
}
createFolder()
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")
folder = nylas.folders.create(
grant_id,
request_body={
"name": 'New Folder',
"parent": None,
}
)
print(folder)
require 'nylas'
nylas = Nylas::Client.new(api_key: '<NYLAS_API_KEY>')
request_body = { name: 'My Custom label' }
label, _ = nylas.folders.create(identifier: ENV["NYLAS_GRANT_ID"], request_body: request_body)
puts label
import com.nylas.NylasClient;
import com.nylas.models.*;
public class CreateLabels {
public static void main(String[] args) throws NylasSdkTimeoutError, NylasApiError {
NylasClient nylas = new NylasClient.Builder("<NYLAS_API_KEY>")).build();
CreateFolderRequest request = new CreateFolderRequest("My Custom label", "", "", "");
Response<Folder> label = nylas.folders().create("<NYLAS_GRANT_ID>"), request);
System.out.println(label);
}
}
import com.nylas.NylasClient
import com.nylas.models.CreateFolderRequest
fun main(args: Array<String>) {
val nylas: NylasClient = NylasClient(apiKey = dotenv["NYLAS_API_KEY"])
val request = CreateFolderRequest("My Custom label")
val label = nylas.folders().create(dotenv["NYLAS_GRANT_ID"], request)
print(label)
}
Organize email messages
To move an email message into a folder or apply a label to it, make an Update Message request that includes the id
of both the folder or label and the email message you want to work with. This overwrites the folder the email message is currently organized in.
The following example moves a specific email message into a folder.
curl --request PUT \
--url 'https://api.us.nylas.com/v3/grants/<NYLAS_GRANT_ID>/messages/<MESSAGE_ID>' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json, application/gzip' \
--header 'Authorization: Bearer <NYLAS_API_KEY>' \
--data '{
"folders": [
"<FOLDER_ID>"
]
}'
{
"request_id": "1",
"data": {
"folders": [
"Label_10",
],
"bcc": null,
"body": "Learn how to Send Email with Nylas APIs",
"cc": null,
"attachments": [],
"from": [
{
"email": "nyla@nylas.com"
}
],
"reply_to": null,
"subject": "Hey Reaching Out with Nylas",
"to": [
{
"name": "DevRel",
"email": "devrel@nylas.com"
}
],
"use_draft": false,
"tracking_options": {
"label": "hey just testing",
"links": true,
"opens": true,
"thread_replies": true
},
"date": 1707839231,
"grant_id": "1",
"id": "1",
"thread_id": "2"
}
}
You can also do this using the v3 Nylas SDKs, as in the examples below.
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)
const identifier = process.env.NYLAS_GRANT_ID
const folderId = process.env.FOLDER_ID
const messageId = process.env.MESSAGE_ID
const updateMessageFolder = async () => {
try {
const updatedMessage = await nylas.messages.update({
identifier,
messageId,
requestBody: {
folders: [folderId]
}
})
console.log('Message updated:', updatedMessage)
} catch (error) {
console.error('Error updating message folder:', error)
}
}
updateMessageFolder()
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")
folder_id = os.environ.get("FOLDER_ID")
message_id = os.environ.get("MESSAGE_ID")
message = nylas.messages.update(
grant_id,
message_id,
request_body={
"folders": [folder_id]
}
)
print(message)
require 'nylas'
nylas = Nylas::Client.new(api_key: '<NYLAS_API_KEY>')
request_body = { folders: ['<FOLDER_ID>'] }
message, _ = nylas.messages.update(identifier: ENV["NYLAS_GRANT_ID"], message_id: "<MESSAGE_ID>", request_body: request_body)
puts message
import com.nylas.NylasClient;
import com.nylas.models.*;
import java.util.List;
public class UpdateMessage {
public static void main(String[] args) throws NylasSdkTimeoutError, NylasApiError {
NylasClient nylas = new NylasClient.Builder("<NYLAS_API_KEY>").build();
List<String> folder = List.of("<FOLDER_ID>");
UpdateMessageRequest request = new UpdateMessageRequest.Builder().folders(folder).build();
Response<Message> message = nylas.messages().update("<NYLAS_GRANT_ID>", "<MESSAGE_ID>", request);
System.out.println(message);
}
}
import com.nylas.NylasClient
import com.nylas.models.UpdateMessageRequest
fun main(args: Array<String>) {
val nylas: NylasClient = NylasClient(apiKey = dotenv["NYLAS_API_KEY"])
val folder = listOf("<FOLDER_ID>")
val request: UpdateMessageRequest = UpdateMessageRequest(folders = folder)
val message = nylas.messages().update("<NYLAS_GRANT_ID>","<MESSAGE>", request)
print(message)
}
Update folders and labels
You can make an Update Folder request to update a folder or label. Depending on the provider, you can update specific parameters to customize the folder or label:
- Google:
text_color
: Set the text color for the label.background_color
: Set the background color for the label.
- Microsoft and EWS:
parent_id
: Set the parent folder. You can use this to create a hierarchy of nested folders.
The following example updates a folder's name.
curl --request PUT \
--url https://api.us.nylas.com/v3/grants/<NYLAS_GRANT_ID>/folders/<FOLDER_ID> \
--header 'Accept: application/json, application/gzip' \
--header 'Authorization: Bearer <NYLAS_API_KEY>' \
--header 'Content-Type: application/json' \
--data '{
"name": "Renamed folder"
}'
{
"request_id": "1",
"data": {
"id": "<FOLDER_ID>",
"grant_id": "<NYLAS_GRANT_ID>",
"name": "Renamed folder",
"system_folder": false
}
}
You can also use the v3 Nylas SDKs, as in the following examples.
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 updateFolder() {
try {
const folder = await nylas.folders.update({
identifier: process.env.NYLAS_GRANT_ID,
folderId: process.env.FOLDER_ID,
requestBody: {
name: "Updated Folder Name",
textColor: "#000000",
backgroundColor: "#434343",
}
})
console.log('Updated Folder:', folder)
} catch (error) {
console.error('Error to update folder:', error)
}
}
updateFolder()
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")
folder = nylas.folders.update(
grant_id,
folder_id=os.environ.get("FOLDER_ID"),
request_body={
"name": "Updated Folder Name",
"text_color": "#000000",
}
)
print(folder)
require 'nylas'
nylas = Nylas::Client.new(
api_key: ENV["NYLAS_API_KEY"]
)
request_body = {
name: "Renamed folder"
}
folder, _ = nylas.folders.update(identifier: ENV["NYLAS_GRANT_ID"],
folder_id: "Label_19", request_body: request_body)
puts folder
import com.nylas.NylasClient;
import com.nylas.models.*;
public class UpdateLabel {
public static void main(String[] args) throws
NylasSdkTimeoutError, NylasApiError {
NylasClient nylas = new NylasClient.Builder("<NYLAS_API_KEY>").build();
UpdateFolderRequest updateRequest = new UpdateFolderRequest.Builder().
name("Renamed ").build();
Response<Folder> folder = nylas.folders().update("<NYLAS_GRANT_ID>",
"<FOLDER_ID>", updateRequest);
}
}
import com.nylas.NylasClient
import com.nylas.models.UpdateFolderRequest
fun main(args: Array<String>) {
val nylas: NylasClient = NylasClient(
apiKey = "<NYLAS_API_KEY>"
)
val requestBody = UpdateFolderRequest.Builder().
name("Renamed Folder").build();
val folder = nylas.folders().update("<NYLAS_GRANT_ID>",
"<FOLDER_ID>", requestBody)
print(folder.data)
}
Delete folders and labels
You can delete folders and labels by making a Delete Folder request or using one of the Nylas SDKs.
⛔️ When you make a Delete Folder request, Nylas deletes the folder and all the email messages it contains. Make sure you move any email messages you want to keep before you delete the folder.
curl --request DELETE \
--url 'https://api.us.nylas.com/v3/grants/<NYLAS_GRANT_ID>/folders/<FOLDER_ID>' \
--header 'Accept: application/json, application/gzip' \
--header 'Authorization: Bearer <NYLAS_API_KEY>'
{
"request_id": "1"
}
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)
const identifier = process.env.NYLAS_GRANT_ID
const folderId = process.env.FOLDER_ID
const deleteFolder = async () => {
try {
await nylas.folders.destroy({ identifier, folderId })
console.log(`Folder with ID ${folderId} deleted successfully.`)
} catch (error) {
console.error(`Error deleting folder with ID ${folderId}:`, error)
}
}
deleteFolder()
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")
folder_id = os.environ.get("FOLDER_ID")
request = nylas.folders.destroy(
grant_id,
folder_id,
)
print(request)
require 'nylas'
nylas = Nylas::Client.new(api_key: '<NYLAS_API_KEY>')
status, _ = nylas.folders.destroy(identifier: ENV["NYLAS_GRANT_ID"], folder_id: "Label_7")
puts status
import com.nylas.NylasClient;
import com.nylas.models.*;
public class DeleteLabels {
public static void main(String[] args) throws NylasSdkTimeoutError, NylasApiError {
NylasClient nylas = new NylasClient.Builder("<NYLAS_API_KEY>").build();
DeleteResponse label = nylas.folders().destroy("<NYLAS_GRANT_ID>", "<LABEL_ID>");
System.out.println(label);
}
}
import com.nylas.NylasClient
import com.nylas.models.UpdateMessageRequest
fun main(args: Array<String>) {
val nylas: NylasClient = NylasClient(apiKey = dotenv["NYLAS_API_KEY"])
val label = nylas.folders().destroy("<NYLAS_GRANT_ID>", "<LABEL_ID>")
print(label)
}
Provider limitations on folders and labels
Keep the following limitations in mind when you're working with folders and labels:
- Because providers structure folders in different ways, Nylas doesn't support nested folders. Instead, Nylas flattens sub-folders and displays them in the same list as top-level folders.
- For Microsoft, you can use the
parent_id
to reflect the folder hierarchy in your project. - On IMAP, the hierarchy is reflected in the folder name (for example,
Accounting.Taxes
orINBOX\Accounting\Taxes
).
- For Microsoft, you can use the
- Because of how IMAP providers handle folders and labels, the folder names that Nylas returns aren't always the same as those listed in the provider's UI (for example, the "Trash" folder might be "Deleted Messages" in a Nylas response). Instead of relying on names, you should use attributes and IDs to get the data you need.
- IMAP servers use provider-specific formats to represent the folder name and hierarchy. When you make a Create Folder request for an IMAP account, Nylas creates a folder with the name you pass. If the name includes the IMAP separator that corresponds with the server settings, Nylas creates a sub-folder based on the folder name.
- Nylas v3 doesn't support using keywords to reference folders on the provider (for example,
in:inbox
returns a400
error). Instead, you should use specific folderid
s to get the data you need. - It might take up to 10 minutes for folders to be available in Nylas after you authenticate an IMAP grant.