# Try it in the sandbox
URL: https://backworkhealth.com/docs/sandbox

Get a free test key with one command and call the API against synthetic data

The sandbox lets you, or your agent, make a real Backwork API call in about a minute. You do not need an account, a plan, or an email address.

The sandbox mirrors four v1 endpoints. Requests and responses have the same shape as production, so code you write here works there after you change the base URL and the key. The data is different: every payer, policy, and code in the sandbox is fictional. The sandbox never returns Backwork data.

## 1. Get a test key [#1-get-a-test-key]

```bash
curl -X POST https://backworkhealth.com/api/sandbox/v1/keys
```

```json
{
  "success": true,
  "data": {
    "api_key": "bwk_test_...",
    "key_id": "bwk_test_...",
    "environment": "sandbox",
    "expires_at": "2026-10-06T12:00:00.000Z",
    "base_url": "https://backworkhealth.com/api/sandbox/v1",
    "disclaimer": "SYNTHETIC SANDBOX DATA. ..."
  },
  "meta": { "request_id": "req_...", "timestamp": "...", "sandbox": true }
}
```

To keep the key in your shell (needs `jq`):

```bash
export BACKWORK_TEST_KEY=$(curl -s -X POST https://backworkhealth.com/api/sandbox/v1/keys | jq -r .data.api_key)
```

The key is shown once. Backwork stores only its SHA-256 hash.

## 2. Call the API [#2-call-the-api]

```bash
# Search policies
curl "https://backworkhealth.com/api/sandbox/v1/policies?q=joint&include=codes" \
  -H "Authorization: Bearer $BACKWORK_TEST_KEY"

# Look up a code
curl "https://backworkhealth.com/api/sandbox/v1/codes/lookup?code=SBX01&include=policies" \
  -H "Authorization: Bearer $BACKWORK_TEST_KEY"

# Check prior auth
curl -X POST "https://backworkhealth.com/api/sandbox/v1/prior-auth/check" \
  -H "Authorization: Bearer $BACKWORK_TEST_KEY" \
  -H "Content-Type: application/json" \
  -d '{"procedure_codes": ["SBX01"], "state": "TX"}'

# Evaluate coverage criteria
curl -X POST "https://backworkhealth.com/api/sandbox/v1/coverage/evaluate" \
  -H "Authorization: Bearer $BACKWORK_TEST_KEY" \
  -H "Content-Type: application/json" \
  -d '{"policy_id": "SANDBOX-POL-001", "parameters": {"age_category": "adult", "diagnosis_codes": ["SBX.01"], "procedure_code": "SBX01"}}'
```

## What the sandbox knows [#what-the-sandbox-knows]

| Code               | Kind      | Prior-auth check result                                                                 |
| ------------------ | --------- | --------------------------------------------------------------------------------------- |
| `SBX01`            | Procedure | Conditional coverage, prior auth required (`SANDBOX-POL-001`)                           |
| `SBX02`            | Procedure | Covered, no prior auth (`SANDBOX-POL-002`, an LCD)                                      |
| `SBX03`            | Drug      | Not covered (`SANDBOX-POL-003`); its code entries have `source: "inferred_title_match"` |
| `SBX04`            | Device    | Only on a retired policy, so the check returns `unknown`                                |
| `SBX.01`, `SBX.02` | Diagnoses | Use them in `icd10` filters and `diagnosis_codes`                                       |

Every code entry has a `source`. `document` means the payer's policy document lists the code. `inferred_title_match` means Backwork attached the code because the policy title names the drug, and the document itself does not list it. Every other sandbox code entry is `document`. See [Code sources](/docs/code-sources).

Every code entry also has a `grounding`: `SBX01` is `grounded`, `SBX.01` is `not_grounded`, the codes of `SANDBOX-POL-002` are `no_source_text`, and the rest are `not_checked`. Every policy has a `source_check`; only `SANDBOX-POL-001` has fictional `source_accuracy` figures. See [Source checks](/docs/source-checks).

Any other code, for example a real CPT code, returns `found: false` (code lookup) or `coverage_status: "unknown"` (prior-auth check). The sandbox never returns a real code description.

## Rules and limits [#rules-and-limits]

* A test key expires 7 days after it is issued.
* Each IP address can get 2 keys a minute and 5 keys a day.
* Each key can make 60 requests a minute.
* Test keys work only on the sandbox. Production routes reject them with [`AUTH_TEST_KEY_SANDBOX_ONLY`](/docs/errors#auth-test-key-sandbox-only).
* The sandbox rejects live keys and OAuth tokens with [`AUTH_SANDBOX_TEST_KEY_REQUIRED`](/docs/errors#auth-sandbox-test-key-required), before it looks them up. Do not send a live key to the sandbox.
* Every response has `meta.sandbox: true`, a `meta.disclaimer`, and the header `X-Backwork-Sandbox: synthetic`.
* The sandbox answers in JSON only. `include=rvu` and `include=rates` return `null`.

<Callout type="warn" title="Fictional data">
  Do not use sandbox responses for coverage, billing, or clinical decisions. They describe made-up payers and policies.
</Callout>

## OpenAPI [#openapi]

The sandbox spec is at [`https://backworkhealth.com/api/sandbox/v1/openapi.json`](https://backworkhealth.com/api/sandbox/v1/openapi.json). It reuses the production schemas, so a client generated from it also works against production.

## Moving to production [#moving-to-production]

When you are ready for real data, [sign up](https://backworkhealth.com/sign-up) and create a live key in [API usage and keys](https://backworkhealth.com/api-usage). Your organization starts with 100 free starter credits, so you do not need to buy anything first. Change the base URL to `https://backworkhealth.com/api/v1` and the key to your `bwk_live_` key; the request and response shapes stay the same. The [Quickstart](/docs/quickstart) walks through it, and [Pricing and credits](/docs/pricing) lists what each call costs.

Sandbox calls are free and never spend credits.
