Email API

The Email Access API provides programmatic access to email operations across connected providers (Google Gmail and Microsoft 365). Search messages, read individual emails, and view full threads.

Base URL

/api/access/email

Authentication

Authorization: Bearer <api_key>

Rate Limits

60 requests/minute300 requests/hour

Email Access Must Be Enabled

Email access is disabled by default on all tokens. You must set emailAccessEnabled: true in the token's permissions before any email endpoints will work.

Key Concepts

  • Multi-provider — Queries fan out to all connected email providers in parallel. Results are merged and sorted by date.
  • Provider-prefixed IDs — All email and thread IDs include a provider prefix for deterministic routing (e.g., google:abc123, m365:xyz789).
  • Independent permissions — Email permissions (emailAccessEnabled, visibleEmailFields, allowedEmailOperations) are completely separate from calendar permissions.

Supported Providers

ProviderPrefixDescription
Google Gmailgoogle:Gmail API via OAuth or service account JWT
Microsoft 365m365:Microsoft Graph API via OAuth or client credentials

Endpoints Overview

MethodEndpointDescriptionPermission
GET/messagesSearch/list emailssearch_emails
GET/messages/{emailId}Get a single emailview_email
GET/threads/{threadId}Get an email threadview_thread
POST/messages/sendSend a new emailsend_email
POST/messages/{emailId}/replyReply to an emailreply_to_email
POST/messages/{emailId}/forwardForward an emailforward_email
DELETE/messages/{emailId}Delete an emaildelete_email
PATCH/messages/{emailId}Modify email propertiesmark_as_read / apply_labels

Tip

Read endpoints include an optional accessInfo field that describes any active access restrictions on the token. This field is omitted when there are no restrictions.
GET/api/access/email/messagesBearer Token

Search/List Emails

Returns emails across all connected providers. Supports free-text search, structured filters, and pagination.

Query Parameters

ParameterTypeDefaultDescription
qstringFree-text search query
fromstringFilter by sender email address
tostringFilter by recipient email address
subjectstringFilter by subject (partial match)
labelstringFilter by label/category
unreadboolFilter by read status (true = unread only)
afterDateTimeEmails received after this date (UTC)
beforeDateTimeEmails received before this date (UTC)
hasAttachmentboolFilter emails with attachments
limitint20Max results (1–50)
includeBodyboolfalseInclude full email body in results
pageTokenstringPagination token from previous response

Examples

GET /messages
GET /messages?q=project+update
GET /messages?from=boss@example.com&unread=true
GET /messages?after=2026-02-01T00:00:00Z&before=2026-02-07T00:00:00Z
GET /messages?hasAttachment=true&limit=10
GET /messages?subject=invoice&from=billing@vendor.com

Response 200 OK

{
"emails": [
{
"id": "google:19485a3b2c1d",
"threadId": "google:19485a3b2c1d",
"subject": "Q1 Project Update",
"from": {
"email": "boss@example.com",
"name": "Jane Smith"
},
"to": [
{ "email": "you@example.com", "name": "You" }
],
"cc": null,
"bcc": null,
"bodyPreview": "Hi team, here's the latest update on the Q1 project...",
"body": null,
"bodyType": null,
"sentAt": "2026-02-07T14:30:00Z",
"receivedAt": "2026-02-07T14:30:02Z",
"isRead": false,
"hasAttachments": true,
"attachments": null,
"labels": ["INBOX", "IMPORTANT"],
"importance": "normal",
"provider": "GOOGLE"
}
],
"totalCount": 42,
"hasMore": true,
"nextPageToken": "token_abc123...",
"accessInfo": null
}

Note

Results from multiple providers are merged and sorted by received date (newest first). When includeBody is false (default), the body and bodyType fields are null. The bodyPreview field is always included when available.
GET/api/access/email/messages/{emailId}Bearer Token

Get Email

Returns a single email by its provider-prefixed ID.

Path Parameters

ParameterTypeDescription
emailIdstringProvider-prefixed email ID (e.g., google:19485a3b2c1d or m365:AAMkAGI2...)

Query Parameters

ParameterTypeDefaultDescription
includeBodybooltrueInclude full email body

Response 200 OK

