CheckboxDocs

Preflight checks

Stateless "check before you ship" calls for AI agents and CI — disclosure text, Stripe params, lifecycle emails, checkout HTML and notice timing — with verdicts per legal requirement and the exact fix.

Preflight checks judge what your code will produce, before anything is deployed. Nothing is stored, no site is needed, and test keys work. Send the text, params, email or HTML; get a verdict per check and per legal requirement, with citations, and a fix the engine has already verified.

CheckEndpointCLIOffline
Disclosure text, placement, consent checkboxPOST /v1/checks/disclosurecheckbox check disclosureyes
Stripe Checkout Session paramsPOST /v1/checks/stripe_checkout_sessioncheckbox check stripe-sessionyes
Stripe Payment Link paramsPOST /v1/checks/stripe_payment_linkcheckbox check payment-linkyes
A lifecycle emailPOST /v1/checks/emailcheckbox check emailyes
Checkout HTML (or a live URL)POST /v1/checks/pagecheckbox check page--file only
When each notice must be sentPOST /v1/checks/notice_schedulecheckbox check notice-scheduleno

--offline runs the same rules engine locally: no key, no network, the same JSON plus "mode": "offline".

Example

Shell
checkbox check disclosure \
  --text "Renews monthly at \$19.99 until you cancel." \
  --merchant-name Joybox --price 19.99 --interval month \
  --consent-checkbox --offline

The same call over HTTP returns JSON like this (trimmed):

JSON
{
  "object": "check_result",
  "kind": "disclosure",
  "verdict": "fail",
  "checks": [
    {
      "check_id": "signup.disclosure.cancellation_policy",
      "status": "fail",
      "severity": "critical",
      "fix": "Explain the cancellation policy and exactly how to cancel in the checkout terms.",
      "requirements": [
        { "id": "US-FED.8403.1", "jurisdiction": "US-FED", "citation": "15 U.S.C. § 8403(1)" },
        { "id": "US-CA.17602.a.1", "jurisdiction": "US-CA", "citation": "Cal. Bus. & Prof. Code § 17602(a)(1); § 17601(a)(2)-(3)" }
      ]
    }
  ],
  "replacement": {
    "disclosure_text": "Your Joybox subscription automatically renews every month at $19.99 (plus applicable taxes) until you cancel. You can cancel anytime online at {{cancel_url}}; cancellation takes effect at the end of your current billing period. To avoid the next charge, cancel before your next billing date (every month).",
    "placeholders": ["{{cancel_url}}"],
    "verified": true
  },
  "rules_version": "1.3.0",
  "catalog_version": "2026.10.31.1",
  "disclaimer": "Automated compliance check against Checkbox’s catalog of automatic-renewal laws. It is not legal advice…",
  "next_action": {
    "type": "replace_text",
    "message": "Failing: signup.disclosure.cancellation_policy (fail), signup.disclosure.conspicuous (needs_review). Replace the disclosure with replacement.disclosure_text, show it directly above the purchase button… then call this check again."
  }
}

next_action.type is one of none, replace_text, apply_patch, replace_template, fix_and_recheck, human_review, provide_input, schedule_notices. Loop until the verdict is pass.

In CI

Exit codes are stable: 0 pass (or only needs_review without --strict), 1 a check failed, 2 needs review with --strict, 3 usage error, 4 not logged in or key rejected, 5 API or network error. A GitHub Actions step:

.github/workflows/compliance.yml (excerpt)
- name: Checkbox preflight
  env:
    CHECKBOX_API_KEY: ${{ secrets.CHECKBOX_API_KEY }}
  run: npx @checkbox-site/cli check stripe-session --file checkout/session-params.json --merchant-name Joybox --cancel-url https://joybox.example/account/cancel

Give CI a restricted key with only checks: read.

Determinism and limits

  • Every result carries rules_version, catalog_version, catalog_hash, as_of and a disclaimer. The same input and as_of date give the same verdicts.
  • On any Stripe-hosted page, clear and conspicuous (signup.disclosure.conspicuous) stays needs_review: Stripe controls the styling.
  • The page check reads static HTML; buttons rendered by JavaScript are not found, so send the rendered HTML. Layout is estimated, and a passing estimate is reported as needs_review, never pass; a scan confirms it.
  • Disclosure and Stripe checks model a desktop page; mobile layouts are judged by scans.
  • Email checks judge content; real send timing is judged by monitoring.
  • Rate limit: 120 checks per minute per account (page with url: 20 per minute).

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.