Messages

Messages are the turns inside a session. Each one has a role (user | assistant | system), an ordered position, and a list of content blocks that describe what's in the turn.

Shape of a message

role'user' | 'assistant' | 'system'

Who produced this turn. system is reserved for server-injected context — clients only ever send user and receive assistant.

indexnumber

Monotonically increasing position in the conversation. Always use it to order, never createdAt — message timestamps can collide.

contentContentBlock[]

The body. See below for the block shape.

deletedAtnumber | null

Soft-delete marker. Messages that have been retracted (for example, when rewinding to retry) are flagged here rather than hard-deleted.

Content blocks

A message body is a list of typed blocks — the same shape the underlying Anthropic API uses, with minimal additions.

text{ type: 'text', text: string }

Plain text. Most user and assistant turns are a single text block.

tool_use{ type: 'tool_use', id, name, input }

Appears in assistant turns when the model wants to invoke a tool. Carries the tool name and a structured argument object.

tool_result{ type: 'tool_result', tool_use_id, content }

Appears in user turns that respond to a tool_use. The server inserts these automatically when you submit a tool response — you don't author them by hand.

Streaming vs non-streaming

The backend exposes two endpoints for sending a user message:

  • POST /v1/messages/:sessionId — buffers the full assistant reply server-side and returns it as JSON. Simpler to consume; higher time-to-first-byte.
  • POST /v1/messages/:sessionId/stream — returns a chunked JSON response (Content-Type: application/json, not text/event-stream) in our platform-defined wire format: { sessionId, events: [...] }, with native Bedrock conversation events inside the events array. Lower latency to first visible token; you need a streaming JSON parser.
Tip

Use streaming whenever the result is displayed live to a user. Use the buffered endpoint for batch jobs, evaluations, and anywhere you want a single JSON to log.

The stream delivers events like messageStart, contentBlockDelta, and messageStop. A single stream can contain multiple messages — for example, when the server handles an internal tool call, you'll see the assistant request the tool, the result, and the assistant's final answer all in one stream.

See the Messages API reference for the full event schema and a working TypeScript example.

When a tool call is emitted mid-response, both endpoints stop and return the pending tool. You then fulfill the tool via the Tools endpoints and call the message endpoint again to resume.