# Compliant conversion suggestions

> Optional, engine-checked ways to make your checkout, Stripe Checkout, lifecycle emails and cancellation flow convert and retain better without breaking automatic-renewal laws.

Compliance tells you what you must not do. Merchants also asked the other question: *what can I do to make the
checkout and the emails perform better and still stay compliant?* Checkbox answers it with **suggestions**: a curated,
deterministic library of changes that commonly help conversion or retention, matched to your actual pages, emails and
Stripe settings, and checked by the same rules engine that judges compliance before you ever see them.

Suggestions are optional. They never block anything, never appear as compliance-plan tasks and never change your score,
compliance status or plan status. They start where the legal floor ends: what the floor is, what "clear and
conspicuous" means in practice and three checkouts that pass are in
[Compliant checkouts that convert](https://checkbox.site/docs/guides/compliant-checkouts-that-convert); this guide does not repeat them.

## How it works {#how}

1. **Detect.** Each suggestion has a detector that reads the same facts the checks use: the purchase button and terms
   on your checkout, your Stripe Checkout params, the subject and body of your emails, the steps of the test
   cancellation. "Your button says *Subscribe* and your plan has a 7-day trial" is a *detected* suggestion; one for a
   surface Checkbox has not seen yet is *recommended*.
2. **Respect the guardrails.** Every suggestion lists the legal rules it must respect, with the catalog requirement ids
   (for example California's and Colorado's "click to cancel" next to any save offer, Minnesota's ask-first rule). A
   suggestion that would be untrue or unlawful for you is withheld with the reason: no "cancel anytime" line while
   online cancellation fails, no reminder promise when trial reminders are off, no per-month figure next to a free
   trial.
3. **Check the after-example.** The compliant baseline with the change applied goes through the matching preflight
   check (`checkDisclosure`, `checkStripeCheckoutSession`, `checkEmail`, or the cancellation checks on a modelled flow)
   for your plan and the states you sell in. Only examples with nothing failing are offered.
4. **Hold what is not compliant yet.** If a surface fails a compliance check, its suggestions wait: fix it with the
   [compliance plan](https://checkbox.site/docs/guides/compliance-plan) first.

No suggestion quotes a conversion figure: the "why" says what commonly helps and why. Test changes on your own traffic.

## Get suggestions {#get}

For copy you are writing (stateless, nothing stored; the same inputs as the [preflight checks](https://checkbox.site/docs/preflight)):

```curl
curl https://app.checkbox.site/v1/suggestions \
  -u "$CHECKBOX_SECRET_KEY:" \
  -H "Content-Type: application/json" \
  -d '{
    "terms": { "merchant_name": "Acme", "price": 24, "interval": "month", "trial_days": 7, "cancel_url": "https://acme.example/account" },
    "disclosure": {
      "text": "Free for 7 days, then $24.00 every month until you cancel. Your Acme subscription renews automatically every month at $24.00. Cancel anytime online at https://acme.example/account before your trial ends to avoid being charged.",
      "button_text": "Subscribe",
      "placement": { "bold": true },
      "consent": { "checkbox": true }
    },
    "jurisdictions": ["US-CA", "US-NY"]
  }'
```
```node
import Checkbox from '@checkbox-site/node';

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

const report = await checkbox.suggestions.generate({
  terms: { merchant_name: 'Acme', price: 24, interval: 'month', trial_days: 7, cancel_url: 'https://acme.example/account' },
  disclosure: {
    text: 'Free for 7 days, then $24.00 every month until you cancel. Your Acme subscription renews automatically every month at $24.00. Cancel anytime online at https://acme.example/account before your trial ends to avoid being charged.',
    button_text: 'Subscribe',
    placement: { bold: true },
    consent: { checkbox: true },
  },
  jurisdictions: ['US-CA', 'US-NY'],
});
for (const s of report.suggestions) console.log(`${s.surface}: ${s.title} -> ${s.apply.content}`);
```
```python
import os
from checkbox import Checkbox

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

report = checkbox.suggestions.generate(
    terms={"merchant_name": "Acme", "price": 24, "interval": "month", "trial_days": 7, "cancel_url": "https://acme.example/account"},
    disclosure={
        "text": "Free for 7 days, then $24.00 every month until you cancel. Your Acme subscription renews automatically every month at $24.00. Cancel anytime online at https://acme.example/account before your trial ends to avoid being charged.",
        "button_text": "Subscribe",
        "placement": {"bold": True},
        "consent": {"checkbox": True},
    },
    jurisdictions=["US-CA", "US-NY"],
)
for s in report["suggestions"]:
    print(s["surface"], s["title"], s["apply"]["content"])
```

You can send any subset of `disclosure`, `page` (`html`), `stripe_checkout_session` (`params`), `emails` (one per
kind) and `cancellation_flow` (one entry per screen), plus `other_plans` for plan-switch suggestions.

For a monitored site, Checkbox uses what it observed (checkout captures, emails, the test cancellation, billing
settings and registered Stripe Checkout params):

```text
GET /v1/sites/{site}/suggestions?surfaces=checkout_page,acknowledgment_email
```

The same report is in the dashboard under **Site → Improve** (grouped by surface, with before/after, the guardrails and
a copy button), in the MCP tool `suggest_improvements`, and in the SDKs as `suggestions.forSite` / `suggestions.generate`
(Python: `suggestions.for_site` / `suggestions.generate`). The compliance plan points to it under
`optional_improvements`, never as a task.

Each suggestion carries `apply.where`, `apply.content` (the exact copy, Stripe JSON patch or flow change),
`apply.instructions`, `preconditions` (what must be true before you use it), `guardrails` and `verification`. After
applying one, run the check named in `verification.operation_id` on your real copy.

Suggestions use the same [status labels](https://checkbox.site/docs/guides/compliant-checkouts-that-convert#statuses) as the rest of
Checkbox: every offered suggestion's after-example is `verification.compliance_status: "compliant"`
(`compliance_label` "Compliant"), and a surface with a check that **Needs a fix** is held (`held_label`) until you fix
it — a suggestion never sits on top of a broken floor.

## The best examples {#examples}

Examples below use a $24.00/month plan with a 7-day trial; yours are written from your own plan terms.

### Checkout page {#checkout}

| Change | Before | After | Guardrail |
|---|---|---|---|
| Name the trial on the button | Subscribe | Start my 7-day free trial | "Free" only if nothing is charged during the trial; the unchecked consent checkbox stays (Cal. § 17602(a)(4), Vt. § 2454a) |
| Say how easy cancelling is, under the button | *(nothing)* | Cancel anytime online from your account, no phone call needed; you keep access until the end of the period you paid for. | Only if true: withheld while online cancellation fails (Cal. § 17602(a)(7) misrepresentation, ROSCA) |
| Promise the reminder you already send | *(nothing)* | We'll email you a reminder 3 days before your trial ends. | The day count is the earliest day inside every applicable state window; withheld when trial reminders are off |
| Show the first charge date | Free trial, then billed monthly. | Nothing is charged today. Your first charge of $24.00 is on November 9, 2026 unless you cancel before then. | Also the "deadline to act" New York and NYC expect |
| Per-month figure on yearly plans | $96.00/year | $96.00 billed yearly ($8.00/month) | Real charge first; in the order summary only; never next to a free trial |
| One semibold line, not a warning box | IMPORTANT: … *(red box)* | The same terms as one semibold line in your page's own font, size and colour — what Checkbox Elements 1.3.0 renders by default (`appearance="line"`) | Still [clear and conspicuous](https://checkbox.site/docs/guides/compliant-checkouts-that-convert#conspicuous): body size, readable contrast, semibold, directly above the button |

A plain, unbolded line is **not** suggested: semibold (or another way of setting the line apart) is what makes it
conspicuous — see [example 1](https://checkbox.site/docs/guides/compliant-checkouts-that-convert#line).

### Stripe Checkout {#stripe}

- **Let the trial start without a card**: `payment_method_collection: "if_required"` with
  `subscription_data.trial_settings.end_behavior.missing_payment_method: "cancel"`. Guardrail: when you collect the card
  later, that page needs the renewal terms and consent again (ROSCA § 8403(1)-(2)).
- **Keep `custom_text.submit` short** (Stripe shows it small and grey) and add a one-line product description to the
  order summary.

### Emails {#emails}

- **Welcome email**: a subject that says what it is ("Welcome to Acme: your subscription details", not "Order #10432
  confirmed") and "Manage or cancel your subscription anytime: …" as the first line.
- **Trial reminder**: lead with what the subscriber got from the trial, then the end date, the charge and how to cancel;
  put the date in the subject ("Your Acme free trial ends on {{trial_end_date}}").
- **Renewal reminder**: offer "change your plan" next to "cancel". Naming another frequency as an option ("or switch
  to monthly billing") is fine, as long as the reminder also states this plan's own amount and frequency ("renews every
  year at $96.00").
- **Price change**: one honest sentence on why, and your cheaper plan with its exact price. The New York
  cancel-within-14-days-with-a-pro-rata-refund paragraph stays.
- **Cancellation email**: "Changed your mind? Restart your subscription anytime at …" and an optional invitation to
  reply.

### Cancellation flow {#cancellation}

One optional, clearly skippable save offer (a discount or a pause), never more:

```text
Your subscription [Cancel subscription] [Change plan]
→ Before you go, would you like to see an offer before you cancel? [Show me the offer] [Cancel subscription]
→ Stay and get 50% off your next month. [Accept offer] [Cancel subscription]
→ Your subscription is canceled. You will not be charged again.
```

- California, Colorado and Arkansas: the "Cancel subscription" button is on every screen and cancels at once.
- Minnesota: ask first and show the offer only after a yes (the second screen). Checkbox drops that screen when you
  do not sell in Minnesota.
- New York and NYC: no unreasonable delay; Checkbox flags more than one offer.

Optional one-tap "Why are you leaving?" choices and a confirmation with a way back are suggested the same way.

## What Checkbox never suggests {#never}

Pre-checked boxes, confirmshaming ("No, I don't like saving money"), hidden or delayed cancel buttons, fake urgency or
scarcity, buried terms, a per-month price instead of the real charge, and claims you cannot keep. The library's tests
fail if an example contains any of them.

## Limits {#limits}

- Checkout examples are checked on the compliant baseline (Checkbox's locked disclosure with your terms) with the
  change applied. Your full page is judged when you run the check on it, or by the next scan.
- Stripe-hosted pages keep placement and styling at `needs_review` (Stripe draws them); that is not a regression.
- Per-subscriber content (trial activity, a year's recap) is yours to fill from real data; Checkbox never invents usage.
- An automated check against Checkbox's catalog, not legal advice.
