@checkbox-site/node 0.2.0 → 0.2.2

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.
package/dist/client.d.ts CHANGED
@@ -45,7 +45,7 @@ export interface Checkbox extends ResourceInstances {
45
45
  */
46
46
  export declare class Checkbox implements RequestSender {
47
47
  #private;
48
- static readonly VERSION = "0.2.0";
48
+ static readonly VERSION = "0.2.2";
49
49
  static readonly API_VERSION = "2026-10-30";
50
50
  static readonly errors: typeof errors;
51
51
  static readonly webhooks: Webhooks;
@@ -900,6 +900,23 @@ export declare class Checkbox implements RequestSender {
900
900
  readonly paginated: false;
901
901
  readonly summary: "Revoke a certificate";
902
902
  };
903
+ readonly listNoticeSends: {
904
+ readonly operationId: "listNoticeSends";
905
+ readonly namespace: "noticeSends";
906
+ readonly method: "list";
907
+ readonly httpMethod: "GET";
908
+ readonly path: "/v1/sites/{site}/notice_sends";
909
+ readonly pathParams: readonly ["site"];
910
+ readonly queryParams: readonly ["limit", "kind", "subscription", "include_samples"];
911
+ readonly body: false;
912
+ readonly idempotent: false;
913
+ readonly auth: true;
914
+ readonly scope: "notices:read";
915
+ readonly response: "json";
916
+ readonly list: true;
917
+ readonly paginated: false;
918
+ readonly summary: "List Checkbox Notices sends";
919
+ };
903
920
  readonly retrieveNoticeSettings: {
904
921
  readonly operationId: "retrieveNoticeSettings";
905
922
  readonly namespace: "noticeSettings";
@@ -852,6 +852,23 @@ export declare const OPERATIONS: {
852
852
  readonly paginated: false;
853
853
  readonly summary: "Revoke a certificate";
854
854
  };
855
+ readonly listNoticeSends: {
856
+ readonly operationId: "listNoticeSends";
857
+ readonly namespace: "noticeSends";
858
+ readonly method: "list";
859
+ readonly httpMethod: "GET";
860
+ readonly path: "/v1/sites/{site}/notice_sends";
861
+ readonly pathParams: readonly ["site"];
862
+ readonly queryParams: readonly ["limit", "kind", "subscription", "include_samples"];
863
+ readonly body: false;
864
+ readonly idempotent: false;
865
+ readonly auth: true;
866
+ readonly scope: "notices:read";
867
+ readonly response: "json";
868
+ readonly list: true;
869
+ readonly paginated: false;
870
+ readonly summary: "List Checkbox Notices sends";
871
+ };
855
872
  readonly retrieveNoticeSettings: {
856
873
  readonly operationId: "retrieveNoticeSettings";
857
874
  readonly namespace: "noticeSettings";
@@ -2150,6 +2167,12 @@ export interface OperationTypes {
2150
2167
  } & T.RevokeCertificateParams;
2151
2168
  response: T.Certificate;
2152
2169
  };
2170
+ listNoticeSends: {
2171
+ args: {
2172
+ site: string;
2173
+ } & T.ListNoticeSendsParams;
2174
+ response: T.NoticeSendList;
2175
+ };
2153
2176
  retrieveNoticeSettings: {
2154
2177
  args: {
2155
2178
  site: string;
@@ -2607,7 +2630,7 @@ export declare class SitesResource extends Resource {
2607
2630
  /**
2608
2631
  * Connect a billing platform.
2609
2632
  *
2610
- * Connects the site's billing platform with read-only credentials (a Stripe restricted key, a Recharge token, a Shopify Admin API token, a Chargebee read-only API key, a Recurly private API key or a Paddle API key with read permissions), so Checkbox reads the customer-portal and reminder settings. Works for test-mode sites too (use an rk_test_ key). The credentials are validated by reading the settings once and stored encrypted.
2633
+ * Connects the site's billing platform with the one restricted key (a Stripe restricted key, a Recharge token, a Shopify Admin API token, a Chargebee read-only API key, a Recurly private API key or a Paddle API key with read permissions), so Checkbox reads the customer-portal and reminder settings. Stripe: One Stripe restricted key per site: Read permissions for the checks, and Write permissions that Checkbox uses only after you click Approve on a fix, or in test mode (the one exception: Webhook Endpoints, used once to add Checkbox's webhook endpoint when you connect the key) (checklist: https://checkbox.site/docs/guides/stripe-key). A full secret key (sk_test_ / sk_live_) is refused on every path with test_key_not_restricted: use a restricted key. API keys and AI agents may connect TEST-mode keys (rk_test_…) only; a live key (rk_live_ / sk_live_) is refused with live_key_requires_dashboard, because only a person signed in to the Checkbox dashboard can connect one. The credentials are validated by reading the settings once and stored encrypted. When the key's Stripe account looks like another site's (the site's prices or Payment Links are not in it, or it is already connected in another workspace), nothing is connected and the error billing_account_mismatch asks the human to confirm; retry with confirm_account_mismatch: true only after they said yes; the key is then held until a person confirms the account in the dashboard (an agent cannot confirm it). The account owner is emailed about every key connected.
2611
2634
  *
2612
2635
  * @param site Unique identifier of the site (site_…).
2613
2636
  * @see POST /v1/sites/{site}/integrations (operation `connectBillingPlatform`, scope `sites:write`)
@@ -2939,6 +2962,18 @@ export declare class CertificatesResource extends Resource {
2939
2962
  */
2940
2963
  revoke(certificate: string, params: T.RevokeCertificateParams, options?: RequestOptions): Promise<T.Certificate>;
2941
2964
  }
2965
+ /** `checkbox.noticeSends` */
2966
+ export declare class NoticeSendsResource extends Resource {
2967
+ /**
2968
+ * List Checkbox Notices sends.
2969
+ *
2970
+ * Read-only: the emails Checkbox Notices sent, or tried to send, for this site (newest first), with status and, for a failed or skipped send, why. A test run's email steps name these rows (notices_send_log). Samples ("Send a test") are left out unless include_samples=true.
2971
+ *
2972
+ * @param site Unique identifier of the site (site_…).
2973
+ * @see GET /v1/sites/{site}/notice_sends (operation `listNoticeSends`, scope `notices:read`)
2974
+ */
2975
+ list(site: string, params?: T.ListNoticeSendsParams, options?: RequestOptions): Promise<T.NoticeSendList>;
2976
+ }
2942
2977
  /** `checkbox.noticeSettings` */
2943
2978
  export declare class NoticeSettingsResource extends Resource {
2944
2979
  /**
@@ -2953,7 +2988,7 @@ export declare class NoticeSettingsResource extends Resource {
2953
2988
  /**
2954
2989
  * Update notice settings.
2955
2990
  *
2956
- * Chooses who sends the required emails (mode: merchant = you send them and Checkbox tracks them, the default; checkbox = Checkbox sends them), and sets branding, cancel_url and the confirmed cancellation policy. add_kinds / remove_kinds turn single notices on or off and leave the others as they are; enabled_kinds replaces the whole list. In checkbox mode, turning a notice on requires cancel_url, a confirmed policy, a connected Stripe, Recharge, Chargebee, Recurly or Paddle account and a sending address; otherwise resource_conflict explains what is missing.
2991
+ * Chooses who sends the required emails (mode: merchant = you send them and Checkbox tracks them, the default; checkbox = Checkbox sends them), and sets branding, cancel_url and the confirmed cancellation policy. add_kinds / remove_kinds turn single notices on or off and leave the others as they are; enabled_kinds replaces the whole list. In checkbox mode, turning a notice on requires cancel_url, a confirmed policy, a support email, a connected Stripe, Recharge, Chargebee, Recurly or Paddle account and a sending address; otherwise resource_conflict explains what is missing. The support email may be the Stripe account's public one (used automatically); the account owner's login address only after the human confirms it in the dashboard (support_email_to_confirm; an agent cannot confirm it). Turning notices on through the API never emails a real subscriber: on a test-mode site only test-run inboxes (and marked test copies to the owner) are emailed, and on a live site real subscribers are emailed only after a person confirms it once in the dashboard, after a preview (real_sends). The account owner is emailed when an agent turns notices on.
2957
2992
  *
2958
2993
  * @param site Unique identifier of the site (site_…).
2959
2994
  * @see POST /v1/sites/{site}/notice_settings (operation `updateNoticeSettings`, scope `notices:write`, live mode needs an activated account)
@@ -2965,7 +3000,7 @@ export declare class NoticesResource extends Resource {
2965
3000
  /**
2966
3001
  * List due notices.
2967
3002
  *
2968
- * The legally required emails you owe subscribers (sites in "You send" mode, the default): kind, the subscriber (billing-platform ids), the legal window for the subscriber's state, the recommended send date, the copy-ready email and the BCC address. Default: everything not yet sent (upcoming, due, overdue), soonest first. Live keys list live subscribers' notices, test keys test-mode ones. Send each one on its send_date (inside its window), then call markNoticeSent (or BCC the notice's bcc address). Subscribe to the notice.due webhook to get each one on its send date.
3003
+ * The legally required emails you owe subscribers (sites in "You send" mode, the default): kind, the subscriber (billing-platform ids), the legal window for the subscriber's state, the recommended send date, the email (ready to send once email.missing_fields is empty) and the BCC address. Default: everything not yet sent (upcoming, due, overdue), soonest first. Live keys list live subscribers' notices, test keys test-mode ones. Send each one on its send_date (inside its window), then call markNoticeSent (or BCC the notice's bcc address). Subscribe to the notice.due webhook to get each one on its send date.
2969
3004
  *
2970
3005
  * @see GET /v1/notices/due (operation `listDueNotices`, scope `notices:read`)
2971
3006
  */
@@ -2989,7 +3024,7 @@ export declare class NoticesResource extends Resource {
2989
3024
  /**
2990
3025
  * Retrieve a due notice.
2991
3026
  *
2992
- * One notice you owe a subscriber, with its window, recommended send date, copy-ready email, BCC address and send status.
3027
+ * One notice you owe a subscriber, with its window, recommended send date, email (ready to send once email.missing_fields is empty), BCC address and send status.
2993
3028
  *
2994
3029
  * @param notice Unique identifier of the due notice (ntd_…).
2995
3030
  * @see GET /v1/notices/{notice} (operation `retrieveDueNotice`, scope `notices:read`)
@@ -3063,7 +3098,7 @@ export declare class ChecksResource extends Resource {
3063
3098
  /**
3064
3099
  * Check a subscription lifecycle email.
3065
3100
  *
3066
- * Checks the content of an acknowledgment (welcome) email, trial-ending reminder, renewal reminder, price-change notice, yearly terms reminder or cancellation confirmation against the requirements for that notice (renewal terms, amount, frequency, how to cancel, trial cancellation). The email is modelled as sent on time, so the verdict is about content; get send dates from checkNoticeSchedule. Prices are judged against what Stripe charges: with `site` (or, without it, the account's one site with Stripe connected) the plan fields come from the site's plans and the email is matched to the plan it names ("Annual") first; a price that contradicts it fails, and `warnings` say which site and plan were used. Returns `required_by` (requirements that make the email mandatory for this plan) and a `template` that passes the checks, with {{merge_tags}}, verified by the engine. Stateless and deterministic: nothing is stored, the same input on the same as_of date gives the same verdicts. Every verdict comes from the Checkbox rules engine over the legal catalog (federal ROSCA / EFTA plus the state automatic-renewal laws); the response carries rules_version, catalog_version and a disclaimer (not legal advice). Read `verdict`, then `next_action`: it tells you exactly what to change and to call the check again until verdict is pass.
3101
+ * Checks the content of an acknowledgment (welcome) email, trial-ending reminder, renewal reminder, price-change notice, yearly terms reminder or cancellation confirmation against the requirements for that notice (renewal terms, amount, frequency, how to cancel, trial cancellation). The email is modelled as sent on time, so the verdict is about content; get send dates from checkNoticeSchedule. Prices are judged against what Stripe charges: with `site` (or, without it and without a price in terms, the account's one site with Stripe connected) the plan fields come from the site's plans and the email is matched to the plan it names ("Annual") first; a price that contradicts it fails, and `warnings` say which site and plan were used. Without `site`, a price you send in terms is judged as sent; when it differs from every plan of that site, the result is at most needs_review and Next is update_setup (update the site's plans first). Returns `required_by` (requirements that make the email mandatory for this plan) and a `template` that passes the checks, with {{merge_tags}}, verified by the engine. Stateless and deterministic: nothing is stored, the same input on the same as_of date gives the same verdicts. Every verdict comes from the Checkbox rules engine over the legal catalog (federal ROSCA / EFTA plus the state automatic-renewal laws); the response carries rules_version, catalog_version and a disclaimer (not legal advice). Read `verdict`, then `next_action`: it tells you exactly what to change and to call the check again until verdict is pass.
3067
3102
  *
3068
3103
  * @see POST /v1/checks/email (operation `checkEmail`, scope `checks:read`)
3069
3104
  */
@@ -3288,7 +3323,7 @@ export declare class TestCredentialsResource extends Resource {
3288
3323
  /**
3289
3324
  * Store a billing test-mode key.
3290
3325
  *
3291
- * Stores the site's Stripe TEST-mode key (rk_test_… preferred) used by test runs, after checking it with Stripe. Live keys are refused (test_key_not_test_mode). Least privilege: Write on Customers, Checkout Sessions, Subscriptions, Test clocks and Customer portal; Read on Prices, Products and Billing portal configuration. Replaces an existing key. Next: createTestRun.
3326
+ * Stores the site's Stripe TEST-mode restricted key (rk_test_…), after checking it with Stripe the way the dashboard's Connect Stripe does. An agent may call this itself once the owner approved the setup; every store is logged on the site's setup timeline and Billing connection line, and the human can revoke it in one click. Live keys are refused (test_key_not_test_mode: a human adds live keys in the dashboard); the owner must have ticked "Let your agent store a Stripe test-mode key" on the approval page of the agent's sign-in or connection (else test_key_declined); a key whose Stripe account looks like another site's is refused with billing_account_mismatch (with confirm_account_mismatch: true the key is connected on hold until a person confirms the account in the dashboard; only a person can confirm it); secret keys (sk_test_…) are refused (test_key_not_restricted). On a test-mode site without a Stripe connection the key also becomes the site's Stripe connection: one key for checks, fixes (only after the human approves each) and test runs. The key's checklist: Customers: Write, Products: Read, Prices: Read, Coupons: Read, Subscriptions: Write, Test clocks: Write, Customer portal: Write, Checkout Sessions: Write, Payment Links: Write, Webhook Endpoints: Write. Replaces an existing key. Next: createTestRun.
3292
3327
  *
3293
3328
  * @param site Unique identifier of the site (site_…).
3294
3329
  * @see POST /v1/sites/{site}/test_credentials (operation `createTestCredential`, scope `test_runs:write`)
@@ -3528,6 +3563,7 @@ export declare const RESOURCES: {
3528
3563
  readonly fixes: typeof FixesResource;
3529
3564
  readonly evidence: typeof EvidenceResource;
3530
3565
  readonly certificates: typeof CertificatesResource;
3566
+ readonly noticeSends: typeof NoticeSendsResource;
3531
3567
  readonly noticeSettings: typeof NoticeSettingsResource;
3532
3568
  readonly notices: typeof NoticesResource;
3533
3569
  readonly lawUpdates: typeof LawUpdatesResource;
@@ -851,6 +851,23 @@ export const OPERATIONS = {
851
851
  paginated: false,
852
852
  summary: "Revoke a certificate",
853
853
  },
854
+ listNoticeSends: {
855
+ operationId: "listNoticeSends",
856
+ namespace: "noticeSends",
857
+ method: "list",
858
+ httpMethod: "GET",
859
+ path: "/v1/sites/{site}/notice_sends",
860
+ pathParams: ["site"],
861
+ queryParams: ["limit", "kind", "subscription", "include_samples"],
862
+ body: false,
863
+ idempotent: false,
864
+ auth: true,
865
+ scope: "notices:read",
866
+ response: "json",
867
+ list: true,
868
+ paginated: false,
869
+ summary: "List Checkbox Notices sends",
870
+ },
854
871
  retrieveNoticeSettings: {
855
872
  operationId: "retrieveNoticeSettings",
856
873
  namespace: "noticeSettings",
@@ -2041,7 +2058,7 @@ export class SitesResource extends Resource {
2041
2058
  /**
2042
2059
  * Connect a billing platform.
2043
2060
  *
2044
- * Connects the site's billing platform with read-only credentials (a Stripe restricted key, a Recharge token, a Shopify Admin API token, a Chargebee read-only API key, a Recurly private API key or a Paddle API key with read permissions), so Checkbox reads the customer-portal and reminder settings. Works for test-mode sites too (use an rk_test_ key). The credentials are validated by reading the settings once and stored encrypted.
2061
+ * Connects the site's billing platform with the one restricted key (a Stripe restricted key, a Recharge token, a Shopify Admin API token, a Chargebee read-only API key, a Recurly private API key or a Paddle API key with read permissions), so Checkbox reads the customer-portal and reminder settings. Stripe: One Stripe restricted key per site: Read permissions for the checks, and Write permissions that Checkbox uses only after you click Approve on a fix, or in test mode (the one exception: Webhook Endpoints, used once to add Checkbox's webhook endpoint when you connect the key) (checklist: https://checkbox.site/docs/guides/stripe-key). A full secret key (sk_test_ / sk_live_) is refused on every path with test_key_not_restricted: use a restricted key. API keys and AI agents may connect TEST-mode keys (rk_test_…) only; a live key (rk_live_ / sk_live_) is refused with live_key_requires_dashboard, because only a person signed in to the Checkbox dashboard can connect one. The credentials are validated by reading the settings once and stored encrypted. When the key's Stripe account looks like another site's (the site's prices or Payment Links are not in it, or it is already connected in another workspace), nothing is connected and the error billing_account_mismatch asks the human to confirm; retry with confirm_account_mismatch: true only after they said yes; the key is then held until a person confirms the account in the dashboard (an agent cannot confirm it). The account owner is emailed about every key connected.
2045
2062
  *
2046
2063
  * @param site Unique identifier of the site (site_…).
2047
2064
  * @see POST /v1/sites/{site}/integrations (operation `connectBillingPlatform`, scope `sites:write`)
@@ -2441,6 +2458,20 @@ export class CertificatesResource extends Resource {
2441
2458
  return this._request(OPERATIONS.revokeCertificate, [certificate], params, options);
2442
2459
  }
2443
2460
  }
2461
+ /** `checkbox.noticeSends` */
2462
+ export class NoticeSendsResource extends Resource {
2463
+ /**
2464
+ * List Checkbox Notices sends.
2465
+ *
2466
+ * Read-only: the emails Checkbox Notices sent, or tried to send, for this site (newest first), with status and, for a failed or skipped send, why. A test run's email steps name these rows (notices_send_log). Samples ("Send a test") are left out unless include_samples=true.
2467
+ *
2468
+ * @param site Unique identifier of the site (site_…).
2469
+ * @see GET /v1/sites/{site}/notice_sends (operation `listNoticeSends`, scope `notices:read`)
2470
+ */
2471
+ list(site, params, options) {
2472
+ return this._request(OPERATIONS.listNoticeSends, [site], params, options);
2473
+ }
2474
+ }
2444
2475
  /** `checkbox.noticeSettings` */
2445
2476
  export class NoticeSettingsResource extends Resource {
2446
2477
  /**
@@ -2457,7 +2488,7 @@ export class NoticeSettingsResource extends Resource {
2457
2488
  /**
2458
2489
  * Update notice settings.
2459
2490
  *
2460
- * Chooses who sends the required emails (mode: merchant = you send them and Checkbox tracks them, the default; checkbox = Checkbox sends them), and sets branding, cancel_url and the confirmed cancellation policy. add_kinds / remove_kinds turn single notices on or off and leave the others as they are; enabled_kinds replaces the whole list. In checkbox mode, turning a notice on requires cancel_url, a confirmed policy, a connected Stripe, Recharge, Chargebee, Recurly or Paddle account and a sending address; otherwise resource_conflict explains what is missing.
2491
+ * Chooses who sends the required emails (mode: merchant = you send them and Checkbox tracks them, the default; checkbox = Checkbox sends them), and sets branding, cancel_url and the confirmed cancellation policy. add_kinds / remove_kinds turn single notices on or off and leave the others as they are; enabled_kinds replaces the whole list. In checkbox mode, turning a notice on requires cancel_url, a confirmed policy, a support email, a connected Stripe, Recharge, Chargebee, Recurly or Paddle account and a sending address; otherwise resource_conflict explains what is missing. The support email may be the Stripe account's public one (used automatically); the account owner's login address only after the human confirms it in the dashboard (support_email_to_confirm; an agent cannot confirm it). Turning notices on through the API never emails a real subscriber: on a test-mode site only test-run inboxes (and marked test copies to the owner) are emailed, and on a live site real subscribers are emailed only after a person confirms it once in the dashboard, after a preview (real_sends). The account owner is emailed when an agent turns notices on.
2461
2492
  *
2462
2493
  * @param site Unique identifier of the site (site_…).
2463
2494
  * @see POST /v1/sites/{site}/notice_settings (operation `updateNoticeSettings`, scope `notices:write`, live mode needs an activated account)
@@ -2471,7 +2502,7 @@ export class NoticesResource extends Resource {
2471
2502
  /**
2472
2503
  * List due notices.
2473
2504
  *
2474
- * The legally required emails you owe subscribers (sites in "You send" mode, the default): kind, the subscriber (billing-platform ids), the legal window for the subscriber's state, the recommended send date, the copy-ready email and the BCC address. Default: everything not yet sent (upcoming, due, overdue), soonest first. Live keys list live subscribers' notices, test keys test-mode ones. Send each one on its send_date (inside its window), then call markNoticeSent (or BCC the notice's bcc address). Subscribe to the notice.due webhook to get each one on its send date.
2505
+ * The legally required emails you owe subscribers (sites in "You send" mode, the default): kind, the subscriber (billing-platform ids), the legal window for the subscriber's state, the recommended send date, the email (ready to send once email.missing_fields is empty) and the BCC address. Default: everything not yet sent (upcoming, due, overdue), soonest first. Live keys list live subscribers' notices, test keys test-mode ones. Send each one on its send_date (inside its window), then call markNoticeSent (or BCC the notice's bcc address). Subscribe to the notice.due webhook to get each one on its send date.
2475
2506
  *
2476
2507
  * @see GET /v1/notices/due (operation `listDueNotices`, scope `notices:read`)
2477
2508
  */
@@ -2501,7 +2532,7 @@ export class NoticesResource extends Resource {
2501
2532
  /**
2502
2533
  * Retrieve a due notice.
2503
2534
  *
2504
- * One notice you owe a subscriber, with its window, recommended send date, copy-ready email, BCC address and send status.
2535
+ * One notice you owe a subscriber, with its window, recommended send date, email (ready to send once email.missing_fields is empty), BCC address and send status.
2505
2536
  *
2506
2537
  * @param notice Unique identifier of the due notice (ntd_…).
2507
2538
  * @see GET /v1/notices/{notice} (operation `retrieveDueNotice`, scope `notices:read`)
@@ -2591,7 +2622,7 @@ export class ChecksResource extends Resource {
2591
2622
  /**
2592
2623
  * Check a subscription lifecycle email.
2593
2624
  *
2594
- * Checks the content of an acknowledgment (welcome) email, trial-ending reminder, renewal reminder, price-change notice, yearly terms reminder or cancellation confirmation against the requirements for that notice (renewal terms, amount, frequency, how to cancel, trial cancellation). The email is modelled as sent on time, so the verdict is about content; get send dates from checkNoticeSchedule. Prices are judged against what Stripe charges: with `site` (or, without it, the account's one site with Stripe connected) the plan fields come from the site's plans and the email is matched to the plan it names ("Annual") first; a price that contradicts it fails, and `warnings` say which site and plan were used. Returns `required_by` (requirements that make the email mandatory for this plan) and a `template` that passes the checks, with {{merge_tags}}, verified by the engine. Stateless and deterministic: nothing is stored, the same input on the same as_of date gives the same verdicts. Every verdict comes from the Checkbox rules engine over the legal catalog (federal ROSCA / EFTA plus the state automatic-renewal laws); the response carries rules_version, catalog_version and a disclaimer (not legal advice). Read `verdict`, then `next_action`: it tells you exactly what to change and to call the check again until verdict is pass.
2625
+ * Checks the content of an acknowledgment (welcome) email, trial-ending reminder, renewal reminder, price-change notice, yearly terms reminder or cancellation confirmation against the requirements for that notice (renewal terms, amount, frequency, how to cancel, trial cancellation). The email is modelled as sent on time, so the verdict is about content; get send dates from checkNoticeSchedule. Prices are judged against what Stripe charges: with `site` (or, without it and without a price in terms, the account's one site with Stripe connected) the plan fields come from the site's plans and the email is matched to the plan it names ("Annual") first; a price that contradicts it fails, and `warnings` say which site and plan were used. Without `site`, a price you send in terms is judged as sent; when it differs from every plan of that site, the result is at most needs_review and Next is update_setup (update the site's plans first). Returns `required_by` (requirements that make the email mandatory for this plan) and a `template` that passes the checks, with {{merge_tags}}, verified by the engine. Stateless and deterministic: nothing is stored, the same input on the same as_of date gives the same verdicts. Every verdict comes from the Checkbox rules engine over the legal catalog (federal ROSCA / EFTA plus the state automatic-renewal laws); the response carries rules_version, catalog_version and a disclaimer (not legal advice). Read `verdict`, then `next_action`: it tells you exactly what to change and to call the check again until verdict is pass.
2595
2626
  *
2596
2627
  * @see POST /v1/checks/email (operation `checkEmail`, scope `checks:read`)
2597
2628
  */
@@ -2864,7 +2895,7 @@ export class TestCredentialsResource extends Resource {
2864
2895
  /**
2865
2896
  * Store a billing test-mode key.
2866
2897
  *
2867
- * Stores the site's Stripe TEST-mode key (rk_test_… preferred) used by test runs, after checking it with Stripe. Live keys are refused (test_key_not_test_mode). Least privilege: Write on Customers, Checkout Sessions, Subscriptions, Test clocks and Customer portal; Read on Prices, Products and Billing portal configuration. Replaces an existing key. Next: createTestRun.
2898
+ * Stores the site's Stripe TEST-mode restricted key (rk_test_…), after checking it with Stripe the way the dashboard's Connect Stripe does. An agent may call this itself once the owner approved the setup; every store is logged on the site's setup timeline and Billing connection line, and the human can revoke it in one click. Live keys are refused (test_key_not_test_mode: a human adds live keys in the dashboard); the owner must have ticked "Let your agent store a Stripe test-mode key" on the approval page of the agent's sign-in or connection (else test_key_declined); a key whose Stripe account looks like another site's is refused with billing_account_mismatch (with confirm_account_mismatch: true the key is connected on hold until a person confirms the account in the dashboard; only a person can confirm it); secret keys (sk_test_…) are refused (test_key_not_restricted). On a test-mode site without a Stripe connection the key also becomes the site's Stripe connection: one key for checks, fixes (only after the human approves each) and test runs. The key's checklist: Customers: Write, Products: Read, Prices: Read, Coupons: Read, Subscriptions: Write, Test clocks: Write, Customer portal: Write, Checkout Sessions: Write, Payment Links: Write, Webhook Endpoints: Write. Replaces an existing key. Next: createTestRun.
2868
2899
  *
2869
2900
  * @param site Unique identifier of the site (site_…).
2870
2901
  * @see POST /v1/sites/{site}/test_credentials (operation `createTestCredential`, scope `test_runs:write`)
@@ -3156,6 +3187,7 @@ export const RESOURCES = {
3156
3187
  fixes: FixesResource,
3157
3188
  evidence: EvidenceResource,
3158
3189
  certificates: CertificatesResource,
3190
+ noticeSends: NoticeSendsResource,
3159
3191
  noticeSettings: NoticeSettingsResource,
3160
3192
  notices: NoticesResource,
3161
3193
  lawUpdates: LawUpdatesResource,
@@ -161,7 +161,7 @@ export interface DeviceToken {
161
161
  site: string | null;
162
162
  /** What the human approved. */
163
163
  consents: {
164
- /** The human allowed Checkbox to use the project's Stripe TEST key (send it with createTestCredential). */
164
+ /** The human allowed Checkbox to use the project's Stripe TEST key (store it with createTestCredential; it must be a restricted rk_test_ key). */
165
165
  stripe_test_key: boolean;
166
166
  /** Live keys were issued. */
167
167
  live_keys: boolean;
@@ -336,7 +336,7 @@ export interface SetupSession {
336
336
  discovered: Record<string, string>;
337
337
  /** Install details. */
338
338
  install: {
339
- /** The exact tag to put in <head> on every page. */
339
+ /** The exact tag to put in <head> of the homepage, pricing, checkout / sign-up and account pages (not needed on every page). */
340
340
  script_tag: string | null;
341
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. */
342
342
  snippet_key: string | null;
@@ -388,7 +388,7 @@ export interface SetupSession {
388
388
  }>;
389
389
  /** Stripe test mode for lifecycle test runs. */
390
390
  stripe: {
391
- /** Whether the human allowed Checkbox to use the project's Stripe TEST key for synthetic subscriptions. */
391
+ /** Whether the human ticked “Let your agent store a Stripe test-mode key” on the approval page (device login or OAuth connection). False: the agent may not store one (createTestCredential answers test_key_declined); the human adds it in the dashboard. Sessions started with a key the human made in the dashboard: true. */
392
392
  test_key_consent: boolean;
393
393
  /** Hint of the key the CLI found (never the key). */
394
394
  test_key_hint: string | null;
@@ -398,18 +398,20 @@ export interface SetupSession {
398
398
  checkout_configs: number;
399
399
  /** Restricted-key recommendation. */
400
400
  restricted_key: {
401
- /** true while no restricted (rk_test_) key is stored. */
401
+ /** true while no restricted (rk_test_) key is stored. The agent stores it with createTestCredential. */
402
402
  recommended: boolean;
403
403
  /** Why. */
404
404
  reason: string;
405
405
  /** Where to create it. */
406
406
  create_url: string;
407
- /** Least-privilege permissions. */
407
+ /** The one key checklist: every permission Checkbox uses (checks, fixes after the human approves, test runs). */
408
408
  permissions: Array<{
409
- /** Stripe resource. */
409
+ /** Stripe resource, as the restricted-key screen names it. */
410
410
  resource: string;
411
- /** Access. */
411
+ /** Access to tick (write includes read). */
412
412
  access: "read" | "write";
413
+ /** One line: why Checkbox needs it. */
414
+ why?: string;
413
415
  }>;
414
416
  };
415
417
  };
@@ -551,8 +553,8 @@ export interface SetupSessionUpdate {
551
553
  support_email?: string;
552
554
  /** 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. */
553
555
  merchant_name?: string;
554
- /** Billing platform. */
555
- billing_platform?: "stripe" | "shopify" | "recharge" | "chargebee" | "recurly" | "paddle" | "woocommerce" | "custom";
556
+ /** Billing platform. lemon_squeezy: Checkbox checks your pages and emails (no billing connection). */
557
+ billing_platform?: "stripe" | "shopify" | "recharge" | "chargebee" | "recurly" | "paddle" | "lemon_squeezy" | "woocommerce" | "custom";
556
558
  /** Plans and prices (sets the free-trial and term facts the law depends on). */
557
559
  plans?: Array<SetupPlan>;
558
560
  /** Facts about the builder's codebase. */
@@ -627,7 +629,7 @@ export interface SetupVerification {
627
629
  scan: {
628
630
  /** Whether a scan was queued now. */
629
631
  queued: boolean;
630
- /** The queued scan (scan_…); with reason "already scanned", the newest scan (read it with retrieveScan). */
632
+ /** The queued scan (scan_…); with a reason, the scan still in progress ("a scan is running/queued": wait for it) or, with "already scanned", the newest scan (read it with retrieveScan). */
631
633
  scan: string | null;
632
634
  /** Why not. */
633
635
  reason: string | null;
@@ -760,6 +762,19 @@ export interface LegalHoldParams {
760
762
  /** Note stored with the hold (who asked, matter). */
761
763
  reason?: string;
762
764
  }
765
+ /** An introductory price or coupon for one billing price (the same as Site settings → Your offer → Introductory price or coupon). */
766
+ export interface SiteIntroOffer {
767
+ /** The billing-platform price the intro applies to (e.g. a Stripe price id). */
768
+ price_id: string;
769
+ /** The intro price per billing period, in minor units (900 = $9.00). Give exactly one of intro_amount, intro_percent_off or intro_amount_off. */
770
+ intro_amount?: number;
771
+ /** A coupon: percent off the regular price. */
772
+ intro_percent_off?: number;
773
+ /** A coupon: amount off per billing period, in minor units. */
774
+ intro_amount_off?: number;
775
+ /** How many billing periods the intro price lasts (default 1). */
776
+ intro_periods?: number;
777
+ }
763
778
  /** Business facts that decide which legal requirements apply. */
764
779
  export interface SiteFacts {
765
780
  /** The offer starts with a free trial. */
@@ -782,6 +797,8 @@ export interface SiteFacts {
782
797
  payment_methods?: Array<"card" | "debit" | "ach" | "wallet" | "other">;
783
798
  /** 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
799
  checkout_type?: "own_page" | "stripe_checkout" | "payment_link";
800
+ /** Introductory prices or coupons per billing price (Site settings → Your offer). Every check, the plan, the Emails-tab templates and generated disclosures compare stated promos with them. Omit to keep the stored ones; [] clears them. A coupon must also exist in your live Stripe account before live sales. */
801
+ intro_offers?: Array<SiteIntroOffer>;
785
802
  }
786
803
  /** Scheduled monitoring. */
787
804
  export interface SiteMonitoring {
@@ -887,7 +904,7 @@ export type SiteCompliance = {
887
904
  } | null;
888
905
  /** What to install on the merchant site. */
889
906
  export interface SiteInstall {
890
- /** Paste into the <head> of every page (or let `checkbox init` do it). */
907
+ /** Paste into the <head> of the homepage, pricing, checkout / sign-up and account pages (or let `checkbox init` do it). It sends only the renewal-relevant blocks of a page. */
891
908
  script_tag: string;
892
909
  /** Public key of the snippet (also the inbound email local part). */
893
910
  snippet_key: string;
@@ -1278,8 +1295,10 @@ export interface Integration {
1278
1295
  export interface ConnectBillingPlatformParams {
1279
1296
  /** Billing platform. */
1280
1297
  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. */
1298
+ /** 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_…" } (rk_test_ in test mode). One Stripe restricted key per site: Read permissions for the checks, and Write permissions that Checkbox uses only after you click Approve on a fix, or in test mode (the one exception: Webhook Endpoints, used once to add Checkbox's webhook endpoint when you connect the key). The checklist: Customers: Write, Products: Read, Prices: Read, Coupons: Read, Subscriptions: Write, Test clocks: Write, Customer portal: Write, Checkout Sessions: Write, Payment Links: Write, Webhook Endpoints: Write (https://checkbox.site/docs/guides/stripe-key). 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). For the platforms other than Stripe, Checkbox only reads. */
1282
1299
  credentials: Record<string, string>;
1300
+ /** Set true only after the human said yes to the billing_account_mismatch question ("This looks like <other site>’s Stripe account. Use it anyway?"). It only proposes the account: the key is connected on hold (nothing from it is used, no test runs) until a person confirms it in the Checkbox dashboard (site Overview: “It is this site’s account: use it”). Default false: such a key is not connected and nothing is evaluated. */
1301
+ confirm_account_mismatch?: boolean;
1283
1302
  }
1284
1303
  /** A queued re-read of the site's billing-platform settings, followed by a re-evaluation. */
1285
1304
  export interface BillingSync {
@@ -1442,6 +1461,8 @@ export interface EvidenceItem {
1442
1461
  screenshot_ref?: string;
1443
1462
  /** When it was captured / received. */
1444
1463
  at?: string;
1464
+ /** Set when a Checkbox test run recorded this page view (not a scan of your site). */
1465
+ test_run_id?: string;
1445
1466
  }
1446
1467
  /** What a verdict was based on. Never a pass without it; needs_review says what is missing. */
1447
1468
  export interface VerdictEvidence {
@@ -1569,7 +1590,7 @@ export interface PlanEdit {
1569
1590
  }
1570
1591
  /** What the caller (usually an AI coding agent) should do next. */
1571
1592
  export interface PlanNextAction {
1572
- /** Stable action type: apply_task, provide_facts, verify_task, answer_question, ask_human_to_confirm, connect_billing_in_dashboard, wait_for_verification, run_first_check, review_wont_fix, done. */
1593
+ /** Stable action type: apply_task, provide_facts, verify_task, answer_question, ask_human_to_confirm, connect_billing_in_dashboard, store_stripe_test_key, wait_for_verification, run_first_check, review_wont_fix, done_for_now (nothing left an agent can do in code now: the rest waits for a deploy / real send, and maybe the owner; the description lists both; finish the change), done. */
1573
1594
  type: string;
1574
1595
  /** One or two sentences telling the agent exactly what to do now. */
1575
1596
  description: string;
@@ -1670,8 +1691,8 @@ export interface Task {
1670
1691
  };
1671
1692
  /** What Checkbox needs before it can give the exact change (observation: it has not seen the page / email yet; facts: plan, price, cancel URL or merchant name). The title stays the same either way. */
1672
1693
  blocked_on: string | null;
1673
- /** Done / declined tasks: verified (its checks pass), no_longer_applicable (its checks no longer apply, e.g. the data source changed), superseded, declined. */
1674
- closed_reason: "verified" | "no_longer_applicable" | "superseded" | "declined" | null;
1694
+ /** Done / declined tasks: verified (its checks pass), no_longer_applicable (its checks no longer apply, e.g. the data source changed), superseded, declined, decided (the owner confirmed a decision, e.g. New York notices by email only: closed, but its checks are not verified). */
1695
+ closed_reason: "verified" | "no_longer_applicable" | "superseded" | "declined" | "decided" | null;
1675
1696
  /** Tasks to finish first (their result changes this task's content). */
1676
1697
  depends_on: Array<string>;
1677
1698
  /** Unfinished tasks among depends_on. */
@@ -1745,7 +1766,7 @@ export interface CompliancePlan {
1745
1766
  site: string;
1746
1767
  /** 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). */
1747
1768
  status: "action_required" | "verifying" | "compliant" | "blocked";
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). */
1769
+ /** The plan status in words to show a person: action_required "Fixes needed", verifying "Checking your changes", compliant "Checks pass", blocked "Your call"; while an agent works the site and everything left waits for a deploy or the owner (next_action done_for_now): "Waiting on deploy and you" or "Waiting on deploy". Show this, never the machine value (`compliant` is a status name, not a legal conclusion). */
1749
1770
  status_label?: string;
1750
1771
  /** The evaluation the plan was built from (null before the first check). */
1751
1772
  evaluation: string | null;
@@ -1798,6 +1819,24 @@ export interface CompliancePlan {
1798
1819
  billing_connected: boolean;
1799
1820
  };
1800
1821
  next_action: PlanNextAction;
1822
+ /** Every open owner choice as ONE batched question (who sends the required emails, plus each question task such as the New York notice channel). Ask it once, early, in one message; the plan's next_action says the same. Absent when there is none. */
1823
+ owner_questions?: {
1824
+ /** How to ask them: once, in one message, while the fixes go on. */
1825
+ description: string;
1826
+ /** Every choice only the owner makes, together. */
1827
+ questions: Array<{
1828
+ /** "email_sender" (who sends the required emails), "notices_support_email" / "notices_cancel_timing" (what Checkbox Notices needs before it sends), or the id of the task whose question it is. */
1829
+ id: string;
1830
+ /** The question, in plain words for the owner. */
1831
+ text: string;
1832
+ /** The answers. */
1833
+ options: Array<string>;
1834
+ /** The tasks the answer settles. */
1835
+ tasks: Array<string>;
1836
+ /** What the agent does with each answer. */
1837
+ on_answer: Record<string, string>;
1838
+ }>;
1839
+ };
1801
1840
  /** Evidence level per required email kind. A plan never reaches status compliant on template_checked emails. */
1802
1841
  email_verification: Array<{
1803
1842
  /** Email kind (acknowledgment, trial_ending, renewal_reminder, annual_terms, charge_notice, price_change, cancellation_confirmation). */
@@ -1928,7 +1967,7 @@ export interface Verification {
1928
1967
  diff: Array<VerificationCheck>;
1929
1968
  /** Plan status after this verification (null while pending). */
1930
1969
  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). */
1970
+ /** The plan status in words to show a person: action_required "Fixes needed", verifying "Checking your changes", compliant "Checks pass", blocked "Your call"; while an agent works the site and everything left waits for a deploy or the owner (next_action done_for_now): "Waiting on deploy and you" or "Waiting on deploy". Show this, never the machine value (`compliant` is a status name, not a legal conclusion). */
1932
1971
  plan_status_label?: string | null;
1933
1972
  next_action: PlanNextAction;
1934
1973
  /** When it was requested. Unix timestamp in seconds. */
@@ -2175,6 +2214,54 @@ export interface CertificateList {
2175
2214
  /** The URL of this list. */
2176
2215
  url: string;
2177
2216
  }
2217
+ /** One email Checkbox Notices sent (or tried to send) for the site. */
2218
+ export interface NoticeSend {
2219
+ /** Unique identifier of the notice (ntc_…). */
2220
+ id: string;
2221
+ /** String representing the object's type. Always "notice_send". */
2222
+ object: "notice_send";
2223
+ /** The site. */
2224
+ site: string;
2225
+ /** Notice kind. */
2226
+ kind: "acknowledgment" | "trial_ending" | "renewal_reminder" | "annual_terms" | "price_change" | "cancellation_confirmation" | "charge_notice";
2227
+ /** sent: the provider accepted it; failed: will be retried while its window is open; skipped: not sent, error says why; bounced; claimed: being sent. */
2228
+ status: "claimed" | "sent" | "failed" | "bounced" | "skipped";
2229
+ /** A "Send a test" sample (never counts toward a check). */
2230
+ sample: boolean;
2231
+ /** Billing platform of the subscription. */
2232
+ platform: string;
2233
+ /** Billing-platform subscription id (null for a sample). */
2234
+ subscription: string | null;
2235
+ /** Masked recipient address. */
2236
+ recipient: string | null;
2237
+ /** Subject line. */
2238
+ subject: string | null;
2239
+ /** Sent after its window opened late. */
2240
+ late: boolean;
2241
+ /** Why it failed or was skipped. */
2242
+ error: string | null;
2243
+ /** Send attempts. */
2244
+ attempts: number;
2245
+ /** When it was due. Unix timestamp in seconds. */
2246
+ due: number | null;
2247
+ /** When it was sent. Unix timestamp in seconds. */
2248
+ sent: number | null;
2249
+ /** When the send was first claimed. Unix timestamp in seconds. */
2250
+ created: number;
2251
+ /** Evidence record of the sent email. */
2252
+ evidence: string | null;
2253
+ }
2254
+ /** A page of checkbox notices sends, newest first. */
2255
+ export interface NoticeSendList {
2256
+ /** String representing the object's type. Always "list". */
2257
+ object: "list";
2258
+ /** Checkbox Notices sends, newest first. */
2259
+ data: Array<NoticeSend>;
2260
+ /** Whether more items exist after this page. Pass the last id as starting_after to fetch them. */
2261
+ has_more: boolean;
2262
+ /** The URL of this list. */
2263
+ url: string;
2264
+ }
2178
2265
  /** Checkbox Notices for a site: the legally required emails Checkbox sends on the merchant's behalf. */
2179
2266
  export interface NoticeSettings {
2180
2267
  /** Unique identifier of the notice settings (ntcs_…). */
@@ -2197,8 +2284,12 @@ export interface NoticeSettings {
2197
2284
  product_name: string | null;
2198
2285
  /** Logo URL (https). */
2199
2286
  logo_url: string | null;
2200
- /** Reply-to / support address. */
2287
+ /** Reply-to / support address every notice names as the business's contact. null until one is set (or while support_email_to_confirm waits for a person). */
2201
2288
  support_email: string | null;
2289
+ /** The Checkbox account's login address (the owner's), offered as the support email but not used: Checkbox sends nothing with it, and does not save it, until a person confirms it once in the dashboard (Emails › Branding). Agents cannot confirm it; ask the human, or set a different support_email they chose. The Stripe account's public support email is used without asking. */
2290
+ support_email_to_confirm: string | null;
2291
+ /** Whether Checkbox Notices emails the site's real subscribers. test_mode: never (test-mode sites email only test-run inboxes and send the owner marked test copies). needs_confirmation: Notices are on, but nothing goes to real subscribers until a person confirms it once in the dashboard (Emails tab, after a preview); an API key or agent cannot confirm it. confirmed: they are emailed. off: Checkbox sends nothing. */
2292
+ real_sends: "test_mode" | "confirmed" | "needs_confirmation" | "off";
2202
2293
  /** Where subscribers cancel online (site domain, hosted cancellation page or billing portal). */
2203
2294
  cancel_url: string | null;
2204
2295
  /** Hex brand colour. */
@@ -2267,7 +2358,7 @@ export interface UpdateNoticeSettingsParams {
2267
2358
  product_name?: string | null;
2268
2359
  /** Logo URL (https). */
2269
2360
  logo_url?: string | null;
2270
- /** Support address. */
2361
+ /** Support address every notice names (required before Checkbox sends). Turning a notice on without one uses the Checkbox cancellation page's or the Stripe account's public support email. The Checkbox account's login address is never used without a person: setting it here answers resource_conflict (next_action confirm_support_email) until the human confirms it once in the dashboard (Emails › Branding). */
2271
2362
  support_email?: string | null;
2272
2363
  /** Online cancellation URL. */
2273
2364
  cancel_url?: string | null;
@@ -2283,7 +2374,7 @@ export interface UpdateNoticeSettingsParams {
2283
2374
  confirm: true;
2284
2375
  } | null;
2285
2376
  }
2286
- /** Copy-ready email for this subscriber. It passes the preflight email check for its kind when every field is filled. */
2377
+ /** The email for this subscriber, rendered from Checkbox's template. Ready to send only when missing_fields is empty; it then passes the preflight email check for its kind. */
2287
2378
  export interface RenderedNoticeEmail {
2288
2379
  /** Checkbox template the email was rendered from (GET /v1/notices/templates). */
2289
2380
  template_id: string;
@@ -2293,10 +2384,10 @@ export interface RenderedNoticeEmail {
2293
2384
  text: string;
2294
2385
  /** HTML body, merge fields filled (values HTML-escaped). */
2295
2386
  html: string;
2296
- /** Merge fields Checkbox could not fill (e.g. cancel_url until you set it); fill them before sending. */
2387
+ /** Merge fields Checkbox could not fill (support_contact until a support email is confirmed, cancel_url when neither the notice settings nor the site name an account page). While this is not empty the email is NOT ready to send: fill each {{field}} first, or a check of the sent copy reopens its task naming the unfilled field. */
2297
2388
  missing_fields: Array<string>;
2298
2389
  }
2299
- /** An email the merchant owes a subscriber, legally required (required: true) or recommended ("You send" mode): what, when, the copy-ready email and how to confirm it was sent. */
2390
+ /** An email the merchant owes a subscriber, legally required (required: true) or recommended ("You send" mode): what, when, the email to send (ready once email.missing_fields is empty) and how to confirm it was sent. */
2300
2391
  export interface DueNotice {
2301
2392
  /** Unique identifier of the due notice (ntd_…). */
2302
2393
  id: string;
@@ -2625,6 +2716,8 @@ export interface CheckWarning {
2625
2716
  export interface CheckReplacement {
2626
2717
  /** Disclosure generated from the plan terms that passes the checks (locked wording). */
2627
2718
  disclosure_text: string;
2719
+ /** The same terms as one short line, verified by the engine like disclosure_text (present only when it passes every targeted check); disclosure_text is then the fuller version. */
2720
+ short_disclosure_text?: string;
2628
2721
  /** Label for the unchecked, required consent checkbox. */
2629
2722
  consent_label: string;
2630
2723
  /** Purchase button label that itself states the renewal. */
@@ -2711,8 +2804,8 @@ export interface DisclosureCheckParams {
2711
2804
  amount?: number;
2712
2805
  /** Three-letter ISO currency (default usd). */
2713
2806
  currency?: string;
2714
- /** Billing interval: day, week, month or year (required). */
2715
- interval: string;
2807
+ /** Billing interval: day, week, month or year (required unless `site` gives the plan). */
2808
+ interval?: string;
2716
2809
  /** Number of intervals between charges (default 1). */
2717
2810
  interval_count?: number;
2718
2811
  /** Free-trial length in days (0 or absent = no trial). */
@@ -2767,6 +2860,10 @@ export interface DisclosureCheckParams {
2767
2860
  };
2768
2861
  /** Evaluate the law as of this date (YYYY-MM-DD, default today). */
2769
2862
  as_of?: string;
2863
+ /** Round 23: a site of yours (site_…): the disclosure is judged against the plan it states among the site's plans (the connected Stripe Prices win over plans typed in setup), with the site's merchant name, cancellation URL and jurisdictions, as verifyTask judges it. Plan fields you send are replaced by the plan's. "none" judges only what you send. */
2864
+ site?: string;
2865
+ /** With a site: judge the disclosure against this plan (name or Stripe Price id). An unknown plan is refused with the list of plans. */
2866
+ plan?: string;
2770
2867
  }
2771
2868
  /** RFC 6902 operation. */
2772
2869
  export interface JsonPatchOperation {
@@ -3180,8 +3277,10 @@ export interface PageCheckParams {
3180
3277
  /** Plan name, as in setup plans[] (updateSetupSession; alias of plan_name). */
3181
3278
  name?: string;
3182
3279
  }>;
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. */
3280
+ /** 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, or to one of payment_links, when absent. */
3184
3281
  checkout_type?: "own_page" | "stripe_checkout" | "payment_link";
3282
+ /** Your Stripe Payment Link URLs (buy.stripe.com or your own domain). A link to one of them is the purchase button, and the purchase and consent complete on Stripe, so no checkbox is added on this page. With site, the Payment Links read from your connected Stripe account are added. */
3283
+ payment_links?: Array<string>;
3185
3284
  /** 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
3285
  site?: string;
3187
3286
  /** Where you sell: "all" (default) or state codes ("US-CA", "CA", "US-NY"; "US-FED" is always included). */
@@ -4191,6 +4290,7 @@ export interface TestCredential {
4191
4290
  last_error: string | null;
4192
4291
  /** When the key was stored. Unix timestamp in seconds. */
4193
4292
  created: number;
4293
+ next_action?: NextAction;
4194
4294
  }
4195
4295
  /** A page of stored test-mode keys. */
4196
4296
  export interface TestCredentialList {
@@ -4238,6 +4338,7 @@ export interface StripeCheckoutConfig {
4238
4338
  metadata: Record<string, string>;
4239
4339
  /** When the config was registered. Unix timestamp in seconds. */
4240
4340
  created: number;
4341
+ next_action?: NextAction;
4241
4342
  }
4242
4343
  /** A page of registered checkout configs, newest first. */
4243
4344
  export interface StripeCheckoutConfigList {
@@ -4482,8 +4583,8 @@ export interface TestRun {
4482
4583
  via: "merchant_flow" | "stripe_portal" | "cancel_url";
4483
4584
  /** 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). */
4484
4585
  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;
4586
+ /** How the cancel path was chosen when none was passed. site_portal_link: Stripe has cancellation on in the customer portal and your site links to it, so the portal was used as declared. registered_url: the account or cancellation page you registered (account_url / cancellation_url) redirects or links to the Stripe customer portal. site_cancel_control: the cancel button or link the last scan found on a public page of your site was used. portal_default: no test account and no other cancel flow is set, and Stripe has cancellation on in the customer portal, so the portal was used (and remembered for this site). site_setting: an earlier run remembered the portal for this site. */
4587
+ inferred_from?: "site_portal_link" | "registered_url" | "site_cancel_control" | "portal_default" | "site_setting" | null;
4487
4588
  /** Stripe showed a subscription set to cancel after the shopper's flow. */
4488
4589
  confirmed_in_stripe: boolean;
4489
4590
  /** The subscription Stripe showed canceled. */
@@ -4667,7 +4768,7 @@ export interface CompliancePlanSummary {
4667
4768
  site: string;
4668
4769
  /** 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). */
4669
4770
  status: "action_required" | "verifying" | "compliant" | "blocked";
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). */
4771
+ /** The plan status in words to show a person: action_required "Fixes needed", verifying "Checking your changes", compliant "Checks pass", blocked "Your call"; while an agent works the site and everything left waits for a deploy or the owner (next_action done_for_now): "Waiting on deploy and you" or "Waiting on deploy". Show this, never the machine value (`compliant` is a status name, not a legal conclusion). */
4671
4772
  status_label?: string;
4672
4773
  /** Two or three sentences for an LLM: where the site stands and what comes next. */
4673
4774
  summary: string;
@@ -4915,6 +5016,17 @@ export interface RevokeCertificateParams {
4915
5016
  /** Private reason. */
4916
5017
  reason: string;
4917
5018
  }
5019
+ /** Parameters of `noticeSends.list()` (listNoticeSends). */
5020
+ export interface ListNoticeSendsParams {
5021
+ /** At most this many rows (default 50). */
5022
+ limit?: number;
5023
+ /** Only this kind. */
5024
+ kind?: "acknowledgment" | "trial_ending" | "renewal_reminder" | "annual_terms" | "price_change" | "cancellation_confirmation" | "charge_notice";
5025
+ /** Only sends for this billing-platform subscription id. */
5026
+ subscription?: string;
5027
+ /** Include "Send a test" samples. */
5028
+ include_samples?: "true" | "false";
5029
+ }
4918
5030
  /** Parameters of `notices.listDue()` (listDueNotices). */
4919
5031
  export interface ListDueNoticesParams {
4920
5032
  /** Number of objects to return, 1-100 (default 10). */
@@ -4999,10 +5111,12 @@ export interface ListReceiptsParams {
4999
5111
  }
5000
5112
  /** Parameters of `testCredentials.create()` (createTestCredential). */
5001
5113
  export interface CreateTestCredentialParams {
5002
- /** Kind of key. Only "stripe_test". */
5003
- type: "stripe_test";
5004
- /** The Stripe test-mode restricted (rk_test_…) or secret (sk_test_…) key. Stored encrypted; never returned. */
5114
+ /** Kind of key: "stripe_test" ("stripe" is accepted as the same). Always stored as a Stripe TEST-mode key. */
5115
+ type: "stripe_test" | "stripe";
5116
+ /** The Stripe test-mode restricted key (rk_test_…). Secret keys (sk_…) and live keys are refused. Stored encrypted; never returned. */
5005
5117
  secret_key: string;
5118
+ /** Set true only after the human said yes: proposes the key even though its Stripe account looks like another site’s (billing_account_mismatch). It is connected on hold, and nothing from it is used, until a person confirms the account in the Checkbox dashboard (site Overview); next to a person’s Stripe connection it is refused. Default false. */
5119
+ confirm_account_mismatch?: boolean;
5006
5120
  }
5007
5121
  /** Parameters of `stripeCheckoutConfigs.create()` (createStripeCheckoutConfig). */
5008
5122
  export interface CreateStripeCheckoutConfigParams {
@@ -5036,6 +5150,8 @@ export interface CreateTestRunParams {
5036
5150
  cancel?: boolean;
5037
5151
  /** State the synthetic shopper visits from (default: the site's first scan region). */
5038
5152
  region?: "US-FED" | "US-AL" | "US-AK" | "US-AZ" | "US-AR" | "US-CA" | "US-CO" | "US-CT" | "US-DE" | "US-DC" | "US-FL" | "US-GA" | "US-HI" | "US-ID" | "US-IL" | "US-IN" | "US-IA" | "US-KS" | "US-KY" | "US-LA" | "US-ME" | "US-MD" | "US-MA" | "US-MI" | "US-MN" | "US-MS" | "US-MO" | "US-MT" | "US-NE" | "US-NV" | "US-NH" | "US-NJ" | "US-NM" | "US-NY" | "US-NC" | "US-ND" | "US-OH" | "US-OK" | "US-OR" | "US-PA" | "US-RI" | "US-SC" | "US-SD" | "US-TN" | "US-TX" | "US-UT" | "US-VT" | "US-VA" | "US-WA" | "US-WV" | "US-WI" | "US-WY";
5153
+ /** Round 23: which plan to run, by the name of a registered checkout config or a Price id (price_…) its line_items use: the run mirrors that config (same as stripe.checkout_config). An unknown plan is refused with the list of registered configs. */
5154
+ plan?: string;
5039
5155
  /** Stripe options. */
5040
5156
  stripe?: {
5041
5157
  /** Registered checkout config (scc_…) to mirror; default: the newest one, else your latest live Checkout Session. "none" skips the registered configs (mirror your live checkout, stripe.price or stripe.payment_link instead). */
@@ -5044,6 +5160,10 @@ export interface CreateTestRunParams {
5044
5160
  price?: string;
5045
5161
  /** Trial for `price` (registered configs carry their own). */
5046
5162
  trial_period_days?: number;
5163
+ /** Mirror mode: a TEST-mode coupon id applied to the test subscription, so it has the same discount as your real subscribers (an intro price, for example). Its emails are then judged against that discount. Not with promotion_code. */
5164
+ coupon?: string;
5165
+ /** Mirror mode: a TEST-mode promotion code (promo_… id, or the code customers type) applied to the test subscription. Not with coupon. */
5166
+ promotion_code?: string;
5047
5167
  /** Live price id -> test-mode price id, when they differ. */
5048
5168
  price_map?: Record<string, string>;
5049
5169
  /** Steps that complete your hosted checkout with card 4242 4242 4242 4242 when it differs from Stripe's default page. */
@@ -5115,7 +5235,7 @@ export interface ListTestRunsParams {
5115
5235
  }
5116
5236
  /** Parameters of `testRuns.retrieve()` (retrieveTestRun). */
5117
5237
  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. */
5238
+ /** Long-poll: wait up to this many seconds (0-30) for a meaningful change before answering: the run finishes, its status changes or a step starts or ends (not every internal phase change while the test clock moves). */
5119
5239
  wait?: number | null;
5120
5240
  }
5121
5241
  /** Parameters of `webhookEndpoints.create()` (createWebhookEndpoint). */
@@ -5188,7 +5308,7 @@ export type TaskVerifiedEvent = Event & {
5188
5308
  previous_attributes?: Record<string, unknown>;
5189
5309
  };
5190
5310
  };
5191
- /** `notice.due`: An email the merchant sends itself ("You send" mode) reached its recommended send date: data.object is the due_notice with the window, send_at, the copy-ready email and its BCC address. Send it now (inside the window), then call markNoticeSent (or BCC the copy). required tells a legally required email from a recommended one. */
5311
+ /** `notice.due`: An email the merchant sends itself ("You send" mode) reached its recommended send date: data.object is the due_notice with the window, send_at, the email (ready to send once email.missing_fields is empty) and its BCC address. Send it now (inside the window), then call markNoticeSent (or BCC the copy). required tells a legally required email from a recommended one. */
5192
5312
  export type NoticeDueEvent = Event & {
5193
5313
  /** Event type. */
5194
5314
  type?: "notice.due";
@@ -5418,12 +5538,22 @@ export declare const ERROR_CODES: {
5418
5538
  readonly test_key_missing: {
5419
5539
  readonly status: 400;
5420
5540
  readonly type: "invalid_request_error";
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).";
5541
+ readonly description: "A Stripe test run needs a Stripe TEST-mode key stored for the site: the agent stores the restricted test key (rk_test_…) with createTestCredential, or a person adds it in the dashboard.";
5422
5542
  };
5423
5543
  readonly test_key_not_test_mode: {
5424
5544
  readonly status: 400;
5425
5545
  readonly type: "invalid_request_error";
5426
- readonly description: "The billing key is a live-mode (or malformed) key; test runs only accept test-mode keys (rk_test_… / sk_test_…).";
5546
+ readonly description: "The billing key is a live-mode (or malformed) key. Agents only store TEST-mode restricted keys (rk_test_…); a human adds live keys in the Checkbox dashboard.";
5547
+ };
5548
+ readonly test_key_not_restricted: {
5549
+ readonly status: 400;
5550
+ readonly type: "invalid_request_error";
5551
+ readonly description: "The key is a full Stripe secret key (sk_test_… or sk_live_…), which is refused on every connect path (createTestCredential, connectBillingPlatform, the dashboard). Use a restricted key (rk_test_…) with the permissions on Checkbox's key checklist instead; `message` lists them.";
5552
+ };
5553
+ readonly test_key_declined: {
5554
+ readonly status: 403;
5555
+ readonly type: "permission_error";
5556
+ readonly description: "The owner did not tick “Let your agent store a Stripe test-mode key” on the approval page of this agent's sign-in (device login) or connection (OAuth). Nothing was stored. Ask them to allow it on the approval page (sign in again) or to add the key themselves in the dashboard.";
5427
5557
  };
5428
5558
  readonly test_key_rejected: {
5429
5559
  readonly status: 400;
@@ -5505,6 +5635,11 @@ export declare const ERROR_CODES: {
5505
5635
  readonly type: "permission_error";
5506
5636
  readonly description: "Checkbox only scans, monitors, fetches and test-runs websites the account has verified (DNS TXT record or /.well-known file): every target host (site, checkout, account and policy URLs) must be on a verified domain. `next_action` says which domain to verify.";
5507
5637
  };
5638
+ readonly live_key_requires_dashboard: {
5639
+ readonly status: 403;
5640
+ readonly type: "permission_error";
5641
+ readonly description: "A live-mode Stripe key (rk_live_ / sk_live_) cannot be connected through the API or by an AI agent: only a person signed in to the Checkbox dashboard can connect one (and never on a test-mode site). Agents store restricted TEST keys (rk_test_…).";
5642
+ };
5508
5643
  readonly account_suspended: {
5509
5644
  readonly status: 403;
5510
5645
  readonly type: "permission_error";
@@ -5535,6 +5670,11 @@ export declare const ERROR_CODES: {
5535
5670
  readonly type: "invalid_request_error";
5536
5671
  readonly description: "The consent already carries a different customer_reference; references are set once and never changed.";
5537
5672
  };
5673
+ readonly billing_account_mismatch: {
5674
+ readonly status: 409;
5675
+ readonly type: "invalid_request_error";
5676
+ readonly description: "The key's Stripe account looks like another site's (the site's prices or Payment Links are not in it, or it is already connected in another workspace), so nothing was stored or evaluated. Ask the human the question in `message`; retry with confirm_account_mismatch: true only if they say yes (that only proposes it: the key is held until a person confirms the account in the dashboard), else use this site's own key. `problems` lists what did not match.";
5677
+ };
5538
5678
  readonly test_run_in_progress: {
5539
5679
  readonly status: 409;
5540
5680
  readonly type: "invalid_request_error";
@@ -18,8 +18,10 @@ export const ERROR_CODES = {
18
18
  api_version_invalid: { status: 400, type: "invalid_request_error", description: "The Checkbox-Version header names an unknown API version." },
19
19
  idempotency_key_invalid: { status: 400, type: "idempotency_error", description: "The Idempotency-Key header is empty or longer than 255 characters." },
20
20
  idempotency_key_reused: { status: 400, type: "idempotency_error", description: "The Idempotency-Key was already used with different parameters within 24 hours." },
21
- test_key_missing: { status: 400, type: "invalid_request_error", 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)." },
22
- test_key_not_test_mode: { status: 400, type: "invalid_request_error", description: "The billing key is a live-mode (or malformed) key; test runs only accept test-mode keys (rk_test_… / sk_test_…)." },
21
+ test_key_missing: { status: 400, type: "invalid_request_error", description: "A Stripe test run needs a Stripe TEST-mode key stored for the site: the agent stores the restricted test key (rk_test_…) with createTestCredential, or a person adds it in the dashboard." },
22
+ test_key_not_test_mode: { status: 400, type: "invalid_request_error", description: "The billing key is a live-mode (or malformed) key. Agents only store TEST-mode restricted keys (rk_test_…); a human adds live keys in the Checkbox dashboard." },
23
+ test_key_not_restricted: { status: 400, type: "invalid_request_error", description: "The key is a full Stripe secret key (sk_test_… or sk_live_…), which is refused on every connect path (createTestCredential, connectBillingPlatform, the dashboard). Use a restricted key (rk_test_…) with the permissions on Checkbox's key checklist instead; `message` lists them." },
24
+ test_key_declined: { status: 403, type: "permission_error", description: "The owner did not tick “Let your agent store a Stripe test-mode key” on the approval page of this agent's sign-in (device login) or connection (OAuth). Nothing was stored. Ask them to allow it on the approval page (sign in again) or to add the key themselves in the dashboard." },
23
25
  test_key_rejected: { status: 400, type: "invalid_request_error", description: "Stripe rejected the test-mode key or it lacks a permission test runs need; `message` names it." },
24
26
  authorization_pending: { status: 400, type: "invalid_request_error", description: "Device login: the human has not approved yet. Keep polling createDeviceToken every `interval` seconds." },
25
27
  slow_down: { status: 400, type: "rate_limit_error", description: "Device login: polling too fast. Add 5 seconds to the interval and keep polling." },
@@ -36,12 +38,14 @@ export const ERROR_CODES = {
36
38
  test_mode_domain_unverified: { status: 403, type: "permission_error", description: "Test mode only scans, monitors, fetches and test-runs localhost or domains the account has verified; verify the domain (createDomainVerification) or send the HTML instead." },
37
39
  test_mode_scan_budget_exhausted: { status: 429, type: "rate_limit_error", 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." },
38
40
  domain_not_verified: { status: 403, type: "permission_error", description: "Checkbox only scans, monitors, fetches and test-runs websites the account has verified (DNS TXT record or /.well-known file): every target host (site, checkout, account and policy URLs) must be on a verified domain. `next_action` says which domain to verify." },
41
+ live_key_requires_dashboard: { status: 403, type: "permission_error", description: "A live-mode Stripe key (rk_live_ / sk_live_) cannot be connected through the API or by an AI agent: only a person signed in to the Checkbox dashboard can connect one (and never on a test-mode site). Agents store restricted TEST keys (rk_test_…)." },
39
42
  account_suspended: { status: 403, type: "permission_error", description: "The account was suspended by Checkbox staff; contact support." },
40
43
  resource_missing: { status: 404, type: "invalid_request_error", description: "No object with this id exists in this mode of the account." },
41
44
  route_not_found: { status: 404, type: "invalid_request_error", description: "No such endpoint. See /v1/openapi.json for the list." },
42
45
  resource_conflict: { status: 409, type: "invalid_request_error", description: "The object is in a state that does not allow this action." },
43
46
  scan_already_queued: { status: 409, type: "invalid_request_error", description: "A scan of this site is already queued or running." },
44
47
  consent_reference_locked: { status: 409, type: "invalid_request_error", description: "The consent already carries a different customer_reference; references are set once and never changed." },
48
+ billing_account_mismatch: { status: 409, type: "invalid_request_error", description: "The key's Stripe account looks like another site's (the site's prices or Payment Links are not in it, or it is already connected in another workspace), so nothing was stored or evaluated. Ask the human the question in `message`; retry with confirm_account_mismatch: true only if they say yes (that only proposes it: the key is held until a person confirms the account in the dashboard), else use this site's own key. `problems` lists what did not match." },
45
49
  test_run_in_progress: { status: 409, type: "invalid_request_error", description: "The site already has a queued or running test run; wait for it (retrieveTestRun) or cancel it (cancelTestRun)." },
46
50
  legal_hold_active: { status: 409, type: "invalid_request_error", 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)." },
47
51
  idempotency_key_in_use: { status: 409, type: "idempotency_error", description: "A request with this Idempotency-Key is still being processed; retry shortly." },
package/dist/version.d.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  /** Version of this SDK (kept equal to packages/sdk-node/package.json "version"; a test checks it). */
2
- export declare const SDK_VERSION = "0.2.0";
2
+ export declare const SDK_VERSION = "0.2.2";
package/dist/version.js CHANGED
@@ -1,2 +1,2 @@
1
1
  /** Version of this SDK (kept equal to packages/sdk-node/package.json "version"; a test checks it). */
2
- export const SDK_VERSION = '0.2.0';
2
+ export const SDK_VERSION = '0.2.2';
package/package.json CHANGED
@@ -1,19 +1,29 @@
1
1
  {
2
2
  "name": "@checkbox-site/node",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "Checkbox Node.js SDK: automatic-renewal-law compliance (ROSCA, California ARL, New York and other state laws) for subscription businesses. Zero dependencies. Published to npm as @checkbox-site/node.",
5
5
  "keywords": [
6
6
  "subscription",
7
+ "subscription-compliance",
7
8
  "auto-renewal",
9
+ "autorenewal",
8
10
  "automatic-renewal",
9
11
  "compliance",
10
12
  "rosca",
11
13
  "click-to-cancel",
12
14
  "california-arl",
15
+ "auto-renewal-law",
16
+ "auto-renewal-compliance",
17
+ "subscription-cancellation",
18
+ "renewal-reminder",
19
+ "stripe-subscriptions",
20
+ "ftc",
21
+ "negative-option",
13
22
  "stripe",
14
23
  "stripe-checkout",
15
24
  "checkout",
16
- "cancellation"
25
+ "cancellation",
26
+ "mcp"
17
27
  ],
18
28
  "license": "MIT",
19
29
  "author": "Checkbox <support@checkbox.site>",