Returns the messages in this conversation with sequence_no > since, plus the
conversation’s current_version at the moment the response was generated. The
messages list is ordered by sequence_no ascending and is gap-free — if the
response contains messages with sequence_no 3, 4, 5, you have all three.
since = 0
loop forever:
r = GET /agents/conversations/{id}/messages?since={since}
process r.messages # may be empty
since = r.current_version # use the head, not r.messages.last.sequence_no
wait briefly
current_version is the conversation’s head at the moment the response was generated
— using it as the next request’s since is the only way to ensure gap-free reads
even when new messages land between the time the response was generated and the time
your client processed it.
Messages are persisted in a single transaction by the workflow’s finalize step (when a run reaches a terminal state). You won’t see partial reads — a run that produces 4 messages either lands all 4 or none.
A run’s id appears in messages[].run_id, so you can correlate messages to the
runs that produced them.
content_blocksThree discriminated variants:
text — plain text. The dominant variant.tool_use — the model requesting a tool call. Carries tool_use_id, the aliased
name, and the model’s arguments.tool_result — the result of a tool call, nested as content_blocks inside the
tool_result block. Carries the original tool_use_id plus an is_error flag.The same tool_use_id appears on the assistant’s tool_use block and on the
subsequent tool (or user, for resume payloads) turn’s tool_result block —
that’s how a UI matches them up.
agent_conversations resource with read verb.
curl "$API/agents/conversations/{id}/messages?since=0" \
-H "Authorization: Bearer $TOKEN"
# → { "current_version": 4, "messages": [ <4 entries> ] }
Then later:
curl "$API/agents/conversations/{id}/messages?since=4" \
-H "Authorization: Bearer $TOKEN"
# → { "current_version": 4, "messages": [] } # nothing new
Documentation Index
Fetch the complete documentation index at: https://docs.narrative.io/llms.txt
Use this file to discover all available pages before exploring further.
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
The conversation's UUID.
UUID identifying a conversation. Returned from POST /agents/conversations and used
in every other agent endpoint that operates on this conversation.
"bc2505b7-068d-44ed-8055-a6f6ffe54ab1"
Return messages with sequence_no > since. Use the previous response's
current_version as the next request's since for gap-free incremental reads.
Default 0 returns the entire conversation from the beginning.
x >= 0A page of messages with sequence_no > since, plus the current head version.
Returned by GET /agents/conversations/{id}/messages?since=N. Carries the
conversation's current head version (current_version) plus the requested page of
messages.
Polling pattern:
since = 0
loop:
response = GET /agents/conversations/{id}/messages?since={since}
process response.messages
since = response.current_version
sleep or wait for an eventThe current_version is the conversation's head at the moment the response was
generated — using it as the next request's since gives gap-free incremental
reads.
Monotonic per-conversation counter, bumped by 1 (or more) every time a successful run appends messages. Two roles:
GET .../messages?since=N — fetch only messages with
sequence_no > N.POST .../runs — set expected_version to the
conversation's current head; if it doesn't match at run-creation time, you get a
Version Conflict
(HTTP 409).Always start a new run cycle by reading the current version from
GET /agents/conversations/{id} rather than caching a value from earlier.
x >= 04
Messages with sequence_no > since. Empty array means no new messages — the
conversation is at version current_version but you've already seen everything.