> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sanning.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Test in the Sandbox

> A Sandbox API key signs your records for real but never puts a stamp on the public record, so nothing you test counts as evidence.

Use the Sandbox while you build. Every other page in these docs is written for Live.

## How the two modes differ

Your API key decides the mode. Your code does not change. The SDK reads the start of the API key and sets the mode for you.

| Setting | Sandbox | Live |
| - | - | - |
| API key starts with | `sanning_test_` | `sanning_prod_` |
| `environment` signed into each record | `"dev"` | `"production"` |
| Records | Signed for real | Signed for real |
| Stamps | Simulated. They never reach the public record. | Published to the public record. They cannot be withdrawn. |
| Evidence | No. The verifier labels the pack as Sandbox. | Yes |
| Retention | Records are deleted after 30 days, or when you reset | Records and stamps are kept. A stamp cannot be withdrawn. |
| Limits | Fixed, as in [Limits and reset](#limits-and-reset) | Set by your plan |
| Billing | Never billed | Billed by plan |

Everything else is the same in both modes: the SDK, the adapters, the record format, the evidence pack and the verifier.

## Make a Sandbox API key

You enter the Sandbox from your Live organization. Confirm your email address first, or the console refuses the switch.

> [!NOTE]
>
> Sanning is in early access. To get an account, [book a call with us](https://calendar.google.com/calendar/u/0/appointments/schedules/AcZssZ18-Dhr-iEjRTlJFuFJNL9aTUjEu3pkzVx6VqyP3iRc_uZJd4hbdkog2KTmOml-hcmqhtGAqbfZ).

1. Sign in to [console.sanning.io](https://console.sanning.io). Open the account menu and select **Switch to sandbox**. A strip across the top of the console says Sandbox.

2. Open **Settings**, then **API keys**, and select **Create key**. Name the key and leave **Verify** unchecked.

3. Copy the key. It starts with `sanning_test_`, and the console shows it once.

4. Make a seed for the Sandbox agent. Run one of these commands and copy the output:

   ```bash OpenSSL theme={"system"}
   openssl rand -hex 32
   ```

   ```bash Python theme={"system"}
   python -c "import secrets; print(secrets.token_hex(32))"
   ```

   ```bash Node.js theme={"system"}
   node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
   ```

5. Export the seed and the Sandbox API key:

   ```bash theme={"system"}
   export SANNING_SIGNING_SEED=SEED
   export SANNING_API_KEY=API_KEY
   ```

   Replace the following:

   * `SEED`: the 64 hex characters that you made in step 4.
   * `API_KEY`: the Sandbox API key from step 3. It starts with `sanning_test_`.

Do not set `environment` in your code: with a Sandbox API key, `environment: "production"` gives an error when you create the anchorer, the object that signs your records and sends them to Sanning.

## Keep the content on local disk

In the Sandbox only, you can keep the content on local disk instead of an S3 bucket. Use the API key and the seed from [Make a Sandbox API key](#make-a-sandbox-api-key).

Install the SDK. Local disk needs no S3 library:

```bash TypeScript theme={"system"}
npm install @sanning/anchor
```

```bash Python theme={"system"}
pip install sanning-anchor
```

Create the anchorer, with the log store on local disk:

```ts TypeScript theme={"system"}
import {
  createAnchorer,
  FsLogStore,
  LocalEd25519Signer,
  MemoryStore,
} from "@sanning/anchor";

const anchorer = createAnchorer({
  signer: LocalEd25519Signer.fromSeedHex(process.env.SANNING_SIGNING_SEED!),
  subject: { type: "agent", agent_id: "claims-triage" },
  apiKey: process.env.SANNING_API_KEY!,
  logStore: new FsLogStore("./logstore"),
  store: new MemoryStore(),
});
```

```python Python theme={"system"}
import os

from sanning_anchor import (
    Anchorer,
    FsLogStore,
    LocalEd25519Signer,
    MemoryStore,
)

anchorer = Anchorer(
    signer=LocalEd25519Signer.from_seed_hex(os.environ["SANNING_SIGNING_SEED"]),
    subject={"type": "agent", "agent_id": "claims-triage"},
    api_key=os.environ["SANNING_API_KEY"],
    log_store=FsLogStore("./logstore"),
    store=MemoryStore(),
)
```

Replace `claims-triage` with the agent ID of your agent. `MemoryStore` keeps the last record of each adapter run in memory.

To build a pack from that folder, give `bundle` the folder as `--logs ./logstore`. A folder is lost with the machine, so use S3 for Live.

## Run your agent and read the result

Add an adapter to your agent as in [Record your agent with an adapter](https://docs.sanning.io/adapters.md), and run it. Each step appears as a record in the console, under **Records**.

Then build an evidence pack for the case and verify it, as in [Build an evidence pack](https://docs.sanning.io/evidence/build.md) and [Verify an evidence pack](https://docs.sanning.io/evidence/verify.md). A Sandbox pack goes through the same steps as a Live one. The verifier checks the records and says Verified, and it marks the pack as Sandbox. On the command line, it exits with code 3 where a Live pack exits with 0. No flag changes that.

## Why a Sandbox pack is never evidence

A simulated stamp is Sanning's own computation: it gives no time from outside Sanning, so no reviewer can check it against anything. The mode is also signed into each record, so relabeling a Sandbox record as a Live one breaks its signature.

A pack carries one mode. The [`bundle`](https://docs.sanning.io/reference/cli#bundle) command refuses a pack that mixes Sandbox and Live records for the same agent, so give your Sandbox agent its own agent ID.

## Limits and reset

Every Sandbox organization has the same fixed limits:

* 5 requests per second and 300 requests per minute.
* 10 active API keys.
* 25 active agents.
* 10,000 records and 500 MB of stored records.

A request over a limit fails with `SANDBOX_LIMIT_REACHED`.

To clear a Sandbox at once, reset it. Only an owner or admin can. A reset does the following:

* Deletes your records, stamps and pack reports.
* Keeps your API keys and signing keys, so your integration keeps recording.
* Retires every agent. The **Agents** page lists each one as Retired, and a retired agent no longer counts toward the limit of 25 active agents.
* Never touches Live.

You can reset once every 5 minutes.

1. Open **Settings**, then **Sandbox**.
2. Select **Reset the sandbox**.
3. Type the organization's name.
4. In the dialog, select **Reset the sandbox**.

## Move to Live

The Sandbox does not carry its agents or signing keys over to Live: your Live agent is a separate identity.

When your agent records what you expect in the Sandbox, change three things:

1. In the console, select **Switch to live** in the strip across the top, and make a Live API key as in the [Quickstart](https://docs.sanning.io/quickstart.md#make-a-live-api-key).
2. Make a new seed for the Live agent. Do not reuse the Sandbox seed: test pipelines and developer machines can hold it, so a Live agent must not sign with it.
3. Replace `SANNING_API_KEY` and `SANNING_SIGNING_SEED` in your service's secrets, and remove any `environment` that you set.

A stamp on the public record cannot be withdrawn, and a case ID cannot be changed after it is recorded. Before your first Live record, check that your case IDs hold no names or other personal data.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.