Skip to main content

Sessions

A session is one conversation with an agent. This page explains how the platform stores history, why an agent "remembers" your last message, and how to browse and delete transcripts.

What a session is

Every invoke belongs to a session, identified by a session_id. The platform persists the full history of that session — every user message, agent reply, and tool call — and replays it to the model on each new turn. That replay is the whole mechanism: the model itself is stateless, so continuity comes from the platform feeding the history back in.

A concrete thread we'll use through this page:

# Turn 1 — a new session is minted and returned
platformctl invoke research-buddy "My boat is a Mastercraft Maristar 245."

You should see:

Nice — a Mastercraft Maristar 245. Noted!
(session: 3f2c8a1e-9d41-4c1b-a2f7-0b1c2d3e4f5a)
# Turn 2 — same session id, so the agent has the history
platformctl invoke research-buddy "What boat do I have?" --session 3f2c8a1e-9d41-4c1b-a2f7-0b1c2d3e4f5a

You should see:

You have a Mastercraft Maristar 245.
(session: 3f2c8a1e-9d41-4c1b-a2f7-0b1c2d3e4f5a)

Session history lives in the platform's managed store and survives the agent scaling to zero. It is per-session working memory: a fresh session starts blank. To carry facts across sessions, use the memory bank.

Optional expiry

By default sessions are kept indefinitely. Your administrator can configure an expiry (SESSION_TTL_SECONDS) so idle sessions age out.

Session ids

  • Omit session_id on invoke and the platform mints a UUID and returns it. This is the recommended path.
  • Ids must match ^[A-Za-z0-9_.-]{1,128}$. A bad id in a URL path returns 400 invalid session id.
  • An anonymous caller who chooses their own id must make it at least 24 characters, or invoke fails with 400: session_id chosen by an unauthenticated caller must be at least 24 characters of unguessable randomness (or omit it and the platform will generate one). A short, guessable id would let anyone else read this conversation. Signed-in callers are exempt.

User ids

Every session belongs to a user, identified by a user_id (must match ^[A-Za-z0-9_.:@-]{1,128}$). You almost never need to set it:

  • Omit user_id and the platform derives one deterministically from the session id (a UUIDv5). Repeat invokes on the same session always resolve to the same user — this is what makes multi-turn continuity work with zero bookkeeping on your side.
  • Set it explicitly when your application has real end users and you want to group each person's sessions under their own id (for example user_id: "alice@example.com").
  • An invalid value returns 400: invalid user_id: must match ^[A-Za-z0-9_.:@-]{1,128}$ (omit it and the platform will derive one from the session).
The classic continuity bug

If turn 2 doesn't remember turn 1, you changed the session_id between calls — or supplied two different user_id values yourself. Reuse both. If you omit user_id entirely, the platform keeps it stable for you.

Browse users and sessions (API)

The control plane exposes a read surface for an agent's conversations. These are management routes: they require signing in, and only the agent's owner (or a project admin) can use them.

MethodPathReturns
GET/v1/agents/{name}/usersWho has talked to this agent
GET/v1/agents/{name}/sessions?user_id=<id>One user's sessions
GET/v1/agents/{name}/sessions/{id}A full transcript
DELETE/v1/agents/{name}/sessions/{id}Deletes one session

All list routes paginate with page_size (default 50, max 200) and an opaque page_token; next_page_token is returned for the next page.

List users

curl -s "$CAI_API/v1/agents/research-buddy/users" \
-H "Authorization: Bearer $CAI_TOKEN"

You should see:

{
"users": [
{
"user_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"first_seen": "2026-08-10T09:12:00Z",
"last_seen": "2026-08-11T14:03:00Z",
"session_count": 2
}
],
"next_page_token": ""
}

List one user's sessions

The user_id query parameter is required — leaving it off returns 400 the user_id query parameter is required.

curl -s "$CAI_API/v1/agents/research-buddy/sessions?user_id=7c9e6679-7425-40de-944b-e07fc1f90ae7" \
-H "Authorization: Bearer $CAI_TOKEN"

You should see:

{
"sessions": [
{
"session_id": "3f2c8a1e-9d41-4c1b-a2f7-0b1c2d3e4f5a",
"created": "2026-08-10T09:12:00Z",
"last_update": "2026-08-10T09:14:21Z",
"event_count": 6,
"preview": "My boat is a Mastercraft Maristar 245."
}
],
"next_page_token": ""
}

Read a transcript

curl -s "$CAI_API/v1/agents/research-buddy/sessions/3f2c8a1e-9d41-4c1b-a2f7-0b1c2d3e4f5a" \
-H "Authorization: Bearer $CAI_TOKEN"

The response carries session_id, user_id, created and last_update (both RFC3339 UTC), state (an object holding agent-written session state — for example anything an ADK tool wrote through tool_context.state), and an ordered events list. Each event carries author ("user" or the agent's name), timestamp, invocation_id, and content.parts — text parts, function_call parts (a tool being called), and function_response parts (the tool's result). Reasoning parts are flagged thought: true.

Event timestamp values are float epoch seconds — the canonical event schema — and come back verbatim from storage. Only the session-level created and last_update fields, here and in the list-sessions response above, are converted to RFC3339 strings.

{
"session_id": "3f2c8a1e-9d41-4c1b-a2f7-0b1c2d3e4f5a",
"user_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"created": "2026-08-10T09:12:00Z",
"last_update": "2026-08-10T09:14:21Z",
"state": {},
"events": [
{
"author": "user",
"timestamp": 1786353120.0,
"invocation_id": "inv-001",
"content": {"parts": [{"text": "My boat is a Mastercraft Maristar 245."}]}
},
{
"author": "research-buddy",
"timestamp": 1786353122.0,
"invocation_id": "inv-001",
"content": {"parts": [{"text": "Nice - a Mastercraft Maristar 245. Noted!"}]}
}
]
}

A missing session returns 404 session <id> not found.

Delete a session

curl -s -X DELETE \
"$CAI_API/v1/agents/research-buddy/sessions/3f2c8a1e-9d41-4c1b-a2f7-0b1c2d3e4f5a" \
-H "Authorization: Bearer $CAI_TOKEN" -o /dev/null -w '%{http_code}\n'

You should see:

204

Deleting a session removes its history; it does not remove anything already committed to the memory bank.

If session browsing answers 503

These routes proxy to the agent's internal read surface using a platform credential. If the platform is not configured with one, every route above answers 503: session browsing is not configured: the control plane has no CAI_INTERNAL_TOKEN, so it cannot authenticate to the agent's read surface. Ask your administrator.

Sessions in the console

On the agent's detail page in the console, the Overview tab has a Users & Sessions section: a table of users (with session counts and first/last seen), each expanding to that user's sessions with a preview, and each session opening as a full transcript. A Resume in Invoke button deep-links the session into the Test tab so you can continue the conversation from the browser.

Summary

QuestionAnswer
Where is history stored?In the platform's managed store, replayed to the model each turn
Does history survive scale-to-zero?Yes
Who mints session ids?The platform, unless you supply one (24+ chars if anonymous)
Who mints user ids?Derived from the session id unless you set one
Can I read transcripts?Yes — owner or project admin, via API or console
Does a new session remember old ones?No — use the memory bank for that