connected apps.md
title: "Connected Apps" description: "List the apps and MCP clients people in your organization connected to MachineMail with OAuth, and disconnect one to revoke its tokens immediately." canonical: "https://machinemail.dev/docs/reference/api/connected-apps"
Connected Apps
List the apps and MCP clients people in your organization connected to MachineMail with OAuth, and disconnect one to revoke its tokens immediately.
Source: https://machinemail.dev/docs/reference/api/connected-apps
| Method | Path | Summary |
|---|---|---|
GET |
/v0/oauth-grants |
List Connected Apps |
DELETE |
/v0/oauth-grants/{grant_id} |
Disconnect App |
List Connected Apps
GET /v0/oauth-grants
Apps and MCP clients people in the organization connected with OAuth. Requires an organization-scoped credential with api_key_read; pod, inbox and sandbox credentials get 403.
Authentication: Authorization: Bearer <api key> or the dashboard mm_session cookie. Permission: none beyond a valid key.
Query parameters
| Field | Type | Description | |
|---|---|---|---|
limit |
integer |
Maximum number of items to return. Default 50, maximum 500; larger values are capped. | |
page_token |
string |
next_page_token from the previous page. | |
ascending |
boolean |
Sort oldest first. |
Response
200 A page of grants (application/json)
| Field | Type | Description | |
|---|---|---|---|
count |
integer |
required | Number of items returned. |
limit |
integer |
Maximum number of items per page. Default 50, maximum 500; larger values are capped. | |
next_page_token |
string |
Page token for pagination. Absent on the last page. | |
oauth_grants |
OAuthGrant[] |
required | Newest first unless ascending is set. |
Each item of oauth_grants is a OAuthGrant:
| Field | Type | Description | |
|---|---|---|---|
grant_id |
string |
required | ID of the grant (oag_...). |
client_id |
string |
required | |
client_name |
string | null |
required | Self-reported by the client at registration. |
client_uri |
string | null |
required | |
logo_uri |
string | null |
required | |
registration |
"dynamic" | "metadata_document" |
required | |
user_id |
string |
required | Who approved it. |
user_email |
string | null |
required | |
scopes |
("inboxes.read" | "inboxes.write" | "messages.read" | "messages.send" | "messages.write" | "webhooks.read" | "webhooks.write" | "domains.read" | "domains.write" | "lists.read" | "lists.write" | "metrics.read" | "pods.read" | "pods.write" | "api_keys.read" | "api_keys.write")[] |
required | |
resource |
string |
required | Audience of its access tokens. |
pod_id |
string | null |
required | Set when the grant is limited to one pod. |
inbox_id |
string | null |
required | Set when the grant is limited to one inbox. |
created_at |
string (date-time) |
required | |
last_used_at |
string (date-time) | null |
required | Last token refresh or API call (updated at most once a minute). |
expires_at |
string (date-time) |
required | When the current refresh token expires unless it is used (30 days after the last refresh). |
Errors
| Status | Meaning |
|---|---|
400 |
Invalid request: error.type is validation and error.param names the field. |
401 |
Missing, invalid, expired or revoked credential. |
403 |
The credential lacks the permission or scope for this request (error.type forbidden), or MachineMail suspended the organization or its sending (account_suspended: error.message says what still works; do not retry or re-register). |
500 |
Unexpected server error. |
Error bodies use the error envelope.
Example
curl "https://api.machinemail.dev/v0/oauth-grants" \
-H "Authorization: Bearer $MACHINEMAIL_API_KEY"
{
"count": 1,
"limit": 50,
"next_page_token": "eyJvIjo1MH0",
"oauth_grants": [
{
"grant_id": "string",
"client_id": "my-client-id",
"client_name": "string",
"client_uri": "https://example.com",
"logo_uri": "https://example.com",
"registration": "dynamic",
"user_id": "usr_01k6x3j0rw0000n8w4yc0g3q5s",
"user_email": "agent@machinemail.dev",
"scopes": ["inboxes.read"],
"resource": "string",
"pod_id": "pod_01k6x2m9qd0001b8j4mr0w3d5f",
"inbox_id": "agent@machinemail.dev",
"created_at": "2026-10-01T12:00:00.000Z",
"last_used_at": "2026-10-01T12:00:00.000Z",
"expires_at": "2026-10-01T12:00:00.000Z"
}
]
}
Disconnect App
DELETE /v0/oauth-grants/{grant_id}
Revokes the grant: its refresh token and every access token issued from it stop working immediately (401 on /mcp and /v0). Returns the grant as it was. Requires an organization-scoped credential with api_key_delete.
Authentication: Authorization: Bearer <api key> or the dashboard mm_session cookie. Permission: none beyond a valid key.
Path parameters
| Field | Type | Description | |
|---|---|---|---|
grant_id |
string |
required | ID of the grant (oag_...). |
Response
200 The revoked grant (application/json)
Errors
| Status | Meaning |
|---|---|
401 |
Missing, invalid, expired or revoked credential. |
403 |
The credential lacks the permission or scope for this request (error.type forbidden), or MachineMail suspended the organization or its sending (account_suspended: error.message says what still works; do not retry or re-register). |
404 |
Not found. Also returned for resources outside the credential scope. |
500 |
Unexpected server error. |
Error bodies use the error envelope.
Example
curl -X DELETE "https://api.machinemail.dev/v0/oauth-grants/string" \
-H "Authorization: Bearer $MACHINEMAIL_API_KEY"
{
"grant_id": "string",
"client_id": "my-client-id",
"client_name": "string",
"client_uri": "https://example.com",
"logo_uri": "https://example.com",
"registration": "dynamic",
"user_id": "usr_01k6x3j0rw0000n8w4yc0g3q5s",
"user_email": "agent@machinemail.dev",
"scopes": ["inboxes.read"],
"resource": "string",
"pod_id": "pod_01k6x2m9qd0001b8j4mr0w3d5f",
"inbox_id": "agent@machinemail.dev",
"created_at": "2026-10-01T12:00:00.000Z",
"last_used_at": "2026-10-01T12:00:00.000Z",
"expires_at": "2026-10-01T12:00:00.000Z"
}