CheckboxDocs

Receipts API

Consent receipts (opt-in per account): for each subscriber checkout where they are on, a tamper-evident record of the disclosure visibly rendered next to the pay button and the consent given — a structured snapshot of the disclosure (visible text, sanitized HTML, legally relevant styles, checkbox st

ate, button label, layout), hashed, chained into the evidence vault, signed and re-rendered as an image on demand. For Stripe-hosted checkouts, reconstructed from Stripe's record. Evidence you can produce; not legal protection.

OperationEndpoint
Mint a capture token for a checkoutPOST /v1/receipt_tokens
List consent receiptsGET /v1/receipts
Record a consent receiptPOST /v1/receipts
Erase a subscriber's receiptsPOST /v1/receipts/erase
Retrieve a consent receiptGET /v1/receipts/{receipt}
Render a receipt as an imageGET /v1/receipts/{receipt}/render.png
Verify a receipt's integrityGET /v1/receipts/{receipt}/verify
Download a self-verifying receipt bundleGET /v1/receipts/{receipt}/export
Retrieve receipt settingsGET /v1/receipt_settings
Update receipt settingsPOST /v1/receipt_settings

The Receipt object

A consent receipt: a tamper-evident record of what one subscriber saw next to the pay button and agreed to at checkout. Evidence you can produce; not a legal opinion.

FieldTypeDescription
idstringUnique identifier of the receipt (rcpt_…).
objectenumString representing the object's type. Always "receipt".
livemodebooleantrue for live-mode objects, false for test mode (ck_test_ keys act on an isolated sandbox).
createdintegerWhen Checkbox recorded the receipt (server time). Unix timestamp in seconds.
sitestringSite the receipt belongs to.
sourceenumelements: <checkbox-disclosure>; snippet: /r.js; api: your server; stripe_*: reconstructed from Stripe's record of a Stripe-hosted page. One of elements, snippet, api, stripe_checkout, stripe_payment_link.
bindingenumbound: the browser presented a valid capture token your server minted; unbound: no (valid) token, so the receipt is a client claim; server: recorded by your server or reconstructed from Stripe. One of bound, unbound, server.
reconstructedbooleantrue when built from Stripe's record instead of the page the subscriber saw (lower evidentiary weight).
evidentiary_weightenumHow the record was obtained, strongest first. Not a legal assessment. One of direct_capture, direct_capture_unbound, server_record, reconstructed_from_stripe.
detectionobjectDisclosure detection.
detection.methodenumHow the disclosure region was found. One of elements, marked, auto, server, stripe.
detection.confidenceenumConfidence that the region is the disclosure. One of high, medium, low.
customer_referencestring | nullVerified subscriber reference (from the capture token, your server, or Stripe).
client_referencestring | nullReference the page claimed (unverified).
email_sha256string | nullHMAC-SHA-256 (keyed per account) of the subscriber's lowercased email, when your server gave one. Personal data: erased with the receipt.
checkout_sessionstring | nullStripe Checkout Session id.
subscriptionstring | nullSubscription id, when known.
consentstring | nullcons_… recorded with this receipt by <checkbox-disclosure>.
pre_checkout_receiptstring | nullFor Stripe-hosted checkouts: the rcpt_… captured on your page before the redirect.
page_urlstring | nullPage (origin + path, query string removed).
languagestring | nullPage / browser language.
user_agent_classstring | nullDevice + browser family (never the full user agent).
viewportobject | nullViewport at submit.
viewport.widthnumberCSS px.
viewport.heightnumberCSS px.
client_timestampinteger | nullDevice clock at capture (unix seconds; informational).
disclosureobjectWhat the disclosure said and how it was shown.
disclosure.textstringDisclosure text the subscriber saw (personal data redacted).
disclosure.sha256stringSHA-256 of the text.
disclosure.presentationobjectHow the disclosure was presented (null fields: not measured).
checkboxobject | nullThe consent checkbox (null: none found).
checkbox.presentbooleanA consent checkbox was found.
checkbox.checkedbooleanIt was ticked at submit.
checkbox.labelstring | nullIts label as captured. Null for receipts reconstructed from Stripe: Stripe's record has no checkbox wording, so none is claimed.
checkbox.requiredbooleanIt was required.
submit_labelstring | nullLabel of the button the subscriber pressed (null when not observed, e.g. Stripe-hosted pages).
stripeReceiptStripeRecord | nullThe Checkout Session as Stripe recorded it (Stripe-hosted checkouts and Payment Links).
flagsarray of stringsThings a reviewer should know: unbound, token_invalid, token_expired, token_used_up, token_site_mismatch, low_confidence_detection, disclosure_not_found, below_fold, not_above_submit, far_from_submit, low_contrast, small_font, hidden, hidden_text (text was present but not visibly rendered; left out), typed_text_masked, checkbox_unchecked, no_consent_checkbox, client_clock_skew, implausible_render_gap, reconstructed, no_pre_checkout_snapshot, linked_by_client_nonce, multiple_pre_checkout_candidates, stripe_mode_mismatch, no_terms_of_service_consent, no_custom_text, test_mode, unsigned.
integrityobjectTamper evidence. verifyReceipt checks all of it.
integrity.receipt_sha256stringSHA-256 of the canonical JSON receipt (keys sorted, no whitespace) — also the evidence record's content hash.
integrity.evidencestring | nullev_… record that chains the receipt into the site's evidence vault.
integrity.chain_hashstring | nullChain hash of that record.
integrity.public_key_idstring | nullEd25519 key that signed the receipt (published at /.well-known/checkbox-keys.json).
integrity.signedinteger | nullWhen it was signed (unix seconds).
retain_untilintegerWhen the receipt is deleted under your retention setting. Unix timestamp in seconds.
render_urlstringPNG of what the subscriber saw, re-rendered from the snapshot (renderReceipt, same auth).
next_actionNextActionWhat the caller (often an AI agent) should do next.

