CheckboxDocs

Compliance plans API

The agent-to-agent fix loop: an ordered, machine-readable plan of changes (requirement + citation, where, the exact patch / copy / Stripe params, how to verify), verification of each change, and questions for the human where a machine cannot decide.

OperationEndpoint
Get the compliance plan for a siteGET /v1/sites/{site}/plan
Get one task of a compliance planGET /v1/tasks/{task}
Claim, decline or reopen a taskPOST /v1/tasks/{task}
Record the human answer to a manual taskPOST /v1/tasks/{task}/answer
Verify a task after applying its changePOST /v1/tasks/{task}/verify
Re-check the whole site nowPOST /v1/sites/{site}/verify
Get a verification (long-poll with ?wait=30)GET /v1/verifications/{verification}
List verifications of a siteGET /v1/sites/{site}/verifications

The CompliancePlan object

The ordered, machine-readable list of changes that makes a site compliant, recomputed from its latest evaluation.

FieldTypeDescription
idstringUnique identifier of the compliance plan (plan_…).
objectenumString representing the object's type. Always "compliance_plan".
livemodebooleantrue for live-mode objects, false for test mode (ck_test_ keys act on an isolated sandbox).
sitestringThe site.
statusenumaction_required (an agent can apply open tasks now), verifying (changes applied; waiting for confirming observations), compliant (every applicable check Checkbox could observe passes — an automated assessment, not a legal determination; see coverage for what was not observed), blocked (only human answers or declined critical tasks remain). One of action_required, verifying, compliant, blocked.
scoreinteger | nullCompliance score 0-100 of the latest evaluation.
insurableboolean | nullPreview flag the planned Checkbox Warranty will key on (no checks failing at high severity). No warranty or insurance is offered yet; this is not an underwriting decision.
evaluationstring | nullThe evaluation the plan was built from (null before the first check).
evaluatedinteger | nullWhen that evaluation ran. Unix timestamp in seconds.
summarystringTwo or three sentences for an LLM: where the site stands and what comes next.
countsobjectTasks per status.
counts.openintegerOpen tasks.
counts.in_progressintegerClaimed tasks.
counts.verifyingintegerTasks waiting for a confirming observation.
counts.manualintegerTasks waiting for a human answer.
counts.doneintegerDone tasks.
counts.wont_fixintegerDeclined tasks.
tasksarray of TasksTasks in the order to do them (done tasks last).
coverageobjectWhat the assessment rests on. Tell the human about not_observed and attested items; never call the site "compliant" without them.
coverage.observedarray of stringsLifecycle stages Checkbox observed (signup, acknowledgment_email, reminders, cancellation, policies, billing_settings).
coverage.not_observedarray of stringsStages Checkbox has no observation of: their checks cannot fail, so passing says nothing about them.
coverage.attestedarray of stringsTask keys resting on a human confirmation instead of an observation.
coverage.billing_connectedbooleanA billing platform is connected (dashboard).
next_actionPlanNextActionWhat the caller (usually an AI coding agent) should do next.
rules_versionstring | nullRules / catalog version of the evaluation.
disclaimerstringAutomated assessment; not legal advice.
generatedintegerWhen the plan was computed. Unix timestamp in seconds.

Get the compliance plan for a site

GET /v1/sites/{site}/plan

Ordered tasks that make the site compliant, recomputed from its latest evaluation: each with the requirement and citation, where to change (file / URL / selector / Stripe object), the exact change (unified-diff template with machine-applicable edits, copy, or Stripe params) and how to verify it. Do plan.next_action: apply the first open task, call verifyTask, repeat until status is compliant. Tasks with status manual hold a question for the human (answerTask); they never block the others.

Scope compliance_plans:read · Operation retrieveCompliancePlan

SDK: checkbox.plans.retrieve() (Node) · checkbox.plans.retrieve() (Python). MCP / agents: operation retrieveCompliancePlan.

Parameters

ParameterInTypeDescription
site requiredpathstringUnique identifier of the site (site_…).

Returns

Returns a CompliancePlan object.

Errors use the standard envelope with a stable code and, where useful, next_action.

