Provider-Specific Threading Support
Whether a message carries a threadId, and whether a whole thread can be fetched in one request, depends on the backend the account uses. This page lists what each one provides.
Gmail / Google Workspace
Both Gmail backends assign a thread ID to every message.
Native Thread Support
Backends:
- IMAP with OAuth2:
threadIdfrom theX-GM-THRIDattribute of Gmail'sX-GM-EXT-1IMAP extension - Gmail API:
threadIdfrom the API
Characteristics:
- Thread ID format: long numeric string, for example
"1759349012996310407", the same value over either backend - Availability: webhooks, message listings, message details, search results
- The
\Allfolder is available for cross-folder thread search - On the Gmail API,
reference.threadIdon submit attaches an outgoing message to a thread directly; see Sending threaded messages
Example Response
curl "https://emailengine.example.com/v1/account/gmail/messages?path=INBOX" \
-H "Authorization: Bearer <token>"
{
"messages": [
{
"id": "AAABkPHBeR0",
"threadId": "1759349012996310407",
"subject": "Project discussion",
"from": {
"address": "colleague@example.com"
}
}
]
}
Microsoft 365 / Outlook
Which backend the account uses decides everything here.
Native Thread Support
Backends:
- Microsoft Graph API:
threadIdis the message's GraphconversationId - IMAP with OAuth2: no thread ID
Only an account added with the Microsoft Graph API backend has a threadId. A Microsoft 365 account added over IMAP with OAuth2 talks to Microsoft's IMAP server, which implements neither OBJECTID nor a Gmail-style extension, so it behaves like any other IMAP account: threads have to be built from headers.
Characteristics (Graph API):
- Thread ID format: Graph conversation ID, for example
"AAQkAGI2THY2ZjRhLTVjNzgtNDMxYS05YTBmLTJiN2M4ZDkxZTQyMwAQAF3xTx0nRUxOhKcvLZQ9r1M=" - Availability: webhooks, message listings, message details, search results
- The
\Allfolder is available for cross-folder thread search; athreadIdsearch on it filters onconversationId
Example Response
{
"messages": [
{
"id": "AAMkAGI2THY2ZjRhLTVjNzgtNDMxYS05YTBmLTJiN2M4ZDkxZTQyMwBGAAAAAABBUq8CzXaBTKl9k7lJ0hJ7BwCXKmSHhLBFTr0AAA==",
"threadId": "AAQkAGI2THY2ZjRhLTVjNzgtNDMxYS05YTBmLTJiN2M4ZDkxZTQyMwAQAF3xTx0nRUxOhKcvLZQ9r1M=",
"subject": "Meeting tomorrow",
"from": {
"address": "manager@example.com"
}
}
]
}
Backend comparison:
| Backend | Threading | \All folder |
|---|---|---|
| Microsoft Graph API | Native | Yes |
| IMAP with OAuth2 | Manual only | No |
Yahoo / AOL / Verizon
Yahoo, AOL, and Verizon IMAP servers implement the OBJECTID extension (RFC 8474), and EmailEngine passes its THREADID attribute on as threadId.
Characteristics:
- Thread ID format: short numeric string, for example
"501" - Availability: webhooks, message listings, message details, search results
- No
\Allfolder: search each folder separately and merge the results, as shown in Searching threads
Example Response
{
"messages": [
{
"id": "AAAAKAAACKM",
"threadId": "501",
"subject": "Question about your service",
"from": {
"address": "customer@example.com"
}
}
]
}
The same applies to any other IMAP server that advertises OBJECTID: the thread ID is available, the \All folder is not.
Other IMAP Providers
An IMAP server without OBJECTID or X-GM-EXT-1 gives EmailEngine no thread identifier.
Characteristics:
- No
threadIdproperty in any response threadIdcannot be used as a search term- No
\Allfolder - Threads are reconstructed client-side from
Message-ID,In-Reply-To, andReferences
The procedure is: search the relevant folders by subject, fetch the candidates, and group them on their headers. Building threads manually has the code.
Provider Comparison Table
| Provider | Backend | Native threading | Thread ID format | \All folder |
|---|---|---|---|---|
| Gmail | IMAP + OAuth2 | Yes | Long numeric | Yes |
| Gmail | Gmail API | Yes | Long numeric | Yes |
| Microsoft 365 | Graph API | Yes | Graph conversation ID | Yes |
| Microsoft 365 | IMAP + OAuth2 | No | N/A (manual only) | No |
| Yahoo/AOL/Verizon | IMAP | Yes (OBJECTID) | Short numeric | No |
| Other IMAP | IMAP | No | N/A (manual only) | No |
Choosing the Backend
Gmail accounts
Either backend gives you thread IDs and the \All folder. Choose between IMAP and the Gmail API on other grounds; see Gmail accounts.
Microsoft 365 / Outlook accounts
Use the Microsoft Graph API backend if you need thread IDs or cross-folder thread search. Over IMAP, neither is available.
Yahoo / AOL / Verizon
Standard IMAP. Thread IDs are available; plan for one search per folder.
Other providers
Plan for client-side threading: building thread relationships from headers, searching several folders, and keeping any thread state in your own application.
Migration Considerations
Switching a Microsoft 365 account from IMAP to the Graph API
- The account has to be re-authorized through an OAuth2 application with the Graph API base scopes; the IMAP grant does not carry over
- Messages get new EmailEngine message IDs, and
threadIdbecomes available - Update your application to use the Graph conversation IDs
- Any thread mapping you built from headers stays valid only as long as you keep the headers it was built from
Testing Thread Support
Check the account type
curl "https://emailengine.example.com/v1/account/example" \
-H "Authorization: Bearer <token>"
Two fields of the account response settle it together:
typenames the provider:gmailfor a Google account,outlookfor a Microsoft account,imapfor a password-authenticated IMAP accountbaseScopessays which backend an OAuth2 account uses:imapfor IMAP with OAuth2,apifor the Gmail or Graph API. It is present only for OAuth2 accounts, and defaults toimapwhen the OAuth2 application does not set it
Test thread ID availability
curl "https://emailengine.example.com/v1/account/example/messages?path=INBOX" \
-H "Authorization: Bearer <token>"
If the entries have no threadId, the backend assigns none, and threads have to be built from headers.
See Also
- Threading overview - The headers and IDs this table is about
- Searching threads - The search strategy each provider needs
- Account types - Choosing the backend that gives you native threading
- Searching messages - What else the search endpoint can filter on