Using the Threads API
The Nylas Threads API gives you more control over how you detect collections of messages, and how you respond to them. This page explains how to work with the Threads API.
How threads work
Most providers organize email messages both as individual messages, and as threads. Threads represent collections of email messages that are related to each other and result from participants replying to an email conversation.
Every email message is associated with a thread, whether that thread contains only one message or many.
When you look at threads from a code perspective, you can detect a thread and group email messages using several criteria (the message subject, recipients, senders, and so on). Grouping several email messages into a thread provides a coherent view of an email conversation. In long or fast-moving conversations, threads help the reader follow the discussion.
For Google and Microsoft accounts, Nylas threads email messages together so they’re as similar as possible to the behavior that end users have come to expect from email clients.
Threads are non-linear
Threads are organized non-linearly, as collections of related email messages. Email service providers use criteria such as the message subject, its recipients, and so on to collect email messages into threads. They also keep track of the message_ids for each email message in the thread.
Because all of a thread’s message_ids are logged, you can reply to a specific email message by referencing its ID. This creates a new branch of the thread — similar to a tree structure — and the email messages in the new branch continue to be associated with the thread.
Build a fully-fledged inbox with the Threads API
You can use the /threads endpoint to emulate popular inbox UIs, like Gmail or Outlook, which group email messages into threads. This gives users a simple, centralized view of their latest email conversation. By combining this view with calls to the /messages endpoint, you can build a fully-fledged inbox in your application.
Before you begin
Before you can use the Threads API, you need the following prerequisites:
- A v3 Nylas application.
- A working authentication configuration. Either…
- A Google or Microsoft grant with at least the following scopes:
- Google:
gmail.readonly - Microsoft:
Mail.Read
- Google:
Get a list of threads
The following examples show how to return the five most recent threads from an authenticated account. For more information on filtering requests, see Avoiding rate limits in Nylas.
!!!include(v3_code_samples/threads/GET/curl.sh)!!!!!!include(v3_code_samples/threads/GET/response.json)!!!!!!include(v3_code_samples/threads/GET/node.js)!!!!!!include(v3_code_samples/threads/GET/python.py)!!!!!!include(v3_code_samples/threads/GET/ruby.rb)!!!!!!include(v3_code_samples/threads/GET/java.java)!!!!!!include(v3_code_samples/threads/GET/kotlin.kt)!!!Return a thread
The following request returns a specific thread.
!!!include(v3_code_samples/threads-id/GET/curl.sh)!!!{ "grant_id": "<NYLAS_GRANT_ID>", "id": "<THREAD_ID>", "object": "thread", "has_attachments": false, "has_drafts": false, "earliest_message_date": 1634149514, "latest_message_received_date": 1634832749, "latest_message_sent_date": 1635174399, "participants": [ { "email": "renee.smith@example.com", "name": "Renee Smith" }, { "email": "rebecca.crumpler@example.com", "name": "Rebecca Lee Crumpler" } ], "snippet": "jnlnnn --Sent with Nylas", "starred": false, "subject": "Dinner Wednesday?", "unread": false, "message_ids": [ // A list of IDs for all messages in the thread. "<MESSAGE_ID>", "<MESSAGE_ID>" ], "draft_ids": [ // A list of IDs for all drafts in the thread. "<DRAFT_ID>" ], "folders": [ // A list of folders that messages in the thread are associated with. "<FOLDER_ID>", "<FOLDER_ID>" ], "latest_draft_or_message": { "body": "Hello, I just sent a message using Nylas!", "date": 1635355739, "attachments": { "content": "YXR0YWNoDQoNCi0tLS0tLS0tLS0gRm9yd2FyZGVkIG1lc3NhZ2UgL=", "content_type": "text/calendar", "id": "<ATTACHMENT_ID>", "size": 1708, "content_type": "application/ics", "filename": "invite.ics", "id": "<ATTACHMENT_ID>", "size": 1708 }, "folders": { // A list of folders the latest message in the thread is associated with. "<FOLDER_ID>", "<FOLDER_ID>" }, "from": { "name": "Renee Smith", "email": "renee.smith@example.com" }, "grant_id": "<NYLAS_GRANT_ID>", "id": "<MESSAGE_ID>", // The message ID for the latest message in the thread. "object": "message", "reply_to": { "name": "Renee Smith", "email": "renee.smith@example.com" }, "snippet": "Hello, I just sent a message using Nylas!", "starred": true, "subject": "Hello From Nylas!", "thread_id": "<THREAD_ID>", "to": { "name": "Geoff Dale", "email": "geoff.dale@example.com" }, "unread": true }}Because threads are non-linear, you can use one of the message_ids listed in the response to reply to a specific email message in the thread. This creates a new branch of the thread, and depending on who responds to it, the structure of the thread can resemble the example below.

Search an inbox for threads
You can add query parameters to a Return all Threads request to search for threads using specific criteria.
You can also use the v3 Nylas SDKs to search for threads, as in the following examples.
!!!include(v3_code_samples/threads/GET/search-inbox-threads.js)!!!!!!include(v3_code_samples/threads/GET/search-inbox-threads.py)!!!require 'nylas'
nylas = Nylas::Client.new(api_key: '<NYLAS_API_KEY>')query_params = { search_query_native: "subject: hello" }threads, _ = nylas.threads.list(identifier: '<NYLAS_GRANT_ID>', query_params: query_params)
threads.each { | thread | puts thread[:subject]}import com.nylas.NylasClient;import com.nylas.models.*;import java.text.SimpleDateFormat;import com.nylas.models.Thread;import java.util.List;
public class SearchThreads { public static void main(String[] args) throws NylasSdkTimeoutError, NylasApiError { NylasClient nylas = new NylasClient.Builder("<NYLAS_API_KEY>").build();
ListThreadsQueryParams queryParams = new ListThreadsQueryParams.Builder(). searchQueryNative("subject: hello"). limit(5). build();
ListResponse<Thread> thread = nylas.threads().list("<NYLAS_GRANT_ID>", queryParams);
for(Thread email : thread.getData()) { System.out.println(email.getSubject()); } }}import com.nylas.NylasClientimport com.nylas.models.*
fun main(args: Array<String>) { val nylas: NylasClient = NylasClient(apiKey = dotenv["NYLAS_API_KEY"]) val queryParams = ListThreadsQueryParams(limit = 5, searchQueryNative = "subject: hello") val threads : List<com.nylas.models.Thread> = nylas.threads().list("<NYLAS_GRANT_ID>", queryParams).data
for(thread in threads) { println(thread.subject) }}