curl https://app.checkbox.site/v1/sites/site_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b/plan \
  -u "$CHECKBOX_SECRET_KEY:"
Response
{
  "id": "plan_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
  "object": "compliance_plan",
  "livemode": false,
  "site": "site_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
  "status": "action_required",
  "score": 62,
  "insurable": false,
  "evaluation": "eval_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
  "evaluated": 1793318400,
  "summary": "StreamMax fails 4 critical checks…",
  "counts": {
    "open": 3,
    "in_progress": 0,
    "verifying": 1,
    "manual": 1,
    "done": 2,
    "wont_fix": 0
  },
  "tasks": [
    {
      "id": "task_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
      "object": "task",
      "livemode": false,
      "site": "site_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
      "key": "signup_disclosure",
      "title": "Show the renewal terms and an unchecked consent box above the Subscribe button",
      "status": "open",
      "priority": "critical",
      "order": 1,
      "check_ids": [
        "signup.disclosure.autorenew_language"
      ],
      "findings": [],
      "requirement": {
        "jurisdictions": [
          "US-FED"
        ],
        "citation": "15 U.S.C. § 8403(1); Cal. Bus. & Prof. Code § 17602(a)(1)",
        "citations": [
          {
            "id": "US-CA.17602.a.1",
            "jurisdiction": "US-CA",
            "citation": "Cal. Bus. & Prof. Code § 17602(a)(1)",
            "source_url": "https://leginfo.legislature.ca.gov/"
          }
        ],
        "plain_language": "Before the purchase, state clearly that the subscription renews automatically until canceled, the price and frequency, and how to cancel."
      },
      "why": "The checkout in US-CA shows no renewal terms near \"Start now\"; the consent checkbox is pre-checked.",
      "where": {
        "kind": "code",
        "file_hint": "app/checkout/page.tsx",
        "url": "https://shop.example/checkout",
        "selector": "#subscribe-button",
        "stripe_object": "checkout.session"
      },
      "change": {
        "type": "patch",
        "content": "--- a/app/checkout/page.tsx\n+++ b/app/checkout/page.tsx\n@@ …",
        "language": "html",
        "explanation": "Insert directly above the purchase button; never pre-check the box.",
        "edits": [
          {
            "op": "insert_before",
            "target": {},
            "content": "<div class=\"checkbox-renewal-terms\">…</div>",
            "attribute": "checked"
          }
        ],
        "engine_verified": true,
        "operation_id": "updateSite",
        "endpoint": "POST /v1/sites/site_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b"
      },
      "verify": {
        "method": "page_fetch",
        "how": "POST /v1/tasks/task_…/verify",
        "expected": "Every listed check passes (layout checks may stay needs_review on a static fetch until the confirming scan)."
      },
      "blocked_on": null,
      "closed_reason": null,
      "depends_on": [],
      "blocked_by": [],
      "question": {
        "text": "Did your subscribers choose email as the channel for account notices?",
        "options": [
          "yes"
        ],
        "why": "New York requires notices in the manner the subscriber selected; no page or email shows that choice.",
        "effect": "yes records the attestation (site fact notice_channel_email) and re-evaluates."
      },
      "answer": {
        "value": "yes",
        "note": null,
        "answered": 1793318400,
        "confirmed_by_human": false,
        "pending_confirmation_url": null
      },
      "decision": {
        "status": "wont_fix",
        "reason": "Annual plan retired; no subscribers left."
      },
      "last_verification": {
        "id": "ver_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
        "status": "failed",
        "created": 1793318400
      },
      "next_action": {
        "type": "apply_task",
        "description": "Apply task_… (add the renewal terms above the Subscribe button in app/checkout/page.tsx), then call verifyTask.",
        "task": "task_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
        "operation_id": "verifyTask",
        "mcp_tool": "verify_task",
        "endpoint": "POST /v1/tasks/task_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b/verify",
        "command": "checkbox fix task_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b"
      },
      "first_seen": 1793318400,
      "done_at": 1793318400
    }
  ],
  "coverage": {
    "observed": [
      "signup"
    ],
    "not_observed": [
      "cancellation"
    ],
    "attested": [],
    "billing_connected": false
  },
  "next_action": {
    "type": "apply_task",
    "description": "Apply task_… (add the renewal terms above the Subscribe button in app/checkout/page.tsx), then call verifyTask.",
    "task": "task_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
    "operation_id": "verifyTask",
    "mcp_tool": "verify_task",
    "endpoint": "POST /v1/tasks/task_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b/verify",
    "command": "checkbox fix task_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b"
  },
  "rules_version": "1.2.0",
  "disclaimer": "Checkbox checks against its legal catalog; it is not legal advice.",
  "generated": 1793318400
}

