Quickstart
Five minutes, a test key and no credit card — preflight a Stripe Checkout Session, drop in a compliant disclosure, register your site and receive webhooks.
This is the manual path. If you use an AI coding agent, you can skip it: tell the agent "Add Checkbox to this project" and it connects through the MCP server's setup_checkbox tool for you (how that works).
1. Get a test key
Sign up (email, GitHub or Google; free) and copy the test secret key from Settings → API keys. Test keys start with ck_test_, act on an isolated sandbox and never need activation. Put the key in your environment:
export CHECKBOX_SECRET_KEY=ck_test_...Check the key. The response tells you the mode and the next step:
curl https://app.checkbox.site/v1/account \
-u "$CHECKBOX_SECRET_KEY:"import Checkbox from '@checkbox-site/cli';
const checkbox = new Checkbox(process.env.CHECKBOX_SECRET_KEY);
const account = await checkbox.account.retrieve();
console.log(account.livemode, account.next_action);import os
from checkbox import Checkbox
checkbox = Checkbox(os.environ["CHECKBOX_SECRET_KEY"])
account = checkbox.account.retrieve()
print(account["livemode"], account["next_action"])2. Preflight your Stripe Checkout Session
Before you deploy, send Checkbox exactly the object your code passes to stripe.checkout.sessions.create, plus what Stripe's params do not say (your brand and where subscribers cancel). No site, no stored data:
curl https://app.checkbox.site/v1/checks/stripe_checkout_session \
-u "$CHECKBOX_SECRET_KEY:" \
-H "Content-Type: application/json" \
-d '{
"params": {
"mode": "subscription",
"line_items": [{
"price_data": {
"currency": "usd",
"unit_amount": 1999,
"recurring": { "interval": "month" },
"product_data": { "name": "Joybox Pro" }
},
"quantity": 1
}],
"subscription_data": { "trial_period_days": 14 },
"success_url": "https://joybox.example/welcome"
},
"merchant": {
"merchant_name": "Joybox",
"cancel_url": "https://joybox.example/account/cancel"
}
}'import Checkbox from '@checkbox-site/cli';
const checkbox = new Checkbox(process.env.CHECKBOX_SECRET_KEY);
const params = {
mode: 'subscription',
line_items: [{
price_data: {
currency: 'usd',
unit_amount: 1999,
recurring: { interval: 'month' },
product_data: { name: 'Joybox Pro' },
},
quantity: 1,
}],
subscription_data: { trial_period_days: 14 },
success_url: 'https://joybox.example/welcome',
};
const result = await checkbox.checks.stripeCheckoutSession({
params,
merchant: { merchant_name: 'Joybox', cancel_url: 'https://joybox.example/account/cancel' },
});
console.log(result.verdict, result.next_action.message);
// Use result.correction.corrected_params for stripe.checkout.sessions.create.
console.log(result.correction.corrected_params.consent_collection);import os
from checkbox import Checkbox
checkbox = Checkbox(os.environ["CHECKBOX_SECRET_KEY"])
params = {
"mode": "subscription",
"line_items": [{
"price_data": {
"currency": "usd",
"unit_amount": 1999,
"recurring": {"interval": "month"},
"product_data": {"name": "Joybox Pro"},
},
"quantity": 1,
}],
"subscription_data": {"trial_period_days": 14},
"success_url": "https://joybox.example/welcome",
}
result = checkbox.checks.stripe_checkout_session(
params=params,
merchant={"merchant_name": "Joybox", "cancel_url": "https://joybox.example/account/cancel"},
)
print(result["verdict"], result["next_action"]["message"])
print(result["correction"]["corrected_params"]["consent_collection"])The response has a verdict per check and per legal requirement, with citations, and a correction:
{
"object": "check_result",
"kind": "stripe_checkout_session",
"verdict": "fail",
"summary": { "pass": 6, "fail": 2, "needs_review": 2, "not_applicable": 0 },
"checks": [
{
"check_id": "signup.consent.affirmative",
"status": "fail",
"severity": "critical",
"requirements": [
{ "id": "US-FED.8403.2", "citation": "15 U.S.C. § 8403(2)" },
{ "id": "US-CA.17602.a.2", "citation": "Cal. Bus. & Prof. Code § 17602(a)(2)" }
]
}
],
"correction": {
"patch": [
{ "op": "add", "path": "/consent_collection", "value": { "terms_of_service": "required" } },
{ "op": "add", "path": "/custom_text", "value": { "submit": { "message": "Your free trial lasts 14 days, then $19.99 every month…" } } }
],
"corrected_params": { "mode": "subscription", "consent_collection": { "terms_of_service": "required" } }
},
"next_action": { "type": "apply_patch", "message": "…Apply correction.patch… then call this check again with the new params." }
}Apply correction.patch (RFC 6902 JSON Patch) or use correction.corrected_params, and check again until the verdict is pass. One check stays needs_review on any Stripe-hosted page: whether the terms are clear and conspicuous depends on styling Stripe controls. The Stripe Checkout guide explains how to close it.
Other preflight checks work the same way: disclosure text, Payment Links, lifecycle emails, checkout HTML and the notice schedule.
3. Drop in a compliant disclosure
If you build your own checkout page, Checkbox Elements renders the locked, compliant disclosure for your terms in a bordered box directly above your pay button, with an unchecked, required consent checkbox, and records each consent as evidence. Add the script and the element (use your publishable key, pk_test_…):
<script src="https://app.checkbox.site/v1/elements.js" defer></script>
<form action="/subscribe" method="post">
<checkbox-disclosure
publishable-key="pk_test_..."
merchant-name="Joybox" amount="1999" currency="usd" interval="month" trial-days="14"
cancel-url="https://joybox.example/account/cancel">
</checkbox-disclosure>
<button type="submit">Start free trial</button>
</form>The pay button stays disabled until the box is ticked. Your server receives checkbox_consent_id (cons_…) with the form; store it with the subscription.
4. Register your site
A site turns one-off checks into monitoring: the synthetic shopper visits your checkout from each state, the snippet sees what real visitors see, and every result lands in your evidence vault. Only url is required:
curl https://app.checkbox.site/v1/sites \
-u "$CHECKBOX_SECRET_KEY:" \
-H "Content-Type: application/json" \
-d '{ "url": "https://joybox.example", "platform": "stripe" }'import Checkbox from '@checkbox-site/cli';
const checkbox = new Checkbox(process.env.CHECKBOX_SECRET_KEY);
const site = await checkbox.sites.create({ url: 'https://joybox.example', platform: 'stripe' });
console.log(site.id, site.install.script_tag);import os
from checkbox import Checkbox
checkbox = Checkbox(os.environ["CHECKBOX_SECRET_KEY"])
site = checkbox.sites.create(url="https://joybox.example", platform="stripe")
print(site["id"], site["install"]["script_tag"])The response includes install: the snippet tag for your pages, an inbound email address to BCC your subscriber emails to, and webhook URLs for your billing platform. Then ask for the compliance plan: GET /v1/sites/{site}/plan returns the ordered list of changes, each with the requirement, the place and the exact fix.
In test mode nothing is monitored on a schedule. To monitor your real site, use a live key and verify your domain — that is the only activation step.
5. Receive webhooks
Subscribe an HTTPS endpoint to the events you care about. The secret is returned once; keep it with your server's configuration:
curl https://app.checkbox.site/v1/webhook_endpoints \
-u "$CHECKBOX_SECRET_KEY:" \
-H "Content-Type: application/json" \
-d '{
"url": "https://joybox.example/hooks/checkbox",
"enabled_events": ["finding.created", "site.compliant", "plan.updated"]
}'import Checkbox from '@checkbox-site/cli';
const checkbox = new Checkbox(process.env.CHECKBOX_SECRET_KEY);
const endpoint = await checkbox.webhookEndpoints.create({
url: 'https://joybox.example/hooks/checkbox',
enabled_events: ['finding.created', 'site.compliant', 'plan.updated'],
});
console.log(endpoint.id, endpoint.secret);import os
from checkbox import Checkbox
checkbox = Checkbox(os.environ["CHECKBOX_SECRET_KEY"])
endpoint = checkbox.webhook_endpoints.create(
url="https://joybox.example/hooks/checkbox",
enabled_events=["finding.created", "site.compliant", "plan.updated"],
)
print(endpoint["id"], endpoint["secret"])Verify every delivery's Checkbox-Signature header before trusting it: see Webhooks.
Next steps
- Build with AI: prompts and repository instructions for Claude Code and Cursor.
- Requirements and jurisdictions: what the law asks for, state by state.
- Test subscriptions: see every lifecycle email and the cancellation flow before customers do.
Checkbox 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.