Skip to content

How to list Microsoft email threads

If you’re building an inbox UI that groups messages into conversations, the Nylas Threads API gives you that view out of the box. For Microsoft 365 and Outlook accounts, Nylas maps Microsoft’s native ConversationId to a unified thread model, so you get conversation grouping without working directly with Microsoft Graph.

The API call is the same whether the account is Microsoft, Google, or IMAP. The differences show up in how each provider groups messages into threads, what metadata is available, and how threads interact with folders. This guide covers those details for Microsoft accounts.

Why use Nylas for threads instead of Microsoft Graph directly?

Section titled “Why use Nylas for threads instead of Microsoft Graph directly?”

Microsoft Graph provides conversation threading through the conversationId property on messages, but building a thread view from it requires significant work. You need to query messages, group them by conversationId, sort by date, track read/unread state per thread, and handle the conversationIndex binary header for sub-threading. Graph also requires Azure AD registration, MSAL token management, and admin consent for enterprise tenants.

Nylas gives you a dedicated /threads endpoint that returns pre-grouped conversations with metadata like latest_draft_or_message, participant lists, and aggregate read state. No Azure AD, no MSAL, no manual grouping logic. And the same code works across Outlook, Gmail, Yahoo, and IMAP.

If you only need Microsoft and already have Graph experience, direct integration works. For multi-provider support or faster development, Nylas handles the threading logic for you.

You’ll need:

  • A Nylas application with a valid API key
  • A grant for a Microsoft 365 or Outlook account
  • The Mail.Read scope enabled in your Azure AD app registration

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

Microsoft organizations often require admin approval before third-party apps can access mailbox data. If your users see a “Need admin approval” screen during auth, it means their organization restricts user consent.

You have two options:

  • Ask the tenant admin to grant consent for your app via the Azure portal
  • Configure your Azure app to request only permissions that don’t need admin consent

Nylas has a detailed walkthrough: Configuring Microsoft admin approval. If you’re targeting enterprise customers, you’ll almost certainly need to deal with this.

You also need to be a verified publisher. Microsoft requires it since November 2020, and without it users see an error during auth.

Make a List Threads request with the grant ID. Nylas returns the most recent threads by default. 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 making a separate call to the Messages API. The same code works for Google, Yahoo, and IMAP accounts.

You can narrow results with query parameters. The same filters available for messages work on threads:

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

Combining filters works the way you’d expect. This pulls threads with unread messages from a specific sender:

Microsoft supports the search_query_native parameter, which maps to the $search query parameter in Microsoft Graph. This uses Microsoft’s Keyword Query Language (KQL) syntax.

Microsoft restricts which query parameters you can combine with search_query_native. You can only use it with in, limit, and page_token. Other query parameters return an error.

KQL queries must be URL-encoded. For example, subject:invoice becomes subject%3Ainvoice in the URL. The SDKs handle this automatically, but you need to encode manually in curl requests.

See the search best practices guide for more on search_query_native across providers.

A few provider-specific details that matter when you’re working with threads on Microsoft accounts.

Microsoft has native conversation grouping

Section titled “Microsoft has native conversation grouping”

Outlook groups messages into conversations using a ConversationId that Microsoft assigns internally. Nylas maps this directly to the thread_id field, which means Microsoft threads are based on the same grouping logic that Outlook uses in its own UI. This is more reliable than subject-line matching because it tracks the actual reply chain.

The grouping considers the subject line, recipients, and In-Reply-To/References headers together. Two messages with the same subject but different participants won’t end up in the same thread.

A single Microsoft thread can include messages across Inbox, Sent Items, Drafts, and Deleted Items. The thread object’s folders array reflects all folders that contain at least one message from that conversation. This is expected behavior since a conversation includes both received and sent messages.

If you’re building a folder-filtered view (like “show threads in Inbox”), use the in query parameter. The API returns threads that have at least one message in the specified folder.

Each thread includes a latest_draft_or_message object containing the most recent message or draft in the conversation, including its body content. This is useful for rendering thread previews in an inbox view without making a separate call to the Messages API for each thread.

The object includes from, to, subject, snippet, body, date, and attachment metadata. If the latest item is a draft, it appears here instead of the most recent received message.

Some fields on the thread object are aggregated from all messages in the conversation:

  • unread is true if any message in the thread is unread
  • starred is true if any message in the thread is starred
  • has_attachments is true if any message in the thread has attachments
  • participants is the union of all senders and recipients across the thread
  • earliest_message_date and latest_message_received_date span the full conversation timeline

To get per-message read/starred state, fetch individual messages using the message_ids from the thread response.

Microsoft throttles API requests at the mailbox level, same as with the Messages API. Nylas handles retries automatically on 429 responses. For apps that need real-time thread updates, use webhooks instead of polling.

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.