POST /v1/proxy/anthropic/v1/messages 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 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 instead.
messages
POST /v1/proxy/anthropic/v1/messages.
string
required
A Vetta model id, exactly as
models.list returns it.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.integer
required
The output allowance. It sets the size of the pre-flight quote held against your balance.
string
The system prompt.
object[]
Tools the model may call, each
{ name, description?, input_schema }. You run them and send the results back as tool_result blocks.window is the second argument, not a body field: the Messages format has no room for a 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.
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.
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 onclient.proxy — but it belongs next to it, because both are things you write rather than read. An agent’s toolset 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:
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
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 — 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.