Sessions over the API
Create sessions from your backend and hand them to a browser.
The console is one client of the Core API; your product is another. The usual shape is two halves:
- Your backend holds an API key. It creates a session for a user, and keeps the key to itself.
- Your browser page gets the session’s session token, and does everything inside that one session: sends messages, follows the run, answers approvals and forms, offers tools of its own.
All of it is plain HTTP at https://api.us.cloud.subako.ai/v1, and the SDKs wrap it.
Creating a session
curl -X POST https://api.us.cloud.subako.ai/v1/sessions \
-H "Authorization: Bearer $SUBAKO_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: ticket-4192-session" \
-d '{
"agent_id": "<agent-id>",
"display_name": "ticket-4192",
"vault_ids": ["<vault-id>"],
"metadata": { "tenant_id": "t_123" }
}'
| Field | |
|---|---|
agent_id |
Required. The session runs the agent’s latest version, and keeps it. |
display_name |
Optional, up to 200 characters. An agent allowed to name its session fills an empty one in. |
vault_ids |
Optional, up to 10. The vaults whose credentials the session’s tools may use. |
metadata |
Optional, up to 50 keys of lowercase letters, digits, and _, each value a string up to 500 characters. Fixed at creation and copied onto every usage record the session makes — so usage can be broken down by your own tenant or customer. It is kept on usage after the session is deleted: put opaque IDs here, never personal data. |
The key needs Sessions › Create. The response is the session, with its first session token:
{
"id": "01a0877f-d3b3-7e73-9eed-a16caee8cff7",
"workspace_id": "01a0877c-03d9-7823-b997-f42147b8b607",
"agent_id": "01a0877d-9a1f-7c40-8e2b-5b3c4d6e7f80",
"agent_version_id": "01a0877e-1b2c-7d3e-9f40-a1b2c3d4e5f6",
"display_name": "ticket-4192",
"status": "idle",
"session_token": "sbk_st_...",
"session_token_expires_at": "2026-09-09T19:48:16Z",
"metadata": { "tenant_id": "t_123" },
"created_at": "2026-09-09T18:48:16Z"
}
The same Idempotency-Key sent again answers the same session rather than creating a second one — but without the token, which is shown once. Mint a fresh one instead.
Session tokens
A session token (sbk_st_…) carries no permissions of its own. It is good for one session — every route under /v1/sessions/{its id}/ — and nothing else: it cannot list sessions, create one, or read anything outside its own.
| API key | Session token | |
|---|---|---|
| Scope | A workspace | One session |
| Carries | The permissions it was minted with | Everything inside its session |
| Lives | On your server | In the browser, or a worker |
| Expires | When revoked, or at its expiry | One hour after it was minted |
Inside its session a token can read and follow the log, send messages, cancel, allow or deny approvals, answer forms, register clients, rename or delete the session, and read and write its volume.
A token lasts an hour. Mint the next one from your backend, before the last runs out:
curl -X POST https://api.us.cloud.subako.ai/v1/sessions/$SESSION_ID/tokens \
-H "Authorization: Bearer $SUBAKO_API_KEY"
That takes Sessions › Manage; a session token cannot mint tokens itself.
Talking to a session
# Say something: starts a run, or steers the one under way.
curl -X POST https://api.us.cloud.subako.ai/v1/sessions/$SESSION_ID/events \
-H "Authorization: Bearer $SUBAKO_SESSION_TOKEN" \
-H "Content-Type: application/json" \
-d '{"type": "input", "text": "Summarize ticket 4192."}'
# {"run_id": "01a08780-...", "outcome": "new_run"}
# Stop the run under way.
curl -X POST https://api.us.cloud.subako.ai/v1/sessions/$SESSION_ID/cancel \
-H "Authorization: Bearer $SUBAKO_SESSION_TOKEN"
Input sent while a run is working answers "outcome": "steered": it joins that run rather than waiting for it. Cancelling is cooperative — the run stops at its next checkpoint and ends with run_cancelled.
Follow what happens with the event stream.
Calling from a browser
A page calls the API with the session token, and the browser asks first whether the origin may: CORS. Origins are allowed per agent, on its page in the console (CORS › Edit), with subako agent set-security, or with the API:
curl -X PUT https://api.us.cloud.subako.ai/v1/agents/$AGENT_ID/security \
-H "Authorization: Bearer $SUBAKO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"allowed_origins": ["https://app.acme.example"]}'
An origin is scheme://host[:port], with no path; * allows any. The list applies to the routes under /v1/sessions/{id}/ of that agent’s sessions, and nothing else: no page may create a session or use an API key, which is what keeps the key on your server.
A browser’s EventSource cannot send an Authorization header, so read the stream with fetch — the TypeScript SDK does.
Listing and cleaning up
curl "https://api.us.cloud.subako.ai/v1/sessions?agent_id=$AGENT_ID&limit=20" \
-H "Authorization: Bearer $SUBAKO_API_KEY"
curl -X DELETE https://api.us.cloud.subako.ai/v1/sessions/$SESSION_ID \
-H "Authorization: Bearer $SUBAKO_API_KEY"
Deleting a session deletes its log and its volume. Usage it recorded stays.
See API conventions for authentication, the workspace header, pagination, errors, and idempotency.