Get one task of a compliance plan

GET /v1/tasks/{task}

The task as in the current plan (recomputed): the change to apply, how to verify, its last verification and next_action.

Scope compliance_plans:read · Operation retrieveTask

SDK: checkbox.tasks.retrieve() (Node) · checkbox.tasks.retrieve() (Python). MCP / agents: operation retrieveTask.

Parameters

ParameterInTypeDescription
task requiredpathstringUnique identifier of the task (task_…).

Returns

Returns a Task object.

Errors use the standard envelope with a stable code and, where useful, next_action.

curl https://app.checkbox.site/v1/tasks/task_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b \
  -u "$CHECKBOX_SECRET_KEY:"
Response
{
  "id": "task_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
  "object": "task",
  "livemode": false,
  "site": "site_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
  "key": "signup_disclosure",
  "title": "Show the renewal terms and an unchecked consent box above the Subscribe button",
  "status": "open",
  "priority": "critical",
  "order": 1,
  "check_ids": [
    "signup.disclosure.autorenew_language",
    "signup.consent.affirmative"
  ],
  "findings": [],
  "requirement": {
    "jurisdictions": [
      "US-FED"
    ],
    "citation": "15 U.S.C. § 8403(1); Cal. Bus. & Prof. Code § 17602(a)(1)",
    "citations": [
      {
        "id": "US-CA.17602.a.1",
        "jurisdiction": "US-CA",
        "citation": "Cal. Bus. & Prof. Code § 17602(a)(1)",
        "source_url": "https://leginfo.legislature.ca.gov/"
      }
    ],
    "plain_language": "Before the purchase, state clearly that the subscription renews automatically until canceled, the price and frequency, and how to cancel."
  },
  "why": "The checkout in US-CA shows no renewal terms near \"Start now\"; the consent checkbox is pre-checked.",
  "where": {
    "kind": "code",
    "file_hint": "app/checkout/page.tsx",
    "url": "https://shop.example/checkout",
    "selector": "#subscribe-button",
    "stripe_object": "checkout.session"
  },
  "change": {
    "type": "patch",
    "content": "--- a/app/checkout/page.tsx\n+++ b/app/checkout/page.tsx\n@@ …",
    "language": "html",
    "explanation": "Insert directly above the purchase button; never pre-check the box.",
    "edits": [
      {
        "op": "insert_before",
        "target": {
          "selector": "#subscribe-button",
          "text": "Start now",
          "tag": "button"
        },
        "content": "<div class=\"checkbox-renewal-terms\">…</div>",
        "attribute": "checked"
      }
    ],
    "engine_verified": true,
    "operation_id": "updateSite",
    "endpoint": "POST /v1/sites/site_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b"
  },
  "verify": {
    "method": "page_fetch",
    "how": "POST /v1/tasks/task_…/verify",
    "expected": "Every listed check passes (layout checks may stay needs_review on a static fetch until the confirming scan)."
  },
  "blocked_on": null,
  "closed_reason": null,
  "depends_on": [],
  "blocked_by": [],
  "question": {
    "text": "Did your subscribers choose email as the channel for account notices?",
    "options": [
      "yes"
    ],
    "why": "New York requires notices in the manner the subscriber selected; no page or email shows that choice.",
    "effect": "yes records the attestation (site fact notice_channel_email) and re-evaluates."
  },
  "answer": {
    "value": "yes",
    "note": null,
    "answered": 1793318400,
    "confirmed_by_human": false,
    "pending_confirmation_url": null
  },
  "decision": {
    "status": "wont_fix",
    "reason": "Annual plan retired; no subscribers left."
  },
  "last_verification": {
    "id": "ver_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
    "status": "failed",
    "created": 1793318400
  },
  "next_action": {
    "type": "apply_task",
    "description": "Apply task_… (add the renewal terms above the Subscribe button in app/checkout/page.tsx), then call verifyTask.",
    "task": "task_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
    "operation_id": "verifyTask",
    "mcp_tool": "verify_task",
    "endpoint": "POST /v1/tasks/task_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b/verify",
    "command": "checkbox fix task_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b"
  },
  "first_seen": 1793318400,
  "done_at": 1793318400
}