Mint a capture token for a checkout

POST /v1/receipt_tokens

Call from your server when you render a checkout page: returns a short-lived token (rct_…) to put into the page (data-receipt-token on the disclosure or form, or receipt-token on <checkbox-disclosure>). Receipts that present it are "bound" to this checkout and carry your customer_reference; receipts without one are accepted but flagged "unbound". For Stripe-hosted checkouts also set metadata.checkbox_receipt_token=<id> on the Checkout Session (or pass checkout_session here).

Scope receipts:write · Idempotent (send Idempotency-Key) · Operation createReceiptToken

SDK: checkbox.receiptTokens.create() (Node) · checkbox.receipt_tokens.create() (Python). MCP / agents: operation createReceiptToken.

Body

FieldTypeDescription
site requiredstringsite_… whose checkout page will present the token.
customer_referencestringYour id for the subscriber (Stripe customer id, your user id, order id). Copied onto the receipt as the verified customer_reference.
checkout_sessionstringStripe Checkout Session id when you already created it (links the Stripe record to this receipt). Or put the token id in the session's metadata.checkbox_receipt_token.
emailstringThe subscriber's email address; only an HMAC-SHA-256 under your account's own key is stored (listReceipts?email= finds receipts by it). Still personal data: covered by retention and eraseReceipts.
expires_inintegerSeconds until the token expires (default 3600).
max_usesintegerReceipts the token may bind (default 1: the subscriber can read the token in the page, so mint one per checkout attempt; raise it for checkouts that legitimately submit several times).
metadataobjectUp to 20 key/value string pairs you can attach to the object.

Returns

Returns a ReceiptToken object.

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

curl https://app.checkbox.site/v1/receipt_tokens \
  -u "$CHECKBOX_SECRET_KEY:" \
  -H "Content-Type: application/json" \
  -d '{
  "site": "site_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
  "customer_reference": "cus_Q2x9"
}'
Response
{
  "id": "rtok_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
  "object": "receipt_token",
  "livemode": false,
  "created": 1793318400,
  "expires": 1793318400,
  "site": "site_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
  "token": "rct_test_8Jq2k3…",
  "customer_reference": "cus_Q2x9",
  "checkout_session": null,
  "max_uses": 3,
  "html_attribute": "data-receipt-token=\"rct_test_8Jq2k3…\"",
  "metadata": {},
  "next_action": {
    "type": "verify_domain",
    "message": "Verify your site domain to turn on live mode.",
    "operation_id": "createDomainVerification",
    "mcp_tool": "call_api",
    "url": "https://checkbox.site/docs/concepts/activation#verify"
  }
}

