Mint short lived access tokens for trusted backends and anonymous visitors.
Auth tokens let a trusted backend mint an Assistant Cloud access token for a workspace, or let a browser begin and continue an anonymous session. The backend route is on https://backend.assistant-api.com and uses an API key. The anonymous routes use the project frontend host and have no Authorization header; see Conventions for hosts and shared error shapes.
The token response
| Field | Type | Meaning |
|---|---|---|
token | string | The HS256 access token returned by the trusted backend route. |
access_token | string | The HS256 access token returned for an anonymous session. |
refresh_token.token | string | The anonymous refresh token. It starts with refresh_0. |
refresh_token.expires_at | ISO 8601 | When the anonymous refresh token expires. Its lifetime is 30 days from creation or its latest successful refresh. |
Every access token has project_id and workspace_id claims. It also has sub for the user, an iss for the project's frontend host, iat for when it was minted, nbf ten seconds before iat, and exp five minutes after iat.
Mint a backend access token
POST /v1/auth/tokens| Field | Type | Required | Rules |
|---|---|---|---|
Authorization | header | yes | Bearer sk_aui_proj_…. This route accepts an API key only. |
Aui-Workspace-Id | header | yes | The workspace the token represents. |
Aui-User-Id | header | no | The user in the token's sub claim. It defaults to __SYSTEM__. |
This route has no request body. Call it from the backend host, not from a browser.
curl https://backend.assistant-api.com/v1/auth/tokens \
-X POST \
-H "Authorization: Bearer $ASSISTANT_API_KEY" \
-H "Aui-Workspace-Id: workspace_123"{ "token": "ey…" }| Status | Body | When |
|---|---|---|
200 | { "token": "<HS256 JWT>" } | The access token was minted. |
403 | { "error": "This endpoint may only be accessed from the backend" } | The credential was not an API key. |
401 or 403 | An authentication error. | The API key or required API key headers were not accepted. See Conventions. |
Minting a token does not create a user, workspace, thread, or refresh token. It may record the API key's last use in the background. Repeating the request produces another access token with a new issuance time.
Start an anonymous session
POST /v1/auth/tokens/anonymous| Field | Type | Required | Rules |
|---|---|---|---|
Authorization | header | no | Do not send a credential. The project is selected from the request host. |
| Request body | body | no | This route has no body. |
The route permits 30 requests per 60 seconds for each client IP address. A limited request has a Retry-After: 60 header.
curl https://proj-0ltyjcuaxpv1.assistant-api.com/v1/auth/tokens/anonymous \
-X POST{
"refresh_token": {
"token": "refresh_0…",
"expires_at": "2026-10-17T09:30:00.000Z"
},
"access_token": "ey…"
}| Status | Body | When |
|---|---|---|
200 | { "refresh_token": { "token", "expires_at" }, "access_token" } | An anonymous identity and its tokens were created. |
403 | { "error": "Invalid issuer format or projectId" } | The request host does not identify a project. |
403 | { "error": "Anonymous access is not allowed" } | The project does not permit anonymous sessions. |
404 | { "error": "Project not found" } | The host identifies no live project. |
429 | { "error": "rate_limited" } | The client IP exceeded 30 requests in 60 seconds. |
On success, Assistant Cloud creates a usr_anon_0… identity and uses it as both the user id and workspace id. It creates a refresh token row that expires 30 days later, then returns a five minute access token. The project policy is checked again as the refresh token is created, so a policy change during the request still answers Anonymous access is not allowed.
Refresh an anonymous session
POST /v1/auth/tokens/refresh| Field | Type | Required | Rules |
|---|---|---|---|
refresh_token | string | yes | Must be nonempty and start with refresh_0. Unknown body keys are ignored. |
The route has no credential and identifies the project from the request host. It permits 120 requests per 60 seconds for each client IP address. A limited request has a Retry-After: 60 header.
curl https://proj-0ltyjcuaxpv1.assistant-api.com/v1/auth/tokens/refresh \
-H "Content-Type: application/json" \
-d '{ "refresh_token": "refresh_0…" }'{ "refresh_token": "refresh_0…" }{
"refresh_token": {
"token": "refresh_0…",
"expires_at": "2026-10-17T09:30:00.000Z"
},
"access_token": "ey…"
}| Status | Body | When |
|---|---|---|
200 | { "refresh_token": { "token", "expires_at" }, "access_token" } | The anonymous session was refreshed. |
400 | { "success": false, "error": … } | refresh_token is missing or empty. |
403 | { "error": "Invalid refresh token format" } | The token does not start with refresh_0. |
403 | { "error": "Invalid refresh token" } | No live anonymous token for an anonymous enabled project matches. |
403 | { "error": "Invalid issuer format or projectId" } | The request host does not identify a project. |
403 | { "error": "Anonymous access is not allowed" } | The project does not permit anonymous sessions. |
404 | { "error": "Project not found" } | The host identifies no live project. |
429 | { "error": "rate_limited" } | The client IP exceeded 120 requests in 60 seconds. |
Refresh is idempotent for identity. The refresh token is not rotated. Its expiry is moved forward to 30 days from the successful refresh, so a client that loses the response can retry without receiving a different anonymous identity.