# Using the Folders API

Source: https://developer.nylas.com/docs/v3/email/folders/

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.

## Folder and label behavior

Folders and labels behave similarly across providers, and Nylas 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](/docs/api/errors/400-response/)). Instead, you should use `id`s in your requests to get the data you need:

1. Make a [Get all Folders request](/docs/reference/api/folders/get-folder/).
2. Inspect the folders Nylas returns, find the one you want to work with, and get its ID.
3. 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](https://www.rfc-editor.org/rfc/rfc9051.html#name-list-response): `\Archive`, `\Drafts`, `\Inbox`, `\Junk`, `\Sent`, and `\Trash`. For IMAP providers, Nylas uses the provider-set values to determine these attributes. When it can't identify the system folders, Nylas falls back to using the folder name to set the appropriate attributes.

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...

1. Make a [Get all Folders request](/docs/reference/api/folders/get-folder/).
2. Inspect the `attributes` field for each folder, find the one you want to work with (in this case, `/Sent`), and get its ID.
3. 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 [Get all Folders request](/docs/reference/api/folders/get-folder/). 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.

```bash
curl --compressed --request GET \
  --url 'https://api.us.nylas.com/v3/grants/<NYLAS_GRANT_ID>/folders' \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer <NYLAS_API_KEY>' \
  --header 'Content-Type: application/json'

```

```json [readLabels-Response (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
    }
  ]
}


```

```js [readLabels-Node.js SDK]

import Nylas from "nylas";

const nylas = new Nylas({
  apiKey: "<NYLAS_API_KEY>",
  apiUri: "<NYLAS_API_URI>",
});

async function fetchFolders() {
  try {
    const folders = await nylas.folders.list({
      identifier: "<NYLAS_GRANT_ID>",
    });

    console.log("folders:", folders);
  } catch (error) {
    console.error("Error fetching folders:", error);
  }
}

fetchFolders();


```

```python [readLabels-Python SDK]

from nylas import Client

nylas = Client(
    "<NYLAS_API_KEY>",
    "<NYLAS_API_URI>"
)

grant_id = "<NYLAS_GRANT_ID>"
folder_id = "<FOLDER_ID>"

folder = nylas.folders.list(
  grant_id
)

print(folder)

```

```ruby [readLabels-Ruby SDK]
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]}")
}
```

```java [readLabels-Java SDK]


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());
  }
}
```

```kt [readLabels-Kotlin SDK]


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

```bash
nylas email folders list
```

See [`nylas email folders list`](https://cli.nylas.com/docs/commands/email-folders-list) for full options. Other folder subcommands: [`create`](https://cli.nylas.com/docs/commands/email-folders-create), [`rename`](https://cli.nylas.com/docs/commands/email-folders-rename), [`delete`](https://cli.nylas.com/docs/commands/email-folders-delete).


> **Info:** 
> **The [Nylas CLI](https://cli.nylas.com/) runs commands against your default grant.** Run [`nylas auth list`](https://cli.nylas.com/docs/commands/auth-list) to see your connected accounts and [`nylas auth switch <email>`](https://cli.nylas.com/docs/commands/auth-switch) to change which one commands run against. See the full [command reference](https://cli.nylas.com/docs/commands).


## Create folders and labels

To create a folder or label, make a [Create Folder request](/docs/reference/api/folders/post-folder/). 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`.

```bash
curl --compressed --request POST \
  --url 'https://api.us.nylas.com/v3/grants/<NYLAS_GRANT_ID>/folders' \
  --header 'Content-Type: application/json' \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer <NYLAS_API_KEY>' \
  --data '{
    "text_color": "#000000",
    "name": "new folder",
    "background_color": "#73AFFF"
  }'

```

```json [createLabel-Response (JSON)]

{
  "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"
  }
}


```

```js [createLabel-Node.js SDK]

import Nylas from "nylas";

const nylas = new Nylas({
  apiKey: "<NYLAS_API_KEY>",
  apiUri: "<NYLAS_API_URI>",
});
const identifier = "<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();


```

```python [createLabel-Python SDK]

from nylas import Client

nylas = Client(
    "<NYLAS_API_KEY>",
    "<NYLAS_API_URI>"
)

grant_id = "<NYLAS_GRANT_ID>"

folder = nylas.folders.create(
  grant_id,
  request_body={
    "name": 'New Folder',
  }
)

print(folder)

```

```ruby [createLabel-Ruby SDK]
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
```

```java [createLabel-Java SDK]


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);
  }
}
```

```kt [createLabel-Kotlin SDK]


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)
}
```

```bash
nylas email folders create "My Custom Label"
```

The CLI uses the folder name as a positional argument — see [`nylas email folders create`](https://cli.nylas.com/docs/commands/email-folders-create) for full options. To set colors or a parent folder, use the [Create Folder request](/docs/reference/api/folders/post-folder/) directly.

## Organize messages

To move a message into a folder or apply a label to it, make an [Update Message request](/docs/reference/api/messages/put-messages-id/) that includes the `id` of both the folder or label and the message you want to work with. This overwrites the folder the message is currently organized in.

```bash
curl --compressed --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' \
  --header 'Authorization: Bearer <NYLAS_API_KEY>' \
  --data '{
    "folders": ["<FOLDER_ID>"]
  }'

```

```json [moveMessage-Response (JSON)]

{
  "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"
  }
}


```

```js [moveMessage-Node.js SDK]

import Nylas from "nylas";

const nylas = new Nylas({
  apiKey: "<NYLAS_API_KEY>",
  apiUri: "<NYLAS_API_URI>",
});
const identifier = "<NYLAS_GRANT_ID>";
const folderId = "<FOLDER_ID>";
const messageId = "<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();


```

```python [moveMessage-Python SDK]

from nylas import Client

nylas = Client(
    "<NYLAS_API_KEY>",
    "<NYLAS_API_URI>"
)

grant_id = "<NYLAS_GRANT_ID>"
folder_id = "<FOLDER_ID>"
message_id = "<MESSAGE_ID>"

message = nylas.messages.update(
  grant_id,
  message_id,
  request_body={
    "folders": [folder_id]
  }
)

print(message)

```

```ruby [moveMessage-Ruby SDK]
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
```

```java [moveMessage-Java SDK]


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);
  }
}
```

```kt [moveMessage-Kotlin SDK]


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](/docs/reference/api/folders/put-folders-id/) 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.

```bash
curl --compressed --request PUT \
  --url 'https://api.us.nylas.com/v3/grants/<NYLAS_GRANT_ID>/folders/<FOLDER_ID>' \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer <NYLAS_API_KEY>' \
  --header 'Content-Type: application/json' \
  --data '{
    "name": "Renamed folder"
  }'

```

```json [updateFolder-Response (JSON)]
{
  "request_id": "1",
  "data": {
    "id": "<FOLDER_ID>",
    "grant_id": "<NYLAS_GRANT_ID>",
    "name": "Renamed folder",
    "system_folder": false
  }
}
```

```js [updateFolder-Node.js SDK]

import Nylas from "nylas";

const nylas = new Nylas({
  apiKey: "<NYLAS_API_KEY>",
  apiUri: "<NYLAS_API_URI>",
});

async function updateFolder() {
  try {
    const folder = await nylas.folders.update({
      identifier: "<NYLAS_GRANT_ID>",
      folderId: "<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();


```

```python [updateFolder-Python SDK]

from nylas import Client

nylas = Client(
    "<NYLAS_API_KEY>",
    "<NYLAS_API_URI>"
)

grant_id = "<NYLAS_GRANT_ID>"

folder = nylas.folders.update(
  grant_id,
  folder_id="<FOLDER_ID>",
  request_body={
    "name": "Updated Folder Name",
    "text_color": "#000000",
  }
)

print(folder)

```

```ruby [updateFolder-Ruby SDK]

require 'nylas'

nylas = Nylas::Client.new(
    api_key: "<NYLAS_API_KEY>"
)

request_body = {
  name: "Renamed folder"
}

folder, _ = nylas.folders.update(identifier: "<NYLAS_GRANT_ID>", 
    folder_id: "Label_19", request_body: request_body)

puts folder

```

```java [updateFolder-Java SDK]

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);
    }
}


```

```kt [updateFolder-Kotlin SDK]

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


```

```bash
nylas email folders rename <FOLDER_ID> "Renamed folder"
```

The CLI's [`rename`](https://cli.nylas.com/docs/commands/email-folders-rename) command only changes the folder name. To update colors or move a folder under a new parent, use the [Update Folder request](/docs/reference/api/folders/put-folders-id/) directly.

## Delete folders and labels

> **Error:** 
> **When you make a Delete Folder request, Nylas deletes the folder and all the messages it contains**. Make sure you move any messages you want to keep before you delete the folder.

```bash
curl --compressed --request DELETE \
  --url 'https://api.us.nylas.com/v3/grants/<NYLAS_GRANT_ID>/folders/<FOLDER_ID>' \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer <NYLAS_API_KEY>'

```

```json [deleteLabelv3-Response (JSON)]

{
  "request_id": "1"
}


```

```js [deleteLabelv3-Node.js SDK]

import Nylas from "nylas";

const nylas = new Nylas({
  apiKey: "<NYLAS_API_KEY>",
  apiUri: "<NYLAS_API_URI>",
});
const identifier = "<NYLAS_GRANT_ID>";
const folderId = "<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();


```

```python [deleteLabelv3-Python SDK]

from nylas import Client

nylas = Client(
    "<NYLAS_API_KEY>",
    "<NYLAS_API_URI>"
)

grant_id = "<NYLAS_GRANT_ID>"
folder_id = "<FOLDER_ID>"

request = nylas.folders.destroy(
  grant_id,
  folder_id,
)

print(request)

```

```ruby [deleteLabelv3-Ruby SDK]
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
```

```java [deleteLabelv3-Java SDK]


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);
  }
}
```

```kt [deleteLabelv3-Kotlin SDK]


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)
}
```

```bash
nylas email folders delete <FOLDER_ID>
```

## 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` or `INBOX\Accounting\Taxes`).
- 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](#folder-and-label-behavior).
- IMAP servers use provider-specific formats to represent the folder name and hierarchy. When you make a [Create Folder request](/docs/reference/api/folders/post-folder/) 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 doesn't support using keywords to reference folders on the provider (for example, `in:inbox` returns a [`400` error](/docs/api/errors/400-response/)). Instead, you should use specific folder `id`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.