List consent receipts

GET /v1/receipts

Receipts newest first. Filter by site, customer_reference (find the receipt behind a disputed subscription), checkout_session, email (hashed before the lookup), source, binding or creation time.

Scope receipts:read · Operation listReceipts

SDK: checkbox.receipts.list() (Node) · checkbox.receipts.list() (Python). MCP / agents: operation listReceipts.

Parameters

ParameterInTypeDescription
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).
sitequerystringOnly receipts of this site.
customer_referencequerystringOnly receipts for this subscriber reference.
checkout_sessionquerystringOnly receipts of this Stripe Checkout Session.
emailquerystringOnly receipts whose email hash matches this address (hashed before the lookup).
sourcequeryenumOnly this source. One of elements, snippet, api, stripe_checkout, stripe_payment_link.
bindingqueryenumOnly this binding. One of bound, unbound, server.
created_gtequeryinteger | nullCreated at or after (unix seconds).
created_ltequeryinteger | nullCreated at or before (unix seconds).

Returns

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

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

curl -G https://app.checkbox.site/v1/receipts \
  -u "$CHECKBOX_SECRET_KEY:" \
  -d limit=3
Response
{
  "object": "list",
  "data": [
    {
      "id": "rcpt_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
      "object": "receipt",
      "livemode": false,
      "created": 1793318400,
      "site": "site_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
      "source": "snippet",
      "binding": "bound",
      "reconstructed": false,
      "evidentiary_weight": "direct_capture",
      "detection": {
        "method": "marked",
        "confidence": "high"
      },
      "customer_reference": "cus_Q2x9",
      "client_reference": null,
      "email_sha256": null,
      "checkout_session": null,
      "subscription": null,
      "consent": null,
      "pre_checkout_receipt": null,
      "page_url": "https://acme.example/checkout",
      "language": "en-US",
      "user_agent_class": "desktop-chrome",
      "viewport": {
        "width": 1280,
        "height": 800
      },
      "client_timestamp": 1793318399,
      "disclosure": {
        "text": "Your Acme subscription renews automatically every month at $19.99 until you cancel.",
        "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
        "presentation": {
          "font_size_px": 16,
          "font_weight": 400,
          "color": "rgb(17, 24, 39)",
          "background_color": "rgb(255, 255, 255)",
          "contrast_ratio": 17.74,
          "visible": true,
          "set_off": true,
          "above_fold": true,
          "above_submit": true,
          "distance_to_submit_px": 12
        }
      },
      "checkbox": {
        "present": true,
        "checked": true,
        "label": "I agree to the automatic renewal terms.",
        "required": true
      },
      "submit_label": "Start subscription",
      "stripe": {
        "checkout_session": "cs_live_a1b2c3",
        "payment_link": null,
        "session_created": 1793318100,
        "completed": 1793318400,
        "terms_of_service": "required",
        "terms_of_service_accepted": true,
        "custom_text": {
          "submit": "Renews monthly at $19.99 until you cancel.",
          "terms_of_service_acceptance": null,
          "after_submit": null
        },
        "amount": 1999,
        "currency": "usd",
        "interval": "month",
        "interval_count": 1,
        "trial_days": 14,
        "subscription": "sub_1Q2"
      },
      "flags": [],
      "integrity": {
        "receipt_sha256": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
        "evidence": "ev_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
        "chain_hash": "2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae",
        "public_key_id": "1a2b3c4d5e6f7a8b",
        "signed": 1793318400
      },
      "retain_until": 1793318400,
      "render_url": "/v1/receipts/rcpt_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b/render.png",
      "next_action": {
        "type": "verify_domain",
        "message": "Verify your site domain to turn on live mode.",
        "operation_id": "createDomainVerification",
        "mcp_tool": "call_api",
        "url": "https://checkbox.site/docs/concepts/activation#verify"
      }
    }
  ],
  "has_more": false,
  "url": "/v1/sites"
}

