# Activation

> Live mode turns on when you prove you control a site's domain, with a DNS TXT record, a file at /.well-known, a meta tag or the live Checkbox snippet — like verifying a sending domain.

Test mode works immediately. Live mode — real scans of your site, certificates, sending notices — turns on for the
whole account the first time you verify the domain of one of your sites. There is no sales call, no card and no review.

Until then, live-mode operations that act on a real site (scans, certificates, turning on Notices) answer:

```json
{
  "error": {
    "type": "permission_error",
    "code": "account_not_activated",
    "message": "Live mode needs an activated account: verify the domain of one of your sites (or use a test key).",
    "next_action": { "type": "verify_domain", "operation_id": "createDomainVerification" }
  }
}
```

Live sites created before activation are stored with monitoring **held** (`monitoring.held_for_activation: true`);
monitoring starts by itself when the account is activated.

## Verify a domain {#verify}

Start a verification for a live site. You get four ways to prove control; any one works:

```bash
curl -X POST https://app.checkbox.site/v1/sites/site_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b/domain_verification \
  -u "$CHECKBOX_LIVE_KEY:"
```

1. **DNS:** a TXT record at `_checkbox-verify.<your domain>` with the value in the response, or
2. **File:** serve the token at `https://<your domain>/.well-known/checkbox-verify.txt`, or
3. **Meta tag:** put `<meta name="checkbox-verify" content="<token>">` (the response's `meta_tag.html`) in the
   `<head>` of `https://<your domain>/`, or
4. **The snippet:** install the site's Checkbox snippet (`install.script_tag`) on your homepage. Checkbox verifies the
   domain when it sees it live — during agent setup this happens on the next `verifySetupSession` (MCP:
   `get_setup_status` with `verify: true`) after you deploy.

For 3 and 4 Checkbox itself loads `https://<your domain>/` (a plain GET; redirects are followed only within
`https://<your domain>` and `https://www.<your domain>`, default port) and reads the HTML tags: the snippet counts only
as a `<script>` element whose `src` is the Checkbox `s.js` and whose `data-key` is this site's snippet key, and the
meta tag only in the page's `<head>`. The key or token mentioned anywhere else (page text, comments, a URL) does not
count, and neither does a snippet beacon: anyone can send one with the public key. A snippet that only renders in the
browser (some frameworks inject scripts at runtime) is not in the HTML Checkbox reads; use the meta tag then. The
`method` of the verification says which proof was found (`dns_txt`, `well_known`, `meta_tag` or `snippet`). A proof
is kept once found; changing the site's URL to another domain forgets it.

Then ask Checkbox to look (it also re-checks on its own for a while):

```bash
curl -X POST https://app.checkbox.site/v1/sites/site_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b/domain_verification/check \
  -u "$CHECKBOX_LIVE_KEY:"
```

When it succeeds, `account.activation.status` becomes `active` (`method: "domain"`) and held monitoring starts.

## Every website Checkbox visits is verified {#per-domain}

Activation turns live mode on; it does not let Checkbox visit any website. Checkbox only scans, monitors, fetches and
test-runs websites your account has verified, in both modes: every URL it navigates to — the site URL, checkout URL,
account login URL, `goto` steps, policy pages, `checkPage` URLs and test-run URLs — must be on a verified domain.

- A verified domain covers its subdomains: verifying `example.com` covers `shop.example.com` and `pay.example.com`.
  Verifying `shop.example.com` covers only `shop.example.com` and below.
- On shared hosting (`*.vercel.app`, `*.netlify.app`, `*.myshopify.com`, `*.github.io`, …) only the exact host counts:
  verify `acme.vercel.app` itself, and preview URLs need their own verification.
- Hosted checkout and billing pages (Stripe Checkout, Payment Links, the customer portal, Shopify checkout, Recharge,
  Paddle, Chargebee, Recurly, Lemon Squeezy) are reached by **clicking through** from a page of your verified website
  (start the scan on your pricing page). They can be the checkout URL, login URL or a `goto` step directly only when
  your billing account is connected (Stripe Checkout, Payment Links, the Stripe customer portal, Shopify checkout,
  Paddle checkout), never for multi-tenant billing portals, and never as the site URL.
- Redirects and navigation are checked too: if a verified page redirects or links the scanner to a website you have
  not verified, Checkbox does not follow it (the scan reports `did not open <host>`), and a page or policy fetch stops
  at that redirect.
- The `/.well-known/checkbox-verify.txt` file must be served by `https://<domain>/` itself on the default port (an
  apex that redirects to the same file on `https://www.<domain>/` is fine). A file only on `www.` or another port does
  not prove the whole domain; use the DNS TXT record then.
- `localhost` and private addresses never need verification in test mode (where the deployment allows them) and can
  never activate live mode.
- One exception, during [agent setup](https://checkbox.site/docs/agent-loop): before the domain is verified, Checkbox reads the site's own
  public homepage and Terms / refund / cancellation / privacy pages once as an **unverified preview** (one plain GET,
  redirects only within the site's own domain, at most once per page every 10 minutes and 30 pages a day per account)
  to find the footer links, see whether the snippet is live and show what the Terms checks say. Nothing from a preview
  is stored as evidence or used for findings, the compliance plan, receipts or certificates; that waits for verification.
- A second exception: a site held **only** because its domain is not verified gets a **read-only scan** (an
  [unverified scan](#unverified-scan)) of its own public pages. Setup queues it on `verifySetupSession` (MCP:
  `get_setup_status` with `verify: true`).

## Unverified scans {#unverified-scan}

Before the domain is verified, Checkbox may look at the site with its browser, but only look:

- **Pages:** the site URL, the configured checkout, account and policy URLs that are on the site's own domain, and the
  links on the site's homepage to pricing, Terms, privacy, refund, cancellation, account and sign-up pages — at most
  20 pages. Navigation and redirects stay on the site's own domain (its subdomains too, except on shared hosting): a
  hosted checkout on another domain (for example `checkout.stripe.com`) is not opened. IP addresses, `localhost` and
  private hosts are never read this way.
- **Read-only:** pages are loaded by URL. Nothing is clicked, typed into or submitted, no account is created and no
  test card is used; inside the browser every request that is not a GET is refused, forms cannot be submitted and
  WebSockets are refused. Links that look like actions (log out, unsubscribe, delete, confirm) are not opened.
- **robots.txt** is honored for `CheckboxScanner` (and `*`); a page it disallows is skipped and listed as skipped.
  Sites can also [opt out](https://checkbox.site/docs/bots#opt-out).
- **Limits:** one per site per 24 hours, and at most three unverified sites per account in 30 days.
- **Results** are labeled **unverified scan** everywhere (`unverified_scan` on the site, the setup session and the
  compliance plan, with `unverified: true`): the pages read, the pages skipped and why, and the checks on those pages.
  They are not evidence: no screenshots or HTML go to the evidence vault, nothing enters the signed evidence chain,
  findings, certificates, exports, receipts or monitoring, and nothing is public. Once the domain is verified the full
  scan runs (verifying queues it) and replaces it.

Otherwise the call answers `403 domain_not_verified` (test mode: `403 test_mode_domain_unverified`; there is no daily
allowance for unverified domains) with `next_action.type: "verify_domain"`. Site objects show
`monitoring.held_for_domain_verification` and `monitoring.verify_domains`, and the site's
[compliance plan](https://checkbox.site/docs/agent-loop) starts with a `verify_domain` task. Setup, the plan and the task all name the same
step: `verifyTask` on that task (MCP: `verify_task`; `POST /v1/sites/{site}/domain_verification/check` does the same
for the site's own domain). With no challenge started yet, the first call starts it and returns the DNS record, file and
meta tag. Publishing one of them (or deploying the snippet) is the human's job: an agent waits until they say it is
done, then calls `verifyTask` again; a failed check means "not published yet", not a code problem. A domain other than
the site's own (a checkout on another domain) is verified in the dashboard (Site → Verify your domain). Verifying
queues the site's first scan right away.

## Fair use {#fair-use}

Checkbox is free to start, with no plan limits on compliance features. Fair-use limits apply: 25 active sites per
account and mode, 300 API requests per minute per account and mode (`RateLimit-*` headers; `429 rate_limit_exceeded`
with `Retry-After`), 16 webhook endpoints per mode, and per-route limits on scans and evaluations. Ask
[support@checkbox.site](mailto:support@checkbox.site) to raise them.
