Authentication¶
The PlusPlus Public API uses bearer tokens. Every request must include an Authorization header:
Requests without a valid token receive 401 Unauthorized.
Token format¶
PlusPlus tokens are opaque, securely generated random secrets of 64 hexadecimal characters, with no fixed prefix. PlusPlus stores only a hash of the token and keeps its first 8 characters so you can tell your tokens apart. Tokens are not JWTs — they cannot be decoded client-side.
Token scopes¶
A token carries a list of scopes that bound what it can reach. Scopes only narrow: a token can never do more than the user who owns it is permitted to do, and the owner's current role applies on every request — demote the owner and the token narrows with them.
Each scope is a family:access string. The families are content, assignments, enrollments, users, surveys, insights, webhooks, tokens, and automations; the access levels are read and write (write implies read). The API's URL prefix decides which family a request needs — for example, GET /users/ needs users:read and POST /assignments/ needs assignments:write.
A token created without explicit scopes gets every family at read and write. Pass scopes when creating a token to narrow it — for example ["content:read"] for a read-only content integration.
The standalone admin scope is a capability for admin-only surfaces (such as /workspace/settings/ and the admin MCP tools), on top of the route's own family scope (content:read/content:write for /workspace/). It is never granted by default, can only be minted by an Admin, and only works while the token's owner holds the Admin role — the scope and the role are both required.
A request outside the token's scopes fails with 403 insufficient_scope. Re-authenticating won't help; mint a token that carries the missing scope.
New tokens can only be granted scopes the creating credential itself carries, so a leaked narrow token cannot mint itself a wider one.
Rotating tokens¶
To rotate a token:
- Create a new token in Settings → API tokens.
- Update the integration that uses the old token to use the new one.
- Revoke the old token.
You can run multiple active tokens at once, which makes zero-downtime rotations straightforward.
Revoking tokens¶
Revoke a token from Settings → API tokens by clicking Revoke next to it. Revocation is immediate — the token cannot be used again, and any in-flight requests using it will fail at next dispatch.
Common authentication errors¶
| Status | Code | Cause |
|---|---|---|
| 401 | unauthenticated |
Missing or malformed Authorization header. |
| 401 | invalid_token |
Token does not exist, has been revoked, or belongs to a different tenant. |
| 403 | forbidden |
Token is valid but the underlying user lacks permission for this operation. |
| 403 | insufficient_scope |
Token is valid but does not carry the scope this route needs. Mint a token with the missing scope. |
Every error response includes a request_id — quote it when contacting support. See Errors for the full envelope.