Record a consent receipt

POST /v1/receipts

Records one receipt from the structured snapshot the browser captured at submit (the /r.js snippet add-on calls this with the publishable key, Origin-checked; servers may call it with a secret key and site). The snapshot is validated strictly and re-sanitized. Next: retrieveReceipt / renderReceipt to see it, verifyReceipt to check its integrity.

Key publishable (pk_…) or secret · Idempotent (send Idempotency-Key) · Operation createReceipt

SDK: checkbox.receipts.create() (Node) · checkbox.receipts.create() (Python). MCP / agents: operation createReceipt.

Body

FieldTypeDescription
sitestringsite_… the receipt belongs to. Optional with a publishable key (resolved from the page Origin); required with a secret key.
snapshot requiredobjectThe structured snapshot captured by /r.js or <checkbox-disclosure> (version 1): the disclosure region's text, sanitized subtree and computed styles, the consent checkbox state and label, the submit label, layout, viewport, page URL without query string, language and user-agent class. Validated strictly and re-sanitized by the server; it never contains form-field values.
tokenstringCapture token (rct_…) your server minted for this checkout with createReceiptToken. Binds the receipt to that checkout; without it the receipt is accepted but flagged "unbound".
client_referencestringA reference the page claims for the subscriber (unverified; kept apart from customer_reference).
capture_noncestringRandom nonce the snippet also put in a Payment Link's client_reference_id (ckbx_<nonce>), linking this pre-checkout snapshot to the Stripe record.
customer_referencestringSecret keys only: your id for the subscriber (Stripe customer / subscription / Checkout Session id). Not an email address.
checkout_sessionstringSecret keys only: the Stripe Checkout Session id this receipt belongs to.
emailstringSecret keys only: the subscriber's email address. Only an HMAC-SHA-256 of it (lowercased, trimmed; keyed per account) is stored.

Returns

Returns a Receipt object.

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

