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

# Sandbox-first (zero wallet, zero key)

> Try Lumina end-to-end without an API key or wallet — the fastest possible first contact for an LLM agent. SANDBOX runs on Base Sepolia testnet.

<Warning>
  **SANDBOX environment — testnet only.** This page describes the `/sandbox/*`
  endpoints, which run on **Base Sepolia (chainId 84532)** with a mock USDC.
  **Production Lumina runs on Base mainnet (chainId 8453) since 2026-05-28.**
  For real policy purchases on mainnet, see [contracts/deployed](/contracts/deployed)
  and [quickstart](/quickstart). The sandbox is purely for exploration and
  returns no production state.
</Warning>

If you are an LLM agent on first contact with Lumina, **start here**. The
sandbox lets you exercise the full purchase path — relayer signs the tx,
relayer pays the gas, **relayer also pays the premium from a sandbox-funded
wallet** — without you having to mint an API key or fund a wallet.

It's the smallest possible "did this protocol work end-to-end?" probe.

## When to use the sandbox

| Scenario                               | Use sandbox?                                              |
| -------------------------------------- | --------------------------------------------------------- |
| LLM agent prototyping, first call      | **Yes** — zero setup                                      |
| Smoke test in CI                       | **Yes** — cheap, fast, no secrets to inject               |
| Integration check after an SDK upgrade | **Yes** — confirms the chain still settles                |
| Production traffic                     | **No** — capped to \$100/IP/hour                          |
| Hedging a real position                | **No** — the bond is owned by the sandbox wallet, not you |

## Discovery: `GET /sandbox/info`

Hit this first to confirm the sandbox is enabled and read its current
configuration. No auth required.

```bash theme={null}
curl https://lumina-api-production-ac85.up.railway.app/sandbox/info
```

```jsonc theme={null}
{
  "enabled":            true,
  "sandboxWallet":      "0x…",                 // wallet that pays premium + holds the bond
  "coverageCapUsdc":    "100000000",            // $100 per call, in 6-dec USDC
  "asset": {
    "symbol":           "BTC",
    "bytes32":          "0x4254430000…"         // pre-encoded asset literal
  },
  "defaultProductId":   "0xe87625ef…dfeaddd",
  "defaultProductName": "FLASHBTC1H-001",
  "rateLimit": {
    "perIp":            10,
    "windowSeconds":    3600
  }
}
```

## Purchase: `POST /sandbox/try`

```bash theme={null}
curl -X POST https://lumina-api-production-ac85.up.railway.app/sandbox/try \
  -H "Content-Type: application/json" \
  -d '{}'                          # all fields optional — uses defaults
```

```ts theme={null}
import { LuminaClient } from '@lumina-org/sdk'   // ^0.6.0

// No apiKey needed for the sandbox surface.
const lumina = new LuminaClient({})

const info  = await lumina.sandbox.info()
const trial = await lumina.sandbox.try()         // uses defaultProductName + capped cover

console.log('policyId:', trial.policyId)
console.log('txHash:  ', trial.txHash)
console.log('product: ', trial.productName)
```

### Switching shields

Pass `productName` (or `productId`) and the API auto-resolves the asset
literal from the registry:

```bash theme={null}
curl -X POST https://lumina-api-production-ac85.up.railway.app/sandbox/try \
  -H "Content-Type: application/json" \
  -d '{ "productName": "FLASHETH24-001" }'        # → asset auto-resolves to ETH
```

```ts theme={null}
await lumina.sandbox.try({ productName: 'FLASHETH48-001' })
```

### Side-by-side: curl ↔ TypeScript

| Step           | curl                                    | TypeScript SDK 0.6                                      |
| -------------- | --------------------------------------- | ------------------------------------------------------- |
| Read config    | `curl /sandbox/info`                    | `await lumina.sandbox.info()`                           |
| Default trial  | `curl -X POST /sandbox/try -d '{}'`     | `await lumina.sandbox.try()`                            |
| Switch product | `-d '{"productName":"FLASHETH24-001"}'` | `lumina.sandbox.try({ productName: 'FLASHETH24-001' })` |
| Custom cover   | `-d '{"coverageAmount":"50000000"}'`    | `lumina.sandbox.try({ coverageAmount: '50000000' })`    |

Both `lumina.sandbox.info()` and `lumina.sandbox.try()` are **public
methods** in SDK 0.6.0 (no `apiKey` required on the client).

## Body fields

| Field            | Type                       | Default                                | Notes                                                                                 |
| ---------------- | -------------------------- | -------------------------------------- | ------------------------------------------------------------------------------------- |
| `productName`    | `string`                   | `FLASHBTC1H-001`                       | One of the 6 active products. See [Products and assets](/agents/products-and-assets). |
| `productId`      | `bytes32`                  | resolved from `productName`            | Mutually exclusive with `productName`.                                                |
| `coverageAmount` | `string` (USDC base units) | `coverageCapUsdc` from `/sandbox/info` | Capped at `100000000` (\$100). Larger values are clamped server-side, not rejected.   |

## Limits

| Limit                 | Value                                                                       |
| --------------------- | --------------------------------------------------------------------------- |
| Coverage cap per call | **\$100** (`100000000` base units)                                          |
| Rate limit            | **10 calls / hour / IP**                                                    |
| Wallet                | Sandbox wallet pays premium and holds the resulting bond                    |
| Trigger payout        | Goes to the sandbox wallet, not you — this is a behavior probe, not a hedge |
| Network               | Base Sepolia (chainId 84532) — testnet only                                 |

## Transitioning to full onboarding

Once your sandbox call succeeds end-to-end, graduate to the real path:

1. **[Mint an API key](/agents/onboarding)** — one wallet signature, you get an `lk_…` key.
2. **Fund the buyer wallet with USDC** (Base Sepolia faucets are linked in the [quickstart](/quickstart)). The relayer still pays the gas; the buyer pays only the premium.
3. **Call `lumina.policies.purchase(...)`** with your `productName`, `buyer`, and `coverageAmount`. See [First policy](/agents/first-policy).
4. **Subscribe to webhooks** for `policy_triggered` and `bond_minted` — see [Webhooks](/agents/webhooks).

If you want to drive real policies with your own wallet, mint test USDC
via the [faucet](/agents/get-test-usdc) first — one POST, 10,000 mUSDC +
0.05 ETH for gas.

The sandbox is intentionally identical to the production path apart from
who owns the buyer wallet and the \$100 cap, so code written against
`lumina.sandbox.try()` is one rename away from `lumina.policies.purchase()`.
