Skip to content

How to list Google email threads

Gmail invented the conversation view that most email clients now copy. Every message in Gmail belongs to a thread, and Google assigns a stable thread_id that persists across the entire conversation. Nylas maps this directly to the Threads API, giving you the same conversation grouping you see in the Gmail UI through a simple REST call.

This guide walks through listing threads from Google accounts and covers the Google-specific details: native thread_id behavior, how labels interact with threads, search operators, and OAuth scopes.

Why use Nylas for threads instead of the Gmail API directly?

Section titled “Why use Nylas for threads instead of the Gmail API directly?”

The Gmail API has a native Threads resource that returns conversation-grouped messages. But using it requires configuring a GCP project, navigating Google’s three-tier OAuth scope system, and for anything beyond basic metadata, going through OAuth verification or a full security assessment. On top of that, the Gmail Threads resource returns message IDs that you then need to fetch individually to get content, requiring multiple API calls per thread.

Nylas gives you a /threads endpoint that includes latest_draft_or_message with the most recent message’s content inline. No extra calls needed. Token refresh, scope management, and the GCP project overhead are handled automatically. And your code works across Gmail, Outlook, Yahoo, and IMAP without any provider-specific branches.

If you only need Gmail and want full control, the Gmail API works well for threads. For multi-provider support or faster development, Nylas simplifies the integration.

You’ll need:

New to Nylas? Start with the quickstart guide to set up your app and connect a test account before continuing here.

Google classifies OAuth scopes into three tiers, and each one comes with different verification requirements:

Scope tierExampleWhat’s required
Non-sensitivegmail.labelsNo verification needed
Sensitivegmail.readonly, gmail.composeOAuth consent screen verification
Restrictedgmail.modifyFull security assessment by a third-party auditor

If your app needs to read thread content (not just metadata), you’ll need at least the gmail.readonly scope, which is classified as sensitive. For read-write access, gmail.modify is restricted and requires a security assessment.

Nylas handles the token management, but your GCP project still needs the right scopes configured. See the Google provider guide for the full setup.

Make a List Threads request with the grant ID. By default, Nylas returns the most recent threads. These examples limit results to 5:

The response includes a latest_draft_or_message object with the most recent message’s content, so you can render a thread preview without a separate Messages API call. The same code works for Microsoft, Yahoo, and IMAP accounts.

You can narrow results with query parameters. Here’s what works with Google accounts:

ParameterWhat it doesExample
subjectMatch on subject line?subject=Weekly standup
fromFilter by sender[email protected]
toFilter by recipient[email protected]
unreadUnread only?unread=true
inFilter by folder or label ID?in=INBOX
received_afterAfter a Unix timestamp?received_after=1706000000
received_beforeBefore a Unix timestamp?received_before=1706100000
has_attachmentOnly results with attachments?has_attachment=true

When using the in parameter with Google accounts, you must use the folder (label) ID, not the display name. Nylas does not support filtering by label name on Google accounts. Use the List Folders endpoint to get the correct IDs.

Here’s how to combine filters. This pulls threads with unread messages from a specific sender:

For more advanced filtering, you can use Gmail’s native search syntax through the search_query_native parameter. This supports the same search operators you’d use in the Gmail search bar:

Some useful Gmail search operators:

OperatorWhat it doesExample
from:Threads from a senderfrom:[email protected]
to:Threads to a recipientto:[email protected]
subject:Subject line containssubject:invoice
has:attachmentHas file attachmentshas:attachment
filename:Attachment filenamefilename:report.pdf
after:Threads after a dateafter:2025/01/01
before:Threads before a datebefore:2025/02/01
is:unreadUnread threadsis:unread
label:Threads with a labellabel:important
ORCombine conditionsfrom:alex OR from:priya

When using search_query_native, you can only combine it with the in, limit, and page_token parameters. Other query parameters will return an error. See the search best practices guide for more details.

A few provider-specific details that matter when you’re working with threads on Gmail and Google Workspace accounts.

Gmail assigns a native thread_id to every message, and Nylas maps this directly to the thread object’s id field. Gmail’s threading algorithm uses In-Reply-To and References headers combined with subject matching to group messages. This is the most accurate threading of any provider because it’s based on Google’s own conversation logic rather than heuristic matching.

The thread_id is stable and persistent. It doesn’t change when messages are archived, labeled, or moved to trash. You can safely store it as a permanent reference to a conversation.

This is the biggest conceptual difference from how threads work visually in Gmail. Labels are assigned to individual messages, but the Gmail UI shows a thread in a label’s view if any message in the thread has that label. Nylas mirrors this: the thread object’s folders array is the union of all labels across every message in the conversation.

A thread might show:

{
"folders": ["INBOX", "SENT", "UNREAD", "CATEGORY_PERSONAL", "IMPORTANT"]
}

If you archive a thread in Gmail, the INBOX label is removed from all messages. But the thread still exists and is accessible through other labels or by its ID.

Like Microsoft, thread-level fields on Google are computed from all messages:

  • unread is true if any message in the thread is unread
  • starred is true if any message is starred
  • has_attachments is true if any message has attachments
  • participants is the union of all senders and recipients
  • message_ids lists every message in the thread

To change read/starred state on individual messages, use the Messages API with specific message IDs from the thread.

Threading works identically on both. The only differences are administrative:

  • Workspace admins can restrict third-party app access. If a Workspace user can’t authenticate, their admin may need to allow your app in the Google Admin console.
  • Delegated mailboxes (shared mailboxes in Workspace) require special handling. See the shared accounts guide.

Google enforces quotas at two levels, same as with the Messages API:

  • Per-user: Each authenticated user has a daily quota for API calls
  • Per-project: Your GCP project has an overall daily limit across all users

Use webhooks or Google Pub/Sub instead of polling to avoid hitting limits.

The Threads API returns paginated responses. When there are more results, the response includes a next_cursor value. Pass it back as page_token to get the next page:

Keep paginating until the response comes back without a next_cursor.