Conversations

Use conversations from an app

Use conversations from an app for people running and reviewing agents.

For: people running and reviewing agents.

Through the API

StartJob takes continue_from (a job ID) or conversation (an ID):

{"agent": "weather", "input": "And in Paris?", "continue_from": "job-1f0c…"}

The typed HTTP route takes them as query parameters: POST /v1/agents/weather/jobs?continue_from=job-1f0c…. GetConversation returns a conversation's latest 50 turns (limit asks for up to 200; turns_count counts them all, and without_content leaves out what was said, so the view is not audited), ListConversations the latest conversations, and GetJob names a job's conversation, turn and continued_from.

To follow a conversation live, subscribe a feed to it: its latest turn's text, steps and approvals as they happen, and each new turn as it starts, on one stream with your other chats and jobs. A feed follows only a chat that is yours, shared with you, or nobody's.

Chat channels continue a conversation from a thread reply through the same field: a thread is a conversation. Conversation IDs that start with ch. are chat threads'; only a channel starts one.

A person's chats have their own calls, for accounts only (an app's key or an operator's certificate is refused):

  • ListMyConversations lists the caller's own chats and those shared with them, pinned first, then by last activity: 20 a page by default and 100 at most, with an opaque next_cursor that stays stable while new turns arrive, and filters for archived, pinned, agent and shared.
  • UpdateMyConversation renames (the owner only), pins, unpins, archives, unarchives, marks read or removes a chat from the caller's list (CHAT_ACTION_REMOVE, which erases nothing).
  • ShareConversation, UnshareConversation and ListConversationShares are the owner's shares with a person or a team.
  • GetConversation names a chat's owner and title (title_by_ai when a model wrote it), the caller's own view of it (mine), and, for its owner, who read it through the audited access (reads). Someone else's private chat needs reason, and is audited.

ListConversations stays the tenant-wide list of conversations' facts, without any title, preview or person's state.

ListStartable lists what the caller may start now, for a picker or a hand-over, a page at a time (25 unless asked, at most 100; the console's picker asks for 50 and searches with query as you type, see the catalog's pages): the agents and flows StartJob would take from them (the operator role in the tenant, kill switches applied), each with its plugin and version, whether it takes part in conversations (conversational, conversation_input) and whose conversations it may continue (continue_from).

conversations_only keeps the agents that take part; continues: weather keeps those that may continue a conversation of weather. A reader gets an empty list and the reason. GetCatalog stays the catalog of every agent and flow, for any reader.

Over A2A and MCP

Agents served over A2A and MCP take part too:

  • A2A: every task has a contextId: its job's conversation, or the job's own ID until it has one. A SendMessage with that contextId and no taskId starts the conversation's next turn as a new task in the same context. A contextId the server never gave is refused, as A2A asks of a server that does not take one (A2A, section 3.4.1). For an agent that takes no part in conversations, or a caller without the content permission, the contextId the server gave starts a new task in a context of its own, as it did before conversations crossed A2A.
  • MCP: the 2026-07-28 revision has no sessions, so a call names its conversation in _meta: every result's _meta has ai.oz0/conversation, and a tools/call whose _meta sends it back is that conversation's next turn. Clients of earlier revisions can send the same key. As with A2A, an agent outside conversations, or a caller without the content permission, starts a new conversation instead.

Both need the content permission, as every continuation does.

Copyright © 2026