# Run a coding agent in a sandbox

> How to give a sandbox's coding agent your credentials, send it a task, follow and continue its conversations, run several at once, and stop the sandbox when they finish.

Every sandbox runs Claude Code and OpenCode. You send a task with `div agent prompt`. The agent works in the sandbox as root in `/root`, with a shell, the files, and the sandbox's desktop and browser, and its messages come back to your terminal.

The agents cost nothing beyond the sandbox's own price. The model's usage is billed to your own API key or subscription. We do not bill for it.

This guide shows how to give the agent credentials, send it tasks, follow its work, and stop the sandbox when it is done.

## Give the agent credentials

The agent uses your credentials, never ours. Choose one of two ways.

### Use an API key

1. Save the key as an org secret. `--from-env` reads it from the shell variable with the same name.

   ```bash
   div secrets set ANTHROPIC_API_KEY --from-env
   ```

2. Create a sandbox that receives the secret.

   ```bash
   SB=$(div sandbox create --size standard --secret ANTHROPIC_API_KEY)
   ```

A sandbox receives only the secrets it names. Their values are masked in the agent's messages and tool output. OpenCode also uses other providers' keys, such as `OPENAI_API_KEY`. Name each one with `--secret`.

To keep the key out of runs, add `--products sandboxes` to `div secrets set`. To give each of your customers their own key, see [Keep each customer's credentials in its own environment](https://docs.divergentlabs.xyz/sandboxes/environments.md).

Use an API key for a sandbox that several people in your org prompt.

### Use your Claude subscription

1. Open a shell on the sandbox.

   ```bash
   div sandbox ssh $SB
   ```

2. Run `claude` and type `/login`.
3. Open the link it prints, sign in, and paste the code back into the terminal.
4. Exit the shell.

Use this for a sandbox you alone use. Anyone in your org who can prompt this sandbox uses your subscription, and a fork of it is signed in too. For a team's sandboxes, use an API key.

To sign OpenCode in to a provider instead, run `opencode auth login` in the shell. OpenCode's own models, named `opencode/…`, need no key.

## Send a task

```bash
div agent prompt $SB "Clone github.com/acme/app, run its tests, and fix the first failure."
```

The agent's messages go to stdout as it writes them. The conversation's id, each tool call the agent makes, and a last line with the outcome and token counts go to stderr. The command exits `0` when the turn finishes and `1` when it fails.

If you press Ctrl-C, `div` stops following and exits `130`. The turn continues in the sandbox.

If the agent has no credentials, the prompt is refused with `credentials_missing`, and the message names both ways to add them.

To use OpenCode, or a different model:

```bash
div agent prompt $SB --harness opencode --model anthropic/claude-sonnet-4-5 "Add a CHANGELOG entry for the fix."
div agent prompt $SB --model opus "Review the fix for edge cases."
```

## Follow and continue a conversation

A prompt continues the sandbox's most recent conversation. The agent remembers the earlier turns.

1. Send a follow-up:

   ```bash
   div agent prompt $SB "Now add a test for that case."
   ```

2. To start a new conversation instead, pass `--new`. To continue an older one, pass `--resume` with its id.

   ```bash
   div agent prompt $SB --new "Update the README's install steps."
   div agent prompt $SB --resume c-261001095246-c2f8 "Also run the linter."
   ```

3. To send a task and return at once, pass `--detach`. The command prints the conversation's id.

   ```bash
   CONV=$(div agent prompt $SB --detach "Upgrade every dependency and fix what breaks.")
   ```

4. List the sandbox's conversations, or print one and follow it while it runs:

   ```bash
   div agent conversations $SB
   div agent conversations $SB $CONV -f
   ```

A conversation runs one turn at a time. A prompt sent while a turn runs waits in a queue and runs next.

Conversations are kept on the sandbox's disk. They survive `stop` and `resume`, and a fork starts with a copy of them.

## Run several conversations at once

Each conversation runs on its own. A sandbox runs up to one conversation at a time per GiB of memory:

| Size | Memory | Conversations at once |
| --- | --- | --- |
| `small` | 2 GiB | 2 |
| `standard` | 4 GiB | 4 |
| `large` | 8 GiB | 8 |
| `xl` | 16 GiB | 16 |

```bash
div agent prompt $SB --new --detach "Fix the failing test in api/."
div agent prompt $SB --new --detach "Fix the failing test in web/."
```

A prompt that would start one more than the limit is refused with `too_many_turns`. Wait for a conversation to finish, or create a larger sandbox. A prompt queued behind a running turn does not count toward the limit.

If you want each task on its own copy of the files, fork the sandbox for each task instead. See [Stop, resume and fork a sandbox](https://docs.divergentlabs.xyz/sandboxes/snapshots.md#fork-a-sandbox).

## Use the desktop and browser

The agent sees and uses the sandbox's desktop with its computer tools: screenshots, clicks, typing, and the accessibility tree. The desktop starts the first time the agent uses it.

```bash
div agent prompt $SB "Start the dev server, open it in the browser, and check that the login form works."
```

To watch, open the sandbox's page in the dashboard. Click **Take over** to use the keyboard and mouse yourself, for example to enter a one-time code, and **Hand back** when you are done. See [Use the desktop and browser](https://docs.divergentlabs.xyz/sandboxes/desktop.md#watch-the-screen-or-take-control).

## Stop the sandbox when the agents finish

A running turn counts as use, so the sandbox is not stopped as idle while an agent works. To stop it once the agents are done, pass `--stop-when-agents-finish`:

```bash
SB=$(div sandbox create --secret ANTHROPIC_API_KEY --stop-when-agents-finish)
div agent prompt $SB --detach "Run the full test suite and fix every failure."
```

The sandbox stops when at least one turn has finished, no turn is running or queued, and nothing has used the sandbox for 2 minutes. Its files and conversations are kept, and it is billed for storage only. `div sandbox ls --json` shows `agents_finished` in `stopped_reason`.

To turn it on or off for an existing sandbox:

```bash
div sandbox set $SB --stop-when-agents-finish on
div sandbox set $SB --stop-when-agents-finish off
```

A stopped sandbox refuses prompts with `not_running`. Resume it first:

```bash
div sandbox resume $SB
div agent prompt $SB "Continue where you left off."
```

## Limitations

- A sandbox created before agents were available refuses prompts with `agent_unavailable`. Create a new sandbox.
- A prompt can be up to 262,144 characters.

For every flag and exit code, see [`div agent`](https://docs.divergentlabs.xyz/sandboxes/cli/agent.md). For agents using MCP, see [Sandbox MCP tools](https://docs.divergentlabs.xyz/sandboxes/mcp.md#coding-agents).
