What’s changing
You only need to migrate the routes listed above. The public beta also adds optional endpoints to retrieve or cancel sessions, view Custom Agent metadata and insights, set credit limits, enable, disable, or delete Custom Agents, and make those changes in bulk. See the Overview for the full set.
Upgrade checklist
1
Replace
GET /v1/agents with POST /v1/agents/query, moving your query parameters into a filter object.2
Replace
GET /v1/agents/:agent_id/threads with POST /v1/sessions/query, filtering on agent_id.3
Replace
GET /v1/threads/:thread_id/messages with POST /v1/sessions/:session_id/events/query, and read agent replies from agent.message events.4
Replace
POST /v1/agents/:agent_id/chat with POST /v1/sessions, moving agent_id into the request body.5
Replace
POST /v1/agents/:agent_id/chatStream with POST /v1/sessions and Accept: text/event-stream, and parse server-sent events instead of NDJSON lines.6
Rename
thread_id to session_id throughout your code, and handle the session statuses the alpha didn’t return: queued, in_progress, canceled, and terminated.Step-by-step guide
Step 1: Query agents instead of listing them
Query agents is aPOST that takes a JSON body. The alpha’s query parameters become filters, each naming a property and pairing it with a condition object, and name becomes the free-text query field. Combine several filters with and or or.
results, has_more, and next_cursor — so your pagination loop keeps working.
One thing to watch for in the results: fields you aren’t entitled to read come back as the string "hidden" rather than being omitted. credit_limit needs full access to the agent, and last_run_at needs edit access.
See Query agents for the full filter, sort, and option list.
Step 2: Query sessions instead of threads
A thread is now a session. Query sessions is workspace-wide rather than nested under an agent, so the agent moves from the path into a filter.
A thread’s single
pending status is now split into queued and in_progress, and cancellation and termination are reported separately from failure. Treat any status you don’t recognize as non-terminal rather than as an error.
Step 3: Read events instead of messages
Message history is now an event stream. Query session events returns one entry per thing that happened in the session — user input, agent output, thinking, tool calls, tool results, and status transitions — each with a monotonically increasingsequence.
Two consequences worth handling explicitly:
- Agent replies are
agent.messageevents, and their text lives incontentparts rather than in a single string. Concatenate thetextparts to reconstruct the reply. - Errors are no longer agent messages. The alpha surfaced inference and tool failures as
role: "agent"messages whosecontentdescribed the error; read the session’serrorobject and itssession.statusevents instead.
Step 4: Create sessions instead of chatting
Create or update a session replaces the chat route.agent_id moves from the path into the body, and one route now covers all three things you do to a session: start it, add a message, and answer a required action.
session_id to continue an existing session, and send session_id with actions to approve or reject something the agent is waiting on.
The response is a session object rather than a chat.invocation:
Poll Retrieve a session for the result, which the alpha had no route for — you no longer have to re-list threads to find the one you just created.
Step 5: Switch streaming from NDJSON to server-sent events
POST /v1/agents/:agent_id/chatStream is replaced by the same POST /v1/sessions request with Accept: text/event-stream. The transport changes twice over: the alpha emitted newline-delimited JSON chunks that were session objects themselves, while the Public beta emits server-sent events whose data is an envelope naming what arrived.
Public beta
type rather than decoding data as a session event directly:
A dropped connection no longer costs you the turn. Persist the
id of the last event.committed.event you received, then reconnect with that exact ID as continue_from — along with the session_id — and the stream replays from there. continue_from takes a committed event’s ID, not its sequence and not a provisional or stream-control record, so anything else fails to resolve. See Create or update a session.