curl https://app.checkbox.site/v1/receipts \
  -u "$CHECKBOX_SECRET_KEY:" \
  -H "Content-Type: application/json" \
  -d '{
  "snapshot": {
    "v": 1,
    "phase": "submit",
    "captured_at": 1793318400000,
    "page_url": "https://acme.example/checkout",
    "viewport": {
      "width": 1280,
      "height": 800
    },
    "scroll": {
      "x": 0,
      "y": 0
    },
    "language": "en-US",
    "user_agent_class": "desktop-chrome",
    "detection": {
      "method": "marked",
      "confidence": "high",
      "reasons": [
        "marked_by_merchant"
      ]
    },
    "region": {
      "text": "Your Acme subscription renews automatically every month at $19.99 until you cancel.",
      "tree": [
        {
          "t": "p",
          "s": {
            "font-size": "16px"
          },
          "c": [
            "Your Acme subscription renews automatically every month at $19.99 until you cancel."
          ]
        }
      ],
      "rect": {
        "x": 40,
        "y": 520,
        "width": 480,
        "height": 72
      },
      "style": {
        "font_size_px": 16,
        "font_weight": 400,
        "color": "rgb(17, 24, 39)",
        "background_color": "rgb(255, 255, 255)",
        "contrast_ratio": 17.74,
        "opacity": 1,
        "visible": true
      },
      "set_off": true,
      "above_fold": true,
      "above_submit": true,
      "distance_to_submit_px": 12,
      "masked_fields": 0
    },
    "checkbox": {
      "present": true,
      "checked": true,
      "label": "I agree to the automatic renewal terms.",
      "required": true
    },
    "submit": {
      "label": "Start subscription",
      "rect": {
        "x": 40,
        "y": 604,
        "width": 480,
        "height": 44
      },
      "kind": "button"
    },
    "render": null
  },
  "site": "site_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b"
}'
Response
{
  "id": "rcpt_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
  "object": "receipt",
  "livemode": false,
  "created": 1793318400,
  "site": "site_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
  "source": "snippet",
  "binding": "bound",
  "reconstructed": false,
  "evidentiary_weight": "direct_capture",
  "detection": {
    "method": "marked",
    "confidence": "high"
  },
  "customer_reference": "cus_Q2x9",
  "client_reference": null,
  "email_sha256": null,
  "checkout_session": null,
  "subscription": null,
  "consent": null,
  "pre_checkout_receipt": null,
  "page_url": "https://acme.example/checkout",
  "language": "en-US",
  "user_agent_class": "desktop-chrome",
  "viewport": {
    "width": 1280,
    "height": 800
  },
  "client_timestamp": 1793318399,
  "disclosure": {
    "text": "Your Acme subscription renews automatically every month at $19.99 until you cancel.",
    "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
    "presentation": {
      "font_size_px": 16,
      "font_weight": 400,
      "color": "rgb(17, 24, 39)",
      "background_color": "rgb(255, 255, 255)",
      "contrast_ratio": 17.74,
      "visible": true,
      "set_off": true,
      "above_fold": true,
      "above_submit": true,
      "distance_to_submit_px": 12
    }
  },
  "checkbox": {
    "present": true,
    "checked": true,
    "label": "I agree to the automatic renewal terms.",
    "required": true
  },
  "submit_label": "Start subscription",
  "stripe": {
    "checkout_session": "cs_live_a1b2c3",
    "payment_link": null,
    "session_created": 1793318100,
    "completed": 1793318400,
    "terms_of_service": "required",
    "terms_of_service_accepted": true,
    "custom_text": {
      "submit": "Renews monthly at $19.99 until you cancel.",
      "terms_of_service_acceptance": null,
      "after_submit": null
    },
    "amount": 1999,
    "currency": "usd",
    "interval": "month",
    "interval_count": 1,
    "trial_days": 14,
    "subscription": "sub_1Q2"
  },
  "flags": [],
  "integrity": {
    "receipt_sha256": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
    "evidence": "ev_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
    "chain_hash": "2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae",
    "public_key_id": "1a2b3c4d5e6f7a8b",
    "signed": 1793318400
  },
  "retain_until": 1793318400,
  "render_url": "/v1/receipts/rcpt_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b/render.png",
  "next_action": {
    "type": "verify_domain",
    "message": "Verify your site domain to turn on live mode.",
    "operation_id": "createDomainVerification",
    "mcp_tool": "call_api",
    "url": "https://checkbox.site/docs/concepts/activation#verify"
  }
}

Erase a subscriber's receipts

POST /v1/receipts/erase

For a subscriber's deletion request: deletes every receipt that matches customer_reference, email (hashed before the lookup) or checkout_session (optionally only for one site). The signed copy in the write-once evidence vault is kept but holds only a salted commitment to the subscriber's identifiers; erasing destroys the salt, so it can no longer be tied to the person. Pending attorney review.

Scope receipts:write · Idempotent (send Idempotency-Key) · Operation eraseReceipts

SDK: checkbox.receipts.erase() (Node) · checkbox.receipts.erase() (Python). MCP / agents: operation eraseReceipts.

Body

FieldTypeDescription
customer_referencestringErase receipts with this customer_reference.
emailstringErase receipts recorded with this email (hashed before the lookup).
checkout_sessionstringErase receipts of this Stripe Checkout Session.
sitestringOnly this site_….

Returns

Returns a ReceiptErasure object.

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

curl https://app.checkbox.site/v1/receipts/erase \
  -u "$CHECKBOX_SECRET_KEY:" \
  -H "Content-Type: application/json" \
  -d '{
  "customer_reference": "cus_Q2x9"
}'
Response
{
  "object": "receipt_erasure",
  "livemode": false,
  "erased": 2
}

Retrieve a consent receipt

GET /v1/receipts/{receipt}

What one subscriber saw and agreed to at checkout: disclosure text and presentation, checkbox state and label, button label, page, time, binding, flags and integrity data. renderReceipt shows it as an image; exportReceipt downloads a self-verifying bundle.

Scope receipts:read · Operation retrieveReceipt

SDK: checkbox.receipts.retrieve() (Node) · checkbox.receipts.retrieve() (Python). MCP / agents: operation retrieveReceipt.

