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

# Authentication

> Personal API tokens, Visor CLI login, scopes, expiry, and revocation.

Every request sends a personal API token in the `Authorization` header with the `Bearer` scheme:

```http theme={null}
Authorization: Bearer visor_pat_<public_id>_<secret>
```

A request without a valid token receives `401`. See [Errors](https://docs.visorfinance.app/errors.md) for each code.

The Visor CLI can also log in through your browser instead of a personal API token. See [Visor CLI login](#visor-cli-login).

## Tokens

* Create, list, and revoke tokens in [Settings > Connected apps](https://dashboard.visorfinance.app/settings/connected_apps).
* You can hold up to **10 active tokens** at a time. Expired and revoked tokens do not count.
* Visor shows the full token only once, right after you create it. Visor stores only a one-way digest of the secret, so nobody, including Visor support, can show it to you again.
* The token list shows a safe prefix such as `visor_pat_abcd2345efgh6789` so you can tell tokens apart.

## Scopes

Each token has an access level that sets its scopes:

| Access level in Settings | Scopes |
| - | - |
| Read only | `pfm:read` |
| Read and record transactions | `pfm:read`, `pfm:transactions:write` |

Each operation lists the scope it requires. A valid token without that scope receives `403 INSUFFICIENT_SCOPE`. A token never gains new permissions after you create it; when Visor adds a new kind of write access, you create a new token to use it.

## Expiry

Choose 30, 90, or 365 days when you create a token, or **Never expires**. After a token expires, requests receive `401 TOKEN_EXPIRED`. Create a new token and replace the old value in your scripts.

> [!WARNING]
>
> A token that never expires works until you revoke it. If it leaks, anyone who has it can read your data until you revoke it. Prefer an expiry, and revoke tokens you no longer use.

## Revocation

Revoke a token in Settings when you no longer need it or think it leaked. Revocation takes effect on the next request, which receives `401 TOKEN_REVOKED`.

## Visor CLI login

The Visor CLI logs in with OAuth 2.0 (authorization code with PKCE) instead of a personal API token:

1. The CLI opens the Visor authorization page (`/oauth/authorize`) in your browser and listens on `http://127.0.0.1:<port>/callback`.
2. You log in to Visor and choose an access level: **Read only** (`pfm:read`) or **Read and record transactions** (`pfm:read`, `pfm:transactions:write`).
3. The CLI exchanges the code at `/oauth/token` and sends the access token as `Authorization: Bearer <access_token>`.

The CLI login has these rules:

* An access token expires after 24 hours and then receives `401 TOKEN_EXPIRED`. The CLI then uses its refresh token, which works for 30 days, to get a new access token.
* Each refresh token is single-use. Store the new access and refresh tokens together after a successful refresh. Reusing the previous refresh token returns `invalid_grant`.
* The scopes, the error codes, the plan check, and the [rate limit](https://docs.visorfinance.app/rate-limits.md) are the same as for a personal API token. Each access token has its own rate limit.
* The CLI login appears as **Visor CLI** in [Settings > Connected apps](https://dashboard.visorfinance.app/settings/connected_apps). Revoke it there to end the login. The next request receives `401 TOKEN_REVOKED`, and the refresh token stops working.
* Only the Visor CLI can use this login on the personal API. Tokens that MCP clients such as Claude or Cursor receive do not work on `/v1`, and Visor CLI tokens do not work on the MCP server.

On a machine without a browser, such as a server or CI, create a personal API token and give it to the CLI.

### End a CLI login

`visor auth logout` can end its server login with `POST /oauth/revoke` (RFC 7009). Send the public CLI `client_id` and either its access token or its refresh token. A client secret, a browser session, and a bearer header are not required.

```bash theme={null}
curl -X POST https://dashboard.visorfinance.app/oauth/revoke \
  --data-urlencode 'client_id=908603ea-465f-4d4c-b5ac-30955885ee1d' \
  --data-urlencode "token=$REFRESH_TOKEN" \
  --data-urlencode 'token_type_hint=refresh_token'
```

`token_type_hint` is optional. Visor checks both token types even if the hint names the wrong type. The response is `200 OK` with an empty body, including for unknown or already revoked tokens.

Revocation ends the whole login, including its older and newer tokens from refresh rotation. Its next `/v1` request receives `401 TOKEN_REVOKED`, and refresh returns `invalid_grant`. Other CLI logins remain active. This endpoint cannot revoke MCP clients or personal API tokens.

A missing or different `client_id` returns `401 invalid_client`. A missing or malformed `token` returns `400 invalid_request`. The OAuth server metadata advertises `revocation_endpoint` and `revocation_endpoint_auth_methods_supported: ["none"]`.

## Plan and availability

The personal API requires an active Pro or Premium plan, checked on every request.

* If your account loses Pro or Premium, requests receive `403 PLAN_REQUIRED`. Your tokens stay in place and work again when the plan returns.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.