Skip to main content
Every sandbox has five coding agents (“harnesses”) installed. Sign them in once, with your Claude or ChatGPT subscription or your own model provider keys. Keys and the Claude token never enter the VM: the host’s egress proxy adds them to each request on the way out.

Harnesses

GET /v1/agents lists them with the providers you have connected, your defaults and the models each can default to. A key is stored per provider, so one Anthropic key serves Claude Code, OpenCode, pi and Kimi Code.

Connect your provider keys

Your keys are yours alone. They are never listed to other members, never pooled, and used only in sandboxes you created or forked. The API stores them sealed (AES-256-GCM) and only ever returns the last 4 characters.
Posting again for the same provider replaces the key. DELETE /v1/agents/credentials/{provider} removes it. Keys belong to a person, so an API key whose member has never signed in to Zode gets 403 no_user.

Use your Claude or ChatGPT subscription

Claude Code can run on your Claude plan (Pro, Max, Team or Enterprise) and Codex on your ChatGPT plan, instead of an API key. Calls then count against your plan’s limits, not your API bill or Zode’s spend caps. In the console, open Agents & proxying, then Claude Code or Codex, and click Sign in on the subscription row. A tab opens on Claude’s or ChatGPT’s own sign-in page:
  • Claude: approve, then paste the code the page shows back into the console.
  • ChatGPT: enter the one-time code the console shows.
The sign-in runs the official CLI (claude setup-token or codex login --device-auth) in one of your running sandboxes. If you have none, Zode starts a short-lived one for the sign-in and deletes it when you finish, so you never need a sandbox first. Zode never sees your password and holds no OAuth client of Anthropic’s or OpenAI’s. You can also run the command on your own machine and paste what it prints: Paste a token for Claude, Paste auth.json for Codex.

Where your login lives

  • Claude: the token stays on the host. Your sessions get a placeholder, and the host swaps the real token in only on requests to api.anthropic.com. Each sandbox has its own placeholder, so one read from inside a VM is useless anywhere else.
  • ChatGPT: Codex needs its auth.json on disk. Zode writes it into the sandbox only while you have a session open there and takes it back, with any refreshed tokens, when the last one ends. Teammates in that sandbox at the same moment, and forks taken then, can read it.
A login is yours: it is sealed, never listed to other members, and used only in sandboxes you created or forked. A teammate’s session in your sandbox does not get it. One sign-in method is in use at a time per agent. Switch to API keys goes back to your keys, and Disconnect deletes the login.

Default harness and models

PATCH /v1/agents/settings stores your default harness and a default model per harness. "" clears a value. A model the harness does not list answers 400 invalid_request.
The models offered are the ones Zode has prices for, so every default is metered. zode prompt uses these defaults.

Run an agent in a sandbox

zode prompt gives the default agent one task in a sandbox and streams what it does. It signs the agent in the way you chose, subscription or keys.
--model picks a model, --cd a directory in the sandbox, and --new makes a sandbox first. The agent runs unattended with its own permission prompts off, since nobody is there to answer them inside the VM. See the CLI. With zode exec you run the agent yourself. On API keys, set the agent’s key variable to any placeholder; the proxy removes it and puts the real key in:
If Zode holds no key for a provider, the request goes out with the agent’s own credentials, untouched.

Workspace keys and failover

Owners and admins can add shared workspace keys under /v1/proxying. Every role can read the settings. For each request the proxy tries, in order:
  1. the key of the person who launched the sandbox, then
  2. the workspace keys for that provider, in failover order (position 0 first).
On a 429, 529 or 503 from the provider, the proxy puts that key on cooldown and resends the same request with the next key. The cooldown follows the provider’s Retry-After (30 s for 429 and 10 s for 529 or 503 when there is none, at most 1 hour). If every key is throttled, the last 429 or 529 reaches the agent with its Retry-After, so the agent backs off. Once a response starts streaming, nothing is retried. A 401 or 403 does not fail over.
A provider takes at most 10 workspace keys (409 too_many_keys). The order call must list every key of that provider exactly once, else 400 order_mismatch.

Loop breaker and caps

PATCH /v1/proxying/settings (owners and admins) sets the loop breaker and the AI spend caps. Amounts are micro-dollars (1 USD = 1,000,000). {"reset": true} restores the breaker defaults. The loop breaker reports today: when it trips it sends a breaker.tripped event to your alerts and webhooks, and calls keep going. The alert says the breaker “flagged a possible loop”, not that it paused the agent. It does not see code changes yet, so a long busy session can trip it. The two caps are the same values as the spend caps in Billing. When a sandbox’s cap or the daily cap is spent, AI calls through Zode keys answer HTTP 402 with {"type":"error","error":{"type":"zode_spend_cap",...}}. See Spend and caps.

AI spend: shown, not billed

You pay your provider directly. Zode adds no markup and does not bill AI calls. The proxy prices each call at the provider’s list price and reports it per repo, branch, PR, member, sandbox and model in zode cost --by model and GET /v1/usage.
AI spend reporting reads the flight recorder, which the hosts do not write to yet. Until they do, usage shows AI spend as $0 in 0 calls. Caps are counted on the host and apply regardless.

Drive Zode from your coding agent

The other direction: an agent on your laptop creates and uses sandboxes through MCP. zode mcp is a stdio MCP server signed in as you.
The agent gets sandbox_list, sandbox_create, sandbox_exec, sandbox_read_file, sandbox_write_file, sandbox_fork, sandbox_stop, sandbox_start and sandbox_delete. See MCP.