---
title: "Revoke a connected app"
method: DELETE
path: "/v1/oauth/grants/{id}"
tags: ["Connected Apps"]
---

# Revoke a connected app

`DELETE /v1/oauth/grants/{id}`

## Request

- Base URL: `https://api.mails.ai`
- URL: `https://api.mails.ai/v1/oauth/grants/{id}`
- Auth: HTTP bearer

**Requires scope:** `manage`. Ends the sign-in, as Revoke in Settings › Connected apps does: every access and refresh token it was issued stops working at once, and the app has to be approved again to get back in. The API keys and webhook endpoints it created, and the webhook signing secrets it was shown, stay; the response counts them, so revoke and rotate those yourself. (Only when one of its refresh tokens is used twice, a sign of theft, does mails.ai remove them as well, and rotate those secrets again.) Idempotent: revoking an app already revoked returns its existing `revoked_at`. Closed to apps connected by sign-in (403 `connected_app_not_allowed`), and to a key tied to one agent (403): use an API key with `manage` that is not tied to an agent, or the mails CLI.

## Path parameters

- `id` string, required

## Response `200`

The revoked app, with what it left behind.

- ConnectedAppRevoked
  - `id` string, required: The sign-in's id (`oag_…`): the id in the path.
  - `client_id` string, required: The app's OAuth client id: the id it registered with, or the address of its client-ID document.
  - `client_name` string, nullable, required: The name the app gave itself, at most 80 characters, or null when it gave none; `mails CLI` for the mails CLI.
  - `first_party` boolean, required: `true` for the mails CLI, `false` for an app somebody connected by signing in.
  - `scope` string, required: What the person had approved: `full_access`, `send` or `read`.
  - `scopes` string[], required: What its tokens could do until the revoke, in the API key scopes: `full_access` = `send` + `read` + `manage`, `send` = `send` + `read`, `read` = `read`. Never more than the role of the person who approved it gave an app: a Member's apps never hold `manage`, and a Billing member's hold `read` only.
  - `created_at` string, date-time, required: When the app was first approved.
  - `approved_at` string, date-time, required: When it was last approved before this revoke.
  - `last_used_at` string, date-time, nullable, required: When one of its tokens was last used, recorded at most once a minute. Null when none was used.
  - `created_api_keys` integer, required: API keys it created that still work after the revoke.
  - `created_webhooks` integer, required: Webhook endpoints it created, still in place after the revoke.
  - `signing_secrets_known` integer, required: Other webhook endpoints still signing with a secret it was shown.
  - `revoked_at` string, date-time, required: When the sign-in was ended and its tokens stopped working. For one that was already revoked, the time it ended then.

## Other responses

- `401`: Missing or invalid API key.
- `403`: The API key lacks the required scope (`insufficient_scope`), or the token belongs to an app connected by sign-in and this operation is closed to connected apps (`connected_app_not_allowed`).
- `404`: Resource not found in this workspace, or the agent a send names is archived (`agent_archived`).
- `500`: Internal server error.

---

[API](https://skmtc.dev/mails/apis/mails-ai-api.md) · [All operations](https://skmtc.dev/mails/apis/mails-ai-api/llms.txt) · [OpenAPI document](https://skmtc.dev/mails/apis/mails-ai-api/revisions/4d4930a8c33b?raw)
