> ## Documentation Index
> Fetch the complete documentation index at: https://opentrain.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# List Tokens

> List every personal API token on the account — names, scopes, status, expiry. Secrets are never returned.

Lists every personal API token on the account — active, expired, and revoked — with metadata only. **Secrets are never returned** after creation; the `preview` field shows just enough (prefix + last 4 characters) to match a token you hold against its record.

Use this to audit what can access the account, find the `id` to pass to [revoke](/docs/developers/api-reference/tokens/revoke), and check how close you are to the 25-active-token cap before [creating](/docs/developers/api-reference/tokens/create) more.

**Requirements:** any valid token — token management needs no specific scope or feature flag, and works pre-claim.

## Request

No parameters.

## Response

<ResponseField name="tokens" type="object[]">
  <Expandable title="token">
    <ResponseField name="id" type="string">
      Token ID — pass to [`DELETE /tokens/{tokenId}`](/docs/developers/api-reference/tokens/revoke).
    </ResponseField>

    <ResponseField name="name" type="string">
      Human-readable label set at creation.
    </ResponseField>

    <ResponseField name="preview" type="string">
      Masked secret, e.g. `ot_pat_c3f9********bd21` — prefix plus the last 4 characters.
    </ResponseField>

    <ResponseField name="scopes" type="string[]">
      The token's [scopes](/docs/developers/concepts/scopes-and-capabilities), sorted.
    </ResponseField>

    <ResponseField name="status" type="string">
      `active`, `expired` (past `expiresAt`), or `revoked`.
    </ResponseField>

    <ResponseField name="organizationId" type="string | null">
      The organization the token is bound to, when applicable.
    </ResponseField>

    <ResponseField name="createdAt" type="string">
      ISO creation timestamp.
    </ResponseField>

    <ResponseField name="lastUsedAt" type="string | null">
      Last time the token authenticated a request — `null` means never used.
    </ResponseField>

    <ResponseField name="expiresAt" type="string | null">
      When the token stops working; `null` means no expiry.
    </ResponseField>

    <ResponseField name="revokedAt" type="string | null">
      When the token was revoked; `null` unless `revoked`.
    </ResponseField>
  </Expandable>
</ResponseField>

## Errors

| Status | `code`         | Meaning                  |
| ------ | -------------- | ------------------------ |
| `401`  | `UNAUTHORIZED` | Missing or invalid token |

<RequestExample>
  ```bash curl theme={null}
  curl -sS https://app.opentrain.ai/api/public/v1/tokens \
    -H "Authorization: Bearer $OT_API_TOKEN"
  ```

  ```bash CLI theme={null}
  opentrain tokens list --json
  ```

  ```json MCP: opentrain_list_tokens theme={null}
  {}
  ```
</RequestExample>

<ResponseExample>
  ```json 200 theme={null}
  {
    "tokens": [
      {
        "id": "<TOKEN_ID>",
        "name": "Hiring agent",
        "preview": "ot_pat_c3f9********bd21",
        "scopes": ["jobs:read", "jobs:write", "proposals:read"],
        "status": "active",
        "organizationId": null,
        "createdAt": "2026-06-12T10:00:00.000Z",
        "lastUsedAt": "2026-06-12T11:30:00.000Z",
        "expiresAt": null,
        "revokedAt": null
      },
      {
        "id": "<TOKEN_ID_2>",
        "name": "Old CI token",
        "preview": "ot_pat_91ab********77e2",
        "scopes": ["jobs:read"],
        "status": "revoked",
        "organizationId": null,
        "createdAt": "2026-05-27T18:30:46.565Z",
        "lastUsedAt": null,
        "expiresAt": null,
        "revokedAt": "2026-05-27T18:36:08.676Z"
      }
    ]
  }
  ```
</ResponseExample>
