# Tokens and scopes

> How to create a Slicer API token, choose its scopes, expiry and spend limit, where to keep the token and how to revoke it.

Source: https://docs.slicer.media/en/api/authentication/

Every API request is signed with a token in the `Authorization: Bearer` header. A token belongs to your account and acts on your behalf, but only within the **scopes** and **spend limit** you chose. That way a reporting script gets read-only access, and an automated montage service can't spend more than its budget.

## Create a token

### 1. Open the developer section

**Profile** → **Developers** in the web app or in the app for iPhone, iPad and Mac. The screen itself is described in the guide [Developers: tokens and apps](https://docs.slicer.media/en/guide/account/developers/).

### 2. Choose Create token and fill in the form

-   **Name** — up to 60 characters, so you can tell tokens apart: "Newsletter server", "Laptop".
-   **Access** — one of the presets or your own set of scopes (below).
-   **Expiry** — 30, 90 or 365 days, or no expiry.
-   **Spend limit** — none, 50, 200 or 1000 tokens a month, or your own number.

A token can only be created in a Slicer app while signed in — another token can't issue one. If you haven't entered your password recently, the app will ask you to confirm it's you.

### 3. Copy the token

The token is shown **once**. Slicer stores only its hash, so it can't be shown again — if you lose it, revoke it and create a new one. Your account email receives an "API token created" message with the token name, access and expiry.

An account can have up to 20 active tokens.

## Send the token

Terminal:

```bash
curl https://api.slicer.media/v1/me \
  -H "Authorization: Bearer $SLICER_TOKEN"
```

The API accepts the token only in the header. Cookies and query parameters are not used for authentication, so a Slicer browser session gives no access to `/v1`.

## Scopes

A scope is permission for a group of actions. Each endpoint requires one or more scopes; the [reference](https://docs.slicer.media/en/api/reference/) lists them for every endpoint.

| Scope | What it allows |
| --- | --- |
| `account:read` | **Account and balance** — See your name, token balance and transaction history |
| `projects:read` | **View projects** — Projects, stages, versions, video text and downloading finished videos |
| `projects:write` | **Edit projects** — Upload materials, edit videos, change the style, choose a version, export and delete projects — free |
| `montage:run` | **Run montage — spends tokens** — Montage, rebuild, retry, AI assistant and caption translation. The price is always confirmed before starting |
| `publish` | **Publish to social networks** — See connected social accounts and publish videos to them |
| `webhooks` | **Webhooks** — Add endpoints for notifications about finished videos and publications |

Presets in the token dialog: **Read only** — `account:read`, `projects:read` · **Montage** — `account:read`, `projects:read`, `projects:write`, `montage:run` · **Full access** — `account:read`, `projects:read`, `projects:write`, `montage:run`, `publish`, `webhooks`

When creating a token, a preset is the quickest choice:

| Preset | Scopes | For |
| --- | --- | --- |
| **Read only** | `account:read`, `projects:read` | reports, dashboards, backing up your videos |
| **Montage** | \+ `projects:write`, `montage:run` | automating montage and edits; the default for AI agents |
| **Full access** | all six, including `publish` and `webhooks` | your own publishing service with notifications |

The style catalog (`GET /v1/styles`), export presets and price estimates (`POST /v1/estimate`) work with any scope.

> **Important.** Without the `montage:run` scope a token can't spend a single token from your balance: montage, rebuild, retry, captions from speech, the AI assistant and caption translation are unavailable to it. Creating a free project without the AI director (`mode: "manual"`), editing and exporting it work without it — `projects:write` is enough. Don't grant this scope to scripts that don't need paid features.

## Expiry

You choose the expiry when creating the token: 30, 90 or 365 days, or no expiry. Seven days before it expires, your account email receives a reminder. After that, requests get `401 token_expired`; a token can't be extended — create a new one and swap it in your program.

## Spend limit

The limit is how many tokens this API token may spend in a calendar month (UTC). It counts every operation started with this token: running (reserved) and completed. If an operation was cancelled or failed and its reservation went back to your balance, it doesn't count.

-   What's left is shown in `GET /v1/me` (`token.spendLimit`, `token.spentThisMonth`) and in every `Quote` (`spendLimitLeft`).
-   An operation that doesn't fit into the limit doesn't start: `402 spend_limit_exceeded`, even if your balance is sufficient.
-   You can change the limit in the token list without reissuing the token.

The limit works together with price confirmation: every paid operation names its price first and starts only with `confirmCost` ([Montage and pricing](https://docs.slicer.media/en/api/montage/)).

## Secret formats

All Slicer secrets are recognizable by their prefix. After the prefix come 43 random characters (256 bits) and a 6-character checksum: the server rejects typos and forgeries before even looking the token up, and secret scanners in repositories can spot Slicer tokens without asking us.

| Prefix | What it is | Lifetime |
| --- | --- | --- |
| `slc_` | API token from your profile | 30, 90, 365 days or no expiry |
| `slc_oat_` | OAuth access token — issued to apps you connected (for example, AI agents) | 1 hour |
| `slc_ort_` | OAuth refresh token — the app exchanges it for a new access token | 60 days, replaced on every exchange |
| `slc_ul_` | the secret of a one-time upload link in `uploadUrl` | up to 1 hour, one file |
| `whsec_` | webhook signing secret | as long as the webhook exists |

## Keeping the token safe

-   Keep the token in an environment variable or a secrets manager. Don't paste it into code or commit it to a repository.
-   **Don't use the token in browsers or mobile apps used by other people.** The API answers requests from any website (CORS without cookies), but a token in page code can be read by anyone — that's the token owner's responsibility. Call the API from your server.
-   One service — one token with the minimum scopes it needs. That way a leak is easy to close without touching anything else.
-   The token list shows when each token was last used and how much it spent this month — unfamiliar activity is a reason to revoke it.

## Revoking a token

You can revoke a token at any time in **Developers** with **Revoke**. The next request with it gets `401 token_revoked`. Tokens are also revoked automatically when the account is deleted or blocked.

## Authentication errors

| Status | Code | What happened |
| --- | --- | --- |
| 401 | `unauthorized` | no `Authorization: Bearer` header |
| 401 | `invalid_token` | token not found or mistyped |
| 401 | `token_revoked` | the token was revoked or the app was disconnected from the account |
| 401 | `token_expired` | the token has expired |
| 403 | `insufficient_scope` | the token lacks a scope the endpoint needs; the missing scopes are in the error message |
| 503 | `api_disabled` | the public API is temporarily turned off |

401 and 403 responses include a `WWW-Authenticate` header with the reason (`error="invalid_token"` or `error="insufficient_scope"` with the required scopes) — OAuth clients rely on it too.

## OAuth tokens

Apps that act on a user's behalf — such as AI agents via the [MCP server](https://docs.slicer.media/en/mcp/) — don't get a token by hand but through OAuth 2.1: the user signs in to Slicer in a browser and grants access on a consent screen. Such an access token (`slc_oat_…`) also works with `/v1`, with the scopes and spend limit chosen on the consent screen. Details — [Signing in: OAuth and tokens](https://docs.slicer.media/en/mcp/authentication/).

## What's next

[QuickstartYour first video through the API in 10 minutes.](https://docs.slicer.media/en/api/quickstart/)[ErrorsThe error format and what to do with each code.](https://docs.slicer.media/en/api/errors/)[Rate limitsHow many requests per minute the API accepts.](https://docs.slicer.media/en/api/rate-limits/)
