---
title: "The live model catalog"
method: GET
path: "/v1/catalog"
---

# The live model catalog

`GET /v1/catalog`

## Request

- Base URL: `https://gateway.caveman.so`
- URL: `https://gateway.caveman.so/v1/catalog`
- Auth: API key in header `x-cave-api-key`

Every model the installation knows, under one canonical id, with the hosts that serve it, the wires each host serves it on, capabilities, effort levels, limits, cache facts, prices per tier, review state and deprecation, each field with its source. Wire facts only: no routing scores or decision data. Updated automatically from models.dev, the LiteLLM map, provider model lists and the AWS price list under Caveman's reviewed facts. A host offering only Caveman's own provider accounts list is left out. A newly seen model is unreviewed: usable when a request names it, never substituted to until approved. Send the ETag back as If-None-Match to get 304 while the catalog is unchanged.

## Headers

- `If-None-Match` string

## Response `200`

The catalog; the weak ETag is its revision

- ModelCatalog
  - `schema` 'caveman.catalog.v1', required
  - `revision` string, required: Opaque revision of this body: it changes when a fact it publishes changes, never for generated_at or fetched_at alone. The weak ETag is W/"<revision>".
  - `generated_at` string, required
  - `sources` object[], required
    - `id` 'models.dev' | 'litellm' | 'aws-pricing' | 'reviewed-catalog' | 'facts', required
    - `license` string, required
    - `fetched_at` string
    - `models` integer, required: Observations the source's last good fetch carried.
  - `models` object[], required
    - `id` string, required: Canonical model id: the maker's first-party id. Host-specific ids (Bedrock profiles, Vertex snapshots, aggregator slugs) fold onto it.
    - `maker` string, required
    - `name` string
    - `review` 'reviewed' | 'unreviewed', required: unreviewed: newly seen and not yet approved. Usable when a request names it; never a routing substitution target.
    - `released_at` string
    - `lifecycle` object, required
      - `status` 'active' | 'legacy' | 'deprecated' | 'retired', required
      - `deprecated_at` string
      - `retires_at` string
      - `replacement` string
    - `limits` object, required
      - `context_tokens` integer
      - `input_tokens` integer
      - `output_tokens` integer
    - `capabilities` object, required: Tri-state: an absent key is unknown.
      - `tools` boolean
      - `vision` boolean
      - `pdf` boolean
      - `structured_output` boolean
      - `reasoning` boolean
      - `streaming` boolean
      - `prompt_cache` boolean
    - `effort` object, required
      - `levels` string[]
      - `default` string
      - `thinking_off` 'effort_none' | 'thinking_disabled' | 'between_tools' | 'unsupported'
    - `hosts` object[], required
      - `host` string, required: anthropic, openai, gemini, vertex, bedrock, deepseek, moonshot, xai, mistral, groq, qwen, z-ai, minimax.
      - `model_id` string, required: The id this host takes on the wire.
      - `region` string, required: global for single-endpoint hosts; an AWS region for Bedrock; any when no source says which regions serve the id.
      - `scope` string: Bedrock inference-profile scope (global, us, eu, apac, jp, au, us-gov, ca); absent for a base id.
      - `surfaces` object[], required
        - `wire` 'messages' | 'responses' | 'chat_completions' | 'generate_content' | 'converse' | 'invoke', required
        - `tools` boolean: false: this wire refuses tools for this model.
        - `per_message_effort` boolean: true: effort can change per message on this wire without breaking the prompt cache.
      - `prices` object[]
        - `tier` 'standard' | 'flex' | 'priority' | 'batch', required
        - `input_per_million` number: USD per million tokens.
        - `output_per_million` number: USD per million tokens.
        - `cache_read_input_per_million` number: USD per million tokens.
        - `cache_write_input_per_million` number: USD per million tokens written to a 5-minute (default TTL) cache.
        - `cache_write_1h_input_per_million` number: USD per million tokens written to a 1-hour cache.
        - `long_context` object
          - `above_tokens` integer, required
          - `input_per_million` number: USD per million tokens.
          - `output_per_million` number: USD per million tokens.
        - `schedule` object: The reviewed daily UTC schedule this price follows, the one billing charges by. The price's own rates are the ones in effect at generated_at; the revision moves when a window opens or closes. From effective_from the rates are default, except inside a window's half-open [start, end) of each UTC day.
          - `effective_from` string, required: RFC 3339.
          - `default` object, required
            - `input_per_million` number: USD per million tokens.
            - `output_per_million` number: USD per million tokens.
            - `cache_read_input_per_million` number: USD per million tokens.
            - `cache_write_input_per_million` number: USD per million tokens written to a 5-minute (default TTL) cache.
            - `cache_write_1h_input_per_million` number: USD per million tokens written to a 1-hour cache.
          - `windows` object[]
            - `start` string, required: UTC time of day, HH:MM:SS.
            - `end` string, required: UTC time of day, HH:MM:SS.
            - `input_per_million` number: USD per million tokens.
            - `output_per_million` number: USD per million tokens.
            - `cache_read_input_per_million` number: USD per million tokens.
            - `cache_write_input_per_million` number: USD per million tokens written to a 5-minute (default TTL) cache.
            - `cache_write_1h_input_per_million` number: USD per million tokens written to a 1-hour cache.
        - `source` string, required: The ingest source the rates come from.
        - `fetched_at` string: The fetch the rates came from as of the catalog's last change (RFC 3339), or the reviewed catalog's verified_at. Not part of the revision: a refetch that changes nothing does not move it.
      - `cache` object
        - `mode` 'explicit' | 'implicit' | 'automatic'
        - `ttl_seconds` integer[]
        - `min_tokens` integer
        - `max_breakpoints` integer
        - `source` string
      - `sources` string[], required
    - `provenance` object, required: Field path (limits.context_tokens, capabilities.tools, effort.levels, ...) to the source that supplied the published value.
    - `conflicts` object[]: Fields the sources disagree on. The published value is chosen's; every source's value is listed.
      - `field` string, required
      - `values` object[], required
        - `source` string, required
        - `value` string, required
      - `chosen` string, required

## Other responses

- `304`: Unchanged since the If-None-Match revision
- `4XX`: Structured failure. `error.code` is stable; `error.request_id` is echoed in the x-cave-request-id header.
- `5XX`: Structured failure. `error.code` is stable; `error.request_id` is echoed in the x-cave-request-id header.

---

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