- List the user’s conversations.
- Load the selected conversation’s history.
- Send the next message with the same
contextId.
Prerequisites
- An Agent Creator agent ID (
agent_<uuid>). An administrator can provide it, or you can copy it from the agent’s URL. - A user-bound JWT or access token sent as
Authorization: Bearer <token>. See Authentication. - Read access to the agent.
Examples use
api.studio.prisme.ai. For sandbox, use
api.sandbox.prisme.ai. For self-hosted deployments, use your instance’s API
host.Step 1 - List conversations
contextId of the conversation the user selects.
Conversations are scoped to the user represented by the token. If the same
application calls this endpoint with another user’s token, that user gets a
different list.
See List conversations for an agent
for filters, pagination, and the response schema.
Step 2 - Load the history
conversationcontains the thread metadata.messagescontains the conversation turns as A2A task records.
- Reverse the
messagesarray. - Keep each task’s
historyarray in its existing order. - Render history entries whose
roleisuseroragent. - Read text and files from each entry’s
partsarray. - If your client uses the OpenAI naming convention, map
agenttoassistant.
role are execution activities, such as tool calls.
You can omit them from a basic chat transcript.
Page 2 contains older turns, so prepend those turns when implementing
“load earlier messages.”
See Get a conversation with its message history
for the complete response schema.
Step 3 - Continue the conversation
Send the next message with the selected conversation’scontextId:
contextId before running
the agent. Omit contextId to start a new conversation, then store the
contextId returned by the first task.status event.
The stream follows this sequence:
task.statusstarts the task.- Zero or more
task.output.deltaevents carry incremental output. task.output.completedends the lifecycle sequence.
task.output.completed, inspect data.status.state. Treat failed as an
error and input-required as a paused task that needs a user response or
approval, not as an empty successful response.
Each frame is a data: <json> line; the server emits no native SSE event:
field. Lifecycle frames use {"event": "<name>", "data": {...}}. Frames
without an event property are transport frames: discard only
{"keepAlive": true}. The server closes the stream with a summary frame shaped
as {"error": ..., "task": {"status": {"state": ...}}}. Inspect it: an early
authorization failure is delivered there, with its code in error.error and
HTTP 200 already committed. Never treat HTTP 200 alone as success.
See Stream an agent reply via SSE
for the request schema and stream contract.
Optional - Send a message that survives a retry
A mobile client can lose the response to a send: the app is killed, or the network drops before the reply arrives. Retrying the same request would run the agent twice and, without acontextId, open a second conversation. To make the
retry safe, send through messages/send with an idempotency key.
1
Mint a key before the first attempt
Generate a key once per logical message, for example a UUID stored with
the queued message, and keep it for every retry of that message. The key
is 1 to 128 characters of
A-Z, a-z, 0-9, ., _, : and -.2
Upload attachments, if any
Read the upload target from the agent instead of hardcoding a workspace:The response is an array of files. Put each file’s
url in a part of the
message, for example
{"url": "<url>", "filename": "report.pdf", "mediaType": "application/pdf"}.3
Send with the key
Keep these rules in mind:
- The key alone identifies the message. The server does not compare the body of a retry with the first one, so a different message sent under a used key gets the first answer. Mint a new key for every new message.
- Retries count against the rate limits. A retry over the limit gets
429, not the stored answer. - The key needs a user identity. With an organization API key that has no user behind it, the server ignores the key and sends the message normally.
- Keys are kept for 7 days by default. After that, the same key is treated as a new message.
messages/streamdoes not support the key.