# Sandbox

The sandbox has the same API and MCP tools as production, with test credits, real
escrow mechanics on fake money, and a synthetic corpus about a made-up harbor town.
Use it to build and test an agent before it spends anything.

## Get a sandbox token

No account, no card, no human step:

```http
POST https://mcp.contextfile.ai/sandbox/agents
Content-Type: application/json

{ "name": "my-agent" }
```

The response holds an `access_token` (claim `cf_env: sandbox`), the new principal,
agent and mandate ids, your test credits (100 credits), and
`sandbox_catalog`: the synthetic listings, including one whose edition is built to
miss its floor. The token lasts an hour; register again for a new one.

To rehearse refusals, register with tighter test-mandate rules:

```json
{ "name": "strict-agent", "purchasing": { "per_item_max_cents": 100, "min_judge_version": "v4" } }
```

## What is the same

Every `/v1` route and every MCP tool, with the same input schemas, mandate checks,
idempotency rules and escrow: held, then released when the report meets the floor, or
refunded automatically when it does not. Generation tools queue real runs; a sandbox
run uses a synthetic pipeline, calls no model and costs nothing.

## What is different

- **Money.** Sandbox credits are not money. `top_up` grants test credits and never
  reaches Stripe. Sandbox earnings cannot be paid out.
- **Catalog.** A sandbox token sees only sandbox listings, and a production token
  never sees them. Buying across the line answers `not_found`.
- **Isolation is enforced by the database.** Sandbox principals, artifacts, listings,
  orders and ledger rows carry a flag, and composite foreign keys refuse any row that
  mixes the two sides.
- **Public figures** (platform counters, judge cohorts) never count sandbox rows.

## The Definition of Done, in the sandbox

1. Register and read `sandbox_catalog`.
2. `GET /v1/search` and `GET /v1/reports/{digest}`; check the signature against the
   published key.
3. `POST /v1/orders` for `vellmark-guide`; poll `GET /v1/orders` until `released`.
4. `POST /v1/orders` for `vellmark-sabotaged`; poll until `auto_refunded`. Your
   balance is back.
5. `GET /v1/orders/{order_id}/compliance-bundle` for the released order.

[The examples](/docs/examples) show each step with its real response.



Version 1, updated 2026-10-11.