Claim, decline or reopen a task

POST /v1/tasks/{task}

status in_progress claims the task (shown to other agents and the dashboard); wont_fix declines it with a reason (the merchant's decision, recorded; a declined critical or high task keeps the plan blocked); open clears the decision. Applying a change does not need this call: call verifyTask.

Scope compliance_plans:write · Idempotent (send Idempotency-Key) · Operation updateTask

SDK: checkbox.tasks.update() (Node) · checkbox.tasks.update() (Python). MCP / agents: operation updateTask.

Parameters

ParameterInTypeDescription
task requiredpathstringUnique identifier of the task (task_…).

Body

FieldTypeDescription
status requiredenumin_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), open clears either. One of open, in_progress, wont_fix.
reasonstringWhy (required for wont_fix).

Returns

Returns a Task object.

Errors use the standard envelope with a stable code and, where useful, next_action.

curl https://app.checkbox.site/v1/tasks/task_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b \
  -u "$CHECKBOX_SECRET_KEY:" \
  -H "Content-Type: application/json" \
  -d '{
  "status": "in_progress"
}'
Response
{
  "id": "task_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
  "object": "task",
  "livemode": false,
  "site": "site_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
  "key": "signup_disclosure",
  "title": "Show the renewal terms and an unchecked consent box above the Subscribe button",
  "status": "open",
  "priority": "critical",
  "order": 1,
  "check_ids": [
    "signup.disclosure.autorenew_language",
    "signup.consent.affirmative"
  ],
  "findings": [],
  "requirement": {
    "jurisdictions": [
      "US-FED"
    ],
    "citation": "15 U.S.C. § 8403(1); Cal. Bus. & Prof. Code § 17602(a)(1)",
    "citations": [
      {
        "id": "US-CA.17602.a.1",
        "jurisdiction": "US-CA",
        "citation": "Cal. Bus. & Prof. Code § 17602(a)(1)",
        "source_url": "https://leginfo.legislature.ca.gov/"
      }
    ],
    "plain_language": "Before the purchase, state clearly that the subscription renews automatically until canceled, the price and frequency, and how to cancel."
  },
  "why": "The checkout in US-CA shows no renewal terms near \"Start now\"; the consent checkbox is pre-checked.",
  "where": {
    "kind": "code",
    "file_hint": "app/checkout/page.tsx",
    "url": "https://shop.example/checkout",
    "selector": "#subscribe-button",
    "stripe_object": "checkout.session"
  },
  "change": {
    "type": "patch",
    "content": "--- a/app/checkout/page.tsx\n+++ b/app/checkout/page.tsx\n@@ …",
    "language": "html",
    "explanation": "Insert directly above the purchase button; never pre-check the box.",
    "edits": [
      {
        "op": "insert_before",
        "target": {
          "selector": "#subscribe-button",
          "text": "Start now",
          "tag": "button"
        },
        "content": "<div class=\"checkbox-renewal-terms\">…</div>",
        "attribute": "checked"
      }
    ],
    "engine_verified": true,
    "operation_id": "updateSite",
    "endpoint": "POST /v1/sites/site_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b"
  },
  "verify": {
    "method": "page_fetch",
    "how": "POST /v1/tasks/task_…/verify",
    "expected": "Every listed check passes (layout checks may stay needs_review on a static fetch until the confirming scan)."
  },
  "blocked_on": null,
  "closed_reason": null,
  "depends_on": [],
  "blocked_by": [],
  "question": {
    "text": "Did your subscribers choose email as the channel for account notices?",
    "options": [
      "yes"
    ],
    "why": "New York requires notices in the manner the subscriber selected; no page or email shows that choice.",
    "effect": "yes records the attestation (site fact notice_channel_email) and re-evaluates."
  },
  "answer": {
    "value": "yes",
    "note": null,
    "answered": 1793318400,
    "confirmed_by_human": false,
    "pending_confirmation_url": null
  },
  "decision": {
    "status": "wont_fix",
    "reason": "Annual plan retired; no subscribers left."
  },
  "last_verification": {
    "id": "ver_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
    "status": "failed",
    "created": 1793318400
  },
  "next_action": {
    "type": "apply_task",
    "description": "Apply task_… (add the renewal terms above the Subscribe button in app/checkout/page.tsx), then call verifyTask.",
    "task": "task_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
    "operation_id": "verifyTask",
    "mcp_tool": "verify_task",
    "endpoint": "POST /v1/tasks/task_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b/verify",
    "command": "checkbox fix task_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b"
  },
  "first_seen": 1793318400,
  "done_at": 1793318400
}

