@checkbox-site/node 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -17,6 +17,8 @@ export interface NextAction {
17
17
  operation_id?: string;
18
18
  /** The MCP tool that performs operation_id on the Checkbox MCP server (`call_api` when there is no dedicated tool). */
19
19
  mcp_tool?: string;
20
+ /** The HTTP method and path of operation_id, with path parameters in braces. */
21
+ endpoint?: string;
20
22
  /** Documentation or dashboard URL for the step, when there is one. */
21
23
  url?: string;
22
24
  }
@@ -32,6 +34,8 @@ export interface Error {
32
34
  message: string;
33
35
  /** The parameter the error relates to, when there is one. */
34
36
  param?: string;
37
+ /** What is missing or wrong, one entry each (terms_incomplete; and every problem of a parameter_invalid / parameter_missing request, so all can be fixed in one try). */
38
+ problems?: Array<string>;
35
39
  /** Link to the documentation of this error code. */
36
40
  doc_url: string;
37
41
  /** Id of the request (also in the Request-Id header). Quote it to support. */
@@ -49,10 +53,35 @@ export interface SetupNextAction {
49
53
  operation_id?: string;
50
54
  /** The MCP tool that performs operation_id (`call_api` when there is no dedicated tool). */
51
55
  mcp_tool?: string;
56
+ /** The HTTP method and path of operation_id, with path parameters in braces. */
57
+ endpoint?: string;
52
58
  /** The equivalent `checkbox` CLI command, when there is one. */
53
59
  command?: string;
54
60
  /** Documentation or dashboard URL for the step. */
55
61
  url?: string;
62
+ /** verify_domain with a started challenge: the DNS TXT record to add. */
63
+ dns?: {
64
+ /** Record type. */
65
+ type: "TXT";
66
+ /** Full record name. */
67
+ name: string;
68
+ /** Record value. */
69
+ value: string;
70
+ };
71
+ /** verify_domain with a started challenge: the file to serve instead of the DNS record. */
72
+ well_known?: {
73
+ /** Where to serve the file. */
74
+ url: string;
75
+ /** The file content. */
76
+ content: string;
77
+ };
78
+ /** verify_domain with a started challenge: or this meta tag on the homepage. The live snippet (install.script_tag) works too: Checkbox verifies the domain when it sees it. */
79
+ meta_tag?: {
80
+ /** The page Checkbox reads (the homepage of the domain). */
81
+ url: string;
82
+ /** The tag to put in its <head>. */
83
+ html: string;
84
+ };
56
85
  }
57
86
  /** A pending device login (RFC 8628 style). */
58
87
  export interface DeviceAuthorization {
@@ -96,11 +125,11 @@ export interface DeviceAuthorizationParams {
96
125
  package_manager?: string;
97
126
  /** Detected billing platform. */
98
127
  billing_platform?: string;
99
- /** Business name (round 3: names the site and workspace instead of the host). */
128
+ /** Business name: names the site and workspace (instead of the host name). */
100
129
  merchant_name?: string;
101
130
  /** Also ask for live-mode keys (live mode activates after domain verification). */
102
131
  live?: boolean;
103
- /** A HINT of the Stripe TEST key found in the project ("sk_test_…a1b2" — never the key). The human is asked once whether Checkbox may use it for synthetic test subscriptions. */
132
+ /** A HINT of the Stripe TEST key found in the project, never the key. Format: "sk_test_" or "rk_test_", the ellipsis character "…" (U+2026), then the key's last 4 characters, e.g. "sk_test_…a1b2". The human is asked once whether Checkbox may use it for synthetic test subscriptions. */
104
133
  stripe_test_key_hint?: string;
105
134
  }
106
135
  /** Keys issued after the human approved the device login. Returned exactly once. */
@@ -139,7 +168,7 @@ export interface DeviceToken {
139
168
  };
140
169
  next_action: SetupNextAction;
141
170
  }
142
- /** A subscription plan as the merchant sells it. */
171
+ /** A subscription plan as the merchant sells it: name, amount (minor units), currency, interval, interval_count, trial_days and the intro_* promo fields, the same shape the checks accept (plan_name, price and intro_price are accepted as aliases). */
143
172
  export interface SetupPlan {
144
173
  /** Plan name. */
145
174
  name?: string;
@@ -153,11 +182,83 @@ export interface SetupPlan {
153
182
  interval_count?: number;
154
183
  /** Free-trial days (0 = none). */
155
184
  trial_days?: number;
185
+ /** Intro / first-period price in minor units (800 = $8.00 for the first period). Give one of intro_amount, intro_percent_off or intro_amount_off. */
186
+ intro_amount?: number;
187
+ /** Intro discount as a percentage off `amount` (a Stripe coupon's percent_off: 20 for 20% off). */
188
+ intro_percent_off?: number;
189
+ /** Intro discount as an amount off `amount`, in minor units (a Stripe coupon's amount_off). */
190
+ intro_amount_off?: number;
191
+ /** How many billing periods the intro price lasts (default 1). */
192
+ intro_periods?: number;
193
+ /** The billing platform's price id (Stripe price_…), so `amount` is compared with the connected Price. */
194
+ price_id?: string;
195
+ /** Alias of `name` (the name the checks also accept). */
196
+ plan_name?: string;
197
+ /** Alias of `amount` in MAJOR units (19 = $19.00); `amount` (minor units) is the canonical field. */
198
+ price?: number | string;
199
+ /** Alias of `intro_amount` in MAJOR units (8 = $8.00). */
200
+ intro_price?: number | string;
156
201
  }
202
+ /** While the domain is not verified: the newest read-only scan of the site's own public pages (labeled "unverified scan": no checkout submitted, not evidence, replaced by the full scan after verification). Null otherwise. */
203
+ export type UnverifiedScan = {
204
+ /** Read-only scan id (uscan_…). */
205
+ id: string;
206
+ /** Object type. */
207
+ object: "unverified_scan";
208
+ /** Always true: read before the domain was verified. Not evidence; no certificate, receipt or monitoring comes from it. */
209
+ unverified: true;
210
+ /** The label every surface shows with these results. */
211
+ label: "unverified scan";
212
+ /** queued, running, completed, failed, or skipped (e.g. the domain got verified first, so the full scan replaces it). */
213
+ status: "queued" | "running" | "completed" | "failed" | "skipped";
214
+ /** When it was queued. Unix timestamp in seconds. */
215
+ created: number;
216
+ /** When it finished. Unix timestamp in seconds. */
217
+ finished: number | null;
218
+ /** Every page considered (at most 20 loaded). */
219
+ pages: Array<{
220
+ /** Page URL. */
221
+ url: string;
222
+ /** home, pricing, terms, privacy, refund, cancellation, account or checkout. */
223
+ kind: string;
224
+ /** captured; skipped (robots.txt, not on the site's own domain, page limit, action link); failed. */
225
+ status: "captured" | "skipped" | "failed";
226
+ /** Why it was skipped or failed. */
227
+ reason?: string;
228
+ }>;
229
+ /** Checks on the loaded pages, in memory (not findings of the site). */
230
+ findings: Array<{
231
+ /** Check id. */
232
+ check_id: string;
233
+ /** Verdict on the loaded pages alone. */
234
+ status: "pass" | "fail" | "needs_review";
235
+ /** critical, high, medium or low. */
236
+ severity: string;
237
+ /** The check, in one line. */
238
+ title: string;
239
+ }>;
240
+ /** Counts. */
241
+ counts: {
242
+ /** Pages captured. */
243
+ pages_captured: number;
244
+ /** Pages skipped. */
245
+ pages_skipped: number;
246
+ /** Failing checks. */
247
+ failing: number;
248
+ /** Checks to review. */
249
+ needs_review: number;
250
+ /** Passing checks. */
251
+ passing: number;
252
+ };
253
+ /** Why it failed or was skipped. */
254
+ error: string | null;
255
+ /** What an unverified scan is (show it with the results). */
256
+ note: string;
257
+ } | null;
157
258
  /** One step of the setup checklist. */
158
259
  export interface SetupStep {
159
260
  /** Stable step key. */
160
- key: "account" | "site" | "snippet" | "policies" | "checks" | "lifecycle_test" | "fixes" | "domain" | "owner_notified";
261
+ key: "account" | "site" | "snippet" | "policies" | "checks" | "connect_billing" | "lifecycle_test" | "fixes" | "domain" | "owner_notified";
161
262
  /** Human-readable title. */
162
263
  title: string;
163
264
  /** done; pending (waiting on Checkbox or a deploy); action_required (the agent must act: see next_action); skipped; failed. */
@@ -222,22 +323,35 @@ export interface SetupSession {
222
323
  /** Plans. */
223
324
  plans: Array<SetupPlan>;
224
325
  };
326
+ /** Notes about this request's input (createSetupSession / updateSetupSession only; never stored): plan amounts below 100 minor units or different from the connected Stripe Price. */
327
+ warnings?: Array<{
328
+ /** Stable warning code. */
329
+ code: "plan_amount_looks_like_major_units" | "plan_amount_mismatch_stripe_price";
330
+ /** What looks wrong and what to send. */
331
+ message: string;
332
+ /** The parameter. */
333
+ param: string;
334
+ }>;
225
335
  /** Policy / pricing links Checkbox found in the site's HTML (terms_url, privacy_url, refund_url, cancellation_url, pricing_url, account_url). */
226
336
  discovered: Record<string, string>;
227
337
  /** Install details. */
228
338
  install: {
229
339
  /** The exact tag to put in <head> on every page. */
230
340
  script_tag: string | null;
231
- /** Public snippet key of the site. */
341
+ /** The site's public snippet key: the data-key of script_tag (and the local part of inbound_email). Use only this key in the snippet tag. */
232
342
  snippet_key: string | null;
233
- /** Test-mode publishable key (pk_test_…) for Checkbox Elements in the browser. */
343
+ /** A different key: the account's test-mode publishable key (pk_test_…) for Checkbox Elements (<checkbox-disclosure>) and consent receipts (data-publishable-key). Not the snippet's data-key. */
234
344
  publishable_key: string | null;
235
345
  /** BCC this address on subscription emails (acknowledgment, reminders) so they are checked. */
236
346
  inbound_email: string | null;
237
347
  /** File the agent added the snippet to. */
238
348
  installed_in: string | null;
239
- /** Whether Checkbox saw the snippet on the live site at the last verify (null: not checked). */
349
+ /** Whether the snippet is live on the site: seen in the homepage at the last verify, or a capture it sent from a page of the site's verified domain (null: not checked). */
240
350
  detected_on_site: boolean | null;
351
+ /** How Checkbox knows the snippet is live: the tag in the homepage HTML, or its first capture from the site's domain. */
352
+ detected_via: "homepage" | "capture" | null;
353
+ /** The page of the snippet's first capture from the site's domain (detected_via capture). */
354
+ first_capture_url: string | null;
241
355
  };
242
356
  /** Policy documents Checkbox fetched (checked by terms.* checks). */
243
357
  policies: Array<{
@@ -245,14 +359,32 @@ export interface SetupSession {
245
359
  kind: string;
246
360
  /** URL fetched. */
247
361
  url: string;
248
- /** Fetch result. */
249
- status: "fetched" | "failed";
362
+ /** Fetch result. preview: read before the site's domain was verified (unverified preview): nothing was stored as evidence and only the Terms checks ran, in memory; it is fetched and stored once the domain is verified. */
363
+ status: "fetched" | "failed" | "preview";
250
364
  /** When it was fetched. Unix timestamp in seconds. */
251
365
  fetched: number;
252
366
  /** Why the fetch failed. */
253
367
  error: string | null;
254
368
  /** Evidence record of the stored page (ev_…). */
255
369
  evidence: string | null;
370
+ /** Not read (or only previewed) because the site's domain is not verified yet. */
371
+ held: boolean;
372
+ /** Unverified preview result (status preview), else null. */
373
+ preview: {
374
+ /** Always true: read before the domain was verified; nothing stored. */
375
+ unverified: true;
376
+ /** Terms checks on this page (none for a privacy policy). */
377
+ checks: Array<{
378
+ /** Check id. */
379
+ check_id: string;
380
+ /** Verdict on this page alone. */
381
+ status: "pass" | "fail" | "needs_review";
382
+ /** The check, in one line. */
383
+ summary: string;
384
+ /** One-sentence fix. */
385
+ fix?: string;
386
+ }>;
387
+ } | null;
256
388
  }>;
257
389
  /** Stripe test mode for lifecycle test runs. */
258
390
  stripe: {
@@ -287,20 +419,61 @@ export interface SetupSession {
287
419
  id: string;
288
420
  /** queued, running, succeeded, failed or canceled. */
289
421
  status: string;
422
+ /** The result in plain words, as the test run says it ("Finished with 2 warnings to review"). succeeded with warnings is not a clean pass. */
423
+ status_label?: string;
290
424
  /** When it started. Unix timestamp in seconds. */
291
425
  created: number;
292
426
  } | null;
427
+ /** The plans Checkbox judges the site against: the declared plans as reconciled with the connected Stripe Prices (Stripe wins), the plans the pay buttons sell and the account's Prices of a declared plan. Empty until a plan is known (updateSetupSession plans[], or connect Stripe). */
428
+ site_plans: Array<{
429
+ /** Plan name (or its price and interval). */
430
+ name: string;
431
+ /** The recurring price, formatted. */
432
+ price: string;
433
+ /** The recurring price in minor units (cents). */
434
+ amount: number;
435
+ /** Currency (lowercase ISO code). */
436
+ currency: string;
437
+ /** day, week, month or year. */
438
+ interval: string;
439
+ /** Intervals between charges. */
440
+ interval_count: number;
441
+ /** Free trial days on this plan (0: none). */
442
+ trial_days: number;
443
+ /** A lower first-period price, if any. */
444
+ intro_price: {
445
+ /** Intro price in minor units. */
446
+ amount: number;
447
+ /** Billing periods at the intro price. */
448
+ periods: number | null;
449
+ } | null;
450
+ /** Every Stripe Price id that names this plan. */
451
+ stripe_price_ids: Array<string>;
452
+ /** declared in setup, chosen in site facts, sold by the pay buttons, or read from the connected Stripe account. */
453
+ source: "declared" | "chosen" | "sold" | "stripe";
454
+ }>;
293
455
  /** Latest verdict of the test-mode site. */
294
456
  compliance: {
295
- /** 0-100. */
296
- score: number;
297
457
  /** When it was evaluated. Unix timestamp in seconds. */
298
458
  evaluated: number;
299
- /** Open failing findings. */
459
+ /**
460
+ * Deprecated: open failing findings (per check). Read `label` (counted in tasks) and `todo` instead.
461
+ * @deprecated
462
+ */
300
463
  failing: number;
301
- /** Open needs-review findings. */
464
+ /**
465
+ * Deprecated: open needs-review findings (per check). Read `label` (counted in tasks) and `todo` instead.
466
+ * @deprecated
467
+ */
302
468
  needs_review: number;
303
- /** Most urgent open findings (details: retrieveFinding; ordered tasks: `checkbox plan --json`). */
469
+ /** The site roll-up label, the same everywhere (dashboard, plan, emails): "2 fixes needed · 1 your call", "Checks pass · 2 live checks pending". */
470
+ label: string | null;
471
+ /** The site roll-up status: needs_fix, your_call, incomplete, compliant or not_checked. */
472
+ status: string | null;
473
+ /**
474
+ * Deprecated: open findings (evidence). The to-do list is `todo` (the compliance plan's ordered open tasks).
475
+ * @deprecated
476
+ */
304
477
  top_findings: Array<{
305
478
  /** Unique identifier of the finding (fnd_…). */
306
479
  id: string;
@@ -313,14 +486,37 @@ export interface SetupSession {
313
486
  /** What is wrong. */
314
487
  title: string;
315
488
  }>;
489
+ /** The to-do list: the compliance plan's ordered open required tasks (same titles, order and counts as the dashboard, MCP get_site_status and the summary email). */
490
+ todo?: Array<{
491
+ /** Plan task id (task_…); its findings are the evidence. */
492
+ task: string;
493
+ /** Task key. */
494
+ key: string;
495
+ /** Task title, the same as in the plan. */
496
+ title: string;
497
+ /** The status the site roll-up counts the task under. */
498
+ status: "needs_fix" | "not_set_up" | "your_call" | "not_checked";
499
+ /** Needs a fix, Not set up yet, Your call or Not checked yet. */
500
+ label: string;
501
+ }>;
316
502
  } | null;
503
+ unverified_scan: UnverifiedScan;
317
504
  /** The setup checklist, in order. */
318
505
  steps: Array<SetupStep>;
319
506
  next_action: SetupNextAction;
320
507
  /** Whether the human got the summary email. */
321
508
  owner_notified: boolean;
322
- /** The summary email: sent, or not_configured when this deployment has no SMTP (null before completeSetupSession). */
323
- owner_email: "sent" | "not_configured" | null;
509
+ /** The summary email, sent only by completeSetupSession and built from the plan at that moment: sent (the mail server accepted it; see owner_email_detail.at), failed (not delivered; owner_email_detail.error says why, and the next completeSetupSession retries), or not_configured when this deployment has no SMTP. Null before completeSetupSession. */
510
+ owner_email: "sent" | "not_configured" | "failed" | null;
511
+ /** Delivery details of the summary email (null before completeSetupSession). */
512
+ owner_email_detail: {
513
+ /** When the summary was handed to the mail server (or failed), unix seconds. */
514
+ at: number | null;
515
+ /** Who it was sent to. */
516
+ to: string | null;
517
+ /** Why it failed (failed only). */
518
+ error: string | null;
519
+ } | null;
324
520
  /** Dashboard page with the setup timeline (for the human). */
325
521
  review_url: string;
326
522
  }
@@ -341,16 +537,16 @@ export interface SetupSessionUpdate {
341
537
  site_url?: string;
342
538
  /** Page where customers subscribe (pricing page or checkout). */
343
539
  checkout_url?: string;
344
- /** Account page where subscribers manage / cancel. */
345
- account_url?: string;
346
- /** Terms of service page. Checkbox fetches and checks it. */
347
- terms_url?: string;
348
- /** Privacy policy page. */
349
- privacy_url?: string;
350
- /** Refund policy page. */
351
- refund_url?: string;
352
- /** Cancellation policy page (if separate from the Terms). */
353
- cancellation_url?: string;
540
+ /** Account page where subscribers manage / cancel. null clears it. */
541
+ account_url?: string | null;
542
+ /** Terms of service page. Checkbox fetches and checks it. null clears it. */
543
+ terms_url?: string | null;
544
+ /** Privacy policy page. null clears it. */
545
+ privacy_url?: string | null;
546
+ /** Refund policy page. null clears it. */
547
+ refund_url?: string | null;
548
+ /** Cancellation policy page (if separate from the Terms). null clears it. */
549
+ cancellation_url?: string | null;
354
550
  /** Support address subscribers can write to. */
355
551
  support_email?: string;
356
552
  /** The brand subscribers know (it names the seller in generated disclosures and emails). Default: the site's host name, which the plan asks you to replace. */
@@ -375,7 +571,7 @@ export interface SetupSessionUpdate {
375
571
  env_file?: string;
376
572
  /** Static files directory (for /.well-known). */
377
573
  public_dir?: string;
378
- /** Where checkout sessions / payment links are created. */
574
+ /** Where checkout sessions / payment links are created: an ARRAY of { file, kind, line?, snippet? } objects, one per place (not a string), e.g. [{"file": "app.py", "line": 40, "kind": "stripe_checkout_session"}]. */
379
575
  checkout_code?: Array<SetupCodeRef>;
380
576
  /** Where the subscribe / pay buttons are rendered. */
381
577
  pay_buttons?: Array<SetupCodeRef>;
@@ -413,6 +609,8 @@ export interface SetupVerification {
413
609
  snippet_detected: boolean | null;
414
610
  /** Why the site could not be loaded. */
415
611
  error: string | null;
612
+ /** Read as an unverified preview (domain not verified yet): one plain GET of the homepage for links and the snippet, nothing stored as evidence. */
613
+ preview: boolean;
416
614
  };
417
615
  /** Policies fetched now. */
418
616
  policies: Array<{
@@ -422,20 +620,64 @@ export interface SetupVerification {
422
620
  ok: boolean;
423
621
  /** Error. */
424
622
  error: string | null;
623
+ /** Read as an unverified preview (domain not verified yet): nothing stored. */
624
+ preview: boolean;
425
625
  }>;
426
626
  /** Synthetic-shopper scan. */
427
627
  scan: {
428
628
  /** Whether a scan was queued now. */
429
629
  queued: boolean;
430
- /** The queued scan (scan_…). */
630
+ /** The queued scan (scan_…); with reason "already scanned", the newest scan (read it with retrieveScan). */
431
631
  scan: string | null;
432
632
  /** Why not. */
433
633
  reason: string | null;
434
634
  };
435
635
  /** Whether compliance was re-evaluated now. */
436
636
  evaluated: boolean;
637
+ /** The site's domain got verified during this call (e.g. the snippet is live on the homepage). */
638
+ domain_verified: {
639
+ /** The domain. */
640
+ domain: string;
641
+ /** snippet, meta_tag, dns_txt or well_known. */
642
+ method: string;
643
+ } | null;
644
+ /** While the domain is not verified: the read-only scan of the site's own public pages (no checkout submitted). */
645
+ unverified_scan: {
646
+ /** Whether a read-only (unverified) scan was queued now. */
647
+ queued: boolean;
648
+ /** Why not (limits: one per site per 24 h, three unverified sites per account in 30 days). */
649
+ reason: string | null;
650
+ } | null;
437
651
  setup_session: SetupSession;
438
652
  }
653
+ /** Account default retention (sites without their own setting use it). */
654
+ export interface Retention {
655
+ /** Years records are kept (consent receipts, disclosures as shown, passing check results, certificates, emails sent, confirmed cancellations, evidence-chain entries). Default 7. */
656
+ records_years: number;
657
+ /** Days superseded check results are kept after a later check replaces them (with their page captures and change history); only summary counts stay. Current results are not deleted. Default 30. */
658
+ superseded_results_days: number;
659
+ /**
660
+ * Deprecated: same as records_years.
661
+ * @deprecated
662
+ */
663
+ good_practice_years: number;
664
+ /**
665
+ * Deprecated: same as superseded_results_days.
666
+ * @deprecated
667
+ */
668
+ problem_history_days: number;
669
+ }
670
+ /** Account-wide legal hold: while active, nothing of this mode's data is deleted. */
671
+ export interface LegalHold {
672
+ /** A legal hold suspends every automatic deletion and refuses deletions and retention shortening. */
673
+ active: boolean;
674
+ /** What the active hold was set on (an account hold covers every site). */
675
+ scope: "site" | "account" | null;
676
+ /** When the hold was turned on. Unix timestamp in seconds. */
677
+ set: number | null;
678
+ /** Note recorded with the hold. */
679
+ reason: string | null;
680
+ }
439
681
  /** The Checkbox account behind the API key. */
440
682
  export interface Account {
441
683
  /** Unique identifier of the account (acct_…). */
@@ -488,10 +730,36 @@ export interface Account {
488
730
  /** Checkbox is free to use. */
489
731
  plan: "free";
490
732
  };
733
+ retention: Retention;
734
+ legal_hold: LegalHold;
491
735
  /** When the account was created. Unix timestamp in seconds. */
492
736
  created: number;
493
737
  next_action: NextAction | null;
494
738
  }
739
+ /** Default retention for every site without its own setting. A longer period for superseded check results keeps a fuller timeline of changes to your site. */
740
+ export interface RetentionParams {
741
+ /** Years records are kept (1-10). On a site, null returns to the account default. */
742
+ records_years?: number | null;
743
+ /** Days superseded check results are kept (7-730). On a site, null returns to the account default. */
744
+ superseded_results_days?: number | null;
745
+ /**
746
+ * Deprecated: use records_years.
747
+ * @deprecated
748
+ */
749
+ good_practice_years?: number | null;
750
+ /**
751
+ * Deprecated: use superseded_results_days.
752
+ * @deprecated
753
+ */
754
+ problem_history_days?: number | null;
755
+ }
756
+ /** Account-wide legal hold: suspends every deletion of the account's records until turned off. */
757
+ export interface LegalHoldParams {
758
+ /** true turns the hold on, false turns it off. */
759
+ active: boolean;
760
+ /** Note stored with the hold (who asked, matter). */
761
+ reason?: string;
762
+ }
495
763
  /** Business facts that decide which legal requirements apply. */
496
764
  export interface SiteFacts {
497
765
  /** The offer starts with a free trial. */
@@ -512,6 +780,8 @@ export interface SiteFacts {
512
780
  plan_price_id?: string;
513
781
  /** Accepted payment methods (debit / ACH bring in Reg E). */
514
782
  payment_methods?: Array<"card" | "debit" | "ach" | "wallet" | "other">;
783
+ /** Where shoppers pay and consent. stripe_checkout / payment_link: your pages redirect to a Stripe-hosted page, so consent is checked on Stripe (consent_collection and custom_text of your registered Checkout configs or Payment Links), and your pricing page needs no checkbox of its own. Unset: detected from pay buttons that link to checkout.stripe.com / buy.stripe.com. */
784
+ checkout_type?: "own_page" | "stripe_checkout" | "payment_link";
515
785
  }
516
786
  /** Scheduled monitoring. */
517
787
  export interface SiteMonitoring {
@@ -528,6 +798,11 @@ export interface SiteMonitoring {
528
798
  /** Domains to verify before Checkbox scans the site (first: createDomainVerification for the site's own domain). */
529
799
  verify_domains: Array<string>;
530
800
  }
801
+ /** The retention in effect for the site. */
802
+ export type SiteRetention = Retention & {
803
+ /** Both values come from the account default (no site override). */
804
+ inherited: boolean;
805
+ };
531
806
  /** A live check Checkbox has not observed yet, and how it completes. */
532
807
  export interface PendingLiveCheck {
533
808
  /** What has not been observed yet. */
@@ -539,9 +814,31 @@ export interface PendingLiveCheck {
539
814
  /** ISO date when it completes on its own (a reminder window), when known. */
540
815
  due: string | null;
541
816
  }
817
+ /** One plan / checkout of the site and its sign-up verdict. */
818
+ export interface CheckoutVerdict {
819
+ /** Plan name, or the checkout when no plan was matched. */
820
+ name: string;
821
+ /** Where the purchase happens: own_page, stripe_checkout (your page → Stripe Checkout), payment_link, checkout_config (a registered Checkout Session config), stripe_hosted. */
822
+ kind: "own_page" | "stripe_checkout" | "payment_link" | "checkout_config" | "stripe_hosted";
823
+ /** The declared plan this checkout sells, when matched. */
824
+ plan: string | null;
825
+ /** User-facing status. needs_fix (a requirement is clearly not met: `compliance.fix` is the one change), pending_live_check (everything Checkbox can see is right; the live event has not been observed yet — counts as passing the checks), verified_live (observed live: proof run, real BCC'd send, Stripe-confirmed cancellation), your_call (a real decision for a person: `compliance.question`), compliant (passes; grey areas carry a `compliance.note`), not_applicable, not_set_up (no sign the email or setting exists yet: `compliance.fix` is the one-click way to set it up; never counts as passing the checks), not_checked (Checkbox has not tried it yet, e.g. the cancel flow: `compliance.fix` says how; never counts as passing the checks). */
826
+ status: "needs_fix" | "pending_live_check" | "verified_live" | "your_call" | "compliant" | "not_applicable" | "not_set_up" | "not_checked";
827
+ /** Label to show. */
828
+ label: string;
829
+ /** Sign-up checks still open on this checkout. */
830
+ open: Array<{
831
+ /** Check id. */
832
+ check_id: string;
833
+ /** Short check title. */
834
+ title: string;
835
+ /** User-facing status. needs_fix (a requirement is clearly not met: `compliance.fix` is the one change), pending_live_check (everything Checkbox can see is right; the live event has not been observed yet — counts as passing the checks), verified_live (observed live: proof run, real BCC'd send, Stripe-confirmed cancellation), your_call (a real decision for a person: `compliance.question`), compliant (passes; grey areas carry a `compliance.note`), not_applicable, not_set_up (no sign the email or setting exists yet: `compliance.fix` is the one-click way to set it up; never counts as passing the checks), not_checked (Checkbox has not tried it yet, e.g. the cancel flow: `compliance.fix` says how; never counts as passing the checks). */
836
+ status: "needs_fix" | "pending_live_check" | "verified_live" | "your_call" | "compliant" | "not_applicable" | "not_set_up" | "not_checked";
837
+ }>;
838
+ }
542
839
  /** Roll-up of the user-facing statuses of the required checks. */
543
840
  export interface ComplianceRollup {
544
- /** needs_fix (a required check needs a fix or something is not set up yet), your_call (a decision is needed), incomplete (only "not checked yet" items are left, e.g. the cancel flow was never tried), compliant (pending live checks count as compliant), not_checked (never evaluated). */
841
+ /** needs_fix (a required check needs a fix or something is not set up yet), your_call (a decision is needed), incomplete (only "not checked yet" items are left, e.g. the cancel flow was never tried), compliant (every required check passes; pending live checks count as passing), not_checked (never evaluated). */
545
842
  status: "needs_fix" | "your_call" | "incomplete" | "compliant" | "not_checked";
546
843
  /** Label to show. */
547
844
  label: string;
@@ -551,11 +848,11 @@ export interface ComplianceRollup {
551
848
  needs_fix: number;
552
849
  /** Decisions for a person. */
553
850
  your_call: number;
554
- /** Compliant, live check pending. */
851
+ /** Checks pass, live check pending. */
555
852
  pending_live_check: number;
556
853
  /** Verified live. */
557
854
  verified_live: number;
558
- /** Compliant. */
855
+ /** Checks pass. */
559
856
  compliant: number;
560
857
  /** Not applicable. */
561
858
  not_applicable: number;
@@ -569,20 +866,20 @@ export interface ComplianceRollup {
569
866
  /** Check id. */
570
867
  check_id: string;
571
868
  }>;
572
- /** Recommended / extra items open (never block compliant). */
869
+ /** Recommended / extra items open (never block the checks from passing). */
573
870
  suggestions: number;
871
+ /** Per-plan / per-checkout verdicts, in the same vocabulary as the roll-up. Present when the site has two or more checkouts, or one on Stripe. */
872
+ checkouts?: Array<CheckoutVerdict>;
574
873
  }
575
874
  /** Latest verdict; null until the first evaluation. */
576
875
  export type SiteCompliance = {
577
- /** Compliance score 0-100 (one decimal place). */
578
- score: number;
579
876
  /** When the latest evaluation ran. Unix timestamp in seconds. */
580
877
  evaluated: number;
581
878
  /** Open findings whose latest status is fail. */
582
879
  open_findings: number;
583
880
  /** Open findings waiting for a human look. */
584
881
  needs_review: number;
585
- /** User-facing roll-up of the required checks: needs_fix > your_call > compliant (pending live checks count as compliant). */
882
+ /** User-facing roll-up of the required checks: needs_fix > your_call > compliant (every required check passes; pending live checks count as passing). */
586
883
  status: "needs_fix" | "your_call" | "incomplete" | "compliant" | "not_checked";
587
884
  /** Label to show. */
588
885
  label: string;
@@ -599,6 +896,33 @@ export interface SiteInstall {
599
896
  /** Billing-platform webhook URLs (platform -> URL). */
600
897
  webhook_urls: Record<string, string>;
601
898
  }
899
+ /** The site's Shopify store connection; null when the site neither uses platform shopify nor has a Shopify connection. */
900
+ export type SiteShopify = {
901
+ /** How the store is connected. app: through the Checkbox Shopify app (Checkbox can publish the verified terms to the app block: publishShopifyTerms). own_app: with the store's own custom-app access token (read-only; use the standalone theme snippet). none: not connected (only the merchant can install the Checkbox app from the Shopify admin). */
902
+ connection: "app" | "own_app" | "none";
903
+ /** The store's myshopify.com domain, when connected. */
904
+ shop: string | null;
905
+ /** Status of the Shopify connection (connected, error, disconnected); null without one. */
906
+ status: string | null;
907
+ /** The newest publish of the verified renewal terms to the Checkbox app block; null when never published. Whether the block is placed on the theme shows in the scans (Checkbox does not read the theme). */
908
+ terms_published: {
909
+ /** The fix application that recorded the publish. */
910
+ application: string;
911
+ /** When the text was published. Unix timestamp in seconds. */
912
+ published: number;
913
+ /** sha256 of the published texts (disclosure + newline + consent label). */
914
+ sha256: string;
915
+ } | null;
916
+ /** Theme editor link that adds the "Renewal terms + consent" block to the product page (the merchant opens it once and clicks Save). Null without a connected store. */
917
+ theme_editor_url: string | null;
918
+ } | null;
919
+ /** The compliance status of the evaluation this scan produced (null until evaluated). Retrieve the evaluation for the checks and counts. */
920
+ export type ScanCompliance = {
921
+ /** Roll-up status of that evaluation: needs_fix, your_call, incomplete, compliant or not_checked. */
922
+ status: "needs_fix" | "your_call" | "incomplete" | "compliant" | "not_checked";
923
+ /** The status label to show, counted in tasks ("2 fixes needed", "Checks pass"). */
924
+ label: string;
925
+ } | null;
602
926
  /** Most recent scan (only with expand[]=latest_scan). */
603
927
  export interface Scan {
604
928
  /** Unique identifier of the scan (scan_…). */
@@ -621,8 +945,7 @@ export interface Scan {
621
945
  warnings: Array<string>;
622
946
  /** The evaluation this scan produced (null until evaluated). */
623
947
  evaluation: string | null;
624
- /** Score of that evaluation (0-100, one decimal place). */
625
- score: number | null;
948
+ compliance: ScanCompliance;
626
949
  /** When the scan started. Unix timestamp in seconds. */
627
950
  started: number | null;
628
951
  /** When the scan finished. Unix timestamp in seconds. */
@@ -640,10 +963,10 @@ export interface DomainVerification {
640
963
  site: string;
641
964
  /** Domain of the site URL. */
642
965
  domain: string | null;
643
- /** not_started until createDomainVerification; verified once the TXT record or file was found. */
966
+ /** not_started until createDomainVerification; verified once the TXT record, the file, the live snippet or the meta tag was found. */
644
967
  status: "not_started" | "pending" | "verified";
645
- /** How control was proven. */
646
- method: "dns_txt" | "well_known" | null;
968
+ /** How control was proven: dns_txt, well_known, snippet (the site's Checkbox snippet live on https://<domain>/), meta_tag (<meta name="checkbox-verify"> on https://<domain>/) or shopify_install (the domain is the primary domain of a Shopify store that installed the Checkbox app and is connected to this site). */
969
+ method: "dns_txt" | "well_known" | "snippet" | "meta_tag" | "shopify_install" | null;
647
970
  /** When it was verified. Unix timestamp in seconds. */
648
971
  verified_at: number | null;
649
972
  /** Last check. Unix timestamp in seconds. */
@@ -666,6 +989,13 @@ export interface DomainVerification {
666
989
  /** Exact file contents. */
667
990
  contents: string;
668
991
  } | null;
992
+ /** Or add this meta tag to the homepage (option 3). Option 4: install the site's Checkbox snippet (install.script_tag) on the homepage; Checkbox verifies the domain when it sees it live. */
993
+ meta_tag: {
994
+ /** The page Checkbox reads (the site's homepage, redirects only within the domain). */
995
+ url: string;
996
+ /** Put this tag in the <head> of that page. */
997
+ html: string;
998
+ } | null;
669
999
  /** Configured scan URLs outside the verified domain (certificates cover only the domain). */
670
1000
  scan_target_problems: Array<string>;
671
1001
  /** Whether live mode is activated for the account. */
@@ -680,6 +1010,8 @@ export interface DomainVerification {
680
1010
  operation_id?: string;
681
1011
  /** The MCP tool that performs operation_id (`call_api` when there is no dedicated tool). */
682
1012
  mcp_tool?: string;
1013
+ /** The HTTP method and path of operation_id. */
1014
+ endpoint?: string;
683
1015
  } | null;
684
1016
  }
685
1017
  /** A subscription business Checkbox monitors. */
@@ -719,6 +1051,8 @@ export interface Site {
719
1051
  login_url: string;
720
1052
  /** Test subscriber email. */
721
1053
  email: string;
1054
+ /** The page that re-activates the test subscription before each cancellation test (null when none is set). */
1055
+ reactivate_url: string | null;
722
1056
  } | null;
723
1057
  /** Number of explicit cancellation steps. */
724
1058
  cancel_steps: number;
@@ -729,16 +1063,35 @@ export interface Site {
729
1063
  /** The checkout page is the home page (checkout_url was omitted or set to the site root). Sign-up checks then judge the home page: set checkout_url to the page with the subscribe button unless the home page really has it. */
730
1064
  homepage_as_checkout: boolean;
731
1065
  };
1066
+ /** Same as checkout.url, under the name updateSite / createSite take. */
1067
+ checkout_url: string;
1068
+ /** Same as checkout.account_url, under the name updateSite takes. */
1069
+ account_url: string | null;
1070
+ /** Same as checkout.terms_url, under the name updateSite takes. */
1071
+ terms_url: string | null;
1072
+ /** Same as checkout.test_account: the test account as saved (the password is write-only and never returned); null when none is set. */
1073
+ test_account: {
1074
+ /** Login page. */
1075
+ login_url: string;
1076
+ /** Test subscriber email. */
1077
+ email: string;
1078
+ /** The re-activation page (null when none is set). */
1079
+ reactivate_url: string | null;
1080
+ } | null;
732
1081
  monitoring: SiteMonitoring;
733
1082
  /** Which requirement tiers Checkbox shows (minimum: required only; balanced: + recommended suggestions; maximum: + extras). Only required items affect compliance. */
734
1083
  protection_level: "minimum" | "balanced" | "maximum";
1084
+ retention: SiteRetention;
1085
+ legal_hold: LegalHold;
735
1086
  compliance: SiteCompliance;
736
1087
  install: SiteInstall;
1088
+ shopify: SiteShopify;
737
1089
  /** Archived (soft-deleted); evidence is retained. */
738
1090
  archived: boolean;
739
1091
  /** When the site was created. Unix timestamp in seconds. */
740
1092
  created: number;
741
1093
  latest_scan?: Scan;
1094
+ unverified_scan: UnverifiedScan;
742
1095
  domain_verification?: DomainVerification;
743
1096
  }
744
1097
  /** A page of sites, newest first. */
@@ -804,7 +1157,7 @@ export interface SiteTestAccount {
804
1157
  password: string;
805
1158
  /** Custom login steps. */
806
1159
  login_steps?: Array<ScanStep>;
807
- /** Optional page on your site that RE-ACTIVATES the test subscription (a test-only route). The cancellation test really cancels the test account; the scanner opens this page after logging in, before cancelling, so every scan starts subscribed. Without it, a scan after a completed cancellation reports "not observed: the test account has no active subscription" (needs review). (Round 3: renamed from reset_url, which meant the opposite of the proof run's stripe.cleanup_url.) */
1160
+ /** Optional page on your site that RE-ACTIVATES the test subscription (a test-only route). The cancellation test really cancels the test account; the scanner opens this page after logging in, before cancelling, so every scan starts subscribed. Without it, a scan after a completed cancellation reports "not observed: the test account has no active subscription" (needs review). (Replaces reset_url, now a deprecated alias.) */
808
1161
  reactivate_url?: string;
809
1162
  /** Deprecated alias of reactivate_url. */
810
1163
  reset_url?: string;
@@ -837,7 +1190,7 @@ export interface CreateSiteParams {
837
1190
  devices?: Array<"desktop" | "mobile">;
838
1191
  /** Scheduled re-scan interval (0 = off, minimum 60). Default 1440 in live mode, 0 in test mode. */
839
1192
  monitoring_interval_minutes?: number;
840
- /** Which requirement tiers Checkbox shows. minimum: the legal floor only (required items). balanced (default): required items plus recommended suggestions (consent receipts, a cancellation confirmation email…), collapsed and never blocking "compliant". maximum: everything, including extra protections (a separate checkbox per term, a pre-purchase summary). Only required items can make a site not compliant, at every level. */
1193
+ /** Which requirement tiers Checkbox shows. minimum: the legal floor only (required items). balanced (default): required items plus recommended suggestions (consent receipts, a cancellation confirmation email…), collapsed and never blocking "Checks pass". maximum: everything, including extra protections (a separate checkbox per term, a pre-purchase summary). Only required items can keep a site's checks from passing, at every level. */
841
1194
  protection_level?: "minimum" | "balanced" | "maximum";
842
1195
  }
843
1196
  export interface UpdateSiteParams {
@@ -868,8 +1221,19 @@ export interface UpdateSiteParams {
868
1221
  devices?: Array<"desktop" | "mobile">;
869
1222
  /** Scheduled re-scan interval (0 = off, minimum 60). Default 1440 in live mode, 0 in test mode. */
870
1223
  monitoring_interval_minutes?: number;
871
- /** Which requirement tiers Checkbox shows. minimum: the legal floor only (required items). balanced (default): required items plus recommended suggestions (consent receipts, a cancellation confirmation email…), collapsed and never blocking "compliant". maximum: everything, including extra protections (a separate checkbox per term, a pre-purchase summary). Only required items can make a site not compliant, at every level. */
1224
+ /** Which requirement tiers Checkbox shows. minimum: the legal floor only (required items). balanced (default): required items plus recommended suggestions (consent receipts, a cancellation confirmation email…), collapsed and never blocking "Checks pass". maximum: everything, including extra protections (a separate checkbox per term, a pre-purchase summary). Only required items can keep a site's checks from passing, at every level. */
872
1225
  protection_level?: "minimum" | "balanced" | "maximum";
1226
+ /** The URLs nested as the site object returns them (checkout.url, checkout.account_url, checkout.terms_url); the flat fields win when both are given. */
1227
+ checkout?: {
1228
+ /** Same as checkout_url. */
1229
+ url?: string;
1230
+ /** Same as account_url. */
1231
+ account_url?: string | null;
1232
+ /** Same as terms_url. */
1233
+ terms_url?: string | null;
1234
+ };
1235
+ retention?: RetentionParams;
1236
+ legal_hold?: LegalHoldParams;
873
1237
  }
874
1238
  /** A billing-platform connection of a site. */
875
1239
  export interface Integration {
@@ -887,13 +1251,55 @@ export interface Integration {
887
1251
  last_synced: number | null;
888
1252
  /** A problem worth fixing, e.g. a test-mode key on a live site. */
889
1253
  warning: string | null;
1254
+ /** Chargebee, Recurly and Paddle: the webhook to add by hand (Chargebee: Settings › Configure Chargebee › API Keys and Webhooks › Webhooks; Recurly: Integrations › Webhooks; Paddle: Events › Notifications › New destination, under Developer tools in older dashboards). Null for platforms whose webhook Checkbox registers itself. */
1255
+ webhook_setup: {
1256
+ /** Webhook URL to add in the platform. */
1257
+ url: string;
1258
+ /** Authentication the webhook uses: basic (enter the username and password below; Chargebee, Recurly) or signature (the platform signs deliveries with a secret key it makes, which you paste into Checkbox; Paddle). */
1259
+ auth: "basic" | "signature";
1260
+ /** Basic-auth username to enter. Null for signature auth. */
1261
+ username: string | null;
1262
+ /** Basic-auth password to enter. Treat it as a secret. Null for signature auth. */
1263
+ password: string | null;
1264
+ /** Events to select. */
1265
+ events: Array<string>;
1266
+ /** Webhook API version to choose. */
1267
+ api_version: string | null;
1268
+ /** Payload format to choose on the endpoint (Recurly: JSON). Null when the platform has no choice. */
1269
+ payload_format: "json" | null;
1270
+ /** Recurly and Paddle: whether the endpoint’s secret key is saved in Checkbox (dashboard › Billing connection › webhook), so every delivery’s signature is checked. Paddle deliveries are refused until it is. Null for platforms without signatures. */
1271
+ signing_key_configured: boolean | null;
1272
+ /** Paddle: whether a notification destination with this URL exists in Paddle (from the settings Checkbox last read; needs the Notification settings: Read permission). Null when unknown or for other platforms. */
1273
+ destination_status: "found" | "inactive" | "missing" | null;
1274
+ /** Paddle: events the destination does not send yet. Null when unknown or for other platforms. */
1275
+ missing_events: Array<string> | null;
1276
+ } | null;
890
1277
  }
891
1278
  export interface ConnectBillingPlatformParams {
892
1279
  /** Billing platform. */
893
- platform: "stripe" | "recharge" | "shopify";
894
- /** Read-only credentials. Stripe: { "secretKey": "rk_test_…" } (a restricted key with read access; rk_test_ in test mode). Recharge: { "apiToken": "…" }. Shopify: { "shop": "store.myshopify.com", "accessToken": "shpat_…" }. */
1280
+ platform: "stripe" | "recharge" | "shopify" | "chargebee" | "recurly" | "paddle";
1281
+ /** Read-only credentials, in snake_case like the rest of the API (the camelCase spellings, secretKey / apiToken / accessToken / apiKey, are accepted too). Stripe: { "secret_key": "rk_test_…" } (a restricted key with read access; rk_test_ in test mode). Recharge: { "api_token": "…" }. Shopify: { "shop": "store.myshopify.com", "access_token": "shpat_…" }. Chargebee: { "site": "acme", "api_key": "live_…" } (the site name before .chargebee.com and a read-only API key). Recurly: { "api_key": "…", "region": "us" } (a private API key of the site; region "eu" for sites hosted in Recurly’s EU data centre, default "us"). Paddle: { "api_key": "pdl_live_apikey_…" } (a Paddle Billing API key with read permissions; sandbox keys, pdl_sdbx_…, read the sandbox; "environment": "live" or "sandbox" only for older keys without that prefix). Checkbox only reads. */
895
1282
  credentials: Record<string, string>;
896
1283
  }
1284
+ /** A queued re-read of the site's billing-platform settings, followed by a re-evaluation. */
1285
+ export interface BillingSync {
1286
+ /** String representing the object's type. Always "billing_sync". */
1287
+ object: "billing_sync";
1288
+ /** The site whose billing settings are re-read. */
1289
+ site: string;
1290
+ /** One entry per connected billing platform. */
1291
+ platforms: Array<{
1292
+ /** The connected billing platform. */
1293
+ platform: "stripe" | "shopify" | "recharge" | "chargebee" | "recurly" | "paddle" | "woocommerce" | "custom";
1294
+ /** The re-read is queued; settings refresh within a minute. */
1295
+ status: "queued";
1296
+ /** When the settings were last read successfully. Unix timestamp in seconds. */
1297
+ last_synced: number | null;
1298
+ /** Why the last read failed, if it did. */
1299
+ last_error: string | null;
1300
+ }>;
1301
+ next_action: NextAction;
1302
+ }
897
1303
  /** A page of scans, newest first. */
898
1304
  export interface ScanList {
899
1305
  /** String representing the object's type. Always "list". */
@@ -917,8 +1323,10 @@ export interface CheckSummary {
917
1323
  severity: "critical" | "high" | "medium" | "low";
918
1324
  /** Lifecycle stage. */
919
1325
  stage: "signup" | "confirmation" | "reminder" | "cancellation" | "config";
920
- /** User-facing status. needs_fix (a clear violation: `compliance.fix` is the one change), pending_live_check (everything Checkbox can see is right; the live event has not been observed yet — counts as compliant), verified_live (observed live: proof run, real BCC'd send, Stripe-confirmed cancellation), your_call (a real decision for a person: `compliance.question`), compliant (passes; grey areas carry a `compliance.note`), not_applicable, not_set_up (no sign the email or setting exists yet: `compliance.fix` is the one-click way to set it up; never counts as compliant), not_checked (Checkbox has not tried it yet, e.g. the cancel flow: `compliance.fix` says how; never counts as compliant). */
1326
+ /** User-facing status. needs_fix (a requirement is clearly not met: `compliance.fix` is the one change), pending_live_check (everything Checkbox can see is right; the live event has not been observed yet — counts as passing the checks), verified_live (observed live: proof run, real BCC'd send, Stripe-confirmed cancellation), your_call (a real decision for a person: `compliance.question`), compliant (passes; grey areas carry a `compliance.note`), not_applicable, not_set_up (no sign the email or setting exists yet: `compliance.fix` is the one-click way to set it up; never counts as passing the checks), not_checked (Checkbox has not tried it yet, e.g. the cancel flow: `compliance.fix` says how; never counts as passing the checks). */
921
1327
  compliance_status: "needs_fix" | "pending_live_check" | "verified_live" | "your_call" | "compliant" | "not_applicable" | "not_set_up" | "not_checked";
1328
+ /** The status in words to show a person ("Needs a fix", "Your call", "Not set up yet", "Not checked yet", "Checks pass"…). Show this, never the machine value. */
1329
+ compliance_status_label: string;
922
1330
  }
923
1331
  /** A compliance verdict for a site at a point in time. */
924
1332
  export interface Evaluation {
@@ -932,8 +1340,6 @@ export interface Evaluation {
932
1340
  site: string;
933
1341
  /** The scan row this evaluation belongs to. */
934
1342
  scan: string;
935
- /** Compliance score 0-100 (severity-weighted, one decimal place, e.g. 82.5). */
936
- score: number;
937
1343
  /** Legal catalog / rules version used. */
938
1344
  rules_version: string;
939
1345
  /** When it was evaluated. Unix timestamp in seconds. */
@@ -1048,13 +1454,13 @@ export interface VerdictEvidence {
1048
1454
  }
1049
1455
  /** What a person should do about one check (the user-facing layer over `status`). */
1050
1456
  export interface ComplianceInfo {
1051
- /** User-facing status. needs_fix (a clear violation: `compliance.fix` is the one change), pending_live_check (everything Checkbox can see is right; the live event has not been observed yet — counts as compliant), verified_live (observed live: proof run, real BCC'd send, Stripe-confirmed cancellation), your_call (a real decision for a person: `compliance.question`), compliant (passes; grey areas carry a `compliance.note`), not_applicable, not_set_up (no sign the email or setting exists yet: `compliance.fix` is the one-click way to set it up; never counts as compliant), not_checked (Checkbox has not tried it yet, e.g. the cancel flow: `compliance.fix` says how; never counts as compliant). */
1457
+ /** User-facing status. needs_fix (a requirement is clearly not met: `compliance.fix` is the one change), pending_live_check (everything Checkbox can see is right; the live event has not been observed yet — counts as passing the checks), verified_live (observed live: proof run, real BCC'd send, Stripe-confirmed cancellation), your_call (a real decision for a person: `compliance.question`), compliant (passes; grey areas carry a `compliance.note`), not_applicable, not_set_up (no sign the email or setting exists yet: `compliance.fix` is the one-click way to set it up; never counts as passing the checks), not_checked (Checkbox has not tried it yet, e.g. the cancel flow: `compliance.fix` says how; never counts as passing the checks). */
1052
1458
  status: "needs_fix" | "pending_live_check" | "verified_live" | "your_call" | "compliant" | "not_applicable" | "not_set_up" | "not_checked";
1053
- /** Label to show: "Needs a fix", "Not set up yet", "Not checked yet", "Looks compliant — live check pending", "Verified live", "Your call", "Compliant", "Looks compliant", "Looks compliant with a note", "Not applicable". */
1459
+ /** Label to show: "Needs a fix", "Not set up yet", "Not checked yet", "Checks pass · live check pending", "Verified live", "Your call", "Checks pass", "Checks pass with a note", "Not applicable". */
1054
1460
  label: string;
1055
1461
  /** Stable code of the mapping rule (docs/ACCURACY.md). */
1056
1462
  reason: string;
1057
- /** required (legal floor: the only tier that can make a site not compliant), recommended (lowers lawsuit risk, conversion-neutral), extra (maximum protection). */
1463
+ /** required (legal floor: the only tier that can keep a site's checks from passing), recommended (clearer records beyond the legal floor, conversion-neutral), extra (maximum protection). */
1058
1464
  tier: "required" | "recommended" | "extra";
1059
1465
  /** needs_fix: the one change that fixes it. */
1060
1466
  fix: string | null;
@@ -1109,7 +1515,7 @@ export interface Finding {
1109
1515
  /** Check-specific details (failing regions/devices/URLs, measurements, quotes). */
1110
1516
  details: Record<string, unknown>;
1111
1517
  evidence: VerdictEvidence;
1112
- /** User-facing status. needs_fix (a clear violation: `compliance.fix` is the one change), pending_live_check (everything Checkbox can see is right; the live event has not been observed yet — counts as compliant), verified_live (observed live: proof run, real BCC'd send, Stripe-confirmed cancellation), your_call (a real decision for a person: `compliance.question`), compliant (passes; grey areas carry a `compliance.note`), not_applicable, not_set_up (no sign the email or setting exists yet: `compliance.fix` is the one-click way to set it up; never counts as compliant), not_checked (Checkbox has not tried it yet, e.g. the cancel flow: `compliance.fix` says how; never counts as compliant). */
1518
+ /** User-facing status. needs_fix (a requirement is clearly not met: `compliance.fix` is the one change), pending_live_check (everything Checkbox can see is right; the live event has not been observed yet — counts as passing the checks), verified_live (observed live: proof run, real BCC'd send, Stripe-confirmed cancellation), your_call (a real decision for a person: `compliance.question`), compliant (passes; grey areas carry a `compliance.note`), not_applicable, not_set_up (no sign the email or setting exists yet: `compliance.fix` is the one-click way to set it up; never counts as passing the checks), not_checked (Checkbox has not tried it yet, e.g. the cancel flow: `compliance.fix` says how; never counts as passing the checks). */
1113
1519
  compliance_status: "needs_fix" | "pending_live_check" | "verified_live" | "your_call" | "compliant" | "not_applicable" | "not_set_up" | "not_checked";
1114
1520
  compliance: ComplianceInfo;
1115
1521
  /** Scan that produced the latest result. */
@@ -1192,14 +1598,16 @@ export interface Task {
1192
1598
  key: string;
1193
1599
  /** Short imperative title. */
1194
1600
  title: string;
1195
- /** open (apply the change), in_progress (an agent claimed it), verifying (a verification is waiting for a confirming observation), done, wont_fix (the merchant declined, with a reason), manual (needs a human answer: see question), pending_live_check (everything Checkbox can see is right; it waits for a live observation — see change for how it completes. Counts as compliant and never blocks the plan). */
1601
+ /** open (apply the change), in_progress (an agent claimed it), verifying (a verification is waiting for a confirming observation), done, wont_fix (the merchant declined, with a reason), manual (needs a human answer: see question), pending_live_check (everything Checkbox can see is right; it waits for a live observation — see change for how it completes. Counts as passing the checks and never blocks the plan). */
1196
1602
  status: "open" | "in_progress" | "verifying" | "done" | "wont_fix" | "manual" | "pending_live_check";
1197
1603
  /** Strictest severity among the task's legal checks. */
1198
1604
  priority: "critical" | "high" | "medium" | "low";
1199
- /** required (the legal floor: the only tier that can keep the site from being compliant), recommended (lowers lawsuit risk, conversion-neutral; shown at protection level balanced and maximum, never blocks), extra (maximum protection only). Always present on API responses. */
1605
+ /** required (the legal floor: the only tier that can keep the site's checks from passing), recommended (clearer records beyond the legal floor, conversion-neutral; shown at protection level balanced and maximum, never blocks), extra (maximum protection only). Always present on API responses. */
1200
1606
  tier?: "required" | "recommended" | "extra";
1201
- /** User-facing status. needs_fix (a clear violation: `compliance.fix` is the one change), pending_live_check (everything Checkbox can see is right; the live event has not been observed yet — counts as compliant), verified_live (observed live: proof run, real BCC'd send, Stripe-confirmed cancellation), your_call (a real decision for a person: `compliance.question`), compliant (passes; grey areas carry a `compliance.note`), not_applicable, not_set_up (no sign the email or setting exists yet: `compliance.fix` is the one-click way to set it up; never counts as compliant), not_checked (Checkbox has not tried it yet, e.g. the cancel flow: `compliance.fix` says how; never counts as compliant). */
1607
+ /** User-facing status. needs_fix (a requirement is clearly not met: `compliance.fix` is the one change), pending_live_check (everything Checkbox can see is right; the live event has not been observed yet — counts as passing the checks), verified_live (observed live: proof run, real BCC'd send, Stripe-confirmed cancellation), your_call (a real decision for a person: `compliance.question`), compliant (passes; grey areas carry a `compliance.note`), not_applicable, not_set_up (no sign the email or setting exists yet: `compliance.fix` is the one-click way to set it up; never counts as passing the checks), not_checked (Checkbox has not tried it yet, e.g. the cancel flow: `compliance.fix` says how; never counts as passing the checks). */
1202
1608
  compliance_status?: "needs_fix" | "pending_live_check" | "verified_live" | "your_call" | "compliant" | "not_applicable" | "not_set_up" | "not_checked";
1609
+ /** The status in words to show a person ("Needs a fix", "Your call", "Not set up yet", "Not checked yet", "Checks pass"…). Show this, never the machine value. */
1610
+ compliance_status_label?: string;
1203
1611
  /** Position in the plan (1 = do first). Dependency-aware. */
1204
1612
  order: number;
1205
1613
  /** Legal checks this task makes pass. */
@@ -1223,7 +1631,7 @@ export interface Task {
1223
1631
  where: {
1224
1632
  /** Where the change is made. */
1225
1633
  kind: "code" | "stripe_setting" | "email_template" | "policy_page" | "dns" | "checkbox_setting" | "billing_platform";
1226
- /** Likely source file (reported by `checkbox init` / updateSetupSession, else a framework convention). */
1634
+ /** Source file reported by `checkbox init` / updateSetupSession (null when none was reported: Checkbox does not guess file names; the root layout of a file-system router is named). */
1227
1635
  file_hint: string | null;
1228
1636
  /** Page (or settings page) where the problem was observed / the change is made. */
1229
1637
  url: string | null;
@@ -1308,6 +1716,15 @@ export interface Task {
1308
1716
  /** When it was requested. Unix timestamp in seconds. */
1309
1717
  created: number;
1310
1718
  } | null;
1719
+ /** Email tasks on a site with several plans: the result of each plan's own email copy (verifyTask with plan). The copy check passes only when every plan passes; one plan's copy never covers another plan. */
1720
+ plan_coverage?: Array<{
1721
+ /** The plan, by name. */
1722
+ plan: string;
1723
+ /** That plan's copy: pass, fail, needs_review, or not_checked (no copy for this plan was verified yet). */
1724
+ verdict: "pass" | "fail" | "needs_review" | "not_checked";
1725
+ /** When that plan's copy was checked. Unix timestamp in seconds. */
1726
+ checked_at: number | null;
1727
+ }>;
1311
1728
  next_action: PlanNextAction;
1312
1729
  /** Email tasks only (null otherwise): what Checkbox has seen of this email. not_seen (nothing yet), template_checked (a template or sample passed the email checks, but Checkbox has not seen it sent for a real event: the task stays open), delivery_seen (captured from a real event: a test run, a notice for a real subscriber, or a BCC copy matching that subscriber's billing event). Only delivery_seen satisfies the task. */
1313
1730
  verification_level: "not_seen" | "template_checked" | "delivery_seen" | null;
@@ -1316,7 +1733,7 @@ export interface Task {
1316
1733
  /** When it was done. Unix timestamp in seconds. */
1317
1734
  done_at: number | null;
1318
1735
  }
1319
- /** The ordered, machine-readable list of changes that makes a site compliant, recomputed from its latest evaluation. */
1736
+ /** The ordered, machine-readable list of changes that makes a site's checks pass, recomputed from its latest evaluation. */
1320
1737
  export interface CompliancePlan {
1321
1738
  /** Unique identifier of the compliance plan (plan_…). */
1322
1739
  id: string;
@@ -1328,14 +1745,16 @@ export interface CompliancePlan {
1328
1745
  site: string;
1329
1746
  /** action_required (an agent can apply open tasks now), verifying (changes applied; waiting for confirming observations), compliant (every required check passes or only waits for a live check — an automated assessment, not a legal determination; see compliance.pending_live_checks and coverage), blocked (only human answers ("Your call") or declined critical tasks remain). */
1330
1747
  status: "action_required" | "verifying" | "compliant" | "blocked";
1331
- /** Compliance score 0-100 of the latest evaluation. */
1332
- score: number | null;
1748
+ /** The plan status in words to show a person: action_required "Fixes needed", verifying "Checking your changes", compliant "Checks pass", blocked "Your call". Show this, never the machine value (`compliant` is a status name, not a legal conclusion). */
1749
+ status_label?: string;
1333
1750
  /** The evaluation the plan was built from (null before the first check). */
1334
1751
  evaluation: string | null;
1335
1752
  /** When that evaluation ran. Unix timestamp in seconds. */
1336
1753
  evaluated: number | null;
1337
1754
  /** Two or three sentences for an LLM: where the site stands and what comes next. */
1338
1755
  summary: string;
1756
+ /** Declared plans (setup plans, i.e. your code) whose price, interval or trial differ from the billing platform's Price they map to. Checkbox checks and writes every fix from the Price, and the page task names the difference; update the page and setup plans, or the Price, so they agree. Absent when none. */
1757
+ plan_terms_conflicts?: Array<string>;
1339
1758
  /** Tasks per status. */
1340
1759
  counts: {
1341
1760
  /** Open tasks. */
@@ -1346,7 +1765,7 @@ export interface CompliancePlan {
1346
1765
  verifying: number;
1347
1766
  /** Tasks waiting for a human answer. */
1348
1767
  manual: number;
1349
- /** Tasks that only wait for a live observation (count as compliant). */
1768
+ /** Tasks that only wait for a live observation (count as passing the checks). */
1350
1769
  pending_live_check?: number;
1351
1770
  /** Done tasks. */
1352
1771
  done: number;
@@ -1361,13 +1780,13 @@ export interface CompliancePlan {
1361
1780
  groups: {
1362
1781
  /** Required tasks (the legal floor). */
1363
1782
  required: Array<string>;
1364
- /** Recommended suggestions (never block compliant). */
1783
+ /** Recommended suggestions (never block the checks from passing). */
1365
1784
  recommended: Array<string>;
1366
1785
  /** Extra protections (maximum only). */
1367
1786
  extra: Array<string>;
1368
1787
  };
1369
1788
  compliance: ComplianceRollup | null;
1370
- /** What the assessment rests on. Tell the human about not_observed and attested items; never call the site "compliant" without them. */
1789
+ /** What the assessment rests on. Tell the human about not_observed and attested items; never tell them the site "is compliant". */
1371
1790
  coverage: {
1372
1791
  /** Lifecycle stages Checkbox observed (signup, acknowledgment_email, reminders, cancellation, policies, billing_settings). */
1373
1792
  observed: Array<string>;
@@ -1379,11 +1798,11 @@ export interface CompliancePlan {
1379
1798
  billing_connected: boolean;
1380
1799
  };
1381
1800
  next_action: PlanNextAction;
1382
- /** Evidence level per required email kind. A plan is never compliant on template_checked emails. */
1801
+ /** Evidence level per required email kind. A plan never reaches status compliant on template_checked emails. */
1383
1802
  email_verification: Array<{
1384
1803
  /** Email kind (acknowledgment, trial_ending, renewal_reminder, annual_terms, charge_notice, price_change, cancellation_confirmation). */
1385
1804
  kind: string;
1386
- /** not_seen, template_checked (template or sample only: never counted as compliant) or delivery_seen (sent for a real event). */
1805
+ /** not_seen, template_checked (template or sample only: never counted as passing) or delivery_seen (sent for a real event). */
1387
1806
  verification_level: "not_seen" | "template_checked" | "delivery_seen";
1388
1807
  /** Why this level, in plain words. */
1389
1808
  reason: string;
@@ -1398,15 +1817,16 @@ export interface CompliancePlan {
1398
1817
  disclaimer: string;
1399
1818
  /** When the plan was computed. Unix timestamp in seconds. */
1400
1819
  generated: number;
1820
+ unverified_scan?: UnverifiedScan;
1401
1821
  /** Optional improvements beyond compliance. Never tasks, never blocking, never counted toward compliance. */
1402
1822
  optional_improvements?: {
1403
- /** Compliant conversion suggestions for this site. */
1823
+ /** Conversion suggestions for this site that keep the checks passing. */
1404
1824
  conversion_suggestions: {
1405
1825
  /** What they are. */
1406
1826
  description: string;
1407
1827
  /** Always false. */
1408
1828
  blocking: false;
1409
- /** Always false: they never change status, score or tasks. */
1829
+ /** Always false: they never change the status or the tasks. */
1410
1830
  counts_toward_compliance: false;
1411
1831
  /** Operation that lists them. */
1412
1832
  operation_id: string;
@@ -1418,11 +1838,16 @@ export interface CompliancePlan {
1418
1838
  };
1419
1839
  }
1420
1840
  export interface UpdateTaskParams {
1421
- /** in_progress claims the task (other agents see it), wont_fix declines it (needs reason; a declined critical/high task keeps the plan from being compliant), not_applicable records that the task does not apply to this business (needs reason, e.g. "no price changes are planned"; the task closes as no_longer_applicable and does not block the plan), open clears any of them. */
1841
+ /** in_progress claims the task (other agents see it), wont_fix declines it (needs reason; a declined critical/high task keeps the plan from reaching status compliant), not_applicable records that the task does not apply to this business (needs reason, e.g. "no price changes are planned"; the task closes as no_longer_applicable and does not block the plan), open clears any of them. */
1422
1842
  status: "open" | "in_progress" | "wont_fix" | "not_applicable";
1423
1843
  /** Why (required for wont_fix). */
1424
1844
  reason?: string;
1425
1845
  }
1846
+ /** The task after answerTask, with the confirmation link at the top level when the human must confirm. */
1847
+ export type AnsweredTask = Task & {
1848
+ /** When the answer waits for the human: the link they open (signed in to Checkbox) to confirm it. Same as answer.pending_confirmation_url; null when nothing waits for confirmation. */
1849
+ confirmation_url: string | null;
1850
+ };
1426
1851
  export interface AnswerTaskParams {
1427
1852
  /** One of the task's question.options (yes / no, or confirmed / needs_change). */
1428
1853
  answer: string;
@@ -1456,13 +1881,17 @@ export interface Verification {
1456
1881
  task: string | null;
1457
1882
  /** One task or the whole site. */
1458
1883
  scope: "task" | "site";
1459
- /** pending (waiting for the confirming scan / re-evaluation), passed (Checkbox observed the expected result), passed_with_gaps (nothing observed fails, but some checks could not be observed: observed missing_data — not verified), failed (it did not: see diff). */
1460
- status: "pending" | "passed" | "passed_with_gaps" | "failed";
1884
+ /** pending (waiting for the confirming scan / re-evaluation), passed (Checkbox observed the expected result: every check passes or does not apply), passed_with_gaps (nothing observed fails, but some checks could not be observed: observed missing_data — not verified), passed_with_notes (nothing observed fails and the task counts as passing, but a check is still needs_review on a part that is not yours to change, such as Stripe's own page layout: see checks), not_checked (a task whose checks could only not be observed yet: nothing to change in the code; next_action says what evidence to provide), pending_live_check (an email whose content passes but that Checkbox has not seen sent for a real event yet: nothing to change; it completes on the first real send or a proof run), failed (it did not: see diff). */
1885
+ status: "pending" | "passed" | "passed_with_gaps" | "passed_with_notes" | "not_checked" | "pending_live_check" | "failed";
1461
1886
  /** How it was re-checked. */
1462
1887
  method: "page_fetch" | "policy_refetch" | "stripe_params" | "email_copy" | "platform_sync" | "attestation" | "evaluation" | "test_run";
1888
+ /** What this verification checked, in words: "the params you sent", "Checkout Sessions read from Stripe", "registered configs", "the HTML you sent", "the email copy you sent (plan …)", "the live page …, fetched now"… */
1889
+ checked: string;
1463
1890
  /** The fast pre-check run immediately (seconds). A failing pre-check fails the verification at once. */
1464
1891
  precheck: {
1465
- /** static_fetch, html, stripe_params, email or policy_fetch. */
1892
+ /** What the pre-check judged (as `checked`). */
1893
+ checked: string;
1894
+ /** static_fetch, html, stripe_params, email, policy_fetch, or billing_sync (Stripe was re-read before judging; its verdict is always needs_review and only carries the note: the re-evaluation decides). */
1466
1895
  source: string;
1467
1896
  /** Pre-check verdict for the task's checks. */
1468
1897
  verdict: "pass" | "fail" | "needs_review";
@@ -1470,6 +1899,26 @@ export interface Verification {
1470
1899
  url: string | null;
1471
1900
  /** What the pre-check can and cannot confirm. */
1472
1901
  note: string;
1902
+ /** Email tasks on a site with several plans: each plan's copy result. A later verification only replaces the result of the plan it judged. */
1903
+ plans?: Array<{
1904
+ /** The plan, by name. */
1905
+ plan: string;
1906
+ /** That plan's copy: pass, fail, needs_review, or not_checked (no copy for this plan was verified yet). */
1907
+ verdict: "pass" | "fail" | "needs_review" | "not_checked";
1908
+ /** When that plan's copy was checked. Unix timestamp in seconds. */
1909
+ checked_at: number | null;
1910
+ }>;
1911
+ /** Each pre-checked check of the task, compact (empty when the pre-check ran no engine check). */
1912
+ checks: Array<{
1913
+ /** Check id. */
1914
+ check_id: string;
1915
+ /** Pre-check result: pass, fail, needs_review or not_applicable. */
1916
+ status: string;
1917
+ /** What the pre-check found, in one line. */
1918
+ reason: string;
1919
+ /** How to fix it, in one line (absent when it passes). */
1920
+ fix?: string;
1921
+ }>;
1473
1922
  } | null;
1474
1923
  /** Confirming scan queued by the verification. */
1475
1924
  scan: string | null;
@@ -1479,6 +1928,8 @@ export interface Verification {
1479
1928
  diff: Array<VerificationCheck>;
1480
1929
  /** Plan status after this verification (null while pending). */
1481
1930
  plan_status: "action_required" | "verifying" | "compliant" | "blocked" | null;
1931
+ /** The plan status in words to show a person: action_required "Fixes needed", verifying "Checking your changes", compliant "Checks pass", blocked "Your call". Show this, never the machine value (`compliant` is a status name, not a legal conclusion). */
1932
+ plan_status_label?: string | null;
1482
1933
  next_action: PlanNextAction;
1483
1934
  /** When it was requested. Unix timestamp in seconds. */
1484
1935
  created: number;
@@ -1490,11 +1941,11 @@ export interface Verification {
1490
1941
  export interface VerifyTaskParams {
1491
1942
  /** page_fetch tasks: the rendered page HTML before you deploy, at most ~900 KB (request bodies are limited to 1 MB). Pre-check only; the confirming scan runs on the live page. */
1492
1943
  html?: string;
1493
- /** stripe_params tasks: exactly what your code now passes to stripe.checkout.sessions.create. */
1944
+ /** stripe_params tasks and the sign-up tasks (signup_disclosure): exactly what your code now passes to stripe.checkout.sessions.create. Judged together with the page (any failing check fails the verification). A task that does not use it refuses it (parameter_invalid, naming the task that takes it). */
1494
1945
  stripe_checkout_session?: Record<string, unknown>;
1495
1946
  /** stripe_params tasks with several Checkout code paths (one per plan, e.g. monthly and annual-with-trial): every params object your code passes to stripe.checkout.sessions.create. The pre-check fails when any of them fails. Without either field, every registered config (newest per name) is checked. */
1496
1947
  stripe_checkout_sessions?: Array<Record<string, unknown>>;
1497
- /** email_copy tasks: the new email template (pre-check; the real email confirms). */
1948
+ /** email_copy tasks: the new email template (pre-check; the real email confirms). On a site with several plans it is checked against every plan and passes when it matches one plan fully (pass plan or price_id to check one plan). */
1498
1949
  email?: {
1499
1950
  /** Email kind (default: from the task). */
1500
1951
  kind?: "acknowledgment" | "trial_reminder" | "renewal_reminder" | "price_change" | "annual_terms" | "charge_notice" | "cancellation_confirmation";
@@ -1505,6 +1956,10 @@ export interface VerifyTaskParams {
1505
1956
  /** HTML body. */
1506
1957
  html?: string;
1507
1958
  };
1959
+ /** email_copy tasks: check the email against this plan only (its name, e.g. "Annual"). */
1960
+ plan?: string;
1961
+ /** email_copy tasks: check the email against the plan with this Stripe Price id only. */
1962
+ price_id?: string;
1508
1963
  /** Re-check a task that is already done (or declined) instead of returning its last result: Checkbox evaluates the site again now and queues a confirming scan, so a regression shows up (pilot: a cancel page switched to phone-only stayed "passed"). */
1509
1964
  recheck?: boolean;
1510
1965
  }
@@ -1571,6 +2026,7 @@ export interface Fix {
1571
2026
  /** Why parts of the fix could not be generated (e.g. plan terms unknown). */
1572
2027
  problems: Array<string>;
1573
2028
  remediation: Remediation;
2029
+ next_action: NextAction | null;
1574
2030
  }
1575
2031
  /** A page of fix plans. */
1576
2032
  export interface FixList {
@@ -1583,6 +2039,38 @@ export interface FixList {
1583
2039
  /** The URL of this list. */
1584
2040
  url: string;
1585
2041
  }
2042
+ /** The verified renewal terms published to the Checkbox Shopify app block (an app-owned metafield; nothing else in the store changes). */
2043
+ export interface ShopifyTermsPublication {
2044
+ /** Id of the recorded fix application (the evidence trail of this publish). */
2045
+ id: string;
2046
+ /** String representing the object's type. Always "shopify_terms_publication". */
2047
+ object: "shopify_terms_publication";
2048
+ /** true for live-mode objects, false for test mode (ck_test_ keys act on an isolated sandbox). */
2049
+ livemode: boolean;
2050
+ /** The site. */
2051
+ site: string;
2052
+ /** The Shopify store (myshopify.com domain) the text was published to. */
2053
+ shop: string;
2054
+ /** The renewal disclosure the "Renewal terms + consent" block now shows (engine-verified). */
2055
+ disclosure: string;
2056
+ /** Label of the unchecked, required consent checkbox the block shows. */
2057
+ consent_label: string;
2058
+ /** sha256 of the published texts (disclosure + newline + consent label). */
2059
+ sha256: string;
2060
+ /** Sign-up checks the published text was verified against. */
2061
+ check_ids: Array<string>;
2062
+ /** When the text was published. Unix timestamp in seconds. */
2063
+ published: number;
2064
+ /** Theme editor link that adds the "Renewal terms + consent" block to the product page. The merchant opens it once and clicks Save (Checkbox never edits the theme). */
2065
+ theme_editor_url: string;
2066
+ next_action: NextAction;
2067
+ }
2068
+ export interface PublishShopifyTermsParams {
2069
+ /** Billing-platform plan / price id to write the terms for (default: the plan Checkbox resolved for the site). */
2070
+ plan?: string;
2071
+ /** Cancellation URL to state (default: the hosted cancellation page or the declared account page). */
2072
+ cancel_url?: string;
2073
+ }
1586
2074
  /** A record in the tamper-evident evidence vault. */
1587
2075
  export interface Evidence {
1588
2076
  /** Unique identifier of the evidence (ev_…). */
@@ -1721,7 +2209,7 @@ export interface NoticeSettings {
1721
2209
  subscribers: {
1722
2210
  /** Active subscriptions Checkbox knows from the billing platform. */
1723
2211
  active: number;
1724
- /** Of those, how many have a known email address (Checkbox can only send to these). */
2212
+ /** Of those, how many Checkbox can email: an address on file, or a Stripe customer whose address it reads when sending. */
1725
2213
  with_email: number;
1726
2214
  } | null;
1727
2215
  /** Confirmed cancellation policy (required before notices go out). */
@@ -1767,8 +2255,12 @@ export interface NoticeSettings {
1767
2255
  export interface UpdateNoticeSettingsParams {
1768
2256
  /** merchant: you send the emails (Checkbox tracks them); checkbox: Checkbox sends them. Turning an enabled_kinds notice on implies checkbox. */
1769
2257
  mode?: "merchant" | "checkbox";
1770
- /** Notices to send (turning one on needs cancel_url, a confirmed policy and a connected Stripe/Recharge account). trial_reminder is accepted as an alias of trial_ending. */
2258
+ /** The full list of notices Checkbox sends: replaces the current list, so a kind left out is turned off. To turn one on or off without touching the others, use add_kinds / remove_kinds. Turning one on needs cancel_url, a confirmed policy and a connected Stripe, Recharge, Chargebee, Recurly or Paddle account. trial_reminder is accepted as an alias of trial_ending. */
1771
2259
  enabled_kinds?: Array<"acknowledgment" | "trial_ending" | "renewal_reminder" | "annual_terms" | "price_change" | "cancellation_confirmation" | "charge_notice" | "trial_reminder">;
2260
+ /** Notices to turn on, added to the ones already on (the others stay as they are). Same prerequisites as enabled_kinds. */
2261
+ add_kinds?: Array<"acknowledgment" | "trial_ending" | "renewal_reminder" | "annual_terms" | "price_change" | "cancellation_confirmation" | "charge_notice" | "trial_reminder">;
2262
+ /** Notices to turn off; the others stay as they are. */
2263
+ remove_kinds?: Array<"acknowledgment" | "trial_ending" | "renewal_reminder" | "annual_terms" | "price_change" | "cancellation_confirmation" | "charge_notice" | "trial_reminder">;
1772
2264
  /** Brand name. */
1773
2265
  brand_name?: string | null;
1774
2266
  /** Product name. */
@@ -1897,9 +2389,9 @@ export interface DueNoticeList {
1897
2389
  export interface NoticeTemplate {
1898
2390
  /** Template id (`<variant>.v1`); due notices name the one they were rendered from. */
1899
2391
  id: string;
1900
- /** Notice kind. */
1901
- kind: "acknowledgment" | "trial_ending" | "renewal_reminder" | "annual_terms" | "price_change" | "cancellation_confirmation";
1902
- /** Variant within the kind (acknowledgment vs acknowledgment_trial, cancellation_confirmation vs _immediate). */
2392
+ /** Notice kind (charge_notice: sent by you with each renewal charge; Checkbox does not schedule it). */
2393
+ kind: "acknowledgment" | "trial_ending" | "renewal_reminder" | "annual_terms" | "price_change" | "cancellation_confirmation" | "charge_notice";
2394
+ /** Variant within the kind (acknowledgment vs acknowledgment_trial, cancellation_confirmation vs _immediate, charge_notice_upcoming before a charge vs charge_notice after it). */
1903
2395
  variant: string;
1904
2396
  /** Human label. */
1905
2397
  label: string;
@@ -1917,7 +2409,7 @@ export interface NoticeTemplate {
1917
2409
  merge_fields: Array<string>;
1918
2410
  /** The kind to pass to checkEmail (/v1/checks/email) for this template. */
1919
2411
  check_kind: string;
1920
- /** BCC address for this kind (when ?site= is given). */
2412
+ /** BCC address for this kind (when ?site= is given): the same address the plan's email task gives. A copy sent to it with the subscriber in To also confirms that subscriber's due notice of this kind. */
1921
2413
  bcc?: string;
1922
2414
  }
1923
2415
  /** Copy-ready templates for every required notice. */
@@ -1943,7 +2435,7 @@ export interface NoticeTemplateCheck {
1943
2435
  /** Always "notice_template_check". */
1944
2436
  object: "notice_template_check";
1945
2437
  /** Notice kind checked. */
1946
- kind: "acknowledgment" | "trial_ending" | "renewal_reminder" | "annual_terms" | "price_change" | "cancellation_confirmation";
2438
+ kind: "acknowledgment" | "trial_ending" | "renewal_reminder" | "annual_terms" | "price_change" | "cancellation_confirmation" | "charge_notice";
1947
2439
  /** pass, fail or needs_review. */
1948
2440
  verdict: string;
1949
2441
  /** Verdict per engine check. */
@@ -1980,7 +2472,7 @@ export interface CheckNoticeTemplateParams {
1980
2472
  /** Site whose plan, brand, cancel URL and jurisdictions fill the merge fields and scope the check. */
1981
2473
  site: string;
1982
2474
  /** Which notice the template is for. */
1983
- kind: "acknowledgment" | "trial_ending" | "renewal_reminder" | "annual_terms" | "price_change" | "cancellation_confirmation";
2475
+ kind: "acknowledgment" | "trial_ending" | "renewal_reminder" | "annual_terms" | "price_change" | "cancellation_confirmation" | "charge_notice";
1984
2476
  /** Your subject (merge fields allowed). */
1985
2477
  subject: string;
1986
2478
  /** Your plain-text body (merge fields allowed). */
@@ -2025,10 +2517,6 @@ export interface LawSiteImpact {
2025
2517
  site: string;
2026
2518
  /** What changed for the site. */
2027
2519
  summary: string;
2028
- /** Score before the change (0-100, one decimal place). */
2029
- score_before: number | null;
2030
- /** Score after re-evaluation (0-100, one decimal place). */
2031
- score_after: number | null;
2032
2520
  /** Checks whose result changed or that the change touches. */
2033
2521
  affected_checks: Array<{
2034
2522
  /** Check id. */
@@ -2113,7 +2601,7 @@ export interface CheckVerdict {
2113
2601
  /** Page checks on static HTML: the engine status on the estimated layout. */
2114
2602
  static_estimate?: "pass" | "fail" | "needs_review" | "not_applicable";
2115
2603
  evidence: VerdictEvidence;
2116
- /** User-facing status. needs_fix (a clear violation: `compliance.fix` is the one change), pending_live_check (everything Checkbox can see is right; the live event has not been observed yet — counts as compliant), verified_live (observed live: proof run, real BCC'd send, Stripe-confirmed cancellation), your_call (a real decision for a person: `compliance.question`), compliant (passes; grey areas carry a `compliance.note`), not_applicable, not_set_up (no sign the email or setting exists yet: `compliance.fix` is the one-click way to set it up; never counts as compliant), not_checked (Checkbox has not tried it yet, e.g. the cancel flow: `compliance.fix` says how; never counts as compliant). */
2604
+ /** User-facing status. needs_fix (a requirement is clearly not met: `compliance.fix` is the one change), pending_live_check (everything Checkbox can see is right; the live event has not been observed yet — counts as passing the checks), verified_live (observed live: proof run, real BCC'd send, Stripe-confirmed cancellation), your_call (a real decision for a person: `compliance.question`), compliant (passes; grey areas carry a `compliance.note`), not_applicable, not_set_up (no sign the email or setting exists yet: `compliance.fix` is the one-click way to set it up; never counts as passing the checks), not_checked (Checkbox has not tried it yet, e.g. the cancel flow: `compliance.fix` says how; never counts as passing the checks). */
2117
2605
  compliance_status: "needs_fix" | "pending_live_check" | "verified_live" | "your_call" | "compliant" | "not_applicable" | "not_set_up" | "not_checked";
2118
2606
  compliance: ComplianceInfo;
2119
2607
  }
@@ -2133,16 +2621,22 @@ export interface CheckWarning {
2133
2621
  /** Related parameter. */
2134
2622
  param?: string;
2135
2623
  }
2136
- /** A compliant replacement, verified by the engine. */
2624
+ /** A suggested replacement that passes the checks, verified by the engine. */
2137
2625
  export interface CheckReplacement {
2138
- /** Compliant disclosure generated from the plan terms (locked wording). */
2626
+ /** Disclosure generated from the plan terms that passes the checks (locked wording). */
2139
2627
  disclosure_text: string;
2140
2628
  /** Label for the unchecked, required consent checkbox. */
2141
2629
  consent_label: string;
2142
2630
  /** Purchase button label that itself states the renewal. */
2143
2631
  button_text: string;
2144
- /** Drop-in markup: disclosure (set off in a box) + unchecked required checkbox + button. */
2632
+ /** Drop-in markup: disclosure + unchecked required checkbox + button. When consent_on is set (the purchase completes on a Stripe Payment Link or Stripe Checkout), the terms only: no checkbox, no button. */
2145
2633
  html: string;
2634
+ /** Set when consent is collected on the Stripe-hosted page, not on this page: html is then the terms only. */
2635
+ consent_on?: "payment_link" | "stripe_checkout";
2636
+ /** What html contains and what is still needed elsewhere (set with consent_on). */
2637
+ note?: string;
2638
+ /** The same markup as JSX for React / Next.js components (className, htmlFor, style objects, self-closed inputs); the text is unchanged. */
2639
+ jsx?: string;
2146
2640
  /** Placeholders left to fill (e.g. {{cancel_url}}). */
2147
2641
  placeholders: Array<string>;
2148
2642
  /** The engine passes every targeted sign-up check on a page using this replacement. */
@@ -2196,17 +2690,19 @@ export interface DisclosureCheckResult {
2196
2690
  /** Not legal advice. */
2197
2691
  disclaimer: string;
2198
2692
  next_action: NextAction;
2199
- /** User-facing roll-up: needs_fix > your_call > incomplete > compliant (pending live checks count as compliant). `verdict` keeps the machine value. */
2693
+ /** User-facing roll-up: needs_fix > your_call > incomplete > compliant (every required check passes; pending live checks count as passing). `verdict` keeps the machine value. */
2200
2694
  compliance_status: "needs_fix" | "your_call" | "incomplete" | "compliant" | "not_checked";
2201
2695
  compliance: ComplianceRollup;
2202
2696
  replacement: CheckReplacement;
2203
2697
  }
2204
- /** A checkout disclosure to check before it ships. */
2698
+ /** A checkout disclosure to check before it ships. The plan fields (price, interval, cancel_url…) may also be nested under `terms` or `merchant`, as in the other checks. */
2205
2699
  export interface DisclosureCheckParams {
2206
2700
  /** The disclosure shown next to the purchase button, exactly as rendered. */
2207
2701
  text: string;
2208
2702
  /** Brand shown to subscribers; used in generated text. */
2209
2703
  merchant_name?: string;
2704
+ /** Alias of merchant_name (the {{brand_name}} merge field). Send one of the two. */
2705
+ brand_name?: string;
2210
2706
  /** Plan / product name. */
2211
2707
  plan_name?: string;
2212
2708
  /** Recurring price in major units (19.99). Or give `amount` in minor units. */
@@ -2221,6 +2717,16 @@ export interface DisclosureCheckParams {
2221
2717
  interval_count?: number;
2222
2718
  /** Free-trial length in days (0 or absent = no trial). */
2223
2719
  trial_days?: number;
2720
+ /** Intro / first-period price in major units ("$34.50 for your first box, then $69 every 2 weeks"). Or give `intro_amount` in minor units. */
2721
+ intro_price?: number | string;
2722
+ /** Intro / first-period price in minor units. */
2723
+ intro_amount?: number;
2724
+ /** How many billing periods the intro price lasts (default 1). */
2725
+ intro_periods?: number;
2726
+ /** Intro discount as a percentage off the recurring price (a Stripe coupon's percent_off: 20 for "20% off your first month"). Lasts `intro_periods` billing periods. Give one of intro_price / intro_amount, intro_percent_off or intro_amount_off. */
2727
+ intro_percent_off?: number;
2728
+ /** Intro discount as an amount off in minor units (a Stripe coupon's amount_off: 200 for $2.00 off). Lasts `intro_periods` billing periods. */
2729
+ intro_amount_off?: number;
2224
2730
  /** https URL where subscribers cancel online (used in generated text; a {{cancel_url}} placeholder otherwise). */
2225
2731
  cancel_url?: string;
2226
2732
  /** When a cancellation takes effect (default period_end). */
@@ -2315,7 +2821,7 @@ export interface StripeCheckoutSessionCheckResult {
2315
2821
  /** Not legal advice. */
2316
2822
  disclaimer: string;
2317
2823
  next_action: NextAction;
2318
- /** User-facing roll-up: needs_fix > your_call > incomplete > compliant (pending live checks count as compliant). `verdict` keeps the machine value. */
2824
+ /** User-facing roll-up: needs_fix > your_call > incomplete > compliant (every required check passes; pending live checks count as passing). `verdict` keeps the machine value. */
2319
2825
  compliance_status: "needs_fix" | "your_call" | "incomplete" | "compliant" | "not_checked";
2320
2826
  compliance: ComplianceRollup;
2321
2827
  /** The fix. */
@@ -2346,10 +2852,12 @@ export interface StripeCheckoutSessionCheckResult {
2346
2852
  placeholders: Array<string>;
2347
2853
  };
2348
2854
  }
2349
- /** What Stripe params do not say: merchant_name, cancel_url, and price / interval when line_items reference a Price id. */
2855
+ /** What Stripe params do not say: merchant_name, cancel_url, and price / interval when line_items reference a Price id. Also accepted as `terms`. Optional with `site`. */
2350
2856
  export interface CheckPlanTerms {
2351
2857
  /** Brand shown to subscribers; used in generated text. */
2352
2858
  merchant_name?: string;
2859
+ /** Alias of merchant_name (the {{brand_name}} merge field). Send one of the two. */
2860
+ brand_name?: string;
2353
2861
  /** Plan / product name. */
2354
2862
  plan_name?: string;
2355
2863
  /** Recurring price in major units (19.99). Or give `amount` in minor units. */
@@ -2364,6 +2872,16 @@ export interface CheckPlanTerms {
2364
2872
  interval_count?: number;
2365
2873
  /** Free-trial length in days (0 or absent = no trial). */
2366
2874
  trial_days?: number;
2875
+ /** Intro / first-period price in major units ("$34.50 for your first box, then $69 every 2 weeks"). Or give `intro_amount` in minor units. */
2876
+ intro_price?: number | string;
2877
+ /** Intro / first-period price in minor units. */
2878
+ intro_amount?: number;
2879
+ /** How many billing periods the intro price lasts (default 1). */
2880
+ intro_periods?: number;
2881
+ /** Intro discount as a percentage off the recurring price (a Stripe coupon's percent_off: 20 for "20% off your first month"). Lasts `intro_periods` billing periods. Give one of intro_price / intro_amount, intro_percent_off or intro_amount_off. */
2882
+ intro_percent_off?: number;
2883
+ /** Intro discount as an amount off in minor units (a Stripe coupon's amount_off: 200 for $2.00 off). Lasts `intro_periods` billing periods. */
2884
+ intro_amount_off?: number;
2367
2885
  /** https URL where subscribers cancel online (used in generated text; a {{cancel_url}} placeholder otherwise). */
2368
2886
  cancel_url?: string;
2369
2887
  /** When a cancellation takes effect (default period_end). */
@@ -2374,6 +2892,10 @@ export interface StripeCheckParams {
2374
2892
  /** Exactly the object your code passes to Stripe (checkout.sessions.create / paymentLinks.create), or a retrieved Payment Link. */
2375
2893
  params: Record<string, unknown>;
2376
2894
  merchant?: CheckPlanTerms;
2895
+ /** A site of yours (site_…): the params are judged as verifyTask judges them — the plan each line_items Price sells (the connected Stripe Prices win over plans typed in setup), the site's merchant name, cancellation URL and jurisdictions; merchant fields you send other than the plan's price / interval / trial are kept. Without it, the params are judged with merchant only (or the one site of the account with Stripe connected when you pass plan). "none" judges only what you send. */
2896
+ site?: string;
2897
+ /** With a site: judge the params against this plan (name or Stripe Price id) instead of the plan their Price id sells. An unknown plan is refused with the list of plans. */
2898
+ plan?: string;
2377
2899
  /** Where you sell: "all" (default) or state codes ("US-CA", "CA", "US-NY"; "US-FED" is always included). */
2378
2900
  jurisdictions?: "all" | Array<string>;
2379
2901
  /** Evaluate the law as of this date (YYYY-MM-DD, default today). */
@@ -2423,7 +2945,7 @@ export interface StripePaymentLinkCheckResult {
2423
2945
  /** Not legal advice. */
2424
2946
  disclaimer: string;
2425
2947
  next_action: NextAction;
2426
- /** User-facing roll-up: needs_fix > your_call > incomplete > compliant (pending live checks count as compliant). `verdict` keeps the machine value. */
2948
+ /** User-facing roll-up: needs_fix > your_call > incomplete > compliant (every required check passes; pending live checks count as passing). `verdict` keeps the machine value. */
2427
2949
  compliance_status: "needs_fix" | "your_call" | "incomplete" | "compliant" | "not_checked";
2428
2950
  compliance: ComplianceRollup;
2429
2951
  /** The fix. */
@@ -2502,20 +3024,22 @@ export interface EmailCheckResult {
2502
3024
  /** Not legal advice. */
2503
3025
  disclaimer: string;
2504
3026
  next_action: NextAction;
2505
- /** User-facing roll-up: needs_fix > your_call > incomplete > compliant (pending live checks count as compliant). `verdict` keeps the machine value. */
3027
+ /** User-facing roll-up: needs_fix > your_call > incomplete > compliant (every required check passes; pending live checks count as passing). `verdict` keeps the machine value. */
2506
3028
  compliance_status: "needs_fix" | "your_call" | "incomplete" | "compliant" | "not_checked";
2507
3029
  compliance: ComplianceRollup;
2508
3030
  /** The email kind checked. */
2509
3031
  email_kind: string;
3032
+ /** With a site: the site's plan the email was judged against. */
3033
+ plan?: string;
2510
3034
  /** Always template_checked: this checks the wording you send in, not that your system sends it. On the site, the email only counts once Checkbox sees it sent for a real event (delivery_seen: a test run, a notice for a real subscriber, or a BCC copy matching that subscriber's billing event). */
2511
3035
  verification_level: "template_checked";
2512
3036
  /** Requirements that make this email mandatory for this plan (empty: not legally required). */
2513
3037
  required_by: Array<string>;
2514
- /** A compliant template generated from the plan terms. */
3038
+ /** A template generated from the plan terms that passes the checks. */
2515
3039
  template: {
2516
- /** Compliant subject. */
3040
+ /** Subject that passes the checks. */
2517
3041
  subject: string;
2518
- /** Compliant plain-text body. */
3042
+ /** Plain-text body that passes the checks. */
2519
3043
  text: string;
2520
3044
  /** The same body as HTML. */
2521
3045
  html: string;
@@ -2539,8 +3063,8 @@ export interface EmailCheckParams {
2539
3063
  text?: string;
2540
3064
  /** HTML body. */
2541
3065
  html?: string;
2542
- /** The plan the email is about (price, interval and cancel_url at least). */
2543
- terms: CheckPlanTerms & {
3066
+ /** The plan the email is about (price, interval and cancel_url at least). Also accepted as `merchant`. Required unless a site with plan terms is used (`site`, or the one site of the account with Stripe connected): then the plan fields come from the price Stripe charges and the other fields (cancel_url, previous_price, support_contact) are kept. A price_change notice always takes the NEW price from here. */
3067
+ terms?: CheckPlanTerms & {
2544
3068
  /** price_change only: the OLD price before the change, major units. price / amount is the NEW price the email announces. */
2545
3069
  previous_price?: number | string;
2546
3070
  /** Price before a price change, minor units. */
@@ -2548,6 +3072,10 @@ export interface EmailCheckParams {
2548
3072
  /** Support email / URL shown in the generated template. */
2549
3073
  support_contact?: string;
2550
3074
  };
3075
+ /** A site of yours (site_…): the email is judged as verifyTask judges it, against the plan it names ("Annual") among the site's plans (the connected Stripe Prices win over plans typed in setup), with the site's jurisdictions. Without it, the one site of the account with Stripe connected is used when there is exactly one (the result says so in warnings, code site_from_stripe). "none" judges only the terms you send. */
3076
+ site?: string;
3077
+ /** With a site: the plan (name or Stripe Price id) the email is for, instead of the plan the email names. */
3078
+ plan?: string;
2551
3079
  /** Where you sell: "all" (default) or state codes ("US-CA", "CA", "US-NY"; "US-FED" is always included). */
2552
3080
  jurisdictions?: "all" | Array<string>;
2553
3081
  /** Evaluate the law as of this date (YYYY-MM-DD, default today). */
@@ -2597,7 +3125,7 @@ export interface PageCheckResult {
2597
3125
  /** Not legal advice. */
2598
3126
  disclaimer: string;
2599
3127
  next_action: NextAction;
2600
- /** User-facing roll-up: needs_fix > your_call > incomplete > compliant (pending live checks count as compliant). `verdict` keeps the machine value. */
3128
+ /** User-facing roll-up: needs_fix > your_call > incomplete > compliant (every required check passes; pending live checks count as passing). `verdict` keeps the machine value. */
2601
3129
  compliance_status: "needs_fix" | "your_call" | "incomplete" | "compliant" | "not_checked";
2602
3130
  compliance: ComplianceRollup;
2603
3131
  /** Whether html was given or fetched from url. */
@@ -2606,8 +3134,8 @@ export interface PageCheckResult {
2606
3134
  extraction: {
2607
3135
  /** How the page was read. */
2608
3136
  mode: "static_html";
2609
- /** Page URL used. */
2610
- url: string;
3137
+ /** Page URL used (null when only html was sent: the page is built from the HTML you sent). */
3138
+ url: string | null;
2611
3139
  /** Purchase buttons found (primary first). */
2612
3140
  purchase_buttons: Array<string>;
2613
3141
  /** Text blocks that read like subscription terms. */
@@ -2632,6 +3160,11 @@ export interface PageCheckResult {
2632
3160
  limitations: Array<string>;
2633
3161
  };
2634
3162
  replacement?: CheckReplacement;
3163
+ /** With two or more plans: one verified replacement per plan, for that plan's own purchase button (never another plan's). */
3164
+ plan_replacements?: Array<CheckReplacement & {
3165
+ /** The plan this replacement is for (name, price, interval, trial). */
3166
+ plan: string;
3167
+ }>;
2635
3168
  }
2636
3169
  /** A checkout page to check. */
2637
3170
  export interface PageCheckParams {
@@ -2642,6 +3175,15 @@ export interface PageCheckParams {
2642
3175
  /** What the page is (default checkout). */
2643
3176
  page_kind?: "checkout" | "pricing";
2644
3177
  terms?: CheckPlanTerms;
3178
+ /** Every plan a multi-plan pricing page sells (price or amount, interval, trial_days each; the same plan fields as setup plans[] in updateSetupSession). Each plan card / button is judged against its own plan; only a price no listed plan charges is a mismatch. Without it, one plan's `terms` leaves other plan cards' prices at needs_review (warning plans_partial). */
3179
+ plans?: Array<CheckPlanTerms & {
3180
+ /** Plan name, as in setup plans[] (updateSetupSession; alias of plan_name). */
3181
+ name?: string;
3182
+ }>;
3183
+ /** Where the shopper pays: own_page (a form on this page), stripe_checkout or payment_link (a Stripe-hosted page that collects consent, so no checkbox is needed here). Inferred from a purchase link to buy.stripe.com / checkout.stripe.com when absent. */
3184
+ checkout_type?: "own_page" | "stripe_checkout" | "payment_link";
3185
+ /** A site of yours (site_…): the page is judged exactly as verifyTask judges it — against the site's plans (the connected Stripe Prices win over plans typed in setup), its jurisdictions and its checkout type. These replace terms, plans, jurisdictions and checkout_type when the site knows them. Without it, the one site of the account with Stripe connected gives the plans when there is exactly one (warning site_from_stripe says so). "none" judges only what you send. */
3186
+ site?: string;
2645
3187
  /** Where you sell: "all" (default) or state codes ("US-CA", "CA", "US-NY"; "US-FED" is always included). */
2646
3188
  jurisdictions?: "all" | Array<string>;
2647
3189
  /** Evaluate the law as of this date (YYYY-MM-DD, default today). */
@@ -2659,9 +3201,9 @@ export interface ScheduledNotice {
2659
3201
  send_date: string;
2660
3202
  /** Recommended send time. Unix timestamp in seconds. */
2661
3203
  send_at: number;
2662
- /** Earliest compliant send time. Unix seconds. */
3204
+ /** Earliest send time that meets the notice timing. Unix seconds. */
2663
3205
  window_opens_at: number;
2664
- /** Latest compliant send time. Unix seconds. */
3206
+ /** Latest send time that meets the notice timing. Unix seconds. */
2665
3207
  window_closes_at: number;
2666
3208
  /** Days before the event (0 = right away). */
2667
3209
  days_before: number;
@@ -2673,6 +3215,8 @@ export interface ScheduledNotice {
2673
3215
  citations: Array<string>;
2674
3216
  /** No requirement states a window; Checkbox’s default window was used. */
2675
3217
  default_window: boolean;
3218
+ /** Why the window is what it is when the states narrow it to a single day, and when to send. */
3219
+ timing_note?: string;
2676
3220
  }
2677
3221
  /** When each legally required notice must be sent. */
2678
3222
  export interface NoticeScheduleResult {
@@ -2686,8 +3230,14 @@ export interface NoticeScheduleResult {
2686
3230
  created: number;
2687
3231
  /** Sign-up date planned for. */
2688
3232
  start_date: string;
3233
+ /** With a site: the site's plan the notices were scheduled for. */
3234
+ plan?: string;
2689
3235
  /** Every legally required notice, in send order. */
2690
3236
  notices: Array<ScheduledNotice>;
3237
+ /** Notes about the input (e.g. an amount that looks like the wrong unit). */
3238
+ warnings?: Array<CheckWarning>;
3239
+ /** How days before are counted when Checkbox judges a send (the email checks, test runs and Notices use the same rule). */
3240
+ rounding_rule: string;
2691
3241
  /** Notice kinds no applicable requirement demands for this plan. */
2692
3242
  not_required: Array<{
2693
3243
  /** Notice kind. */
@@ -2711,7 +3261,11 @@ export interface NoticeScheduleResult {
2711
3261
  }
2712
3262
  /** A subscription to plan the legally required notices for. */
2713
3263
  export interface NoticeScheduleParams {
2714
- terms: CheckPlanTerms;
3264
+ terms?: CheckPlanTerms;
3265
+ /** A site of yours (site_…): the plan's terms (Stripe Prices win over plans typed in setup) and jurisdictions come from the site. With several plans, name one with plan (or send terms). */
3266
+ site?: string;
3267
+ /** With a site: the plan (name or Stripe Price id) to schedule the notices for. An unknown plan is refused with the list of plans. */
3268
+ plan?: string;
2715
3269
  /** Sign-up date of the subscription to plan for (default today). */
2716
3270
  start_date?: string;
2717
3271
  /** A planned price change to schedule the notice for. */
@@ -2746,7 +3300,7 @@ export interface SuggestionGuardrail {
2746
3300
  /** Catalog requirement ids the rule comes from. */
2747
3301
  requirement_ids: Array<string>;
2748
3302
  }
2749
- /** One optional, compliant conversion suggestion. */
3303
+ /** One optional conversion suggestion that keeps the checks passing. */
2750
3304
  export interface Suggestion {
2751
3305
  /** Stable id of the suggestion in Checkbox’s library. */
2752
3306
  key: string;
@@ -2768,6 +3322,8 @@ export interface Suggestion {
2768
3322
  label: string;
2769
3323
  /** Your current copy (or a typical example). */
2770
3324
  text: string;
3325
+ /** your_copy: the text is your own copy (captured by Checkbox or sent by you); example: typical copy, not yours (label it “Example”). */
3326
+ source: "your_copy" | "example";
2771
3327
  };
2772
3328
  /** After. */
2773
3329
  after: {
@@ -2803,7 +3359,7 @@ export interface Suggestion {
2803
3359
  verified: boolean;
2804
3360
  /** Checks that did not pass (empty when verified). */
2805
3361
  open_checks: Array<string>;
2806
- /** The after-example's status roll-up (the same labels as compliance on sites and check results): compliant for every offered suggestion. */
3362
+ /** The after-example's status roll-up (the same labels as compliance on sites and check results): compliant (checks pass) for every offered suggestion. */
2807
3363
  compliance_status: "needs_fix" | "your_call" | "incomplete" | "compliant" | "not_checked";
2808
3364
  /** Its label. */
2809
3365
  compliance_label: string;
@@ -2815,7 +3371,7 @@ export interface Suggestion {
2815
3371
  /** Placeholders you must fill (e.g. {{cancel_url}}). */
2816
3372
  placeholders: Array<string>;
2817
3373
  }
2818
- /** Optional, compliant conversion suggestions for a checkout, Stripe Checkout, lifecycle emails and the cancellation flow. Never a compliance task. */
3374
+ /** Optional conversion suggestions that keep the checks passing, for a checkout, Stripe Checkout, lifecycle emails and the cancellation flow. Never a compliance task. */
2819
3375
  export interface SuggestionReport {
2820
3376
  /** Id of this report (sugr_…). Reports are computed on request and not stored. */
2821
3377
  id: string;
@@ -2829,7 +3385,7 @@ export interface SuggestionReport {
2829
3385
  site: string | null;
2830
3386
  /** Always true: suggestions are optional and never block anything. */
2831
3387
  optional: true;
2832
- /** Always false: suggestions never count for or against compliance, the score or the plan status. */
3388
+ /** Always false: suggestions never count for or against compliance or the plan status. */
2833
3389
  counts_toward_compliance: false;
2834
3390
  /** One paragraph for an LLM or a human. */
2835
3391
  summary: string;
@@ -2853,7 +3409,7 @@ export interface SuggestionReport {
2853
3409
  observed: boolean;
2854
3410
  /** Failing checks that hold it. */
2855
3411
  held_by: Array<string>;
2856
- /** The status label of those checks ("Needs a fix"), or null. */
3412
+ /** The status label of those checks ("1 fix needed", "2 fixes needed"), or null. */
2857
3413
  held_label: string | null;
2858
3414
  /** Suggestions offered for it. */
2859
3415
  offered: number;
@@ -2881,6 +3437,8 @@ export interface SuggestionReport {
2881
3437
  operation_id?: string;
2882
3438
  /** The MCP tool for operation_id. */
2883
3439
  mcp_tool?: string;
3440
+ /** The HTTP method and path of operation_id. */
3441
+ endpoint?: string;
2884
3442
  };
2885
3443
  /** Not legal advice; optional; results vary. */
2886
3444
  disclaimer: string;
@@ -2890,8 +3448,8 @@ export interface SuggestionsParams {
2890
3448
  terms?: CheckPlanTerms;
2891
3449
  /** Other plans you sell (enables “point to a cheaper plan” and plan-choice suggestions). */
2892
3450
  other_plans?: Array<CheckPlanTerms & {
2893
- /** Plan name shown to subscribers. */
2894
- name: string;
3451
+ /** Plan name shown to subscribers (or give plan_name, as in the checks). */
3452
+ name?: string;
2895
3453
  }>;
2896
3454
  /** Where you sell: "all" (default) or state codes ("US-CA", "CA", "US-NY"; "US-FED" is always included). */
2897
3455
  jurisdictions?: "all" | Array<string>;
@@ -2979,6 +3537,10 @@ export interface SuggestionsParams {
2979
3537
  trial_reminders?: boolean;
2980
3538
  /** Your site’s base URL (used in example links). */
2981
3539
  site_url?: string;
3540
+ /** Where subscribers manage their subscription (restart and switch-plan links; never the cancel step). Default: derived from terms.cancel_url. */
3541
+ account_url?: string;
3542
+ /** You ship physical goods (boxes, deliveries): examples talk about the next box instead of access. Default: inferred from your plan names and copy. */
3543
+ sells_goods?: boolean;
2982
3544
  }
2983
3545
  export interface ElementsRelease {
2984
3546
  /** Semver of the bundle. */
@@ -3066,6 +3628,12 @@ export interface DisclosureTerms {
3066
3628
  interval_count?: number;
3067
3629
  /** Free-trial length in days (0 or absent: no trial). */
3068
3630
  trial_days?: number;
3631
+ /** Intro / first-period charge in minor units, stated before the regular price ("$34.50 for your first 2 weeks, then $69.00 every 2 weeks"). Must be below amount. */
3632
+ intro_amount?: number;
3633
+ /** How many billing periods the intro price lasts (default 1). */
3634
+ intro_periods?: number;
3635
+ /** The intro price as a percentage off amount (a coupon's percent_off), instead of intro_amount. Needs amount. */
3636
+ intro_percent_off?: number;
3069
3637
  /** https address where subscribers cancel online. */
3070
3638
  cancel_url?: string;
3071
3639
  /** When a cancellation takes effect (default period_end). */
@@ -3134,7 +3702,7 @@ export interface Consent {
3134
3702
  client_timestamp: number | null;
3135
3703
  /** On-screen measurement summary (null for server-recorded consents). */
3136
3704
  presentation: {
3137
- /** Guard-rail violations measured on screen. */
3705
+ /** Guard-rail issues measured on screen. */
3138
3706
  violations: Array<string>;
3139
3707
  /** Safe styles replaced the theme. */
3140
3708
  fallback_applied: boolean;
@@ -3225,7 +3793,7 @@ export interface ConsentPresentationInput {
3225
3793
  /** Viewport height (CSS px). */
3226
3794
  height: number;
3227
3795
  } | null;
3228
- /** Guard-rail violations the element detected. */
3796
+ /** Guard-rail issues the element detected. */
3229
3797
  violations?: Array<string>;
3230
3798
  /** The element replaced the theme with safe styles. */
3231
3799
  fallback_applied?: boolean;
@@ -3480,7 +4048,7 @@ export interface Receipt {
3480
4048
  /** When it was signed (unix seconds). */
3481
4049
  signed: number | null;
3482
4050
  };
3483
- /** When the receipt is deleted under your retention setting. Unix timestamp in seconds. */
4051
+ /** When the receipt is deleted: consent time plus your retention setting, pushed out to one year after its subscription ends when that is later (Cal. Bus. & Prof. Code § 17602(a)(6)). Unix timestamp in seconds. */
3484
4052
  retain_until: number;
3485
4053
  /** PNG of what the subscriber saw, re-rendered from the snapshot (renderReceipt, same auth). */
3486
4054
  render_url: string;
@@ -3590,7 +4158,7 @@ export interface ReceiptSettings {
3590
4158
  livemode: boolean;
3591
4159
  /** Receipts are collected. Off by default: turn on after adding the receipts paragraph to your privacy policy (browser receipts answer 403 receipts_disabled when off; Elements consents are recorded without a receipt). */
3592
4160
  enabled: boolean;
3593
- /** Days a receipt is kept (default 1461 = 4 years: the California Unfair Competition Law limitation period; pending attorney review). */
4161
+ /** Days a receipt is kept (default 1461 = 4 years: the California Unfair Competition Law limitation period; adjust to your counsel's advice). */
3594
4162
  retention_days: number;
3595
4163
  /** Last change. Unix timestamp in seconds. */
3596
4164
  updated: number | null;
@@ -3598,7 +4166,7 @@ export interface ReceiptSettings {
3598
4166
  export interface ReceiptSettingsUpdateParams {
3599
4167
  /** Turn receipt collection on or off. */
3600
4168
  enabled?: boolean;
3601
- /** Days to keep receipts (30–3653). Applies to new receipts. */
4169
+ /** Days to keep receipts (1096–3653, i.e. 3 to 10 years; California requires verification of consent to be kept at least three years, Cal. Bus. & Prof. Code § 17602(a)(6)). Applies to new receipts. */
3602
4170
  retention_days?: number;
3603
4171
  }
3604
4172
  /** A billing-platform TEST-mode key Checkbox uses for synthetic test subscriptions. Stored encrypted; never live mode. */
@@ -3662,6 +4230,10 @@ export interface StripeCheckoutConfig {
3662
4230
  params_hash: string;
3663
4231
  /** Parameters that were dropped because they are not mirrored (customer, URLs, metadata…). */
3664
4232
  ignored_params: Array<string>;
4233
+ /** What Checkbox did not store or judge (ignored_params in words), and on registration which older configs this one replaced. */
4234
+ warnings: Array<string>;
4235
+ /** Registration only: older configs with the same name, or for the same Price ids, that this one replaced (deleted). */
4236
+ replaced?: Array<string>;
3665
4237
  /** Up to 20 key/value string pairs you can attach to the object. */
3666
4238
  metadata: Record<string, string>;
3667
4239
  /** When the config was registered. Unix timestamp in seconds. */
@@ -3693,7 +4265,7 @@ export type TestRunRemediation = {
3693
4265
  summary: string;
3694
4266
  /** Steps to fix it. */
3695
4267
  steps: Array<string>;
3696
- /** Compliant copy to use, when there is one. */
4268
+ /** Suggested copy that passes the checks, when there is one. */
3697
4269
  suggested_copy: string | null;
3698
4270
  /** Code that applies the fix, when there is one. */
3699
4271
  snippet: {
@@ -3726,8 +4298,8 @@ export interface TestRunStep {
3726
4298
  key: string;
3727
4299
  /** Human-readable step title. */
3728
4300
  title: string;
3729
- /** passed: observed, with evidence, and every judged check passed (never on an assumption); failed: a check failed or the step broke the run; warning: needs review — could not be fully observed or proven (see code and fix); skipped: not applicable or turned off. */
3730
- status: "pending" | "running" | "passed" | "failed" | "warning" | "skipped";
4301
+ /** passed: observed, with evidence, and every judged check passed (never on an assumption); failed: a check failed or the step broke the run; warning: needs review — could not be fully observed or proven (see code and fix); skipped: not applicable or turned off; info: informational only (e.g. a bare Stripe-hosted test checkout that is not your checkout): its checks are listed but not counted and need no fix. */
4302
+ status: "pending" | "running" | "passed" | "failed" | "warning" | "skipped" | "info";
3731
4303
  /** What was observed, in one or two sentences. */
3732
4304
  summary: string | null;
3733
4305
  /** When the step started. Unix timestamp in seconds. */
@@ -3770,10 +4342,29 @@ export interface TestRun {
3770
4342
  type: "stripe" | "generic";
3771
4343
  /** Stripe runs: mirror (Checkbox mirrors your checkout into test mode and moves a test clock through trial and renewal) or real_checkout (the shopper buys through YOUR checkout on your test deployment, so your own webhook handlers and email code fire: the proof that your real system works). null for generic runs. */
3772
4344
  mode: "mirror" | "real_checkout" | null;
3773
- /** succeeded means the run finished (steps may still have failing checks); failed means it stopped early (see failure). */
4345
+ /** succeeded means the run finished and no step failed (steps may still have warnings to review); failed means it stopped early, or finished with a failed step (see failure and steps[].fix). */
3774
4346
  status: "queued" | "running" | "succeeded" | "failed" | "canceled";
4347
+ /** The status in plain words, counting steps: "Finished with 6 warnings to review", "Finished with 1 failed step", "Finished: every observed step passed". succeeded with warnings is not a clean pass. */
4348
+ status_label: string;
3775
4349
  /** Internal phase (prepare, checkout, await_ack, advance, settle, cancel, await_cancel_email, finalize, done). */
3776
4350
  phase: string;
4351
+ /** While the run is queued or running: what it waits for and until when. null once it finished. */
4352
+ waiting_for: {
4353
+ /** What the run is waiting for, in plain words. */
4354
+ what: string;
4355
+ /** When the run stops waiting for it at the latest (null: unknown). Unix timestamp in seconds. */
4356
+ until: number | null;
4357
+ /** Test-clock time the run is at, or moving to (null without a test clock). Unix timestamp in seconds. */
4358
+ clock_time: number | null;
4359
+ /** The step the run is on (1-based), of steps_total steps that will run (skipped steps not counted). */
4360
+ step: number | null;
4361
+ /** Steps that will run. */
4362
+ steps_total: number | null;
4363
+ /** When the whole run is expected to be done, from typical step times (an estimate; a wait that runs long moves it later; null: none). Unix timestamp in seconds. */
4364
+ eta: number | null;
4365
+ /** Whole minutes until eta, from typical step times (null: no estimate). */
4366
+ minutes_left: number | null;
4367
+ } | null;
3777
4368
  /** Always true: runs use the billing platform's test mode; nothing is charged. */
3778
4369
  test_mode: true;
3779
4370
  /** Email address of the synthetic test subscriber; mail sent there is captured as evidence. */
@@ -3798,8 +4389,6 @@ export interface TestRun {
3798
4389
  } | null;
3799
4390
  /** Outcome of a finished run. */
3800
4391
  result: {
3801
- /** Compliance score (0-100) of the observed steps alone. */
3802
- score: number | null;
3803
4392
  /** Counts. */
3804
4393
  summary: {
3805
4394
  /** Checks that passed. */
@@ -3844,8 +4433,8 @@ export interface TestRun {
3844
4433
  subscription: string | null;
3845
4434
  /** Mirrored test-mode Checkout Session. */
3846
4435
  checkout_session: string | null;
3847
- /** Where the checkout configuration came from (mirror mode). */
3848
- mirrored_from: "registered" | "live" | "request" | "payment_link" | null;
4436
+ /** Where the checkout configuration came from (mirror mode). stripe_session: the newest Checkout Session your code created, read with a test-mode monitoring key. */
4437
+ mirrored_from: "registered" | "live" | "request" | "payment_link" | "stripe_session" | null;
3849
4438
  /** Registered config used (scc_…). */
3850
4439
  checkout_config: string | null;
3851
4440
  /** Compliance fingerprint of the mirrored checkout. */
@@ -3891,8 +4480,10 @@ export interface TestRun {
3891
4480
  cancellation: {
3892
4481
  /** Where the shopper cancelled. */
3893
4482
  via: "merchant_flow" | "stripe_portal" | "cancel_url";
3894
- /** false: nothing told Checkbox how customers cancel, so it used the Stripe portal (step warning cancel_flow_not_configured). */
4483
+ /** false: nothing told Checkbox how customers cancel, so it used the Stripe portal (step warning cancel_flow_not_configured: the cancel itself worked). true also when inferred (inferred_from). */
3895
4484
  declared_by_merchant: boolean;
4485
+ /** site_portal_link: no cancel_via was given, Stripe has cancellation on in the customer portal and your site links to it, so the portal was used as declared. registered_url: no cancel_via was given and the account or cancellation page you registered (account_url / cancellation_url) redirects or links to the Stripe customer portal, so the portal was used as declared. */
4486
+ inferred_from?: "site_portal_link" | "registered_url" | null;
3896
4487
  /** Stripe showed a subscription set to cancel after the shopper's flow. */
3897
4488
  confirmed_in_stripe: boolean;
3898
4489
  /** The subscription Stripe showed canceled. */
@@ -3965,7 +4556,7 @@ export interface Event {
3965
4556
  id: string;
3966
4557
  /** String representing the object's type. Always "event". */
3967
4558
  object: "event";
3968
- /** Event type: site.score_changed, finding.created, finding.resolved, scan.completed, scan.failed, law.changed, certificate.issued, certificate.lapsed, certificate.revoked, notice.sent, notice.due, notice.overdue, consent.created, receipt.created, test_run.completed, test_run.failed, plan.updated, site.compliant, task.verified. */
4559
+ /** Event type: site.compliance_changed, finding.created, finding.resolved, scan.completed, scan.failed, law.changed, certificate.issued, certificate.lapsed, certificate.revoked, notice.sent, notice.due, notice.overdue, consent.created, receipt.created, test_run.completed, test_run.failed, plan.updated, site.checks_passed, site.compliant (deprecated), task.verified. */
3969
4560
  type: string;
3970
4561
  /** API version used to render data.object. */
3971
4562
  api_version: string;
@@ -4008,18 +4599,32 @@ export interface Feedback {
4008
4599
  /** String representing the object's type. Always "feedback". */
4009
4600
  object: "feedback";
4010
4601
  /** Kind of feedback. */
4011
- type: "bug" | "idea" | "question";
4602
+ type: "bug" | "idea" | "question" | "review";
4012
4603
  /** open until Checkbox staff reply or close it. */
4013
4604
  status: "open" | "replied" | "closed";
4605
+ /** true when text that looked like a secret, card number or email address was replaced with [redacted] before it was stored. */
4606
+ redacted: boolean;
4014
4607
  /** When it was received. Unix timestamp in seconds. */
4015
4608
  created: number;
4016
4609
  }
4017
4610
  export interface FeedbackParams {
4018
- /** bug: something is broken; idea: a missing feature or improvement; question: something unclear. Default idea. */
4019
- type?: "bug" | "idea" | "question";
4020
- /** What you tried, what happened and what you expected (at most 5000 characters). */
4021
- message: string;
4022
- /** Optional context that helps us reproduce it. */
4611
+ /** bug: something is broken; idea: a missing feature or improvement; question: something unclear; review: a structured review of Checkbox the product (send only after the human said yes and saw the text; no site names, URLs, customer data, quotes of the site's pages or emails, or claims that the site broke a law). Default idea. */
4612
+ type?: "bug" | "idea" | "question" | "review";
4613
+ /** What you tried, what happened and what you expected (at most 5000 characters). Required except for type review. Secrets, card numbers and email addresses are replaced with [redacted]. */
4614
+ message?: string;
4615
+ /** type review (required): how likely the human is to recommend Checkbox, 0-10. */
4616
+ score?: number;
4617
+ /** type review: what worked, at most 5 short phrases. */
4618
+ liked?: Array<string>;
4619
+ /** type review: what did not work, at most 5 short phrases. */
4620
+ disliked?: Array<string>;
4621
+ /** type review: Checkbox verdicts the human believes were wrong, each "<check id>: <short reason about Checkbox's verdict>" (at most 5; the reason is kept to 200 characters). */
4622
+ wrong_verdicts?: Array<string>;
4623
+ /** type review: whether the human would keep using Checkbox. */
4624
+ would_keep_using?: boolean;
4625
+ /** type review: framework and billing, short. */
4626
+ stack?: string;
4627
+ /** Optional context that helps us reproduce it. For type review only agent and tool are kept (reviews never carry the site or request id). */
4023
4628
  context?: {
4024
4629
  /** Site id the feedback is about. */
4025
4630
  site?: string;
@@ -4031,6 +4636,25 @@ export interface FeedbackParams {
4031
4636
  agent?: string;
4032
4637
  };
4033
4638
  }
4639
+ /** The one-time prompt to ask the human for a review of the session. */
4640
+ export interface ReviewPrompt {
4641
+ /** String representing the object's type. Always "review_prompt". */
4642
+ object: "review_prompt";
4643
+ /** The site. */
4644
+ site: string;
4645
+ /** true exactly once per site, while its plan status is compliant (checks pass): ask the human once whether they want to send a review. false afterwards. */
4646
+ show: boolean;
4647
+ /** Why show is true or false. */
4648
+ reason: "first_time" | "already_shown" | "not_compliant";
4649
+ /** The instruction for the agent when show is true; null otherwise. */
4650
+ message: string | null;
4651
+ /** When the prompt was first shown for this site (null before). Unix timestamp in seconds. */
4652
+ shown_at: number | null;
4653
+ }
4654
+ export interface ReviewPromptParams {
4655
+ /** What reached "Checks pass": the plan (retrieveCompliancePlan) or the verification of the last required task (verifyTask). Default plan_compliant. */
4656
+ trigger?: "plan_compliant" | "last_task_verified";
4657
+ }
4034
4658
  /** A compliance plan without task content (webhook payload). */
4035
4659
  export interface CompliancePlanSummary {
4036
4660
  /** Unique identifier of the compliance plan (plan_…). */
@@ -4043,8 +4667,8 @@ export interface CompliancePlanSummary {
4043
4667
  site: string;
4044
4668
  /** action_required (an agent can apply open tasks now), verifying (changes applied; waiting for confirming observations), compliant (every required check passes or only waits for a live check — an automated assessment, not a legal determination; see compliance.pending_live_checks and coverage), blocked (only human answers ("Your call") or declined critical tasks remain). */
4045
4669
  status: "action_required" | "verifying" | "compliant" | "blocked";
4046
- /** Compliance score 0-100 of the latest evaluation. */
4047
- score: number | null;
4670
+ /** The plan status in words to show a person: action_required "Fixes needed", verifying "Checking your changes", compliant "Checks pass", blocked "Your call". Show this, never the machine value (`compliant` is a status name, not a legal conclusion). */
4671
+ status_label?: string;
4048
4672
  /** Two or three sentences for an LLM: where the site stands and what comes next. */
4049
4673
  summary: string;
4050
4674
  /** Tasks per status. */
@@ -4057,7 +4681,7 @@ export interface CompliancePlanSummary {
4057
4681
  verifying: number;
4058
4682
  /** Tasks waiting for a human answer. */
4059
4683
  manual: number;
4060
- /** Tasks that only wait for a live observation (count as compliant). */
4684
+ /** Tasks that only wait for a live observation (count as passing the checks). */
4061
4685
  pending_live_check?: number;
4062
4686
  /** Done tasks. */
4063
4687
  done: number;
@@ -4065,7 +4689,7 @@ export interface CompliancePlanSummary {
4065
4689
  wont_fix: number;
4066
4690
  };
4067
4691
  next_action: PlanNextAction;
4068
- /** What the assessment rests on. Tell the human about not_observed and attested items; never call the site "compliant" without them. */
4692
+ /** What the assessment rests on. Tell the human about not_observed and attested items; never tell them the site "is compliant". */
4069
4693
  coverage: {
4070
4694
  /** Lifecycle stages Checkbox observed (signup, acknowledgment_email, reminders, cancellation, policies, billing_settings). */
4071
4695
  observed: Array<string>;
@@ -4139,6 +4763,8 @@ export interface ListSetupSessionsParams {
4139
4763
  export interface UpdateAccountParams {
4140
4764
  /** API version to pin. */
4141
4765
  api_version?: string;
4766
+ retention?: RetentionParams;
4767
+ legal_hold?: LegalHoldParams;
4142
4768
  }
4143
4769
  /** Parameters of `sites.list()` (listSites). */
4144
4770
  export interface ListSitesParams {
@@ -4426,7 +5052,7 @@ export interface CreateTestRunParams {
4426
5052
  cancel_url?: string;
4427
5053
  /** Clicks that cancel in your flow (after login / cancel_url), e.g. [{ "action": "click", "text": "Cancel subscription" }, { "action": "click", "text": "Confirm" }]. */
4428
5054
  cancel_steps?: Array<ScanStep>;
4429
- /** How your customers cancel. Default: your flow when test_account / cancel_url / cancel_steps describe it, else the Stripe portal reported as a warning (cancel_flow_not_configured). */
5055
+ /** How your customers cancel. Default: your flow when test_account / cancel_url / cancel_steps describe it; else the Stripe portal, taken as declared when Stripe has portal cancellation on and your site links to the portal, or when the account or cancellation page you registered redirects or links to the portal; otherwise reported as a warning (cancel_flow_not_configured: the cancel worked, but how your customers cancel was not given). */
4430
5056
  cancel_via?: "merchant_flow" | "stripe_portal";
4431
5057
  /** A test account the shopper logs into: to buy as a logged-in user (real_checkout) and to cancel through your in-app flow. Mail to its address counts when you BCC the site's Checkbox address. */
4432
5058
  test_account?: {
@@ -4443,9 +5069,9 @@ export interface CreateTestRunParams {
4443
5069
  payment_link?: string;
4444
5070
  /** real_checkout: the page of your TEST deployment that leads to your Stripe test-mode checkout (a pricing page, or a route that creates the Checkout Session and redirects). */
4445
5071
  checkout_url?: string;
4446
- /** real_checkout: clicks from checkout_url to the payment page, e.g. [{ "action": "click", "text": "Start free trial" }]. */
5072
+ /** real_checkout: clicks from checkout_url to the payment page, e.g. [{ "action": "click", "text": "Start free trial" }]. In fill values, {{email}} is the run inbox and {{password}} is stripe.test_account.password when a test account is given, so an account created here can log in for the cancellation. */
4447
5073
  pre_checkout_steps?: Array<ScanStep>;
4448
- /** A page of your test deployment Checkbox opens before the checkout (after logging in) that CLEANS UP the test account (ends its subscription), so every run starts without one. Mirror mode opens it before cancelling the test account's subscription. (Round 3: renamed from reset_url, which meant the opposite of the site's test_account.reactivate_url.) */
5074
+ /** A page of your test deployment Checkbox opens before the checkout (after logging in) that CLEANS UP the test account (ends its subscription), so every run starts without one. Mirror mode opens it before cancelling the test account's subscription. */
4449
5075
  cleanup_url?: string;
4450
5076
  /** Deprecated alias of cleanup_url. */
4451
5077
  reset_url?: string;
@@ -4487,11 +5113,16 @@ export interface ListTestRunsParams {
4487
5113
  /** Cursor: an object id; returns the objects before it (newer). */
4488
5114
  ending_before?: string;
4489
5115
  }
5116
+ /** Parameters of `testRuns.retrieve()` (retrieveTestRun). */
5117
+ export interface RetrieveTestRunParams {
5118
+ /** Long-poll: wait up to this many seconds (0-30) for the run to move on (status, phase or a step changes) before answering. */
5119
+ wait?: number | null;
5120
+ }
4490
5121
  /** Parameters of `webhookEndpoints.create()` (createWebhookEndpoint). */
4491
5122
  export interface CreateWebhookEndpointParams {
4492
5123
  /** HTTPS URL. */
4493
5124
  url: string;
4494
- /** Event types to send, or ["*"] for all: site.score_changed, finding.created, finding.resolved, scan.completed, scan.failed, law.changed, certificate.issued, certificate.lapsed, certificate.revoked, notice.sent, notice.due, notice.overdue, consent.created, receipt.created, test_run.completed, test_run.failed, plan.updated, site.compliant, task.verified. */
5125
+ /** Event types to send, or ["*"] for all: site.compliance_changed, finding.created, finding.resolved, scan.completed, scan.failed, law.changed, certificate.issued, certificate.lapsed, certificate.revoked, notice.sent, notice.due, notice.overdue, consent.created, receipt.created, test_run.completed, test_run.failed, plan.updated, site.checks_passed, site.compliant (deprecated), task.verified. */
4495
5126
  enabled_events: Array<string>;
4496
5127
  /** Description. */
4497
5128
  description?: string;
@@ -4511,7 +5142,7 @@ export interface ListWebhookEndpointsParams {
4511
5142
  export interface UpdateWebhookEndpointParams {
4512
5143
  /** HTTPS URL. */
4513
5144
  url?: string;
4514
- /** Event types to send, or ["*"] for all: site.score_changed, finding.created, finding.resolved, scan.completed, scan.failed, law.changed, certificate.issued, certificate.lapsed, certificate.revoked, notice.sent, notice.due, notice.overdue, consent.created, receipt.created, test_run.completed, test_run.failed, plan.updated, site.compliant, task.verified. */
5145
+ /** Event types to send, or ["*"] for all: site.compliance_changed, finding.created, finding.resolved, scan.completed, scan.failed, law.changed, certificate.issued, certificate.lapsed, certificate.revoked, notice.sent, notice.due, notice.overdue, consent.created, receipt.created, test_run.completed, test_run.failed, plan.updated, site.checks_passed, site.compliant (deprecated), task.verified. */
4515
5146
  enabled_events?: Array<string>;
4516
5147
  /** Description (null clears it). */
4517
5148
  description?: string | null;
@@ -4543,7 +5174,7 @@ export type PlanUpdatedEvent = Event & {
4543
5174
  type?: "plan.updated";
4544
5175
  data?: {
4545
5176
  object: CompliancePlanSummary;
4546
- /** plan.updated: the previous status and score. */
5177
+ /** plan.updated: the previous status. */
4547
5178
  previous_attributes?: Record<string, unknown>;
4548
5179
  };
4549
5180
  };
@@ -4553,7 +5184,7 @@ export type TaskVerifiedEvent = Event & {
4553
5184
  type?: "task.verified";
4554
5185
  data?: {
4555
5186
  object: Verification;
4556
- /** plan.updated: the previous status and score. */
5187
+ /** plan.updated: the previous status. */
4557
5188
  previous_attributes?: Record<string, unknown>;
4558
5189
  };
4559
5190
  };
@@ -4607,10 +5238,10 @@ export type TestRunFailedEvent = Event & {
4607
5238
  previous_attributes?: Record<string, unknown>;
4608
5239
  };
4609
5240
  };
4610
- /** `site.score_changed`: A site's compliance score changed (data.previous_attributes.score has the old score). */
4611
- export type SiteScoreChangedEvent = Event & {
5241
+ /** `site.compliance_changed`: A re-evaluation changed the site's check results; data.object is the site, with its current compliance status and label in data.object.compliance. */
5242
+ export type SiteComplianceChangedEvent = Event & {
4612
5243
  /** Event type. */
4613
- type?: "site.score_changed";
5244
+ type?: "site.compliance_changed";
4614
5245
  data?: {
4615
5246
  object: Site;
4616
5247
  /** Previous values of changed fields. */
@@ -4637,7 +5268,7 @@ export type FindingResolvedEvent = Event & {
4637
5268
  previous_attributes?: Record<string, unknown>;
4638
5269
  };
4639
5270
  };
4640
- /** `scan.completed`: A scan finished (the evaluation may follow in a separate site.score_changed event). */
5271
+ /** `scan.completed`: A scan finished (the evaluation may follow in a separate site.compliance_changed event). */
4641
5272
  export type ScanCompletedEvent = Event & {
4642
5273
  /** Event type. */
4643
5274
  type?: "scan.completed";
@@ -4717,7 +5348,17 @@ export type ConsentCreatedEvent = Event & {
4717
5348
  previous_attributes?: Record<string, unknown>;
4718
5349
  };
4719
5350
  };
4720
- /** `site.compliant`: A site's compliance plan became compliant: nothing is left to apply, verify or answer; data.object is the site. */
5351
+ /** `site.checks_passed`: A site's compliance plan reached the status where its checks pass (plan status value `compliant`): nothing is left to apply, verify or answer; data.object is the site. Passing the checks is not a certification of legal compliance. */
5352
+ export type SiteChecksPassedEvent = Event & {
5353
+ /** Event type. */
5354
+ type?: "site.checks_passed";
5355
+ data?: {
5356
+ object: Site;
5357
+ /** Previous values of changed fields. */
5358
+ previous_attributes?: Record<string, unknown>;
5359
+ };
5360
+ };
5361
+ /** `site.compliant`: Deprecated alias of site.checks_passed, kept so existing endpoints keep working: sent at the same moment with the same data.object. Subscribe to site.checks_passed instead (an endpoint on "*" receives both). */
4721
5362
  export type SiteCompliantEvent = Event & {
4722
5363
  /** Event type. */
4723
5364
  type?: "site.compliant";
@@ -4728,9 +5369,9 @@ export type SiteCompliantEvent = Event & {
4728
5369
  };
4729
5370
  };
4730
5371
  /** Every event Checkbox delivers to webhook endpoints, discriminated by `type`. */
4731
- export type WebhookEvent = PlanUpdatedEvent | TaskVerifiedEvent | NoticeDueEvent | NoticeOverdueEvent | ReceiptCreatedEvent | TestRunCompletedEvent | TestRunFailedEvent | SiteScoreChangedEvent | FindingCreatedEvent | FindingResolvedEvent | ScanCompletedEvent | ScanFailedEvent | LawChangedEvent | CertificateIssuedEvent | CertificateLapsedEvent | CertificateRevokedEvent | NoticeSentEvent | ConsentCreatedEvent | SiteCompliantEvent;
5372
+ export type WebhookEvent = PlanUpdatedEvent | TaskVerifiedEvent | NoticeDueEvent | NoticeOverdueEvent | ReceiptCreatedEvent | TestRunCompletedEvent | TestRunFailedEvent | SiteComplianceChangedEvent | FindingCreatedEvent | FindingResolvedEvent | ScanCompletedEvent | ScanFailedEvent | LawChangedEvent | CertificateIssuedEvent | CertificateLapsedEvent | CertificateRevokedEvent | NoticeSentEvent | ConsentCreatedEvent | SiteChecksPassedEvent | SiteCompliantEvent;
4732
5373
  /** Every webhook event type. */
4733
- export declare const WEBHOOK_EVENT_TYPES: readonly ["plan.updated", "task.verified", "notice.due", "notice.overdue", "receipt.created", "test_run.completed", "test_run.failed", "site.score_changed", "finding.created", "finding.resolved", "scan.completed", "scan.failed", "law.changed", "certificate.issued", "certificate.lapsed", "certificate.revoked", "notice.sent", "consent.created", "site.compliant"];
5374
+ export declare const WEBHOOK_EVENT_TYPES: readonly ["plan.updated", "task.verified", "notice.due", "notice.overdue", "receipt.created", "test_run.completed", "test_run.failed", "site.compliance_changed", "finding.created", "finding.resolved", "scan.completed", "scan.failed", "law.changed", "certificate.issued", "certificate.lapsed", "certificate.revoked", "notice.sent", "consent.created", "site.checks_passed", "site.compliant"];
4734
5375
  export type WebhookEventType = (typeof WEBHOOK_EVENT_TYPES)[number];
4735
5376
  /** Stable error codes (`error.code`), with HTTP status, type and meaning. Codes are never renamed. */
4736
5377
  export declare const ERROR_CODES: {
@@ -4777,7 +5418,7 @@ export declare const ERROR_CODES: {
4777
5418
  readonly test_key_missing: {
4778
5419
  readonly status: 400;
4779
5420
  readonly type: "invalid_request_error";
4780
- readonly description: "A Stripe test run needs a Stripe TEST-mode key stored for the site (createTestCredential).";
5421
+ readonly description: "A Stripe test run needs a Stripe TEST-mode key stored for the site (a person adds it in the dashboard on the site's Proof page).";
4781
5422
  };
4782
5423
  readonly test_key_not_test_mode: {
4783
5424
  readonly status: 400;
@@ -4857,7 +5498,7 @@ export declare const ERROR_CODES: {
4857
5498
  readonly test_mode_scan_budget_exhausted: {
4858
5499
  readonly status: 429;
4859
5500
  readonly type: "rate_limit_error";
4860
- readonly description: "No longer returned (round 6): test mode has no scan budget for unverified domains any more, they are refused with test_mode_domain_unverified. Kept so older clients still recognise the code.";
5501
+ readonly description: "No longer returned: test mode has no scan budget for unverified domains any more, they are refused with test_mode_domain_unverified. Kept so older clients still recognise the code.";
4861
5502
  };
4862
5503
  readonly domain_not_verified: {
4863
5504
  readonly status: 403;
@@ -4899,16 +5540,36 @@ export declare const ERROR_CODES: {
4899
5540
  readonly type: "invalid_request_error";
4900
5541
  readonly description: "The site already has a queued or running test run; wait for it (retrieveTestRun) or cancel it (cancelTestRun).";
4901
5542
  };
5543
+ readonly legal_hold_active: {
5544
+ readonly status: 409;
5545
+ readonly type: "invalid_request_error";
5546
+ readonly description: "A legal hold is on for the account or the site: deleting data and shortening retention are refused until it is turned off (updateAccount / updateSite legal_hold).";
5547
+ };
4902
5548
  readonly idempotency_key_in_use: {
4903
5549
  readonly status: 409;
4904
5550
  readonly type: "idempotency_error";
4905
5551
  readonly description: "A request with this Idempotency-Key is still being processed; retry shortly.";
4906
5552
  };
5553
+ readonly shopify_not_connected: {
5554
+ readonly status: 409;
5555
+ readonly type: "invalid_request_error";
5556
+ readonly description: "The site's Shopify store is not connected through the Checkbox Shopify app, so Checkbox cannot publish to the app block. Only the merchant can connect it: install the Checkbox app from the Shopify admin and click \"Connect to Checkbox\" (`next_action` has the exact step).";
5557
+ };
4907
5558
  readonly resource_archived: {
4908
5559
  readonly status: 410;
4909
5560
  readonly type: "invalid_request_error";
4910
5561
  readonly description: "The object is archived; restore it before changing it.";
4911
5562
  };
5563
+ readonly terms_incomplete: {
5564
+ readonly status: 422;
5565
+ readonly type: "invalid_request_error";
5566
+ readonly description: "Checkbox cannot write the exact, verified renewal terms yet: plan facts are missing (price, interval, trial, cancellation URL or merchant name). `problems` lists them; `next_action` names the call that sets them.";
5567
+ };
5568
+ readonly fix_verification_failed: {
5569
+ readonly status: 422;
5570
+ readonly type: "invalid_request_error";
5571
+ readonly description: "The generated disclosure did not pass every sign-up check of the rules engine, so nothing was published. The message names the failing checks.";
5572
+ };
4912
5573
  readonly body_too_large: {
4913
5574
  readonly status: 413;
4914
5575
  readonly type: "invalid_request_error";
@@ -4944,6 +5605,11 @@ export declare const ERROR_CODES: {
4944
5605
  readonly type: "permission_error";
4945
5606
  readonly description: "Consent receipts are turned off for this account (updateReceiptSettings enabled=true turns them on).";
4946
5607
  };
5608
+ readonly platform_error: {
5609
+ readonly status: 502;
5610
+ readonly type: "api_error";
5611
+ readonly description: "The merchant's platform (e.g. Shopify) refused or failed the change; nothing was recorded as applied. Retry later; `message` has the platform's answer.";
5612
+ };
4947
5613
  readonly feature_unavailable: {
4948
5614
  readonly status: 503;
4949
5615
  readonly type: "api_error";