A session is a handle, not a store
Because the handle is cheap and the harness is the source of truth,
resuming a session means addressing an existing one by its
session_id -
not by its metadata. app.session(metadata=...) always mints a new session,
so hold onto the Session you created (or stash its id) and resume by that.
session_id (or fetch-then-send); see
the Sessions API.
Sessions run inside a karta
Kartas & memory covers this model in full; here is how it maps onto sessions. For a user-facing product, each stable user id can get its own durable karta - a life coach or tutor that remembers one person across visits. Use verified identity when the agent needs to act on per-user data or credentials. Soft or anonymous ids can provide continuity, but they are advisory only; any browser page can set them, so your backend must not treat them as proof of who the user is. To have a team work with a roster of virtual employees, name stableagent_instance_id values from your backend. One team might use
auditor-west, auditor-east, reviewer-risk, reviewer-finance, and
reviewer-compliance as five separate kartas. Each karta has its own files,
sessions, memory, and working style; each acting person is still attributed per
turn for usage and per-seat caps.
How you name a shared karta depends on the surface:
-
From your backend (server-to-server with an API key, or a backend-minted
session token), pass it in session metadata:
- In an embedded widget, configure the stable karta id on the embed key itself (Embed keys -> the key -> “Karta ID”). Every widget session from that key then joins that virtual employee, backend worker, or other deliberately shared karta.
agent_instance_id is the API field behind the public karta noun. It is
trusted only when it comes from your backend or the embed key’s server-side
config. Public browser metadata cannot redirect a widget into another shared
karta.
Participants and attribution
A session is not limited to one human and one bot. Multiple participants - humans and AIs - can share a session, and every message is attributed to its sender.Sub-agent handoff
A session has a current sub-agent, and you can hand off mid-conversation to another sub-agent. The handoff fires anagent.handoff
lifecycle hook.
Pending input & approvals
When the harness needs permission - to run a tool, write a file - it emits aninput_required event and the
session records pending_input. You resolve it with a decision:
approve_once, approve_session, or deny. How aggressively Karta prompts is
governed by permission_mode and the
input_required_policy config.
Over HTTP
The same model is exposed on the wire: create a session, send (or stream) messages, resolve inputs. See the Sessions and Messages API reference.Sub-agents
Discovery, routing, and handoff.
Streaming events
The typed events every message and approval flows through.

