---
title: "Get Chat Archive Content"
method: GET
path: "/api/v1/chat/archives/{project_id}/{archive_id}"
tags: ["chat"]
---

# Get Chat Archive Content

`GET /api/v1/chat/archives/{project_id}/{archive_id}`

Get one archive's message bodies on demand, scoped to the project's chat.

The archive UUID doubles as a strong ETag (content never changes once
written), so a matching ``If-None-Match`` short-circuits to 304 before the
expensive blob read. The validator is client-constructible from the URL,
so the short-circuit is gated on a cheap existence+scope check — a forged
validator for an out-of-scope or missing archive still 404s. Blob
validation is intentionally skipped on the 304 path: blobs are immutable
after write, so a validator for a corrupt archive cannot come from a real
200, and a fresh (unconditional) read still 422s.

## Path parameters

- `archive_id` string, uuid, required

## Response `200`

Successful Response

- ArchiveContentResponseSchema — Schema for one archive's message bodies, fetched on demand.
  - `archived_messages` union[], required — The validated archived messages for one archive.
    - union
      - ModelRequest — A request generated by Pydantic AI and sent to a model, e.g. a message from the Pydantic AI app to the model.
        - `parts` union[], required
          - union
            - SystemPromptPart — A system prompt, generally written by the application developer. This gives the model context and guidance on how to respond.
              - …
            - UserPromptPart — A user prompt, generally written by the end user. Content comes from the `user_prompt` parameter of [`Agent.run`][pydantic_ai.agent.AbstractAgent.run], [`Agent.run_sync`][pydantic_ai.agent.AbstractAgent.run_sync], and [`Agent.run_stream`][pydantic_ai.agent.AbstractAgent.run_stream].
              - …
            - ToolSearchReturnPart — Typed view of a [`ToolReturnPart`][pydantic_ai.messages.ToolReturnPart] for the local `search_tools` function return. Used on the local-fallback path (and as the synthetic-injection target on non-native providers receiving cross-provider history). The native server-side path uses [`NativeToolSearchReturnPart`][pydantic_ai.messages.NativeToolSearchReturnPart] instead. To detect a tool-search part regardless of execution path (native server-side vs. local fallback), check `part.tool_kind == 'tool-search'` — this works across both call/return and both server/local variants. Shadows `content` with a narrower [`ToolSearchReturnContent`][pydantic_ai.messages.ToolSearchReturnContent] `TypedDict`.
              - …
            - LoadCapabilityReturnPart — Typed `ToolReturnPart` for the `load_capability` tool.
              - …
            - ToolReturnPart — A tool return message, this encodes the result of running a tool.
              - …
            - RetryPromptPart — A message back to a model asking it to try again. This can be sent for a number of reasons: * Pydantic validation of tool arguments failed, here content is derived from a Pydantic [`ValidationError`][pydantic_core.ValidationError] * a tool raised a [`ModelRetry`][pydantic_ai.exceptions.ModelRetry] exception * no tool was found for the tool name * the model returned plain text when a structured response was expected * Pydantic validation of a structured response failed, here content is derived from a Pydantic [`ValidationError`][pydantic_core.ValidationError] * an output validator raised a [`ModelRetry`][pydantic_ai.exceptions.ModelRetry] exception
              - …
        - `timestamp` string, date-time, nullable
        - `instructions` string, nullable
        - `kind` 'request'
        - `run_id` string, nullable
        - `conversation_id` string, nullable
        - `metadata` object, nullable
        - `state` 'complete' | 'interrupted'
      - ModelResponse — A response from a model, e.g. a message from the model to the Pydantic AI app.
        - `parts` union[], required
          - union
            - TextPart — A plain text response from a model.
              - …
            - ToolSearchCallPart — Typed view of a [`ToolCallPart`][pydantic_ai.messages.ToolCallPart] for the local `search_tools` function call. Used on the local-fallback path (and as the synthetic-injection target on non-native providers receiving cross-provider history). The native server-side path uses [`NativeToolSearchCallPart`][pydantic_ai.messages.NativeToolSearchCallPart] instead. To detect a tool-search part regardless of execution path (native server-side vs. local fallback), check `part.tool_kind == 'tool-search'` — this works across both call/return and both server/local variants. Shadows `args` with the canonical typed shape. The `str` variant covers the streaming / partial-args case before parsing completes; once parsed, `args` is a [`ToolSearchArgs`][pydantic_ai.messages.ToolSearchArgs] `TypedDict`.
              - …
            - LoadCapabilityCallPart — Typed `ToolCallPart` for the `load_capability` tool.
              - …
            - ToolCallPart — A tool call from a model.
              - …
            - NativeToolSearchCallPart — Typed view of a [`NativeToolCallPart`][pydantic_ai.messages.NativeToolCallPart] for tool search. Used on the native server-side tool-search path (Anthropic BM25/regex, OpenAI Responses) where the provider executes the search and emits a native result. The local-fallback path uses [`ToolSearchCallPart`][pydantic_ai.messages.ToolSearchCallPart] instead. To detect a tool-search part regardless of execution path (native server-side vs. local fallback), check `part.tool_kind == 'tool-search'` — this works across both call/return and both server/local variants. Shadows `args` with a narrower type. The `str` variant covers the streaming / partial-args case before parsing completes; once parsed, `args` is a [`ToolSearchArgs`][pydantic_ai.messages.ToolSearchArgs] `TypedDict`.
              - …
            - NativeToolCallPart — A tool call to a native tool. For native tools with a stable cross-provider shape (currently `tool_search`), this base class can be promoted to a typed subclass with a narrowed `args` `TypedDict`. See [`NativeToolSearchCallPart`][pydantic_ai.messages.NativeToolSearchCallPart] for the canonical example. Adding a typed subclass for a future native tool (see `pydantic_ai._tool_search` for a worked example): 1. Add a sibling `pydantic_ai/_<name>.py` module that defines the cross-provider `TypedDict`s, the `NativeToolCallPart` / `NativeToolReturnPart` subclasses, and registers their narrowers into `_NATIVE_CALL_NARROWERS` / `_NATIVE_RETURN_NARROWERS` keyed by `tool_kind`. Subclass overrides `tool_kind: Literal['<emitter>']` to match the emitting [`AbstractNativeTool.kind`][pydantic_ai.native_tools.AbstractNativeTool.kind], and shadows `args` / `content` with a narrower type. 2. Late-import the new module from this file (alongside the existing tool-search import) so registration runs whenever `pydantic_ai.messages` is imported. 3. Add the subclass to `ModelResponsePart`'s discriminated union and to `_model_response_part_discriminator` so Pydantic deserialization auto-promotes on `model_validate` / `model_validate_json`. Dispatch is by `tool_kind`, not `tool_name`. This protects users whose tools happen to share a name with one of ours from accidentally getting their parts promoted (and failing shape validation against the typed `args`/`content`). The `provider_details` field carries genuinely non-portable provider extras (e.g. Anthropic's `strategy: 'bm25' | 'regex'` for tool search). Promote a field to a typed slot in `args` / `content` only when at least two of OpenAI, Anthropic, and Google support it (cf. [issue #3885](https://github.com/pydantic/pydantic-ai/issues/3885)). MCP server tools land here with `tool_kind='mcp_server'` (label stays in `tool_name='mcp_server:<label>'`); typed-subclass work for MCP is tracked by [issue #3561](https://github.com/pydantic/pydantic-ai/issues/3561).
              - …
            - NativeToolSearchReturnPart — Typed view of a [`NativeToolReturnPart`][pydantic_ai.messages.NativeToolReturnPart] for tool search. Used on the native server-side tool-search path (Anthropic BM25/regex, OpenAI Responses) where the provider executes the search and emits a native result. The local-fallback path uses [`ToolSearchReturnPart`][pydantic_ai.messages.ToolSearchReturnPart] instead. To detect a tool-search part regardless of execution path (native server-side vs. local fallback), check `part.tool_kind == 'tool-search'` — this works across both call/return and both server/local variants. Shadows `content` with a narrower [`ToolSearchReturnContent`][pydantic_ai.messages.ToolSearchReturnContent] `TypedDict`.
              - …
            - NativeToolReturnPart — A tool return message from a native tool. For native tools with a stable cross-provider shape (currently `tool_search`), a `NativeToolReturnPart` may be promoted to a typed subclass like [`NativeToolSearchReturnPart`][pydantic_ai.messages.NativeToolSearchReturnPart] with a narrowed `content` `TypedDict`. See `NativeToolCallPart` for the pattern.
              - …
            - ThinkingPart — A thinking response from a model.
              - …
            - CompactionPart — A compaction part that summarizes previous conversation history. Compaction parts contain an opaque or readable summary of prior messages, produced by provider-specific compaction mechanisms. They must be round-tripped back to the same provider in subsequent requests. For Anthropic, `content` contains a readable text summary. For OpenAI, `content` is `None` and the encrypted data is stored in `provider_details`.
              - …
            - FilePart — A file response from a model.
              - …
        - `usage` RequestUsage — LLM usage associated with a single request. This is an implementation of `genai_prices.types.AbstractUsage` so it can be used to calculate the price of the request using [genai-prices](https://github.com/pydantic/genai-prices).
          - `input_tokens` integer
          - `cache_write_tokens` integer
          - `cache_read_tokens` integer
          - `output_tokens` integer
          - `input_audio_tokens` integer
          - `cache_audio_read_tokens` integer
          - `output_audio_tokens` integer
          - `details` object
        - `model_name` string, nullable
        - `timestamp` string, date-time
        - `kind` 'response'
        - `provider_name` string, nullable
        - `provider_url` string, nullable
        - `provider_details` object, nullable
        - `provider_response_id` string, nullable
        - `finish_reason` 'stop' | 'length' | 'content_filter' | 'tool_call' | 'error', nullable
        - `run_id` string, nullable
        - `conversation_id` string, nullable
        - `metadata` object, nullable
        - `state` 'complete' | 'incomplete' | 'suspended' | 'interrupted'

## Other responses

- `422` — Validation Error

---

[API](https://skmtc.net/maia-analytics/apis/maia-api.md) · [All operations](https://skmtc.net/maia-analytics/apis/maia-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/maia-analytics/maia-api/versions/ba2b8d962161/schema)
