> ## 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.

# proxy

> One org-level model call in the Messages format — client.proxy.

One method. [`POST /v1/proxy/anthropic/v1/messages`](/docs/api/proxy) is a compatibility endpoint: its whole point is that a Messages-format client you already have works unchanged. This is the typed way to reach it from *this* client, for the case where you want one model call and none of the machinery a [session](/docs/sdk/sessions) brings — no agent, no tools, no event log, no state between calls. It bills the organization directly, and the ledger entry carries no session or agent id.

If you want a durable agent that keeps working across turns, use [`sessions.create`](/docs/sdk/sessions#create) instead.

## messages

```ts theme={"system"}
client.proxy.messages(body: ProxyMessageCreate, window?: Window): Promise<ProxyMessage>
```

`POST /v1/proxy/anthropic/v1/messages`.

<ParamField body="model" type="string" required>A Vetta model id, exactly as [`models.list`](/docs/sdk/models) returns it.</ParamField>
<ParamField body="messages" type="object[]" required>The conversation. Each turn is `{ role: "user" | "assistant", content }`, and `content` is a string or an array of `text` / `tool_use` / `tool_result` blocks.</ParamField>
<ParamField body="max_tokens" type="integer" required>The output allowance. It sets the size of the pre-flight quote held against your balance.</ParamField>
<ParamField body="system" type="string">The system prompt.</ParamField>
<ParamField body="tools" type="object[]">Tools the model may call, each `{ name, description?, input_schema }`. You run them and send the results back as `tool_result` blocks.</ParamField>

`window` is the second argument, not a body field: the Messages format has no room for a [completion window](/docs/concepts/completion-window), so it travels as the `Vetta-Window` header. Unset means `immediate`, and a window is never quietly downgraded — a model with no published price in the window you asked for is refused with `window_unavailable` before anything is spent.

```ts theme={"system"}
const reply = await client.proxy.messages(
  {
    model: "openai/gpt-oss-120b",
    max_tokens: 1024,
    messages: [{ role: "user", content: "Name three sorting algorithms." }],
  },
  "priority",
);
```

The reply carries `id` (the request id, the same value as the `x-request-id` header and the ledger entry), `content`, `stop_reason`, and `usage` with the format's four token counters. The exact five-tier split you were charged on is on [`credits.ledger`](/docs/sdk/credits).

There is deliberately **no streaming method**. Set up a Messages-format client against `<baseUrl>/v1/proxy/anthropic` and stream with that — keeping it working unchanged is what the endpoint is for. Fields the endpoint cannot carry (`temperature`, `top_p`, `stop_sequences`, `thinking`, …) are absent from `ProxyMessageCreate` for the same reason the server refuses them: a silently dropped setting is a call you paid for and did not ask for.

## Configuring an agent's tools

Not a route, and not on `client.proxy` — but it belongs next to it, because both are things you write rather than read. An agent's [toolset](/docs/capabilities/tools) is a field on the agent, and `configs` is replaced wholesale on the wire, so changing one tool by hand means resending every other one unchanged. `withTool` does that for you:

```ts theme={"system"}
import { createClient, withTool } from "@usenaive-sdk/vetta";

const agent = await client.agents.get("agt_01H...");

await client.agents.update(agent.id, {
  tools: withTool(agent.tools, "web_fetch", {
    permission: "ask",
    config: { allowed_domains: ["docs.example.com"], max_content_tokens: 2000 },
  }),
});
```

Every field of the settings is optional and what you omit keeps its current value; `config` merges key by key, so setting a cap does not clear a domain filter. A tool named for the first time is created enabled at the toolset's own default permission. `WebToolConfig` types the domain filters and content cap that `web_search` and `web_fetch` read; `MediaToolConfig` types the `models` allow-list that `generate_image` and `generate_video` read — omit it and the agent keeps the low-cost models only.

## completions

```ts theme={"system"}
client.proxy.completions(body: ProxyCompletionCreate, window?: Window): Promise<ProxyCompletion>
```

`POST /v1/proxy/openai/v1/chat/completions`. The same proxy in the Chat Completions dialect, for a client that speaks that envelope and nothing else.

Same balance, same rate card, same meter as [`messages`](#messages) — only the envelope differs. `max_completion_tokens` (or `max_tokens`) is optional here, unlike the Messages door: omit it and the call is bounded by whatever the model may emit.

Like its sibling, there is no streaming method: a client that streams this dialect already has one, and the endpoint exists so that client keeps working. Point it at `<baseUrl>/v1/proxy/openai`.

```ts theme={"system"}
const reply = await client.proxy.completions({
  model: "zai-org/GLM-5.2-FP8",
  messages: [{ role: "user", content: "Summarise this invoice." }],
});

console.log(reply.choices[0]?.message.content, reply.usage.total_tokens);
```
