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/emailAuthentication
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
| Provider | Prefix | Description |
|---|---|---|
| Google Gmail | google: | Gmail API via OAuth or service account JWT |
| Microsoft 365 | m365: | Microsoft Graph API via OAuth or client credentials |
Endpoints Overview
| Method | Endpoint | Description | Permission |
|---|---|---|---|
| GET | /messages | Search/list emails | search_emails |
| GET | /messages/{emailId} | Get a single email | view_email |
| GET | /threads/{threadId} | Get an email thread | view_thread |
| POST | /messages/send | Send a new email | send_email |
| POST | /messages/{emailId}/reply | Reply to an email | reply_to_email |
| POST | /messages/{emailId}/forward | Forward an email | forward_email |
| DELETE | /messages/{emailId} | Delete an email | delete_email |
| PATCH | /messages/{emailId} | Modify email properties | mark_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 TokenSearch/List Emails
Returns emails across all connected providers. Supports free-text search, structured filters, and pagination.
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
| q | string | — | Free-text search query |
| from | string | — | Filter by sender email address |
| to | string | — | Filter by recipient email address |
| subject | string | — | Filter by subject (partial match) |
| label | string | — | Filter by label/category |
| unread | bool | — | Filter by read status (true = unread only) |
| after | DateTime | — | Emails received after this date (UTC) |
| before | DateTime | — | Emails received before this date (UTC) |
| hasAttachment | bool | — | Filter emails with attachments |
| limit | int | 20 | Max results (1–50) |
| includeBody | bool | false | Include full email body in results |
| pageToken | string | — | Pagination 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 TokenGet Email
Returns a single email by its provider-prefixed ID.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
| emailId | string | Provider-prefixed email ID (e.g., google:19485a3b2c1d or m365:AAMkAGI2...) |
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
| includeBody | bool | true | Include 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
| Status | Description |
|---|---|
| 404 | Email not found |
GET
/api/access/email/threads/{threadId}Bearer TokenGet Email Thread
Returns all messages in a thread by provider-prefixed thread ID.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
| threadId | string | Provider-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
| Status | Description |
|---|---|
| 404 | Thread not found |
Data Types
Email Object Fields
| Field | Type | Description |
|---|---|---|
| id | string | Provider-prefixed email ID (e.g., google:abc123) |
| threadId | string? | Provider-prefixed thread ID |
| subject | string? | Email subject line |
| from | Participant? | Sender |
| to | Participant[]? | To recipients |
| cc | Participant[]? | CC recipients |
| bcc | Participant[]? | BCC recipients |
| bodyPreview | string? | Short body preview/snippet |
| body | string? | Full email body (only when requested) |
| bodyType | string? | Body content type: text or html |
| sentAt | DateTime? | When the email was sent (UTC) |
| receivedAt | DateTime? | When the email was received (UTC) |
| isRead | bool | Whether the email has been read |
| hasAttachments | bool | Whether the email has attachments |
| attachments | Attachment[]? | Attachment metadata |
| labels | string[]? | Email labels/categories |
| importance | string? | Priority: low, normal, high |
| provider | string | Source provider: GOOGLE or M365 |
Participant Object
| Field | Type | Description |
|---|---|---|
| string | Email address | |
| name | string? | Display name |
Attachment Object
| Field | Type | Description |
|---|---|---|
| id | string | Attachment identifier |
| name | string | File name |
| contentType | string? | MIME content type |
| size | long | File size in bytes |
| isInline | bool | Whether the attachment is inline (embedded in body) |
Thread Object
| Field | Type | Description |
|---|---|---|
| id | string | Provider-prefixed thread ID |
| subject | string? | Thread subject (from first message) |
| messages | Email[] | All messages in the thread |
| messageCount | int | Total number of messages |
| participants | Participant[] | All unique participants in the thread |
| lastMessageAt | DateTime? | Timestamp of the most recent message |
| provider | string | Source provider: GOOGLE or M365 |