# Sandboxes

A sandbox is a hidden branch for one task. Create it from any branch or commit in milliseconds, push to it, run its checks, and merge it back with one command. Agents get one per task; people use them for experiments that should not clutter the branch list.

> **Beta:** Sandboxes are in beta, free within the [published limits](https://rebasely.com/docs/limits#live).

*Diagram: 1. A sandbox is created from a commit of main in milliseconds, as the hidden ref refs/sandbox/a-fixer/fix-login. 2. Its owner pushes commits to it; it never shows up in branch lists or clones. 3. Workflows that declare on: sandbox run its checks. 4. When they pass, the sandbox merges back into main as a fast-forward, a merge commit or one squashed commit, and ends.*

*A sandbox leaves main as a hidden ref, gets its own commits and checks, and merges back.*

## How a sandbox works

- Its ref is `refs/sandbox/<owner>/<name>`. The owner is `a-<agent>` for an agent and `u-<id>` for a person; the name is yours to pick (lowercase letters, digits, `.`, `_` and `-`, up to 64), or a generated one.
- It does not show up in branch lists, ref advertisements or clones. Fetch it by name when you need it.
- Only its owner and the repository's owners push to it. A push never creates one: create it with the CLI, the API or the `sandbox.create` tool.
- It expires after 24 hours without a push. People can ask for up to 30 days, agents up to 7. An ended sandbox is kept for 7 days for its history.

## From creation to merge

### 1. Create it

From `main`, with a git worktree for it next to your clone:

```sh
rebasely sandbox create --from main --name fix-login --worktree ../fix-login
```

Without `--worktree`, the CLI prints the fetch, worktree and push commands instead.

### 2. Push to it

```sh
cd ../fix-login
git commit -am "Fix the login redirect"
git push origin HEAD:refs/sandbox/<owner>/fix-login
```

### 3. Run its checks

Workflows run on a sandbox only if they declare `on: sandbox`, and such runs never get secrets. `--wait` follows them and exits 1 if one fails.

```sh
rebasely sandbox checks fix-login --wait
```

### 4. Merge it

```sh
rebasely sandbox merge fix-login --into main --mode squash
```

`--mode` is `ff` (the default), `merge` or `squash`. A merge or a squash writes a commit, which needs an account at least 7 days old or a verified one. A conflicting merge writes nothing and lists the files and lines. `--expect <sha>` refuses the merge if the sandbox moved since you read it.

Or open a [pull request](https://rebasely.com/docs/pull-requests) from the sandbox when people should review it first. `rebasely sandbox list` and `rebasely sandbox delete` do what they say.

## The API and MCP

CLI:

```sh
rebasely sandbox create --from main --name fix-login
rebasely sandbox merge fix-login --into main
```

API:

```sh
curl -fsS -X POST -H "Authorization: Bearer $REBASELY_TOKEN" -H "content-type: application/json" \
  -d '{"from":"main","name":"fix-login"}' https://rebasely.com/api/v1/repos/<org>/<repo>/sandboxes
```

MCP:

```json
{"name": "sandbox.create", "arguments": {"repo": "<org>/<repo>", "from": "main", "name": "fix-login"}}
```

| Request | What it does |
| --- | --- |
| `GET /sandboxes` | The repository's sandboxes (`?mine=1`, `?ended=1`) |
| `POST /sandboxes` | Create one: `{from?, name?, ttl_s?, live?}` |
| `GET`, `DELETE /sandboxes/<owner>/<name>` | Read or delete one |
| `POST /sandboxes/<owner>/<name>/merge` | Merge: `{into?, mode?, expect?, message?, delete?}` |
| `POST /sandboxes/<owner>/<name>/checks` | Run its `on: sandbox` workflows |

Paths are under `/api/v1/repos/<org>/<repo>`. A person's token needs `repo:write`, an agent's `sandbox:write`. A sandbox created with `{"live": true}` works like any [live branch](https://rebasely.com/docs/live) until it is merged or deleted.

## Limits and settings

At most 20 active sandboxes per person or agent in a repository, 200 per repository and 1,000 per organization. An owner can turn sandboxes off for a repository in its settings, under Live and sandboxes. Creating one then fails with `sandboxes_disabled`; existing sandboxes can still be pushed, merged and deleted.

> **Tip:** Coding agents work best with one sandbox and one git worktree per task. `rebasely agent init` adds the [Rebasely agent skill](https://rebasely.com/docs/skills/rebasely/SKILL.md), which tells them to.

---

Source: https://rebasely.com/docs/sandboxes
