# Test mode and live mode

> Test keys act on an isolated sandbox that never needs activation; live keys monitor your real site once your domain is verified.

Every Checkbox account has two modes, chosen by the key you send — the same model as Stripe.

| | Test mode | Live mode |
|---|---|---|
| Secret key | `ck_test_…` | `ck_live_…` (older organization keys `sk_live_…` also work) |
| Publishable key (browser) | `pk_test_…` | `pk_live_…` |
| Data | An isolated sandbox: sites, findings, evidence and events you create with test keys | Your real sites |
| Activation | Never needed | [Verify a domain](https://checkbox.site/docs/concepts/activation) once |
| Scheduled monitoring | Off by default | Daily by default (`monitoring_interval_minutes`) |
| Preflight checks, plans, setup sessions | Yes | Yes |
| Stripe test subscriptions ([test runs](https://checkbox.site/docs/guides/test-runs)) | Yes | Yes (always against Stripe **test** mode) |

Test keys are free and one click away, so test mode only touches **your** site: Checkbox scans, monitors, fetches pages
and runs [test runs](https://checkbox.site/docs/guides/test-runs) for `localhost` / private addresses (local development) and for hosts within
a domain your account has [verified](https://checkbox.site/docs/concepts/activation) (in either mode). For any other host, test mode gives a
few on-demand scans a day (`429 test_mode_scan_budget_exhausted` after that), no scheduled monitoring (held, like live
monitoring before activation), no server-side page fetch (send the rendered HTML instead) and no test runs
(`403 test_mode_domain_unverified`). Verifying the domain lifts all of it and starts held monitoring.

Every object has `livemode: true | false`, and every response carries the `Checkbox-Mode: test | live` header. Objects
never cross modes: a test key cannot read a live site, and the reverse.

## Restricted keys {#restricted-keys}

Restricted keys (`rk_test_…`, `rk_live_…`) carry per-resource scopes such as `{ "checks": "read" }` or
`{ "sites": "write" }` (write implies read). Give CI jobs and agents the least they need: a key with only
`checks: read` can run every preflight check and nothing else. Each operation's required scope is listed in the
[API reference](https://checkbox.site/docs/api) and in the OpenAPI document (`x-checkbox-scope`).

## Publishable keys {#publishable-keys}

Publishable keys are safe in browser code. They work only for the browser-facing endpoints of
[Checkbox Elements](https://checkbox.site/docs/elements) (recording a consent, loading a disclosure), and only from pages on your site's
domains (the `Origin` is checked). Every other endpoint refuses them with `publishable_key_not_allowed`.

## Which key do I have? {#which-key}

```curl
curl https://app.checkbox.site/v1/account \
  -u "$CHECKBOX_SECRET_KEY:"
```
```node
import Checkbox from '@checkbox-site/cli';

const checkbox = new Checkbox(process.env.CHECKBOX_SECRET_KEY);

console.log(checkbox.mode); // 'test' or 'live', from the key prefix
const account = await checkbox.account.retrieve();
console.log(account.livemode, account.activation.status);
```
```python
import os
from checkbox import Checkbox

checkbox = Checkbox(os.environ["CHECKBOX_SECRET_KEY"])

print(checkbox.mode)  # "test" or "live", from the key prefix
account = checkbox.account.retrieve()
print(account["livemode"], account["activation"]["status"])
```