{
"id": "google:19485a3b2c1d",
"threadId": "google:19485a3b2c1d",
"subject": "Q1 Project Update",
"from": {
"email": "boss@example.com",
"name": "Jane Smith"
},
"to": [
{ "email": "you@example.com", "name": "You" }
],
"cc": [
{ "email": "team@example.com", "name": "Team" }
],
"bcc": null,
"bodyPreview": "Hi team, here's the latest update...",
"body": "<html><body><p>Hi team, here's the latest update on the Q1 project...</p></body></html>",
"bodyType": "html",
"sentAt": "2026-02-07T14:30:00Z",
"receivedAt": "2026-02-07T14:30:02Z",
"isRead": true,
"hasAttachments": true,
"attachments": [
{
"id": "att_001",
"name": "report.pdf",
"contentType": "application/pdf",
"size": 245760,
"isInline": false
}
],
"labels": ["INBOX", "IMPORTANT"],
"importance": "normal",
"provider": "GOOGLE"
}

Error Responses

StatusDescription
404Email not found
GET/api/access/email/threads/{threadId}Bearer Token

Get Email Thread

Returns all messages in a thread by provider-prefixed thread ID.

Path Parameters

ParameterTypeDescription
threadIdstringProvider-prefixed thread ID (e.g., google:19485a3b2c1d or m365:AAQkAGI2...)

Response 200 OK

{
"id": "google:19485a3b2c1d",
"subject": "Q1 Project Update",
"messages": [
{
"id": "google:19485a3b2c1d",
"threadId": "google:19485a3b2c1d",
"subject": "Q1 Project Update",
"from": { "email": "boss@example.com", "name": "Jane Smith" },
"to": [{ "email": "you@example.com", "name": "You" }],
"body": "<p>Hi team, here's the update...</p>",
"bodyType": "html",
"sentAt": "2026-02-07T14:30:00Z",
"receivedAt": "2026-02-07T14:30:02Z",
"isRead": true,
"hasAttachments": false,
"provider": "GOOGLE"
},
{
"id": "google:19485a3b2c2e",
"threadId": "google:19485a3b2c1d",
"subject": "Re: Q1 Project Update",
"from": { "email": "you@example.com", "name": "You" },
"to": [{ "email": "boss@example.com", "name": "Jane Smith" }],
"body": "<p>Thanks for the update. Looks great!</p>",
"bodyType": "html",
"sentAt": "2026-02-07T15:00:00Z",
"receivedAt": "2026-02-07T15:00:01Z",
"isRead": true,
"hasAttachments": false,
"provider": "GOOGLE"
}
],
"messageCount": 2,
"participants": [
{ "email": "boss@example.com" },
{ "email": "you@example.com" }
],
"lastMessageAt": "2026-02-07T15:00:01Z",
"provider": "GOOGLE"
}

Note

Gmail uses native thread IDs. Microsoft 365 uses conversationId for threading. Messages are returned in chronological order (oldest first). Thread body content is always included.

Error Responses

StatusDescription
404Thread not found

Data Types

Email Object Fields

FieldTypeDescription
idstringProvider-prefixed email ID (e.g., google:abc123)
threadIdstring?Provider-prefixed thread ID
subjectstring?Email subject line
fromParticipant?Sender
toParticipant[]?To recipients
ccParticipant[]?CC recipients
bccParticipant[]?BCC recipients
bodyPreviewstring?Short body preview/snippet
bodystring?Full email body (only when requested)
bodyTypestring?Body content type: text or html
sentAtDateTime?When the email was sent (UTC)
receivedAtDateTime?When the email was received (UTC)
isReadboolWhether the email has been read
hasAttachmentsboolWhether the email has attachments
attachmentsAttachment[]?Attachment metadata
labelsstring[]?Email labels/categories
importancestring?Priority: low, normal, high
providerstringSource provider: GOOGLE or M365

Participant Object

FieldTypeDescription
emailstringEmail address
namestring?Display name

Attachment Object

FieldTypeDescription
idstringAttachment identifier
namestringFile name
contentTypestring?MIME content type
sizelongFile size in bytes
isInlineboolWhether the attachment is inline (embedded in body)

Thread Object

FieldTypeDescription
idstringProvider-prefixed thread ID
subjectstring?Thread subject (from first message)
messagesEmail[]All messages in the thread
messageCountintTotal number of messages
participantsParticipant[]All unique participants in the thread
lastMessageAtDateTime?Timestamp of the most recent message
providerstringSource provider: GOOGLE or M365