models, this catalogue is a constant of the deploy rather than a live read — a harness needs an adapter compiled in, so the list cannot change without a release. It is still cursor-paged like every other listing, so you write one loop for both.
list
GET /v1/harnesses. Every harness, including those still in preview.
Each entry:
string
The value you pass as
harness on agents.create.string
A display name, for a picker.
"hosted" | "local"
hosted runs on our infrastructure. local runs on your own machine against your own logged-in account."usage" | "account"
usage is metered to your credit balance. account bills to the account you are already logged in to, so it does not touch your balance."ga" | "preview"
preview means the loop runs but its contract may still move."isolate" | "sandbox" | "local"
Where the loop runs, and therefore what an idle session costs.
isolate runs in the session itself and holds no sandbox between turns. sandbox runs the agent on a micro-VM, which the session holds across turns. local runs on your own machine. This is a different question from location, which is about who operates it.boolean
Whether a session on it runs today. This is a different question from
status: a harness can be preview and runnable, or published and not yet runnable. Starting a session on one with runnable: false is a 501 naming the field — refused at start, never discovered part-way through a turn.object
What the loop can be admitted for — see below.
Capabilities
Harnesses differ, and the differences are load-bearing. Read them before you create an agent:boolean
The loop can hold a tool call and wait for a decision. A harness with
false here cannot serve a toolset whose permission is ask.boolean
The loop can honour
structured_output_required.boolean
The loop emits incremental
message.delta events. With false, you still get message.completed — the answer arrives whole rather than as it is written.boolean
The tools Vetta contributes reach the loop’s model — the team tools,
mcp_servers and connected accounts — governed by the agent’s tools policy. It does not say by which road: a loop Vetta hosts is handed them for the turn, an agent that is a CLI process in a machine of its own is given a session-scoped tool endpoint to call. On the second road a tool whose permission is ask is left out rather than gated, and wait_for_agents does not pause the turn. agents.create refuses a multiagent or a non-empty mcp_servers on a harness declaring false, naming the field; no published harness declares false.400 naming the field. It is never a quiet best effort that looks like it worked.
retrieve
GET /v1/harnesses/{id}. One harness, for when you already hold a base and want to know what it can be admitted for.
A base with no adapter behind it is a 404, not an empty row — including an id reserved in a picker but not yet runnable.