# Authentication

The REST API, the GraphQL API and the MCP server all authenticate with an
**API token** sent in the `Authorization` header:

```http
Authorization: Bearer jmi_Ab3dE9xY...
```

A token is 47 characters: `jmi_` followed by 43 random characters. Tokens in
query strings or cookies are not accepted.

## Creating a token

Open **Settings → API tokens** in the dashboard and choose:

- **Name**: what the token is for ("Terraform", "Status board", "Claude"),
  1-64 characters. It appears in the token list and in the audit log.
- **Role**: `viewer`, `member` or `admin` (below), at most your own role in
  the organisation.
- **Expiry**: 1 to 365 days, or never. The dashboard suggests 90 days.

Creating a token asks for your password again if you have not entered it in
the last 10 minutes. The token is shown **once**; copy it into your secret
store straight away. JustMonitorIt keeps only a hash of it and cannot show
it again. The list keeps the first 8 characters after `jmi_` (the
**prefix**) so you can tell tokens apart, and shows when and from which
address each one was last used.

An organisation can have at most 50 tokens.

## Whose token it is

A token belongs to **you and one organisation**. It works only on that
organisation's paths (`/orgs/{org}/...`); with any other organisation's id
the API answers `404 not_found`, as it would to a non-member. `GET /token`
tells a program which organisation its token belongs to.

The token acts for you, so:

- Changes made with it are recorded in the audit log as yours, with
  `data.api_token` naming the token (`{"id": "tok_...", "name": "..."}`).
  Acknowledging an incident with a token shows you as the acknowledger.
- Its **effective role** is the lower of the token's role and your current
  role in the organisation, checked on every request.
- If your role is lowered below a token's role, that token is revoked (the
  audit log records `api_token.revoked` with reason `creator_role_lost`).
- If you leave or are removed from the organisation, all your tokens for it
  are deleted.
- If your account is suspended, your tokens stop working at once
  (`403 account_suspended`).

## Roles

| Action | `viewer` | `member` | `admin` |
|---|---|---|---|
| Read monitors, results, uptime, incidents, contacts, notifications, plan and usage | yes | yes | yes |
| Create, change, pause, resume and delete monitors; run checks and path traces | | yes | yes |
| Acknowledge incidents and add notes | | yes | yes |
| Create, change, verify, test and delete contacts | | yes | yes |
| Rename the organisation, change its timezone | | | yes |
| Invite people (not as owner), change members' roles (not to or from owner), remove members (not owners) | | | yes |
| Read the audit log | | | yes |

The [REST reference](generated/rest-reference.md) lists the lowest token
role of every operation. A token whose role is too low gets
`403 forbidden`.

### What a token can never do

Some actions need a person signed in to the dashboard:

- **Owner-only actions**: subscribing and the billing portal, exporting the
  organisation's data, deleting the organisation, granting or removing
  ownership, inviting an owner. There are no owner tokens, so these answer
  `403 forbidden`.
- **Actions that ask for your password again**, such as re-enabling an email
  contact that bounced: `403 forbidden` with the detail "This action needs a
  signed-in session; API tokens cannot perform it."
- **Account and session endpoints**: managing tokens themselves, your
  profile, passwords and two-factor settings, the list of your
  organisations, accepting invitations and the dashboard's live event
  stream. With a token these answer `401 unauthenticated`.

## Expiry and revocation

An expired or revoked token gets `401 unauthenticated` with

```http
WWW-Authenticate: Bearer realm="JustMonitorIt", error="invalid_token"
```

Revoke a token in **Settings → API tokens**. You can revoke your own
tokens; owners and admins can revoke anyone's. Revocation takes effect on the
next request.

From one IP address, more than 30 rejected tokens a minute are answered with
`429 rate_limited` (with `Retry-After`) without checking the token.

## Rate limits

Each token may make 600 reads (`GET`) a minute. Writes count against 120 a
minute for you (shared with your dashboard sessions and your other tokens)
and 120 a minute for the organisation. Some operations have their own
limits, listed in [REST conventions](rest.md#rate-limits). A request over a
limit gets `429 rate_limited` with a `Retry-After` header in seconds.

## Keeping tokens safe

- Use one token per program or integration, so you can revoke one without
  breaking the others.
- Give each token the lowest role that works: `viewer` for dashboards and
  reports.
- Set an expiry, and rotate tokens by creating the new one before revoking
  the old one.
- Keep tokens in a secret manager or your CI's secret store, never in source
  control. If one leaks, revoke it in the dashboard; the audit log shows
  what it did.
- The API is for servers and scripts. It sends no CORS headers, so a
  browser page on another site cannot call it; do not put a token in
  front-end code.