Parameters

ParameterInTypeDescription
receipt requiredpathstringUnique identifier of the receipt (rcpt_…).

Returns

Returns a Receipt object.

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

curl https://app.checkbox.site/v1/receipts/rcpt_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b \
  -u "$CHECKBOX_SECRET_KEY:"
Response
{
  "id": "rcpt_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
  "object": "receipt",
  "livemode": false,
  "created": 1793318400,
  "site": "site_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
  "source": "snippet",
  "binding": "bound",
  "reconstructed": false,
  "evidentiary_weight": "direct_capture",
  "detection": {
    "method": "marked",
    "confidence": "high"
  },
  "customer_reference": "cus_Q2x9",
  "client_reference": null,
  "email_sha256": null,
  "checkout_session": null,
  "subscription": null,
  "consent": null,
  "pre_checkout_receipt": null,
  "page_url": "https://acme.example/checkout",
  "language": "en-US",
  "user_agent_class": "desktop-chrome",
  "viewport": {
    "width": 1280,
    "height": 800
  },
  "client_timestamp": 1793318399,
  "disclosure": {
    "text": "Your Acme subscription renews automatically every month at $19.99 until you cancel.",
    "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
    "presentation": {
      "font_size_px": 16,
      "font_weight": 400,
      "color": "rgb(17, 24, 39)",
      "background_color": "rgb(255, 255, 255)",
      "contrast_ratio": 17.74,
      "visible": true,
      "set_off": true,
      "above_fold": true,
      "above_submit": true,
      "distance_to_submit_px": 12
    }
  },
  "checkbox": {
    "present": true,
    "checked": true,
    "label": "I agree to the automatic renewal terms.",
    "required": true
  },
  "submit_label": "Start subscription",
  "stripe": {
    "checkout_session": "cs_live_a1b2c3",
    "payment_link": null,
    "session_created": 1793318100,
    "completed": 1793318400,
    "terms_of_service": "required",
    "terms_of_service_accepted": true,
    "custom_text": {
      "submit": "Renews monthly at $19.99 until you cancel.",
      "terms_of_service_acceptance": null,
      "after_submit": null
    },
    "amount": 1999,
    "currency": "usd",
    "interval": "month",
    "interval_count": 1,
    "trial_days": 14,
    "subscription": "sub_1Q2"
  },
  "flags": [],
  "integrity": {
    "receipt_sha256": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
    "evidence": "ev_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
    "chain_hash": "2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae",
    "public_key_id": "1a2b3c4d5e6f7a8b",
    "signed": 1793318400
  },
  "retain_until": 1793318400,
  "render_url": "/v1/receipts/rcpt_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b/render.png",
  "next_action": {
    "type": "verify_domain",
    "message": "Verify your site domain to turn on live mode.",
    "operation_id": "createDomainVerification",
    "mcp_tool": "call_api",
    "url": "https://checkbox.site/docs/concepts/activation#verify"
  }
}

Render a receipt as an image

GET /v1/receipts/{receipt}/render.png

A PNG of "what the subscriber saw", rendered on demand in an isolated Chromium (no network, scripts disabled) from the sanitized snapshot — a reconstruction, labeled as such, not a screenshot taken from the browser.

Scope receipts:read · Operation renderReceipt

SDK: checkbox.receipts.render() (Node) · checkbox.receipts.render() (Python). MCP / agents: operation renderReceipt.

Parameters

ParameterInTypeDescription
receipt requiredpathstringUnique identifier of the receipt (rcpt_…).

Returns

Returns the file (image/png).

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

curl https://app.checkbox.site/v1/receipts/rcpt_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b/render.png \
  -u "$CHECKBOX_SECRET_KEY:"

Verify a receipt's integrity

GET /v1/receipts/{receipt}/verify

Re-hashes the stored receipt, checks Checkbox's Ed25519 signature over its hash and chain position, and verifies the site's evidence chain. For a check that does not rely on Checkbox, download exportReceipt and run its verify.mjs.

Scope receipts:read · Operation verifyReceipt

