---
title: "Hydrate one page of a Cortex Agent Thread's message history, oldest first."
method: GET
path: "/v1/agent/threads/{id}/messages"
tags: ["agent"]
---

# Hydrate one page of a Cortex Agent Thread's message history, oldest first.

`GET /v1/agent/threads/{id}/messages`

## Request

- Base URL: `http://localhost:8080`
- URL: `http://localhost:8080/v1/agent/threads/{id}/messages`
- Auth: one of:
  - API key in cookie `dvt_session`
  - HTTP bearer

Ownership is checked against dvt's own `agent_threads` index BEFORE any engine call — another user's thread (even in the same org) 404s, and the engine is never called. On a 200, content is read through from Snowflake on demand for this one request and is never stored by dvt (ADR-0082 D6 no-chat-content) — the same no-persistence rule every other `/v1/agent/*` route in this file follows. Messages are returned oldest first (Cortex's own Threads REST API returns them newest first; this endpoint reverses that order). The server strips the `<dvt_context>` block it prepends to popup user turns from user message text (see `POST /v1/agent/run`), so clients never see it.

## Query parameters

- `limit` integer
- `before` string

## Response `200`

Messages, oldest first.

- object
  - `data` AgentThreadMessage[], required
    - `messageId` string, required: The opaque Snowflake message id.
    - `parentId` string, required: The parent message's id, or "0" for the thread's root message.
    - `role` 'user' | 'assistant', required
    - `createdOn` integer, required: Milliseconds since epoch (Snowflake's own timestamp).
    - `content` object[], required
  - `meta` Meta, required: Response metadata.
    - `requestId` string, required: Correlates with the X-Request-Id header.
    - `total` integer: Item count, present on collection responses.
    - `nextCursor` string, nullable: Opaque keyset-pagination cursor, present on paginated responses (e.g. GET /v1/dashboards) when more rows exist beyond this page. Pass it back as the `cursor` query param to fetch the next page; absent or null on the last page.
    - `roleResolveDegraded` boolean: Snowflake mode only (DVT-2260), on GET /v1/dashboards: present and true when the caller's live Snowflake role resolution failed or was unavailable — role-shared dashboards may be missing from this page. Omitted (not merely false) whenever resolution succeeded or the role-share arm does not apply (off snowflake mode, an org admin/owner, or off the ingress listener).

## Other responses

- `400`: Malformed request.
- `401`: Distinguished by the Problem `type` (DVT-3518/DVT-3961, ADR-0082): - `https://docs.dvt.dev/errors/unauthorized` — missing, invalid, or expired session, same as every other route's `Unauthorized` response. - `https://docs.dvt.dev/errors/agent-caller-token-missing` — snowflake mode, `DVT_AGENT_IDENTITY=caller` only (DVT-3961, ADR-0082 D2d.4): this request carried no ingress caller token for the Cortex Agent call. Reconnect through the Snowflake-ingress-fronted session and retry.
- `403`: Several shapes, distinguished by the Problem `type` (DVT-3518/DVT-3961, ADR-0082): - `https://docs.dvt.dev/errors/agent-consent-required` — no active Snowflake Cortex Agent PAT is registered for the caller, or the stored one has expired or been revoked. Never emitted in snowflake mode under `DVT_AGENT_IDENTITY=caller` — there is no per-user PAT to re-consent for. Register a fresh PAT via `PUT /v1/agent/credential`, then retry. - `https://docs.dvt.dev/errors/agent-caller-not-authorized` — snowflake mode, `DVT_AGENT_IDENTITY=caller` only (DVT-3961, ADR-0082 D2d.4): Snowflake rejected the signed-in user's own combined ingress token for this Cortex Agent. Carries an additive `reason` (`usage_denied` | `token_rejected`) when the engine reported one. Ask a Snowflake administrator to grant USAGE on the agent to your role.
- `404`: Resource does not exist.
- `502`: The analytics engine could not be reached (`https://docs.dvt.dev/errors/engine-unavailable`) or returned an error (`https://docs.dvt.dev/errors/engine-error`). One 502 on this shape is NOT an engine fault and says so: when Snowflake refuses the caller's-rights LOGIN, the Problem type is `https://docs.dvt.dev/errors/caller-connect-refused` — no session was established and the caller's SQL was never reached, so the remediation is a fresh dvt session rather than the engine logs (DVT-4345).
- `503`: The service or a required dependency is temporarily unavailable.

---

[API](https://skmtc.dev/dvt/apis/dvt-rest-api.md) · [All operations](https://skmtc.dev/dvt/apis/dvt-rest-api/llms.txt) · [OpenAPI document](https://skmtc.dev/dvt/apis/dvt-rest-api/revisions/00016f504165?raw)