Record the human answer to a manual task

POST /v1/tasks/{task}/answer

For tasks with status manual: record the human's answer to task.question (ask them; never answer on their behalf). Answers that assert a legal fact (yes, confirmed) are stored as a proposal and return next_action.type "ask_human_to_confirm" with a link the human opens while signed in to Checkbox; only their confirmation writes the attestation, sets the site fact and re-evaluates. no / needs_change turn the task into a change for the agent; done (after a dashboard-only step) re-checks at once. Every answer is stored in the evidence vault.

Scope compliance_plans:write · Idempotent (send Idempotency-Key) · Operation answerTask

SDK: checkbox.tasks.answer() (Node) · checkbox.tasks.answer() (Python). MCP / agents: operation answerTask.

Parameters

ParameterInTypeDescription
task requiredpathstringUnique identifier of the task (task_…).

Body

FieldTypeDescription
answer requiredstringOne of the task's question.options (yes / no, or confirmed / needs_change).
notestringContext from the human (stored with the attestation).

Returns

Returns a Task object.

Errors use the standard envelope with a stable code and, where useful, next_action.

curl https://app.checkbox.site/v1/tasks/task_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b/answer \
  -u "$CHECKBOX_SECRET_KEY:" \
  -H "Content-Type: application/json" \
  -d '{
  "answer": "yes"
}'
Response
{
  "id": "task_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
  "object": "task",
  "livemode": false,
  "site": "site_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
  "key": "signup_disclosure",
  "title": "Show the renewal terms and an unchecked consent box above the Subscribe button",
  "status": "open",
  "priority": "critical",
  "order": 1,
  "check_ids": [
    "signup.disclosure.autorenew_language",
    "signup.consent.affirmative"
  ],
  "findings": [],
  "requirement": {
    "jurisdictions": [
      "US-FED"
    ],
    "citation": "15 U.S.C. § 8403(1); Cal. Bus. & Prof. Code § 17602(a)(1)",
    "citations": [
      {
        "id": "US-CA.17602.a.1",
        "jurisdiction": "US-CA",
        "citation": "Cal. Bus. & Prof. Code § 17602(a)(1)",
        "source_url": "https://leginfo.legislature.ca.gov/"
      }
    ],
    "plain_language": "Before the purchase, state clearly that the subscription renews automatically until canceled, the price and frequency, and how to cancel."
  },
  "why": "The checkout in US-CA shows no renewal terms near \"Start now\"; the consent checkbox is pre-checked.",
  "where": {
    "kind": "code",
    "file_hint": "app/checkout/page.tsx",
    "url": "https://shop.example/checkout",
    "selector": "#subscribe-button",
    "stripe_object": "checkout.session"
  },
  "change": {
    "type": "patch",
    "content": "--- a/app/checkout/page.tsx\n+++ b/app/checkout/page.tsx\n@@ …",
    "language": "html",
    "explanation": "Insert directly above the purchase button; never pre-check the box.",
    "edits": [
      {
        "op": "insert_before",
        "target": {
          "selector": "#subscribe-button",
          "text": "Start now",
          "tag": "button"
        },
        "content": "<div class=\"checkbox-renewal-terms\">…</div>",
        "attribute": "checked"
      }
    ],
    "engine_verified": true,
    "operation_id": "updateSite",
    "endpoint": "POST /v1/sites/site_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b"
  },
  "verify": {
    "method": "page_fetch",
    "how": "POST /v1/tasks/task_…/verify",
    "expected": "Every listed check passes (layout checks may stay needs_review on a static fetch until the confirming scan)."
  },
  "blocked_on": null,
  "closed_reason": null,
  "depends_on": [],
  "blocked_by": [],
  "question": {
    "text": "Did your subscribers choose email as the channel for account notices?",
    "options": [
      "yes"
    ],
    "why": "New York requires notices in the manner the subscriber selected; no page or email shows that choice.",
    "effect": "yes records the attestation (site fact notice_channel_email) and re-evaluates."
  },
  "answer": {
    "value": "yes",
    "note": null,
    "answered": 1793318400,
    "confirmed_by_human": false,
    "pending_confirmation_url": null
  },
  "decision": {
    "status": "wont_fix",
    "reason": "Annual plan retired; no subscribers left."
  },
  "last_verification": {
    "id": "ver_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
    "status": "failed",
    "created": 1793318400
  },
  "next_action": {
    "type": "apply_task",
    "description": "Apply task_… (add the renewal terms above the Subscribe button in app/checkout/page.tsx), then call verifyTask.",
    "task": "task_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
    "operation_id": "verifyTask",
    "mcp_tool": "verify_task",
    "endpoint": "POST /v1/tasks/task_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b/verify",
    "command": "checkbox fix task_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b"
  },
  "first_seen": 1793318400,
  "done_at": 1793318400
}

