---
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](#list-connected-apps) |
| `DELETE` | `/v0/oauth-grants/{grant_id}` | [Disconnect App](#disconnect-app)           |

## List Connected Apps

```http
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](/content/docs/reference/api/objects#oauthgrant/index.html):

| 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](/content/docs/reference/errors/index.html).

#### Example

```bash title="Request"
curl "https://api.machinemail.dev/v0/oauth-grants" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"
```

```json title="Response 200"
{
  "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

```http
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](/content/docs/reference/errors/index.html).

#### Example

```bash title="Request"
curl -X DELETE "https://api.machinemail.dev/v0/oauth-grants/string" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"
```

```json title="Response 200"
{
  "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"
}
```
