---
title: "Get thread messages"
method: GET
path: "/v1/threads/{threadId}/messages"
---

# Get thread messages

`GET /v1/threads/{threadId}/messages`

## Request

- Base URL: `https://api.runbear.io`
- URL: `https://api.runbear.io/v1/threads/{threadId}/messages`
- Auth: one of:
  - HTTP bearer
  - HTTP bearer

Retrieve the messages of a specific thread, including the thread title and message content with processed citations and file references. An assistant message carrying `interrupted` holds only the text produced before its turn ended without delivering a reply. A long thread returns its newest messages only, with `truncated` set. Messages sent with files carry `attachments`.

## Path parameters

- `threadId` string, uuid, required: ID of the thread to retrieve messages from

## Response `200`

Default Response

- object
  - `truncated` boolean, required: True when the thread holds more messages than were returned. The response carries the NEWEST messages, so the omitted ones are the oldest.
  - `thread` object, required
    - `id` string, uuid, required: Unique identifier of the thread
    - `title` string, nullable, required: Title of the thread, null if not set
    - `assistantId` string, uuid, required: Unique identifier of the assistant associated with this thread
  - `messages` ThreadMessage[], required: Array of messages in the thread
    - `role` 'user' | 'assistant' | 'system', required: Role of the message sender
    - `content` string, required: Content of the message
    - `id` string, required: Message identifier
    - `traceId` string, nullable, required: Langfuse trace id for the turn that produced this message. Null for user and system messages, and for messages produced before trace-id persistence shipped. Traces are retained for 90 days, after which this id no longer resolves.
    - `interrupted` boolean: Present and true when the turn ended without delivering a reply, so `content` holds only the text the assistant had produced up to that point. Recorded for non-streaming runs too, where that text was never sent to you — the message reflects what the assistant produced, not what you received. Treat presence as the signal: the field is omitted for a completed message, and also wherever a partial cannot be captured, so its absence is not a guarantee that nothing was lost.
    - `components` ResponseComponent[]: Components this message carried, in the order they were produced. Omitted when it carried none. `content` already contains a prose description of the same choices, so a client that renders a component should suppress that trailing block rather than show both.
      - `componentId` string, required: Opaque key for this component instance. Echoed back by the SDK for analytics only: the server neither resolves it nor treats it as an authorization input.
      - `name` string, required: Render key. Built-in names include confirm, select, card, list, table, chart. Treat any other value as a component this client does not render and show fallbackText.
      - `props` object, required: Component-specific payload, passed through verbatim. Its shape depends on `name`; a client that does not recognise `name` must not read it.
      - `fallbackText` string, required: Prose to show instead whenever no renderer matches `name`. Never empty.
    - `attachments` ThreadMessageAttachment[]: Files sent with this message, in the order they were sent. Omitted when it carried none.
      - `name` string, required: Filename of the attached file.
      - `mimeType` string, required: Content type (MIME type) of the attached file.
      - `url` string, required: URL of the attached file. For a file uploaded through `POST /v1/files/upload` this is a short-lived signed URL, re-issued on every listing call and valid for about one hour; fetch a fresh listing rather than storing it. A URL that points elsewhere is returned exactly as it was sent.

## Other responses

- `401`: The credential is missing, malformed, or expired. `code` discriminates the cause; only `pass_expired` is renewable.
- `403`: The presented credential is not permitted to perform this action against this agent.
- `404`: The thread does not exist, or it is not accessible with the presented credential. Absent and inaccessible threads are deliberately indistinguishable.
- `422`: The thread's owning agent has a type the public API cannot run.
- `429`: Retry after the number of seconds in the `Retry-After` header. Sent when a browser session pass has exhausted its per-minute request budget (API-key reads are not charged against a budget here), or when an API key could not be checked because key validation is rate limited (`code` is `rate_limited`).

---

[API](https://skmtc.dev/runbear/apis/runbear-api.md) - [All operations](https://skmtc.dev/runbear/apis/runbear-api/llms.txt) - [OpenAPI document](https://skmtc.dev/runbear/apis/runbear-api/revisions/c6a9c3066a5a?raw)