Verify a task after applying its change

POST /v1/tasks/{task}/verify

Runs the fastest re-check that can confirm the task (static fetch of the live checkout or the html you send, the Stripe params you send, the email copy you send, a re-fetch of the Terms) and queues the confirming observation (a scan, a billing-platform sync, the next email). A failing pre-check fails the verification at once with a diff. Pass ?wait=30 to long-poll; otherwise poll retrieveVerification or wait for the task.verified webhook. Then follow next_action.

Scope compliance_plans:write · Idempotent (send Idempotency-Key) · Operation verifyTask

SDK: checkbox.tasks.verify() (Node) · checkbox.tasks.verify() (Python). MCP / agents: operation verifyTask.

Parameters

ParameterInTypeDescription
task requiredpathstringUnique identifier of the task (task_…).
waitqueryinteger | nullLong-poll: wait up to this many seconds (0-30) for the verification to resolve before answering.

Body

FieldTypeDescription
htmlstringpage_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.
stripe_checkout_sessionobjectstripe_params tasks: exactly what your code now passes to stripe.checkout.sessions.create.
emailobjectemail_copy tasks: the new email template (pre-check; the real email confirms).
email.kindenumEmail kind (default: from the task). One of acknowledgment, trial_reminder, renewal_reminder, price_change, annual_terms, charge_notice, cancellation_confirmation.
email.subject requiredstringSubject.
email.textstringPlain-text body.
email.htmlstringHTML body.

Returns

Returns a Verification object.

Errors use the standard envelope with a stable code and, where useful, next_action.

curl https://app.checkbox.site/v1/tasks/task_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b/verify \
  -u "$CHECKBOX_SECRET_KEY:" \
  -H "Content-Type: application/json" \
  -d '{}'
