> ## Documentation Index
> Fetch the complete documentation index at: https://vetta.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Models

> The model catalogue an agent can run on — read live from the inference network, never a fixed list.

> [!NOTE]
>
> There is **no fixed list of models**. The catalogue is read from the inference network and cached briefly, so a model published this morning is runnable this morning. Search it here; pass what you find as `model` on an [agent](https://vetta.sh/docs/api/agents.md) or a [session](https://vetta.sh/docs/api/sessions.md), or as `model` to the [model proxy](https://vetta.sh/docs/api/proxy.md).

## The model object

**object** `string`

Always `model`.

**id** `string`

The model's id. This is what `model` takes on an agent, a session and the proxy.

**context\_window** `integer`

Maximum context length in tokens, as the provider that will serve it publishes it.

**max\_output\_tokens** `integer`

The longest reply this model may produce. It is also the output half of the [pre-flight quote](https://vetta.sh/docs/concepts/budgets.md), so a model with a large allowance reserves more against your balance for the same prompt.

**supported\_windows** `string[]`

Which [completion windows](https://vetta.sh/docs/concepts/completion-window.md) this model can run in. `immediate` is always present; `priority` and `loose` appear only for pool-hosted models.

**efforts** `string[]`

Effort levels the model accepts, from what it publishes. Empty when it accepts none.

**No price is published here**, the same line image and video rows of [`GET /v1/media/models`](https://vetta.sh/docs/api/media) draw. A mesh row is the exception: its price is fixed by the options, so that catalogue lists it. What a call costs depends on the window it runs in and on which of the five token tiers its usage lands in; a single figure on this reply would be a guess. See [the model router](https://vetta.sh/docs/concepts/model-router.md#what-a-model-call-costs) for how a call is metered, and [Pricing](https://vetta.sh/docs/platform/pricing.md).

## List the catalogue

`GET /v1/models` — any valid key; no scope.

**window** `string`

`immediate`, `priority` or `loose`. Narrows the list to models that window can actually serve — the same derivation the router refuses on, so a model listed for a window is never refused for it.

**search** `string`

Free text, matched against a model's id and name. Omit it to list them all.

**limit** `number`

Page size, 1–100. Defaults to 20.

**after** `string`

The `next_cursor` of the previous page. Opaque — it is not a row id.

The catalogue runs to several hundred entries, so **this reply is paged** ([Pagination](https://vetta.sh/docs/api/pagination.md)). Nothing should assume one call returns the whole catalogue.

```bash cURL theme={"system"}
curl -fsSL "https://api.vetta.sh/v1/models?search=glm&limit=2" \
  -H "authorization: Bearer sk_live_..."
```

```typescript TypeScript theme={"system"}
const page = await vetta.models.list({ search: "glm", limit: 2 });
```

```bash CLI theme={"system"}
vetta models list --search glm --limit 2
```

```json Response theme={"system"}
{
  "object": "list",
  "data": [
    {
      "object": "model",
      "id": "zai-org/GLM-5.2-FP8",
      "context_window": 1048576,
      "max_output_tokens": 32768,
      "supported_windows": ["immediate", "priority", "loose"],
      "efforts": ["high"]
    }
  ],
  "has_more": true,
  "next_cursor": "2"
}
```

Ordering is cheapest published input rate first, then by id, so a page boundary is stable within one read.

## Retrieve one model

`GET /v1/models/{id}` — any valid key; no scope.

> [!WARNING]
>
> A model id contains a `/`, so it must be **percent-encoded** in the path: `z-ai/glm-5.3-flash` becomes `z-ai%2Fglm-5.3-flash`.

Use this when you already hold an id — the model an agent is set to, say — and want to know what it can do before you spend on it. It answers on the ids this route *lists*; a model the catalogue republishes under a different spelling is resolved for billing but is not itself an id you can retrieve.

```bash cURL theme={"system"}
curl -fsSL "https://api.vetta.sh/v1/models/z-ai%2Fglm-5.3-flash" \
  -H "authorization: Bearer sk_live_..."
```

```typescript TypeScript theme={"system"}
const model = await vetta.models.retrieve("z-ai/glm-5.3-flash");
console.log(model.supported_windows); // ["immediate"]
```

```bash CLI theme={"system"}
vetta models get z-ai/glm-5.3-flash
```

```json Response theme={"system"}
{
  "object": "model",
  "id": "z-ai/glm-5.3-flash",
  "context_window": 1000000,
  "max_output_tokens": 32768,
  "supported_windows": ["immediate"],
  "efforts": ["low", "medium", "high"]
}
```

## Choose a model for a conversation

`POST /v1/models/auto_select` — scope `proxy:write` (or `sessions:write`). [`Idempotency-Key`](https://vetta.sh/docs/api/overview#idempotency) accepted.

An **optional add-on** — the capability page is [Model auto-selection](https://vetta.sh/docs/concepts/model-selection.md). You name two to sixteen catalogue ids, each with one line on what it is for, and hand over the conversation so far; the reply is **one of those ids**, which you then pass unchanged as `model` to the [model proxy](https://vetta.sh/docs/api/proxy.md), an [agent](https://vetta.sh/docs/api/agents.md) or a [session](https://vetta.sh/docs/api/sessions.md). It selects; it does not call the model it selected, and nothing about routing, the catalogue or `vetta/auto` changes whether or not you use it.

**options** `object` *required*

Catalogue id → description, **2 to 16 entries**. Every key must be an id [the catalogue](#list-the-catalogue) lists, spelled exactly — an unknown id, an alias or `vetta/auto` is `validation_failed` with `param: "options.<id>"`. A description is trimmed and must be 1 to 500 characters after trimming.

**messages** `object[]` *required*

The conversation, **1 to 32 turns** of `{ "role": "user" | "assistant", "content": string }`, each `content` at least one character. The `content` lengths must **sum to 32000 characters or fewer**; over that the request is `validation_failed` with `param: "messages"`. Nothing is trimmed, windowed or truncated for you — send less if you want less considered.

**default** `string`

One of the `options` keys, else `validation_failed` with `param: "default"`. Returned in place of the pick when `min_confidence` is set and not met.

**min\_confidence** `number`

A number above `0` and at most `1`. Requires `default` — a threshold with nothing to fall back to is `validation_failed` with `param: "min_confidence"`.

```bash cURL theme={"system"}
curl -fsSL "https://api.vetta.sh/v1/models/auto_select" \
  -H "authorization: Bearer sk_live_..." \
  -H "content-type: application/json" \
  -d '{
    "options": {
      "z-ai/glm-5.3-flash": "Routine coding, edits and tool use",
      "deepseek/deepseek-v4-flash-0731": "Strict JSON output that must match a schema",
      "google/gemma-4-31B-it": "Short factual answers where speed matters"
    },
    "messages": [{ "role": "user", "content": "What year did the Berlin Wall fall?" }],
    "default": "z-ai/glm-5.3-flash",
    "min_confidence": 0.5
  }'
```

```typescript TypeScript theme={"system"}
const pick = await vetta.models.autoSelect({
  options: {
    "z-ai/glm-5.3-flash": "Routine coding, edits and tool use",
    "deepseek/deepseek-v4-flash-0731": "Strict JSON output that must match a schema",
    "google/gemma-4-31B-it": "Short factual answers where speed matters",
  },
  messages,
  default: "z-ai/glm-5.3-flash",
  min_confidence: 0.5,
});
// pick.model is a catalogue id — pass it as `model` on the next call.
```

```json Response theme={"system"}
{
  "object": "model_selection",
  "model": "google/gemma-4-31B-it",
  "confidence": 0.81,
  "probabilities": {
    "z-ai/glm-5.3-flash": 0.12,
    "deepseek/deepseek-v4-flash-0731": 0.07,
    "google/gemma-4-31B-it": 0.81
  },
  "defaulted": false,
  "spent_micro_usd": 11,
  "usage": { "input_tokens": 210 }
}
```

**object** `string`

Always `model_selection`.

**model** `string`

One of the `options` keys — the id to pass on.

**confidence** `number | null`

The selector's probability for its own choice; `null` when it reported no distribution.

**probabilities** `object | null`

The full distribution over the `options` keys, or `null`.

**defaulted** `boolean`

`true` only when `default` was returned in place of the selector's pick.

**spent\_micro\_usd** `integer`

What this call debited, in micro-USD.

**usage.input\_tokens** `integer`

The input tokens the selection consumed — the reported count, or the pre-flight estimate the debit was priced from when none was reported.

**The selection rule.** One choice is asked over `options`, about the conversation, with a fixed question: which option should answer the latest user message, given each option's description.

* Without `min_confidence`, `model` is the selector's choice and `defaulted` is `false`.
* With `min_confidence`, if `confidence` is `null` **or** below the threshold, `model` is `default` and `defaulted` is `true`; `confidence` and `probabilities` still report what the selector said. `default` does nothing without `min_confidence`.
* An answer that is not one of the `options` keys is `internal_error` (500), never a silent default.

**It fails closed.** `default` is a confidence policy, not an outage policy. A deploy with no selector configured answers `feature_not_configured` (501); a selector that cannot be reached answers `rate_limited` (429) or `internal_error` (500), exactly as the model proxy does for an upstream failure. None of those costs anything. A caller who wants "use my default when selection is unavailable" catches the error and does so in their own code.

**What it costs.** An organization-level call like the proxy: no session hold, no session or agent id on the entry. The conversation is estimated before the call and the quote is held against the organization's balance until the call settles, so the balance less what other calls in flight are holding must cover it, else `insufficient_credits` (402) before any spend. Afterwards **one debit, one `input` line item** — the selector reads and emits nothing billable — booked under your `Idempotency-Key` if you sent one, else this request's id, and readable on [`GET /v1/credits/ledger`](https://vetta.sh/docs/api/credits#ledger). `spent_micro_usd` on the reply is what the ledger actually took. A refused or failed call is not debited.

## Naive Managed Agents Auto

`vetta/auto` is in the catalogue like any other id, and it picks the model per request. It serves `immediate` only. Because it publishes no rate card of its own, it is quoted against a price ceiling that is enforced upstream — a call that no model can serve within your budget is refused before it runs, never served at a higher price. See [the model router](https://vetta.sh/docs/concepts/model-router.md#naive-managed-agents-auto).

## Errors

| Status | Code | When |
| - | - | - |
| **400** | `validation_failed` | `window` is not one of `immediate\|priority\|loose`. On `auto_select`: an unknown key (`param: "options.<id>"`), fewer than 2 or more than 16 options, more than 32 turns or more than 32000 characters of content (`param: "messages"`), a `default` that is not an option (`param: "default"`), a `min_confidence` with no `default` (`param: "min_confidence"`), or a body key the route does not take. |
| **402** | `insufficient_credits` | `auto_select`: the balance, less what other calls in flight hold, is below the pre-flight quote. Nothing was spent. |
| **404** | `not_found` | No model with that id — including an id this deploy cannot serve. |
| **429** | `rate_limited` | `auto_select`: the selector is busy. Retry shortly; nothing was spent. |
| **500** | `internal_error` | `auto_select`: the selector could not complete the request, or answered something that is not one of your options. Nothing was spent. |
| **501** | `feature_not_configured` | This deploy has no inference network configured — an empty list would say "the network publishes no models", which is a different fact. On `auto_select`: this deploy has no selector configured. |

A transient failure to reach the network answers **500** rather than a stale or empty catalogue. The failed read is not cached, so an immediate retry is the right response to one.

> [card] [Next: the model router](https://vetta.sh/docs/concepts/model-router.md)
>
> How a call is routed, what the completion window changes, and how tokens are metered.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.