SDK: checkbox.receipts.verify() (Node) · checkbox.receipts.verify() (Python). MCP / agents: operation verifyReceipt.

Parameters

ParameterInTypeDescription
receipt requiredpathstringUnique identifier of the receipt (rcpt_…).

Returns

Returns a ReceiptVerification object.

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

curl https://app.checkbox.site/v1/receipts/rcpt_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b/verify \
  -u "$CHECKBOX_SECRET_KEY:"
Response
{
  "object": "receipt_verification",
  "receipt": "rcpt_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
  "verified": true,
  "checks": {
    "content": {
      "ok": true,
      "message": "sha256 matches"
    },
    "signature": {
      "ok": true,
      "message": "signed by 1a2b3c4d5e6f7a8b"
    },
    "chain": {
      "ok": true,
      "message": "42 records checked"
    },
    "index": {
      "ok": true,
      "message": "the receipt as shown matches the signed document",
      "linked_after_signing": []
    }
  },
  "receipt_sha256": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
  "verified_at": 1793318400,
  "offline": "GET /v1/receipts/rcpt_…/export, unzip, node verify.mjs --keys checkbox-keys.json"
}

Download a self-verifying receipt bundle

GET /v1/receipts/{receipt}/export

ZIP for a lawyer, insurer or court expert: manifest.json (the receipt's evidence record with its chain links) + manifest.sig.json, the canonical receipt JSON under records/, receipt.sig.json (Checkbox's signature over the receipt hash), receipt.png and render.html (the reconstruction), README.md and verify.mjs (zero-dependency offline verifier: node verify.mjs --keys checkbox-keys.json).

Scope receipts:read · Operation exportReceipt

SDK: checkbox.receipts.export() (Node) · checkbox.receipts.export() (Python). MCP / agents: operation exportReceipt.

Parameters

ParameterInTypeDescription
receipt requiredpathstringUnique identifier of the receipt (rcpt_…).

Returns

Returns the file (application/zip).

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

curl https://app.checkbox.site/v1/receipts/rcpt_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b/export \
  -u "$CHECKBOX_SECRET_KEY:"

Retrieve receipt settings

GET /v1/receipt_settings

Whether consent receipts are collected for this account (in this mode) and how long they are kept.

Scope receipts:read · Operation retrieveReceiptSettings

SDK: checkbox.receiptSettings.retrieve() (Node) · checkbox.receipt_settings.retrieve() (Python). MCP / agents: operation retrieveReceiptSettings.

Returns

Returns a ReceiptSettings object.

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

curl https://app.checkbox.site/v1/receipt_settings \
  -u "$CHECKBOX_SECRET_KEY:"
Response
{
  "object": "receipt_settings",
  "livemode": false,
  "enabled": true,
  "retention_days": 1461,
  "updated": 1793318400
}

Update receipt settings

POST /v1/receipt_settings

Turn receipts on or off and set the retention in days (default 1461 = 4 years, the California UCL limitation period; pending attorney review). A new retention applies to receipts recorded afterwards.

Scope receipts:write · Idempotent (send Idempotency-Key) · Operation updateReceiptSettings

SDK: checkbox.receiptSettings.update() (Node) · checkbox.receipt_settings.update() (Python). MCP / agents: operation updateReceiptSettings.

Body

FieldTypeDescription
enabledbooleanTurn receipt collection on or off.
retention_daysintegerDays to keep receipts (30–3653). Applies to new receipts.

Returns

Returns a ReceiptSettings object.

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

curl https://app.checkbox.site/v1/receipt_settings \
  -u "$CHECKBOX_SECRET_KEY:" \
  -H "Content-Type: application/json" \
  -d '{
  "retention_days": 1461
}'
Response
{
  "object": "receipt_settings",
  "livemode": false,
  "enabled": true,
  "retention_days": 1461,
  "updated": 1793318400
}

Checkbox is compliance software, not a law firm; nothing in these docs is legal advice (details). You remain solely responsible for your subscription program, and Checkbox takes on no legal liability for it (Terms). Checkbox is a System1 company; Trust center · Status. For AI agents: every page is available as Markdown at the same URL plus .md; the index is /llms.txt.