# Workspaces

> Source: https://developers.anymail.watch/workspaces/

A workspace holds prospects, campaigns, mailboxes and settings. Every token belongs to exactly one workspace. An API token belongs to the workspace it was generated in. An OAuth token belongs to the workspace picked on the consent screen.

| Method | Path | Action |
|---|---|---|
| `GET` | `/api/v1/workspaces` | The workspace of this token |

## List workspaces

```bash
curl "https://app.anymail.watch/api/v1/workspaces" \
  -H "Authorization: Bearer $ANYMAIL_TOKEN"
```

**Response `200`**

```json
{
  "data": [
    { "id": "00000000-0000-0000-0000-000000000001", "name": "Example Ltd", "created_at": "2026-08-01T00:00:00.000+00:00", "current": true }
  ],
  "next_cursor": null
}
```

The list has one row today, the workspace of the token, with `current: true`. It is a list so that a token for several workspaces can use the same shape later.

This call needs only the `read` scope, so it is a cheap way to check a token. The [CLI](/cli/) uses it on `anymail login`.

## The X-Workspace header

Send `X-Workspace: <workspace id>` on any request to state which workspace you mean. When it names another workspace than the one of the token, the request fails before it does anything.

```bash
curl "https://app.anymail.watch/api/v1/campaigns" \
  -H "Authorization: Bearer $ANYMAIL_TOKEN" \
  -H "X-Workspace: 00000000-0000-0000-0000-000000000001"
```

**Response `403`** when the id does not match

```json
{ "error": "This token does not have access to the workspace named in X-Workspace.", "code": "workspace_forbidden" }
```

The header is optional. Without it, the request uses the workspace of the token. Use it in a script that holds tokens for several workspaces, so that a mixed-up token fails loudly and does not write to the wrong workspace.

## Related

- [Authentication](/authentication/)
- [Domains](/domains/)
- [Errors](/errors/)
