# Authentication and tokens

Project keys, short-lived tokens, OAuth for apps and account tokens, with the scopes each one holds.

## Kinds of credential

Every credential is sent the same way, as `Authorization: Bearer`. They differ in what they reach and how long they live.

- **Secret key**: A key for servers. Belongs to one project. Can be limited by scope, address and expiry, and replaced with an overlap.
- **Publishable key**: A key for browsers. Public reads and form-style writes only, and it must name the origins it may be used from.
- **Short-lived token**: Made from a key with POST /keys/tokens for one browser, one agent run or one outside call. Lives 60 to 3,600 seconds (900 by default), holds at most the scopes of the key that made it and cannot manage keys.
- **OAuth**: For apps. Client credentials at POST /oauth/token, where the client id is the key prefix and the client secret is the key. For an app acting for a person, authorisation code with PKCE: register the app, send the person to the consent screen, and the person can take the grant back at any time.
- **Account token**: For the command line and agents that work above one project. Made by a signed-in person with POST /account/tokens. Lists and makes organisations and projects, and reaches nothing inside a project. Lives 90 days unless you choose another length, up to 365.

## Scopes

A scope is `area:level`. The areas are the ones in the API reference, such as `contacts`, `inbox` or `shop`. The levels are `read`, `write` and `admin`, and a higher level includes the ones below it. Each operation lists the scope it needs. A key with no matching scope answers 403.

An account token has its own three scopes: `account:read`, `account:write` (which includes read) and `account:members`, which is held only when the person asks for it and lets the token invite or change members below the admin role.

## Limit a key

When you make a key you can set the scopes, the days until it expires, the addresses it may call from, the origins a publishable key may be used on, its own requests-per-minute limit, and whether it is live or test.

## Replace and revoke

`POST /keys/{id}/rotate` answers a new key while the old one keeps working for an overlap, so you can deploy the new secret without a gap. `DELETE /keys/{id}` revokes a key at once. `GET /keys/events` lists when each key was made, replaced and revoked. Secrets are stored only as a hash, so a lost secret cannot be shown again.

## Make a short-lived token

Your server keeps the key and hands the browser or the agent a token that expires in minutes.

Request:

```
curl -sS https://api.rivier.ai/keys/tokens \
  -H "Authorization: Bearer $RIVIER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "scopes": ["contacts:read"], "ttlSeconds": 600 }'
```

Response:

```
{
  "token": "ipn_st_…",
  "token_type": "Bearer",
  "expires_in": 600,
  "expires_at": "2026-11-10T12:10:00.000Z",
  "scopes": ["contacts:read"],
  "key_id": "…"
}
```

## What stays with a person

Some actions are kept for a signed-in person whatever a key holds: approving and sending a campaign, changing the plan or billing, and profile and security settings. Others need the admin level, which ordinary read and write keys do not hold: bulk import, export and erasure of contacts, and making or revoking keys. An agent can prepare these and a person approves them in the app.
