---
title: "Account"
description: "Every operation in this group: what it accepts, what it returns and the errors it can answer with."
url: "https://openemail.uk/docs/api/reference/account"
area: "API"
category: "Reference"
---

# Account

Every operation in this group: what it accepts, what it returns and the errors it can answer with.

## Operations

What this key is and may do.

### `GET /addresses`

What this key may send as

The answer to an unexplained 403 or 409. `unrestricted` is true only on a key with neither allowlist set, and it means any local-part on a verified domain is accepted, including ones nobody has created. A key holding whole domains reads as `unrestricted: false` and still takes any local-part on those domains, so `GET /keys/self` is where you read which ones. `canSend` on an address is false when the address is disabled, when neither allowlist on the key covers it, or when the domain cannot sign yet, and `sendingVerified` on each domain is that last fact on its own.

Requires the `emails:send` scope.

- Scopes: `emails:send`.

**Query parameters**

- `limit` (`integer`, at least 1, at most 100, default `25`): Rows per page, 1 to 100.
- `cursor` (`string`): The previous page's `nextCursor`, passed back as it came. It is opaque: it holds where the last row sat in this list's order, so a row deleted or edited between pages never breaks the walk, and the next page starts at the first row that sorts after it. A value this list did not hand out is a 400 `invalid_cursor`.

**Returns**

- `200`: A page of addresses, alphabetically, with `hasMore` and `nextCursor`, plus `unrestricted` and every sendable domain on each page.

**Errors**

- The errors every operation can return: `400`, `401`, `403`, `404`, `422`, `500`, described in the [error catalog](https://openemail.uk/docs/api/errors).

Also available in: SDK [`addresses.list()`](https://openemail.uk/docs/sdk/reference/addresses#list), [`addresses.listAll()`](https://openemail.uk/docs/sdk/reference/addresses#listAll), [`addresses.iterate()`](https://openemail.uk/docs/sdk/reference/addresses#iterate); CLI [`openemail addresses list`](https://openemail.uk/docs/cli/reference/addresses#addresses-list); MCP [`whoAmI`](https://openemail.uk/docs/mcp/tools/workspace#whoAmI).

### `GET /keys/self`

What this key is

Needs no scope: a key may always describe itself.

`scopes` is the EFFECTIVE list and the only one that authorises anything: the scopes on the key itself, intersected with the permissions of the role it was issued under. `grantedScopes` is what the key was created holding, and `roleId` names the ceiling that narrowed it, so anything in the first list and missing from the second was removed by that role.

That difference is the answer to the confusing 403. A key created with `emails:send` and capped by a viewer role is refused for lacking `emails:send`, which reads as a lie against the key the console is displaying; the fix is to change the role rather than to mint another key. `roleId` is null on a key with no ceiling, which is what every key issued before roles existed still has.

Two independent lists narrow what the key may send as. `domainAllowlist` holds whole domains, and the key may send as any address on one of them, including addresses created after the key was. `addressAllowlist` holds individual addresses. Both null or both empty means the key may send as any address the workspace owns. With either one set the key is narrowed, and reads of sent mail, tracking and calendar narrow to the same set. An address whose domain is already in `domainAllowlist` is dropped from `addressAllowlist` when the lists are written, so the two never overlap.

- Needs an API key or an OAuth access token, and no scope.

**Returns**

- `200`: Id, mode, effective scopes, the role capping them, and both allowlists.

**Errors**

- The errors every operation can return: `400`, `401`, `403`, `404`, `422`, `500`, described in the [error catalog](https://openemail.uk/docs/api/errors).

Also available in: SDK [`me.get()`](https://openemail.uk/docs/sdk/reference/me#get); CLI [`openemail me get`](https://openemail.uk/docs/cli/reference/me#me-get); MCP [`whoAmI`](https://openemail.uk/docs/mcp/tools/workspace#whoAmI).

### `POST /keys/self/rotate`

Replace this key's secret

Mints a new secret for the key making the call and returns it once. There is no body and no way to name another key here: this call rotates the caller and nothing else, and `POST /keys/{id}/rotate` is the one that reaches other keys, behind `keys:manage`.

The old secret stops working the instant this returns. There is no overlap window and no grace period, and the response is the only place the new secret ever appears, so a caller that drops it has locked itself out until somebody in the console rotates the key again.

Everything else about the key is unchanged: same id, same name, same mode, same scopes, same role, same allowlists and same expiry. Only the last four characters move, because they are part of the secret. The request history hangs off the id rather than off the secret, so it runs straight through a rotation and reads as one key on both sides of it rather than as two.

Weigh that before granting `keys:write`. A stolen key holding it can rotate itself and take the secret away from the person who owns the key. It cannot hide while doing so, because the id does not move and revoking it from the console still works.

Requires the `keys:write` scope.

- Scopes: `keys:write`.

**Returns**

- `200`: The body of `GET /keys/self`, plus `token`, the new secret in full and for the only time, `rotationCount`, an integer counting every rotation this key has had, and `rotatedAt`, when this one landed, ISO-8601.

**Errors**

- `403`: `insufficient_scope`: the key lacks `keys:write`. `api_key_only`: the request carried an OAuth access token, which has no secret to rotate.
- `404`: `resource_not_found`: the key is gone. It authenticated this request and was deleted before the rotation landed, which is the only way to reach this.
- `409`: `revoked`: the key was revoked between authenticating this request and rotating it. `expired`: it passed its expiry in the same gap. Neither is rotatable, and a key in either state authenticates nothing afterwards, so the answer is a new key from the console.
- The errors every operation can return: `400`, `401`, `422`, `500`, described in the [error catalog](https://openemail.uk/docs/api/errors).

Also available in: SDK [`me.rotate()`](https://openemail.uk/docs/sdk/reference/me#rotate); CLI [`openemail me rotate`](https://openemail.uk/docs/cli/reference/me#me-rotate).

### `GET /ping`

Auth smoke test

- Needs an API key or an OAuth access token, and no scope.

**Returns**

- `200`: ok, with the effective scopes and the role that capped them.

**Errors**

- The errors every operation can return: `400`, `401`, `403`, `404`, `422`, `500`, described in the [error catalog](https://openemail.uk/docs/api/errors).

Also available in: SDK [`me.ping()`](https://openemail.uk/docs/sdk/reference/me#ping); CLI [`openemail me ping`](https://openemail.uk/docs/cli/reference/me#me-ping).