Response
{
  "id": "ver_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
  "object": "verification",
  "livemode": false,
  "site": "site_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
  "task": "task_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
  "scope": "task",
  "status": "pending",
  "method": "page_fetch",
  "precheck": {
    "source": "static_fetch",
    "verdict": "pass",
    "url": "https://shop.example/checkout",
    "note": "Static fetch: text checks are exact; layout is estimated until the confirming scan."
  },
  "scan": "scan_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
  "checks": [
    {
      "check_id": "signup.disclosure.price",
      "expected": "pass",
      "observed": "fail",
      "source": "static_fetch",
      "detail": "No recurring price near the purchase button."
    }
  ],
  "diff": [
    {
      "check_id": "signup.disclosure.price",
      "expected": "pass",
      "observed": "fail",
      "source": "static_fetch",
      "detail": "No recurring price near the purchase button."
    }
  ],
  "plan_status": "action_required",
  "next_action": {
    "type": "apply_task",
    "description": "Apply task_… (add the renewal terms above the Subscribe button in app/checkout/page.tsx), then call verifyTask.",
    "task": "task_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
    "operation_id": "verifyTask",
    "mcp_tool": "verify_task",
    "endpoint": "POST /v1/tasks/task_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b/verify",
    "command": "checkbox fix task_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b"
  },
  "created": 1793318400,
  "completed": 1793318400,
  "expires": 1793318400
}

Re-check the whole site now

POST /v1/sites/{site}/verify

Re-fetches the registered policies, pre-checks the checkout, re-evaluates and queues a scan. Use it for the first check after setup, or after applying several tasks. Pass ?wait=30 to long-poll; then get the plan (retrieveCompliancePlan).

Scope compliance_plans:write · Idempotent (send Idempotency-Key) · Operation verifySite

SDK: checkbox.sites.verify() (Node) · checkbox.sites.verify() (Python). MCP / agents: operation verifySite.

Parameters

ParameterInTypeDescription
site requiredpathstringUnique identifier of the site (site_…).
waitqueryinteger | nullLong-poll: wait up to this many seconds (0-30) for the verification to resolve before answering.

Returns

Returns a Verification object.

Errors use the standard envelope with a stable code and, where useful, next_action.

curl https://app.checkbox.site/v1/sites/site_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b/verify \
  -u "$CHECKBOX_SECRET_KEY:" \
  -X POST
Response
{
  "id": "ver_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
  "object": "verification",
  "livemode": false,
  "site": "site_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
  "task": "task_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
  "scope": "task",
  "status": "pending",
  "method": "page_fetch",
  "precheck": {
    "source": "static_fetch",
    "verdict": "pass",
    "url": "https://shop.example/checkout",
    "note": "Static fetch: text checks are exact; layout is estimated until the confirming scan."
  },
  "scan": "scan_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
  "checks": [
    {
      "check_id": "signup.disclosure.price",
      "expected": "pass",
      "observed": "fail",
      "source": "static_fetch",
      "detail": "No recurring price near the purchase button."
    }
  ],
  "diff": [
    {
      "check_id": "signup.disclosure.price",
      "expected": "pass",
      "observed": "fail",
      "source": "static_fetch",
      "detail": "No recurring price near the purchase button."
    }
  ],
  "plan_status": "action_required",
  "next_action": {
    "type": "apply_task",
    "description": "Apply task_… (add the renewal terms above the Subscribe button in app/checkout/page.tsx), then call verifyTask.",
    "task": "task_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
    "operation_id": "verifyTask",
    "mcp_tool": "verify_task",
    "endpoint": "POST /v1/tasks/task_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b/verify",
    "command": "checkbox fix task_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b"
  },
  "created": 1793318400,
  "completed": 1793318400,
  "expires": 1793318400
}

Get a verification (long-poll with ?wait=30)

GET /v1/verifications/{verification}

The verification's status (pending, passed, failed), expected vs observed per check, the diff and next_action. ?wait=N (≤ 30) holds the request until it resolves or N seconds pass.

Scope compliance_plans:read · Operation retrieveVerification

SDK: checkbox.verifications.retrieve() (Node) · checkbox.verifications.retrieve() (Python). MCP / agents: operation retrieveVerification.

Parameters

ParameterInTypeDescription
verification requiredpathstringUnique identifier of the verification (ver_…).
waitqueryinteger | nullLong-poll: wait up to this many seconds (0-30) for the verification to resolve before answering.

Returns

Returns a Verification object.

Errors use the standard envelope with a stable code and, where useful, next_action.

