The checkbox command — connect a project with one approval, preflight changes, work the compliance plan, and use it in CI. Every command prints one JSON document with --json.
npx @checkbox-site/cli initThe CLI is built for agents first: with --json every command writes exactly one JSON document to stdout (progress and links go to stderr), includes a next_action when there is something to do, and uses stable exit codes. Without it, output is short and human-readable.
Credentials
The key is taken from --api-key, then CHECKBOX_API_KEY, then the key saved by checkbox login or checkbox init (~/.config/checkbox/config.json, mode 0600; CHECKBOX_CONFIG_DIR overrides). The API base is --api-base, then CHECKBOX_API_BASE, then https://app.checkbox.site. checkbox whoami shows which key is used and where it came from:
checkbox whoamiExit codes
| Code | Meaning |
|---|---|
| 0 | OK. For checks: everything passed, or only needs_review without --strict |
| 1 | A compliance check failed (plan --exit-code: not compliant yet; verify: failed) |
| 2 | A check needs review and --strict was given (verify: still pending) |
| 3 | Usage error |
| 4 | Not logged in, or the key was rejected |
| 5 | API, network or local error |
Offline checks
checkbox check … --offline runs the rules engine locally: no key, no network, the same JSON plus "mode": "offline":
checkbox check email --kind acknowledgment --subject "Welcome to Joybox Pro" \
--text "Thanks for subscribing to Joybox Pro. Your subscription renews automatically every month at \$19.99 until you cancel. Cancel anytime online at https://joybox.example/account/cancel." \
--merchant-name Joybox --price 19.99 --interval month --cancel-url https://joybox.example/account/cancel --offlineCommands
| Command | What it does |
|---|---|
checkbox answer | Record the human's answer to a manual plan task (attestations need their confirmation link) |
checkbox check | Preflight compliance checks: disclosure text, Stripe params, emails, checkout HTML |
checkbox fix | Show the change for a plan task (exact diff of your file for code tasks) |
checkbox init | Add Checkbox to this project: one browser approval, then snippet, keys, policies and first checks |
checkbox login | Save an API key for this machine (verified against the API) |
checkbox logout | Remove the API key saved by checkbox login |
checkbox plan | Show the compliance plan: ordered tasks to apply, then verify |
checkbox verify | Re-check a plan task (or the whole site) after applying a change |
checkbox whoami | Show the account and mode the current API key acts on |
checkbox answer
Record the human's answer to a manual plan task (attestations need their confirmation link)
Usage: checkbox answer <task_id> <answer> [--note "<context from the human>"] [--json]
The answer must be one of the task's question.options (`checkbox plan` shows them): yes / no, confirmed /
needs_change, or done / not_now for steps only a person can do in the dashboard (e.g. connecting the billing
platform). "yes" and "confirmed" only count once the human confirms them: show them the link in next_action.checkbox check
Preflight compliance checks: disclosure text, Stripe params, emails, checkout HTML
Usage: checkbox check <disclosure|stripe-session|payment-link|email|page|notice-schedule> [flags]
Sub-commands:
disclosure Checkout disclosure text + placement + consent checkbox
stripe-session Params passed to stripe.checkout.sessions.create
payment-link Payment Link create params or a retrieved link object
email Lifecycle email (acknowledgment, reminders, price change, cancellation confirmation)
page Checkout page HTML (--file) or a live URL (--url, activated live accounts)
notice-schedule Exact dates each legally required notice must be sent (online only)
Plan flags (the subscription the checkout sells):
--price <19.99> | --amount <1999> recurring price (major units | minor units)
--currency usd --interval month|year|week|day --interval-count 1 --trial-days 14
--merchant-name "Joybox" --plan-name "Pro" --cancel-url https://… --cancel-timing period_end|immediately
disclosure: --text "…" | --file terms.txt [--button-text Subscribe] [--no-above-button] [--no-same-page]
[--font-size 14] [--contrast 7] [--bold] [--boxed] [--consent-checkbox] [--prechecked] [--consent-label "…"]
stripe-session: --file params.json (the object passed to stripe.checkout.sessions.create; - for stdin)
payment-link: --file link.json (paymentLinks.create params, or a retrieved link incl. its id)
email: --kind trial_reminder --subject "…" (--text "…" | --file email.txt|email.html) [--previous-price 14.99]
page: --file checkout.html | --url https://… (url: online, activated live accounts) [--page-kind checkout|pricing]
notice-schedule: plan flags + [--start-date YYYY-MM-DD] [--price-change-date YYYY-MM-DD --new-price 24.99] [--cycles 2]
Common: --jurisdictions US-CA,US-NY (default all) · --as-of YYYY-MM-DD · --body request.json (send a full request body)
--offline (run the rules engine locally; no key or network) · --strict (needs_review exits 2) · --verbose · --json
Exit: 0 pass (or needs_review without --strict) · 1 fail · 2 needs_review with --strict · 3 usage · 4 auth · 5 error
Examples:
checkbox check disclosure --text "Renews monthly at $19.99 until you cancel." --price 19.99 --interval month --consent-checkbox
checkbox check stripe-session --file session.json --merchant-name Joybox --cancel-url https://joybox.com/cancel --json
checkbox check email --kind acknowledgment --file emails/welcome.html --price 19.99 --interval month --offlinecheckbox fix
Show the change for a plan task (exact diff of your file for code tasks)
Usage: checkbox fix <task_id> [--file <path>] [--out <patch file>] [--json]
Prints the task's change. For code tasks it reads --file (default: the task's file_hint when it exists in this
directory), applies the task's anchored edits in memory and prints an exact unified diff — it never edits your files.
Flags:
--file <path> Source file that renders the page (component, template, HTML)
--out <path> Also write the diff to this file (then: git apply <path>)
--json { object: "task_fix", diff, applied, unmatched, content, explanation, verify, next_action }checkbox init
Add Checkbox to this project: one browser approval, then snippet, keys, policies and first checks
Usage: checkbox init [--yes] [--json] [--site-url <url>] [--terms-url <url>] [--dry-run] [--verify] [--complete]
Run it in the project root. What it does (idempotent; re-run any time):
1. detects the framework, billing platform, checkout code and pay buttons
2. signs you in: prints ONE link ("Open … and click Approve") and opens the browser; new accounts are free
3. writes CHECKBOX_SECRET_KEY and the publishable key to .env.local / .env (and git-ignores it)
4. installs the Checkbox snippet in the root layout (marked with checkbox:snippet comments)
5. registers the site, Terms / refund / cancellation policy URLs (fetched and checked by Checkbox)
6. with your permission, uses the project's Stripe TEST key for a synthetic test subscription
7. runs the first checks and prints the next step (`checkbox plan --json`); the human gets the summary email
when the setup is finished (every check passes, or `checkbox init --complete`)
Flags (agents: use --yes --json):
--yes, -y No questions; apply every change
--json One JSON document on stdout (progress and the login link on stderr)
--site-url <url> Public URL of the site (default: detected from env / package.json)
--checkout-url <url> Pricing or checkout page
--terms-url, --privacy-url, --refund-url, --cancellation-url <url> Policy pages (default: found in the site footer)
--account-url <url> Account page where subscribers cancel
--merchant-name <name> Brand named as the seller in generated legal copy (default: detected <title> / package name)
--plan <spec> Plan terms, e.g. "19.99/month,trial=14" (several: separate with ;). Default: read from
inline price_data in your Checkout Session code
--support-email <addr> Support address for subscribers
--dry-run Show the planned file changes; write nothing
--no-snippet Do not touch the layout (print the tag instead)
--no-stripe Do not offer the Stripe test key / test subscription
--live Also request live-mode keys and write the domain-verification file
--no-wait Start the login, print the link and exit (run `checkbox init` again to continue)
--wait-seconds <n> How long to wait for the approval (default 900 on a terminal, 100 otherwise)
--no-open Do not open the browser
--verify Re-check the site now (after deploying) and print the updated checklist
--complete Finish the setup and email the human the summary (sent automatically the first time every
check passes; run this when you stop earlier)
--relogin Ignore the saved login and approve again
--agent <name> Name of the AI agent shown on the approval page (auto-detected for Claude Code, Cursor…)checkbox login
Save an API key for this machine (verified against the API)
Usage: checkbox login [--api-key <key> | <key> | --stdin] [--no-verify]
Flags:
--api-key <key> The key (ck_test_…, ck_live_…, rk_…, sk_live_…). Also accepted as the first argument.
--stdin Read the key from stdin (echo $KEY | checkbox login --stdin)
--no-verify Save without calling the API
Without a key on an interactive terminal, you are prompted for one. Keys: https://app.checkbox.site/settings/api-keys
No account yet? `checkbox init` creates one with a single browser approval.
In CI, set CHECKBOX_API_KEY instead of logging in.checkbox logout
Remove the API key saved by checkbox login
Usage: checkbox logoutcheckbox plan
Show the compliance plan: ordered tasks to apply, then verify
Usage: checkbox plan [--site <site_id>] [--all] [--exit-code] [--json]
Flags:
--site <id> Site (default: $CHECKBOX_SITE, the site `checkbox init` created for this project, or your only site)
--all Also list done and declined tasks
--exit-code Exit 1 while the plan is not compliant (for CI)
--json The plan object exactly as the API returns it (for agents)
The loop: apply plan.next_action → `checkbox fix <task>` (prints the change, or an exact diff of your file) →
`checkbox verify <task> --wait` → `checkbox plan` again, until status is compliant. Tasks marked [!] need a human
answer (answerTask); they never block the others.checkbox verify
Re-check a plan task (or the whole site) after applying a change
Usage: checkbox verify [task_id] [--wait] [--timeout <s>] [--html-file <f>] [--stripe-params <f>] [--email-file <f>] [--site <id>] [--json]
With a task id: runs the fastest re-check for the task (static fetch of your live checkout, a re-fetch of your Terms,
the Stripe params or email copy you pass) and queues the confirming scan / sync. Without: re-checks the whole site.
Flags:
--wait Wait until the verification passes or fails (long-poll)
--timeout <s> Give up waiting after this many seconds (default 600)
--html-file <f> Pre-check this rendered HTML before deploying (page tasks)
--stripe-params <f> JSON your code now passes to stripe.checkout.sessions.create (Stripe tasks)
--email-file <f> JSON { subject, text | html, kind? } of the new email template (email tasks)
Exit codes: 0 passed · 1 failed · 2 still pending (not waited, or timed out) · 3 usage · 4 auth · 5 errorcheckbox whoami
Show the account and mode the current API key acts on
Usage: checkbox whoamiCheckbox is compliance software, not a law firm; nothing in these docs is legal advice (details). For AI agents: every page is available as Markdown at the same URL plus .md; the index is /llms.txt.