# Supervisor plane

A **supervisor** is a crew lead: someone who watches work and unblocks it, rather than doing it. The supervisor plane is a third credential type (`sv_`) alongside the workspace key and the worker token, with its own client in every SDK — `FivexerSupervisor`.

It exists because the two credentials that came before it are both wrong for this job. A workspace key can do everything, which is far too much for a phone on a depot floor. A worker token can only reach its own queue, which is far too little to see the crew's.

## Getting a session

A supervisor session is redeemed from a **single-use link** — no password, no PIN:

```
typescriptimport { FivexerSupervisor } from '@fivexer/sdk';

const sv = new FivexerSupervisor({ baseUrl: 'https://api.fivexer.com' });
const session = await sv.acceptInvite({ token: tokenFromLink });
// session.expiresAt is epoch-milliseconds
```

`GET /v1/supervisor-auth/entry` (`sv.entry()`) is unauthenticated and answers `{ consoleUrl }` — where this deployment's dashboard lives, or `null` if it declares none. It deliberately takes no workspace ID: echoing back a caller-supplied one would turn it into an existence oracle.

`acceptInvite` is equally careful. Expired, already-used, revoked, and never-existed all answer with the same `400 invalid_token`, because any distinction between them tells someone grinding tokens which guesses were close.

**There is no `refresh`.** Once a session expires it can only be replaced by a new link. The clients have no recovery path on purpose — inventing one would hide the fact that the link is the credential.

## The board

Everything a supervisor sees comes from one call:

```
typescriptconst board = await sv.overview();

board.counts; // { queued, pending, parked, oldestWaitMs }
board.crew; // [{ workerId, backlog, available }], busiest first
board.parked; // up to 50 tasks: { id, tags, priority, createdAt }
board.teamKey; // null means the whole workspace, not a missing value
```

This is one endpoint rather than four by design. It is a phone on a depot floor, and four round trips over a bad connection show a board that assembles itself in pieces. `parked` is capped at 50 server-side for the same reason.

## What a supervisor can do

Four actions, all scoped to the supervisor's team:

```
typescriptawait sv.tasks.unpark(taskId); // put stalled work back in play
await sv.tasks.setPriority(taskId, 95); // move it up the queue
await sv.tasks.assign(taskId, workerId); // hand it to a specific person
await sv.workers.setAvailability(workerId, false, { releaseBacklog: true });
```

In Python, Java, and PHP these are flat methods on the client (`sv.unpark(...)`, `sv.set_priority(...)`); only the TypeScript client groups them under `tasks` and `workers`.

Two rules worth knowing before you rely on them:

- **`assign` is scope-checked at both ends.** A task from another crew, or a worker outside this one, is a `403` rather than a silent move. If the matcher itself refuses an in-scope assignment — a veto, a full backlog, a prior rejection — that surfaces as `400 assign_blocked`. `force` bypasses the matcher checks but never worker existence, and never the scope check.
- **Pausing never releases implicitly.** `setAvailability(workerId, false)` hides someone from matching but leaves their backlog alone. `releaseBacklog: true` is the explicit redistribution move, and only *pending* work moves — accepted work stays with whoever accepted it. The result's `releasedTaskIds` is non-empty only when you asked for it.

## Push

The supervisor plane has its own Web Push registration:

```
typescriptconst config = await sv.push.config(); // { enabled, publicKey }
if (config.enabled) await sv.push.subscribe(subscription);
```

`subscribe` answers `{ ok: true }`, not the `{ endpoint, createdAt }` the worker plane returns — the supervisor table is keyed by endpoint and has nothing else to hand back.

`sv.logout()` drops this supervisor's push subscriptions server-side along with the session. A handed-over phone must stop buzzing with another crew's work, so this is one trust boundary rather than two.

## What a supervisor cannot reach

The plane is deliberately narrow. There is no supervisor route to create tasks or workers, edit skills, workflows or notification sequences, read decision traces, or touch anything outside the team the session is scoped to. Those all stay on the workspace plane behind an `sk_` key.

See [auth & keys](/docs/concepts/auth-and-keys) for how the three planes compare, and the [API reference](/docs/api) for every supervisor operation.