curl https://app.checkbox.site/v1/verifications/ver_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b \
  -u "$CHECKBOX_SECRET_KEY:"
Response
{
  "id": "ver_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
  "object": "verification",
  "livemode": false,
  "site": "site_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
  "task": "task_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
  "scope": "task",
  "status": "pending",
  "method": "page_fetch",
  "precheck": {
    "source": "static_fetch",
    "verdict": "pass",
    "url": "https://shop.example/checkout",
    "note": "Static fetch: text checks are exact; layout is estimated until the confirming scan."
  },
  "scan": "scan_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
  "checks": [
    {
      "check_id": "signup.disclosure.price",
      "expected": "pass",
      "observed": "fail",
      "source": "static_fetch",
      "detail": "No recurring price near the purchase button."
    }
  ],
  "diff": [
    {
      "check_id": "signup.disclosure.price",
      "expected": "pass",
      "observed": "fail",
      "source": "static_fetch",
      "detail": "No recurring price near the purchase button."
    }
  ],
  "plan_status": "action_required",
  "next_action": {
    "type": "apply_task",
    "description": "Apply task_… (add the renewal terms above the Subscribe button in app/checkout/page.tsx), then call verifyTask.",
    "task": "task_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
    "operation_id": "verifyTask",
    "mcp_tool": "verify_task",
    "endpoint": "POST /v1/tasks/task_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b/verify",
    "command": "checkbox fix task_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b"
  },
  "created": 1793318400,
  "completed": 1793318400,
  "expires": 1793318400
}

List verifications of a site

GET /v1/sites/{site}/verifications

Verifications newest first (optionally for one task).

Scope compliance_plans:read · Operation listVerifications

SDK: checkbox.verifications.list() (Node) · checkbox.verifications.list() (Python). MCP / agents: operation listVerifications.

Parameters

ParameterInTypeDescription
site requiredpathstringUnique identifier of the site (site_…).
limitqueryintegerNumber of objects to return, 1-100 (default 10).
starting_afterquerystringCursor: an object id; returns the objects after it (older).
ending_beforequerystringCursor: an object id; returns the objects before it (newer).
taskquerystringOnly this task (task_…).

Returns

Returns a list ({ object: "list", data, has_more, url }) of Verification objects.

Errors use the standard envelope with a stable code and, where useful, next_action.

curl -G https://app.checkbox.site/v1/sites/site_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b/verifications \
  -u "$CHECKBOX_SECRET_KEY:" \
  -d limit=3
Response
{
  "object": "list",
  "data": [
    {
      "id": "ver_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
      "object": "verification",
      "livemode": false,
      "site": "site_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
      "task": "task_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
      "scope": "task",
      "status": "pending",
      "method": "page_fetch",
      "precheck": {
        "source": "static_fetch",
        "verdict": "pass",
        "url": "https://shop.example/checkout",
        "note": "Static fetch: text checks are exact; layout is estimated until the confirming scan."
      },
      "scan": "scan_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
      "checks": [
        {
          "check_id": "signup.disclosure.price",
          "expected": "pass",
          "observed": "fail",
          "source": "static_fetch",
          "detail": "No recurring price near the purchase button."
        }
      ],
      "diff": [
        {
          "check_id": "signup.disclosure.price",
          "expected": "pass",
          "observed": "fail",
          "source": "static_fetch",
          "detail": "No recurring price near the purchase button."
        }
      ],
      "plan_status": "action_required",
      "next_action": {
        "type": "apply_task",
        "description": "Apply task_… (add the renewal terms above the Subscribe button in app/checkout/page.tsx), then call verifyTask.",
        "task": "task_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
        "operation_id": "verifyTask",
        "mcp_tool": "verify_task",
        "endpoint": "POST /v1/tasks/task_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b/verify",
        "command": "checkbox fix task_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b"
      },
      "created": 1793318400,
      "completed": 1793318400,
      "expires": 1793318400
    }
  ],
  "has_more": false,
  "url": "/v1/sites"
}

Checkbox is compliance software, not a law firm; nothing in these docs is legal advice (details). For AI agents: every page is available as Markdown at the same URL plus .md; the index is /llms.txt.