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

# Start without a key

> Try the API with sample data, exercise errors and pagination, then switch to live data.

Use the sandbox to build an API client without an account or key. It returns fixed sample data at `https://0xinsider.com/sandbox` and does not place orders or store your writes.

If you want to inspect real data first, the [public pick ledger](/api-reference/endpoint/get-pick-of-the-day-ledger) is available without a credential.

## Make a sandbox request

```bash theme={null}
curl "https://0xinsider.com/sandbox/api/v1/leaderboard?limit=3"
```

Append a documented API path to the sandbox base URL. Responses follow the operation's documented fields and envelope, and include `X-Oxi-Sandbox: true`.

The examples use 7 synthetic wallets and markets. Wallet addresses start with `0x51ab`, markets have names such as "Sandbox Rovers", and the data is fixed; do not treat its grades, prices, or P\&L as real observations.

<span id="every-other-operation-the-sandbox" />

## What works in the sandbox

| Request | Result |
| - | - |
| A documented JSON read | A sample response with the documented field types. |
| A paginated list | A page from the fixed collection. |
| A trader or market batch | One result per submitted identity, in input order, with matching metadata counts. |
| A documented JSON write, including webhooks | A sample success response. No write is stored. |
| Trader or market `context.md` | Markdown describing the same sample data as the corresponding JSON endpoint. |
| Trader export download | A `302` redirect to a sample CSV. No trader history is exported. |
| Remote MCP `GET /api/v1/mcp` | `405` with `Allow: POST` and `X-Mcp-Error-Code: -32004`. |
| `GET /api/v1/stream` | `400 bad_request`. Open live Server-Sent Events with a live credential. |
| An unknown path or unsupported method | `404 not_found` or `405` with `Allow`. |

The sandbox is the second server in the [OpenAPI specification](https://0xinsider.com/api/v1/openapi.json). It exercises response parsing, request shapes, pagination, and error handling; it does not establish production freshness, latency, or trading performance.

<span id="page-through-a-list" />

## Read more than one page

A request with `limit=3` can return:

```json theme={null}
{ "has_more": true, "next_cursor": "sbx_3", "total": 7 }
```

Send `cursor=sbx_3` to get rows 4 through 6, then `cursor=sbx_6` for the final row. Stop when `has_more` becomes `false`; the last page omits `next_cursor` or uses `null` where the operation permits it.

[Event replay](/api-reference/endpoint/get-event-replay-since) always keeps a cursor. Its final populated page returns `sbx_7`, and that cursor returns an empty page with the same cursor and completeness `caught_up`.

An unknown cursor, or one beyond the collection, returns `400` with reason `cursor_expired`. Supported grade filters can reduce the collection, so not every filtered list contains all 7 rows.

<span id="it-refuses-what-the-live-api-refuses" />

## Check invalid requests

```bash theme={null}
curl -i "https://0xinsider.com/sandbox/api/v1/leaderboard?limit=abc"
```

The sandbox validates queries and JSON bodies against OpenAPI:

| Input problem | Response |
| - | - |
| A value outside the parameter schema | `400`, reason `invalid_query`. |
| Missing, malformed, or invalid JSON | `400`, reason `invalid_body`; `error.param` identifies the field when available. |
| A JSON body without `Content-Type: application/json` | `415`, reason `unsupported_media_type`. |
| An unknown query parameter | It is ignored and named in `X-Query-Ignored`. With `X-Query-Validation: strict`, it returns `400 unknown_query_parameter`. |

Successful reads include `X-Effective-Query` for parameters the sandbox actually applies. Other documented filters can be validated without reproducing production filtering.

<Note>
  The sandbox rejects numeric values outside the schema's bounds. Live list endpoints clamp whole-number `limit` values into range, so `limit=0` can fail here while the live API uses `limit=1`.
</Note>

<span id="simulate-an-error-before-you-meet-one" />

## Simulate an error

Add `sandbox_status` to request an error documented for that operation:

```bash theme={null}
curl -i \
  "https://0xinsider.com/sandbox/api/v1/leaderboard?sandbox_status=429"
```

For example, a simulated `429` or `503` includes `Retry-After: 60` and `error.retry_at`. Use these responses to exercise your [error handling](/errors) before going live.

<span id="the-sandbox-key-is-optional" />

## Use an optional sandbox key

Most clients can call the sandbox with no credential. If your framework requires one, request a sandbox key:

```bash theme={null}
curl -X POST "https://api.0xinsider.com/api/v1/agents/register"
```

The `201` response includes an `oxi_sk_test_` key, the sandbox base URL, and links for obtaining live access. Sandbox keys do not change the returned data and cannot be listed or revoked.

Production refuses a sandbox key with `401 invalid_api_key` and reason `sandbox_api_key`. A live key also does not make the sandbox return live data.

<span id="1-request-real-data" />

## Inspect the public ledger

This request returns production ledger data without a key:

```bash theme={null}
curl "https://api.0xinsider.com/api/v1/pick-of-the-day/ledger" \
  | jq '.data.entries[] | select(.state == "opened")'
```

A `sealed` entry contains a commitment hash and timestamps, with its side and price hidden. An `opened` entry reveals the payload and nonce after settlement, so you can verify that they match the commitment.

The ledger returns all entries without pagination. [`0xinsider/picks`](https://github.com/0xinsider/picks) mirrors it and includes a verifier; the [ledger reference](/api-reference/endpoint/get-pick-of-the-day-ledger) explains the commitment fields and verification limits.

<span id="what-this-does-not-give-you" />

## Limits

The sandbox has no production event stream, persistent writes, or real trading data. A sandbox key never grants access to authenticated production endpoints.

<span id="move-to-live-data" />

## Switch to live data

1. Subscribe to Pro or Max on [Pricing](https://0xinsider.com/pricing).
2. Generate a live key on [Developers](https://0xinsider.com/developers).
3. Change the base URL to `https://api.0xinsider.com` and send `Authorization: Bearer <key>`.

The documented envelopes and field types stay the same. Cursor values and data change; start live pagination from the first page.

| Client | Sandbox | Live |
| - | - | - |
| Python | `oxinsider.Client.sandbox()` | `oxinsider.Client()` reads `OXINSIDER_API_KEY`. |
| Go | `oxinsider.New(oxinsider.WithBaseURL("https://0xinsider.com/sandbox"))` | `oxinsider.New(oxinsider.WithBearerToken(key))`. |
| TypeScript | `OxinsiderApiClient.sandbox()` | `new OxinsiderApiClient({ apiKey })`. |
| Rust | `Client::sandbox()` | Follow the [Rust client setup](/integrations/rust-client). |

<span id="go-next" />

## Continue building

Continue with the [quickstart](/quickstart) for common reads or [authentication](/authentication) to choose scopes and manage keys.


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