Skip to content

Checkout tools

MCP tools for Checkout: checkout_hosted_attach_payment_method, checkout_hosted_confirm, checkout_hosted_confirm_waitlist, checkout_hosted_get, checkout_hosted_join_waitlist, checkout_hosted_leave_waitlist, checkout_hosted_payment_secret, checkout_hosted_resume_waitlist, checkout_hosted_start_payment, checkout_hosted_submit_details, checkout_sessions_create, checkout_sessions_expire, checkout_sessions_get.

  • checkout_hosted_attach_payment_method: Add the payment method
  • checkout_hosted_confirm: Confirm the payment
  • checkout_hosted_confirm_waitlist: Confirm a waitlist sign-up
  • checkout_hosted_get: Get a hosted checkout
  • checkout_hosted_join_waitlist: Join the waitlist
  • checkout_hosted_leave_waitlist: Leave the waitlist
  • checkout_hosted_payment_secret: Get the payment component's secret
  • checkout_hosted_resume_waitlist: Continue to checkout from the waitlist
  • checkout_hosted_start_payment: Start the payment step
  • checkout_hosted_submit_details: Submit the customer's details
  • checkout_sessions_create: Create a checkout session
  • checkout_sessions_expire: Expire a checkout session
  • checkout_sessions_get: Get a checkout session

checkout_hosted_attach_payment_method

Add the checkout payment method. Operation checkout.hosted.attach_payment_method · Brand level · permission checkout:write · risk tier write · since M4

Records the payment method the customer entered (the Stripe Payment Element's pm_…, or a fake test card) and reads its card's country from the processor. The card country joins the location evidence in a new evidence set and the sale is quoted again (spec §13.3). If the total changes, the page shows the new total, the customer confirms it, and the payment intent is updated before the charge (checkout.hosted.confirm refuses an outdated total with checkout_total_changed).

The brand's risk rules run again with the card's fingerprint and country (spec §20): a refused card is risk_payment_declined, and the customer can try another.

Public: the hosted page calls it with the session key.

Annotations: readOnlyHint: false · destructiveHint: false · idempotentHint: false · openWorldHint: true

Arguments

ArgumentTypeRequiredDescription
sessionIdID (cs_…)yesThe checkout session's ID (cs_…).
keystringnoThe session key from the hosted URL (?key=…). Required without an API key; signed-in callers with checkout:write don't need it.
paymentMethodstringyesThe payment method the customer entered (Stripe pm_…; the fake processor's pm_fake_…). (1–255 characters)
entity_idID (ent_…)noOptional: the brand's legal entity (ent_…); brand_id alone is enough.
brand_idID (brd_…)noThe brand to act on (brd_…), inside your API key's reach. Needed with an organization or entity key; a brand key acts on its own brand.
idempotency_keystringnoA unique string for this change. Retrying with the same key and arguments never acts twice. When left out, the server generates one and returns it in the result's idempotency_key. (1–255 characters)
  • Brand: pass brand_id with an organization or entity key; a brand key acts on its own brand.
  • Idempotency: the result returns the idempotency_key used, yours or one the server generated. Retry with it: a call with the same key and arguments never acts twice (keys are kept for 24 hours).
  • Dry run: not supported. dry_run: true fails with dry_run_not_supported.

Errors

Example

A card from Germany

Arguments:

JSON
{
  "sessionId": "cs_01m4tx5nj8emwbyf7y9vcf48aa",
  "key": "Zk3tq8Vb2xQ9mN4rP7sL1yH6cJ0wE5aD-uT_fG8hK2o",
  "paymentMethod": "pm_fake_card_de",
  "brand_id": "brd_01jbx4m3v8e9t0s6k2c5n7q1wz",
  "idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}

Result output:

JSON
{
  "id": "cs_01m4tx5nj8emwbyf7y9vcf48aa",
  "object": "checkout.hosted_session",
  "livemode": false,
  "status": "open",
  "mode": "payment",
  "currency": "EUR",
  "brand": {
    "slug": "genno",
    "name": "Genno",
    "primaryColor": null,
    "termsUrl": "https://genno.example/terms",
    "privacyUrl": "https://genno.example/privacy",
    "supportEmail": null
  },
  "seller": {
    "legalName": "Etna Labs AG",
    "address": "Dammstrasse 16, 6300 Zug, Switzerland",
    "taxId": "CHE-181.927.786 MWST"
  },
  "lineItems": [
    {
      "id": "1",
      "description": "Genno credits",
      "quantity": 1,
      "amount": {
        "amount": "100000000",
        "currency": "EUR"
      },
      "recurring": null,
      "adjustableQuantity": null,
      "discount": null
    }
  ],
  "subscription": null,
  "topup": null,
  "setup": null,
  "collectBusinessDetails": "auto",
  "prefill": {
    "email": "anna@example.com",
    "name": null,
    "country": "DE",
    "subdivision": null,
    "business": null
  },
  "quote": {
    "id": "tq_01m4tx5nj8emwbyf7y9vcf48ab",
    "decision": "charge",
    "customerType": "b2c",
    "country": "DE",
    "lines": [
      {
        "id": "1",
        "description": "Genno credits",
        "quantity": 1,
        "treatment": "charge",
        "net": {
          "amount": "84033613",
          "currency": "EUR"
        },
        "tax": {
          "amount": "15966387",
          "currency": "EUR"
        },
        "gross": {
          "amount": "100000000",
          "currency": "EUR"
        },
        "ratePpm": "190000",
        "jurisdictionId": "DE",
        "jurisdictionName": "Germany",
        "taxName": "VAT",
        "regimeId": "EU_OSS_NON_UNION",
        "pendingRegistration": false,
        "taxBehavior": "inclusive"
      }
    ],
    "totals": {
      "net": {
        "amount": "84033613",
        "currency": "EUR"
      },
      "tax": {
        "amount": "15966387",
        "currency": "EUR"
      },
      "gross": {
        "amount": "100000000",
        "currency": "EUR"
      }
    },
    "inclusive": true,
    "reverseCharge": false,
    "reverseChargeWording": null,
    "validUntil": "2026-10-14T10:30:00.000Z",
    "unverifiedRules": false
  },
  "blocked": null,
  "waitlist": null,
  "payment": {
    "started": true,
    "intent": "payment",
    "component": "fake",
    "publishableKey": null,
    "paymentMethod": {
      "ref": "pm_fake_card_de",
      "type": "card",
      "cardCountry": "DE",
      "brand": "visa",
      "last4": "4242"
    },
    "upToDate": true
  },
  "legal": {
    "termsAccepted": true,
    "immediatePerformanceRequired": true,
    "immediatePerformanceText": "I want the service to start now, and I understand that I lose my right to withdraw once it has started."
  },
  "successUrl": null,
  "cancelUrl": "https://shop.example/cart",
  "expiresAt": "2026-10-15T10:00:00.000Z",
  "locale": {
    "preferred": [],
    "brand": ["en"]
  }
}

checkout_hosted_confirm

Confirm the checkout payment. Operation checkout.hosted.confirm · Brand level · permission checkout:write · risk tier financial · since M4

The customer's confirmation: the brand's terms accepted and, for EU and UK consumers buying digital services delivered at once, the consent to immediate performance and the loss of the withdrawal right (stored with the time, the text version and the IP country). The total the customer saw must still be the quote's (checkout_total_changed otherwise) and the quote must be current (checkout_quote_expired).

The brand's risk rules run a last time (spec §20): a refused payment is risk_payment_declined; when they ask for 3-D Secure, the payment intent requests it. The payment intent is brought up to date, then:

  • fake processor: the payment is confirmed here with the chosen test card: succeeded, processing, requires_action (a fake 3-D Secure challenge: confirm again to pass it) or a decline;
  • Stripe: the answer is client_confirm, and the browser confirms in the Payment Element (3-D Secure included);
  • Mollie (redirect): the answer is redirect with redirectUrl, Mollie's payment page, where the buyer chooses a method the brand's Mollie profile offers (cards, iDEAL, Bancontact, …) and pays; Mollie sends them back to the checkout's success page. The session waits for the webhook (processing); a payment that fails, is cancelled or expires on Mollie's page brings it back to open, and confirming again starts a new payment.

The sale is recorded only when the processor's webhook confirms the payment; poll checkout.hosted.get until the session is complete. Public: the hosted page calls it with the session key.

Annotations: readOnlyHint: false · destructiveHint: false · idempotentHint: false · openWorldHint: true

Arguments

ArgumentTypeRequiredDescription
sessionIdID (cs_…)yesThe checkout session's ID (cs_…).
keystringnoThe session key from the hosted URL (?key=…). Required without an API key; signed-in callers with checkout:write don't need it.
paymentMethodstringnoThe fake processor's payment method to charge (the Stripe Payment Element confirms in the browser). (1–255 characters)
expectedTotalobjectyesThe total the customer saw and agreed to pay.
acceptTermsbooleanyesThe customer accepted the brand's terms.
immediatePerformancebooleannoEU and UK consumers buying digital services: consent to immediate performance and the loss of the withdrawal right.
localeone of en, de, fr, hr, it, esnoThe language the consents were shown in; they are recorded with it (text version 2026-10-20/de).
entity_idID (ent_…)noOptional: the brand's legal entity (ent_…); brand_id alone is enough.
brand_idID (brd_…)noThe brand to act on (brd_…), inside your API key's reach. Needed with an organization or entity key; a brand key acts on its own brand.
idempotency_keystringnoA unique string for this change. Retrying with the same key and arguments never acts twice. When left out, the server generates one and returns it in the result's idempotency_key. (1–255 characters)
  • Brand: pass brand_id with an organization or entity key; a brand key acts on its own brand.
  • Idempotency: the result returns the idempotency_key used, yours or one the server generated. Retry with it: a call with the same key and arguments never acts twice (keys are kept for 24 hours).
  • Dry run: not supported. dry_run: true fails with dry_run_not_supported.

Errors

Example

Pay with a fake test card

Arguments:

JSON
{
  "sessionId": "cs_01m4tx5nj8emwbyf7y9vcf48aa",
  "key": "Zk3tq8Vb2xQ9mN4rP7sL1yH6cJ0wE5aD-uT_fG8hK2o",
  "paymentMethod": "pm_fake_card_de",
  "expectedTotal": {
    "amount": "100000000",
    "currency": "EUR"
  },
  "acceptTerms": true,
  "immediatePerformance": true,
  "brand_id": "brd_01jbx4m3v8e9t0s6k2c5n7q1wz",
  "idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}

Result output:

JSON
{
  "session": {
    "id": "cs_01m4tx5nj8emwbyf7y9vcf48aa",
    "object": "checkout.hosted_session",
    "livemode": false,
    "status": "processing",
    "mode": "payment",
    "currency": "EUR",
    "brand": {
      "slug": "genno",
      "name": "Genno",
      "primaryColor": null,
      "termsUrl": "https://genno.example/terms",
      "privacyUrl": "https://genno.example/privacy",
      "supportEmail": null
    },
    "seller": {
      "legalName": "Etna Labs AG",
      "address": "Dammstrasse 16, 6300 Zug, Switzerland",
      "taxId": "CHE-181.927.786 MWST"
    },
    "lineItems": [
      {
        "id": "1",
        "description": "Genno credits",
        "quantity": 1,
        "amount": {
          "amount": "100000000",
          "currency": "EUR"
        },
        "recurring": null,
        "adjustableQuantity": null,
        "discount": null
      }
    ],
    "subscription": null,
    "topup": null,
    "setup": null,
    "collectBusinessDetails": "auto",
    "prefill": {
      "email": "anna@example.com",
      "name": null,
      "country": "DE",
      "subdivision": null,
      "business": null
    },
    "quote": {
      "id": "tq_01m4tx5nj8emwbyf7y9vcf48ab",
      "decision": "charge",
      "customerType": "b2c",
      "country": "DE",
      "lines": [
        {
          "id": "1",
          "description": "Genno credits",
          "quantity": 1,
          "treatment": "charge",
          "net": {
            "amount": "84033613",
            "currency": "EUR"
          },
          "tax": {
            "amount": "15966387",
            "currency": "EUR"
          },
          "gross": {
            "amount": "100000000",
            "currency": "EUR"
          },
          "ratePpm": "190000",
          "jurisdictionId": "DE",
          "jurisdictionName": "Germany",
          "taxName": "VAT",
          "regimeId": "EU_OSS_NON_UNION",
          "pendingRegistration": false,
          "taxBehavior": "inclusive"
        }
      ],
      "totals": {
        "net": {
          "amount": "84033613",
          "currency": "EUR"
        },
        "tax": {
          "amount": "15966387",
          "currency": "EUR"
        },
        "gross": {
          "amount": "100000000",
          "currency": "EUR"
        }
      },
      "inclusive": true,
      "reverseCharge": false,
      "reverseChargeWording": null,
      "validUntil": "2026-10-14T10:30:00.000Z",
      "unverifiedRules": false
    },
    "blocked": null,
    "waitlist": null,
    "payment": {
      "started": true,
      "intent": "payment",
      "component": "fake",
      "publishableKey": null,
      "paymentMethod": {
        "ref": "pm_fake_card_de",
        "type": "card",
        "cardCountry": "DE",
        "brand": "visa",
        "last4": "4242"
      },
      "upToDate": true
    },
    "legal": {
      "termsAccepted": true,
      "immediatePerformanceRequired": true,
      "immediatePerformanceText": "I want the service to start now, and I understand that I lose my right to withdraw once it has started."
    },
    "successUrl": null,
    "cancelUrl": "https://shop.example/cart",
    "expiresAt": "2026-10-15T10:00:00.000Z",
    "locale": {
      "preferred": [],
      "brand": ["en"]
    }
  },
  "confirmation": "succeeded",
  "redirectUrl": null
}

checkout_hosted_confirm_waitlist

Confirm a waitlist sign-up. Operation checkout.hosted.confirm_waitlist · Brand level · permission checkout:write · risk tier write · since M4

Confirms a waitlist entry with the token from its email (double opt-in, spec §23). The token is the proof: no session key is needed. Only the latest link sent works, for 7 days; confirming twice changes nothing.

Annotations: readOnlyHint: false · destructiveHint: false · idempotentHint: true · openWorldHint: false

Arguments

ArgumentTypeRequiredDescription
sessionIdID (cs_…)yesThe checkout session's ID (cs_…).
entryID (wl_…)yesThe waitlist entry (wl_…) from the confirmation link.
tokenstringyesThe token from the confirmation link. (1–100 characters)
entity_idID (ent_…)noOptional: the brand's legal entity (ent_…); brand_id alone is enough.
brand_idID (brd_…)noThe brand to act on (brd_…), inside your API key's reach. Needed with an organization or entity key; a brand key acts on its own brand.
idempotency_keystringnoA unique string for this change. Retrying with the same key and arguments never acts twice. When left out, the server generates one and returns it in the result's idempotency_key. (1–255 characters)
  • Brand: pass brand_id with an organization or entity key; a brand key acts on its own brand.
  • Idempotency: the result returns the idempotency_key used, yours or one the server generated. Retry with it: a call with the same key and arguments never acts twice (keys are kept for 24 hours).
  • Dry run: not supported. dry_run: true fails with dry_run_not_supported.

Errors

Example

Confirm from the email

Arguments:

JSON
{
  "sessionId": "cs_01m4tx5nj8emwbyf7y9vcf48aa",
  "entry": "wl_01m4tx5nj8emwbyf7y9vcf48ah",
  "token": "q9VhN3bXk2mR7tY4wP8sZ1cL6fJ0dG5aE-uB_nH3oKx",
  "brand_id": "brd_01jbx4m3v8e9t0s6k2c5n7q1wz",
  "idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}

Result output:

JSON
{
  "status": "confirmed",
  "brandName": "Genno",
  "country": "GB",
  "countryName": "United Kingdom"
}

checkout_hosted_get

Get a hosted checkout. Operation checkout.hosted.get · Brand level · permission checkout:read · risk tier read · since M4

Returns a checkout session as its hosted page shows it: the brand and the seller's disclosure, the line items, the customer's details so far, the current tax quote (lines with rate, jurisdiction and regime; the totals), why the sale is paused and whether the waitlist is offered, the payment step, the legal consents and, once complete, the success URL. The page polls it until the session is complete.

Public: the hosted page calls it without an API key, with the session key from its URL (?key=…).

Annotations: readOnlyHint: true · destructiveHint: false · idempotentHint: true · openWorldHint: false

Arguments

ArgumentTypeRequiredDescription
sessionIdID (cs_…)yesThe checkout session's ID (cs_…).
keystringnoThe session key from the hosted URL (?key=…). Required without an API key; signed-in callers with checkout:write don't need it.
entity_idID (ent_…)noOptional: the brand's legal entity (ent_…); brand_id alone is enough.
brand_idID (brd_…)noThe brand to act on (brd_…), inside your API key's reach. Needed with an organization or entity key; a brand key acts on its own brand.
  • Brand: pass brand_id with an organization or entity key; a brand key acts on its own brand.
  • Read-only: changes nothing; idempotency_key is ignored.

Errors

  • resource_not_found: No such checkout session for this brand and mode, or (on the hosted page) the session key is missing or wrong.

Example

A consumer in Germany, quoted

Arguments:

JSON
{
  "sessionId": "cs_01m4tx5nj8emwbyf7y9vcf48aa",
  "key": "Zk3tq8Vb2xQ9mN4rP7sL1yH6cJ0wE5aD-uT_fG8hK2o",
  "brand_id": "brd_01jbx4m3v8e9t0s6k2c5n7q1wz"
}

Result output:

JSON
{
  "id": "cs_01m4tx5nj8emwbyf7y9vcf48aa",
  "object": "checkout.hosted_session",
  "livemode": false,
  "status": "open",
  "mode": "payment",
  "currency": "EUR",
  "brand": {
    "slug": "genno",
    "name": "Genno",
    "primaryColor": null,
    "termsUrl": "https://genno.example/terms",
    "privacyUrl": "https://genno.example/privacy",
    "supportEmail": null
  },
  "seller": {
    "legalName": "Etna Labs AG",
    "address": "Dammstrasse 16, 6300 Zug, Switzerland",
    "taxId": "CHE-181.927.786 MWST"
  },
  "lineItems": [
    {
      "id": "1",
      "description": "Genno credits",
      "quantity": 1,
      "amount": {
        "amount": "100000000",
        "currency": "EUR"
      },
      "recurring": null,
      "adjustableQuantity": null,
      "discount": null
    }
  ],
  "subscription": null,
  "topup": null,
  "setup": null,
  "collectBusinessDetails": "auto",
  "prefill": {
    "email": "anna@example.com",
    "name": null,
    "country": "DE",
    "subdivision": null,
    "business": null
  },
  "quote": {
    "id": "tq_01m4tx5nj8emwbyf7y9vcf48ab",
    "decision": "charge",
    "customerType": "b2c",
    "country": "DE",
    "lines": [
      {
        "id": "1",
        "description": "Genno credits",
        "quantity": 1,
        "treatment": "charge",
        "net": {
          "amount": "84033613",
          "currency": "EUR"
        },
        "tax": {
          "amount": "15966387",
          "currency": "EUR"
        },
        "gross": {
          "amount": "100000000",
          "currency": "EUR"
        },
        "ratePpm": "190000",
        "jurisdictionId": "DE",
        "jurisdictionName": "Germany",
        "taxName": "VAT",
        "regimeId": "EU_OSS_NON_UNION",
        "pendingRegistration": false,
        "taxBehavior": "inclusive"
      }
    ],
    "totals": {
      "net": {
        "amount": "84033613",
        "currency": "EUR"
      },
      "tax": {
        "amount": "15966387",
        "currency": "EUR"
      },
      "gross": {
        "amount": "100000000",
        "currency": "EUR"
      }
    },
    "inclusive": true,
    "reverseCharge": false,
    "reverseChargeWording": null,
    "validUntil": "2026-10-14T10:30:00.000Z",
    "unverifiedRules": false
  },
  "blocked": null,
  "waitlist": null,
  "payment": {
    "started": false,
    "intent": null,
    "component": null,
    "publishableKey": null,
    "paymentMethod": null,
    "upToDate": false
  },
  "legal": {
    "termsAccepted": false,
    "immediatePerformanceRequired": true,
    "immediatePerformanceText": "I want the service to start now, and I understand that I lose my right to withdraw once it has started."
  },
  "successUrl": null,
  "cancelUrl": "https://shop.example/cart",
  "expiresAt": "2026-10-15T10:00:00.000Z",
  "locale": {
    "preferred": [],
    "brand": ["en"]
  }
}

checkout_hosted_join_waitlist

Join the waitlist. Operation checkout.hosted.join_waitlist · Brand level · permission checkout:write · risk tier write · since M4

When a sale is paused for the customer's location (the session is blocked because the seller isn't registered there yet), the customer can ask to be told when the brand can sell there: “Notify me when {brand} can sell in {country}” (spec §23). The entry stores the email, the country, what they wanted to buy and its value, and stays pending until the customer confirms through the link in the email (double opt-in; the link works for 7 days). Joining again sends a new link; a confirmed entry stays confirmed.

Public: the hosted page calls it with the session key.

Annotations: readOnlyHint: false · destructiveHint: false · idempotentHint: false · openWorldHint: true

Arguments

ArgumentTypeRequiredDescription
sessionIdID (cs_…)yesThe checkout session's ID (cs_…).
keystringnoThe session key from the hosted URL (?key=…). Required without an API key; signed-in callers with checkout:write don't need it.
emailstringyesWhere the confirmation and, later, the notification go. (at most 254 characters)
consentbooleanyesThe customer agreed to “Notify me when {brand} can sell in {country}”.
localeone of en, de, fr, hr, it, esnoThe language the consent was shown in: it is stored in that language, and the emails use it.
entity_idID (ent_…)noOptional: the brand's legal entity (ent_…); brand_id alone is enough.
brand_idID (brd_…)noThe brand to act on (brd_…), inside your API key's reach. Needed with an organization or entity key; a brand key acts on its own brand.
idempotency_keystringnoA unique string for this change. Retrying with the same key and arguments never acts twice. When left out, the server generates one and returns it in the result's idempotency_key. (1–255 characters)
  • Brand: pass brand_id with an organization or entity key; a brand key acts on its own brand.
  • Idempotency: the result returns the idempotency_key used, yours or one the server generated. Retry with it: a call with the same key and arguments never acts twice (keys are kept for 24 hours).
  • Dry run: not supported. dry_run: true fails with dry_run_not_supported.

Errors

Example

A consumer in the UK

Arguments:

JSON
{
  "sessionId": "cs_01m4tx5nj8emwbyf7y9vcf48aa",
  "key": "Zk3tq8Vb2xQ9mN4rP7sL1yH6cJ0wE5aD-uT_fG8hK2o",
  "email": "oliver@example.com",
  "consent": true,
  "brand_id": "brd_01jbx4m3v8e9t0s6k2c5n7q1wz",
  "idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}

Result output:

JSON
{
  "id": "cs_01m4tx5nj8emwbyf7y9vcf48aa",
  "object": "checkout.hosted_session",
  "livemode": false,
  "status": "blocked",
  "mode": "payment",
  "currency": "EUR",
  "brand": {
    "slug": "genno",
    "name": "Genno",
    "primaryColor": null,
    "termsUrl": "https://genno.example/terms",
    "privacyUrl": "https://genno.example/privacy",
    "supportEmail": null
  },
  "seller": {
    "legalName": "Etna Labs AG",
    "address": "Dammstrasse 16, 6300 Zug, Switzerland",
    "taxId": "CHE-181.927.786 MWST"
  },
  "lineItems": [
    {
      "id": "1",
      "description": "Genno credits",
      "quantity": 1,
      "amount": {
        "amount": "100000000",
        "currency": "EUR"
      },
      "recurring": null,
      "adjustableQuantity": null,
      "discount": null
    }
  ],
  "subscription": null,
  "topup": null,
  "setup": null,
  "collectBusinessDetails": "auto",
  "prefill": {
    "email": "oliver@example.com",
    "name": null,
    "country": "GB",
    "subdivision": null,
    "business": null
  },
  "quote": null,
  "blocked": {
    "reason": "registration_required",
    "country": "GB",
    "countryName": "United Kingdom",
    "waitlistOffered": true,
    "businessOffered": true
  },
  "waitlist": {
    "entryId": "wl_01m4tx5nj8emwbyf7y9vcf48ah",
    "status": "pending",
    "email": "oliver@example.com",
    "consentText": "Notify me when Genno can sell in United Kingdom"
  },
  "payment": {
    "started": false,
    "intent": null,
    "component": null,
    "publishableKey": null,
    "paymentMethod": null,
    "upToDate": false
  },
  "legal": {
    "termsAccepted": false,
    "immediatePerformanceRequired": true,
    "immediatePerformanceText": "I want the service to start now, and I understand that I lose my right to withdraw once it has started."
  },
  "successUrl": null,
  "cancelUrl": "https://shop.example/cart",
  "expiresAt": "2026-10-15T10:00:00.000Z",
  "locale": {
    "preferred": [],
    "brand": ["en"]
  }
}

checkout_hosted_leave_waitlist

Leave the waitlist. Operation checkout.hosted.leave_waitlist · Brand level · permission checkout:write · risk tier write · since M7

Takes a customer off the brand's waitlist with the link from the waitlist's emails (the confirmation and the one saying the brand can sell): the entry is never notified, and a pending one can't be confirmed any more. The token is the proof: no session key is needed. Leaving twice changes nothing. Joining again later starts a new double opt-in (spec §23).

Public: the hosted page calls it when the customer confirms with a button, never on page load.

Annotations: readOnlyHint: false · destructiveHint: false · idempotentHint: true · openWorldHint: false

Arguments

ArgumentTypeRequiredDescription
sessionIdID (cs_…)yesThe checkout session's ID (cs_…).
entryID (wl_…)yesThe waitlist entry (wl_…) from the link.
tokenstringyesThe token from the link. (1–100 characters)
entity_idID (ent_…)noOptional: the brand's legal entity (ent_…); brand_id alone is enough.
brand_idID (brd_…)noThe brand to act on (brd_…), inside your API key's reach. Needed with an organization or entity key; a brand key acts on its own brand.
idempotency_keystringnoA unique string for this change. Retrying with the same key and arguments never acts twice. When left out, the server generates one and returns it in the result's idempotency_key. (1–255 characters)
  • Brand: pass brand_id with an organization or entity key; a brand key acts on its own brand.
  • Idempotency: the result returns the idempotency_key used, yours or one the server generated. Retry with it: a call with the same key and arguments never acts twice (keys are kept for 24 hours).
  • Dry run: not supported. dry_run: true fails with dry_run_not_supported.

Errors

Example

Leave from the email

Arguments:

JSON
{
  "sessionId": "cs_01m4tx5nj8emwbyf7y9vcf48aa",
  "entry": "wl_01m4tx5nj8emwbyf7y9vcf48ah",
  "token": "Qm9vdF9sZWF2ZV90b2tlbl9leGFtcGxlXzAwMDAwMDA",
  "brand_id": "brd_01jbx4m3v8e9t0s6k2c5n7q1wz",
  "idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}

Result output:

JSON
{
  "object": "waitlist_departure",
  "status": "left",
  "brandName": "Genno",
  "country": "GB",
  "countryName": "United Kingdom",
  "leftAt": "2026-10-19T09:30:00.000Z"
}

checkout_hosted_payment_secret

Get the checkout payment secret. Operation checkout.hosted.payment_secret · Brand level · permission checkout:read · risk tier read · since M4

Returns what the browser's payment component needs to show and confirm the session's payment: Stripe's client secret and the connection's publishable key, read from the processor each time. It is never stored by Ownrecord. Call it after checkout.hosted.start_payment.

Public: the hosted page calls it with the session key.

Annotations: readOnlyHint: true · destructiveHint: false · idempotentHint: true · openWorldHint: true

Arguments

ArgumentTypeRequiredDescription
sessionIdID (cs_…)yesThe checkout session's ID (cs_…).
keystringnoThe session key from the hosted URL (?key=…). Required without an API key; signed-in callers with checkout:write don't need it.
entity_idID (ent_…)noOptional: the brand's legal entity (ent_…); brand_id alone is enough.
brand_idID (brd_…)noThe brand to act on (brd_…), inside your API key's reach. Needed with an organization or entity key; a brand key acts on its own brand.
  • Brand: pass brand_id with an organization or entity key; a brand key acts on its own brand.
  • Read-only: changes nothing; idempotency_key is ignored.

Errors

Example

Stripe

Arguments:

JSON
{
  "sessionId": "cs_01m4tx5nj8emwbyf7y9vcf48aa",
  "key": "Zk3tq8Vb2xQ9mN4rP7sL1yH6cJ0wE5aD-uT_fG8hK2o",
  "brand_id": "brd_01jbx4m3v8e9t0s6k2c5n7q1wz"
}

Result output:

JSON
{
  "component": "stripe_payment_element",
  "clientSecret": "pi_3Q0example_secret_example",
  "publishableKey": "pk_test_51Qexample",
  "intent": "payment"
}

checkout_hosted_resume_waitlist

Continue to checkout from the waitlist. Operation checkout.hosted.resume_waitlist · Brand level · permission checkout:write · risk tier write · since M7

Once the brand can sell in a waitlist customer's country, the email it sends them links here: a fresh checkout session for what they wanted to buy (the lines, URLs and settings of the session they joined from, with their email), made when they click, so the link doesn't expire with a session. While that session is open, the same link returns it. The token is the proof: no session key is needed. Send the customer to url.

Public: the hosted page calls it when the customer clicks “Continue to checkout”.

Annotations: readOnlyHint: false · destructiveHint: false · idempotentHint: false · openWorldHint: false

Arguments

ArgumentTypeRequiredDescription
sessionIdID (cs_…)yesThe checkout session's ID (cs_…).
entryID (wl_…)yesThe waitlist entry (wl_…) from the link.
tokenstringyesThe token from the link. (1–100 characters)
entity_idID (ent_…)noOptional: the brand's legal entity (ent_…); brand_id alone is enough.
brand_idID (brd_…)noThe brand to act on (brd_…), inside your API key's reach. Needed with an organization or entity key; a brand key acts on its own brand.
idempotency_keystringnoA unique string for this change. Retrying with the same key and arguments never acts twice. When left out, the server generates one and returns it in the result's idempotency_key. (1–255 characters)
  • Brand: pass brand_id with an organization or entity key; a brand key acts on its own brand.
  • Idempotency: the result returns the idempotency_key used, yours or one the server generated. Retry with it: a call with the same key and arguments never acts twice (keys are kept for 24 hours).
  • Dry run: not supported. dry_run: true fails with dry_run_not_supported.

Errors

Example

From the “opened” email

Arguments:

JSON
{
  "sessionId": "cs_01m4tx5nj8emwbyf7y9vcf48aa",
  "entry": "wl_01m4tx5nj8emwbyf7y9vcf48ah",
  "token": "Qm9vdF9sZWF2ZV90b2tlbl9leGFtcGxlXzAwMDAwMDA",
  "brand_id": "brd_01jbx4m3v8e9t0s6k2c5n7q1wz",
  "idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}

Result output:

JSON
{
  "object": "waitlist_checkout",
  "sessionId": "cs_01m6c9r2wq4h8xg3a7k5d1n0ve",
  "url": "https://ownrecord.io/c/genno/cs_01m6c9r2wq4h8xg3a7k5d1n0ve?key=Hk2pq7Vb4xR9mN3sT6wL1yG8cJ0eE5aD-uF_dK2oZ8q",
  "expiresAt": "2026-10-20T09:30:00.000Z"
}

checkout_hosted_start_payment

Start the checkout payment. Operation checkout.hosted.start_payment · Brand level · permission checkout:write · risk tier write · since M4

Prepares the payment for the current quote's total at the brand's processor: a payment intent with the session and the quote in its metadata, created once per quote version ({session}:intent:{quoteVersion}), or the session's intent updated when the total changed. The session keeps one active intent. The answer says which payment component to show (fake in development, or the Stripe Payment Element with the connection's publishable key); the browser gets Stripe's client secret from checkout.hosted.payment_secret.

Call it again after a re-quote: it brings the intent up to date. Public: the hosted page calls it with the session key.

The brand's risk rules run first (spec §20): a refused payment is risk_payment_declined and no intent is made; a payment that needs 3-D Secure gets an intent that asks the bank for it.

Annotations: readOnlyHint: false · destructiveHint: false · idempotentHint: false · openWorldHint: true

Arguments

ArgumentTypeRequiredDescription
sessionIdID (cs_…)yesThe checkout session's ID (cs_…).
keystringnoThe session key from the hosted URL (?key=…). Required without an API key; signed-in callers with checkout:write don't need it.
entity_idID (ent_…)noOptional: the brand's legal entity (ent_…); brand_id alone is enough.
brand_idID (brd_…)noThe brand to act on (brd_…), inside your API key's reach. Needed with an organization or entity key; a brand key acts on its own brand.
idempotency_keystringnoA unique string for this change. Retrying with the same key and arguments never acts twice. When left out, the server generates one and returns it in the result's idempotency_key. (1–255 characters)
  • Brand: pass brand_id with an organization or entity key; a brand key acts on its own brand.
  • Idempotency: the result returns the idempotency_key used, yours or one the server generated. Retry with it: a call with the same key and arguments never acts twice (keys are kept for 24 hours).
  • Dry run: not supported. dry_run: true fails with dry_run_not_supported.

Errors

Example

Start the payment

Arguments:

JSON
{
  "sessionId": "cs_01m4tx5nj8emwbyf7y9vcf48aa",
  "key": "Zk3tq8Vb2xQ9mN4rP7sL1yH6cJ0wE5aD-uT_fG8hK2o",
  "brand_id": "brd_01jbx4m3v8e9t0s6k2c5n7q1wz",
  "idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}

Result output:

JSON
{
  "id": "cs_01m4tx5nj8emwbyf7y9vcf48aa",
  "object": "checkout.hosted_session",
  "livemode": false,
  "status": "open",
  "mode": "payment",
  "currency": "EUR",
  "brand": {
    "slug": "genno",
    "name": "Genno",
    "primaryColor": null,
    "termsUrl": "https://genno.example/terms",
    "privacyUrl": "https://genno.example/privacy",
    "supportEmail": null
  },
  "seller": {
    "legalName": "Etna Labs AG",
    "address": "Dammstrasse 16, 6300 Zug, Switzerland",
    "taxId": "CHE-181.927.786 MWST"
  },
  "lineItems": [
    {
      "id": "1",
      "description": "Genno credits",
      "quantity": 1,
      "amount": {
        "amount": "100000000",
        "currency": "EUR"
      },
      "recurring": null,
      "adjustableQuantity": null,
      "discount": null
    }
  ],
  "subscription": null,
  "topup": null,
  "setup": null,
  "collectBusinessDetails": "auto",
  "prefill": {
    "email": "anna@example.com",
    "name": null,
    "country": "DE",
    "subdivision": null,
    "business": null
  },
  "quote": {
    "id": "tq_01m4tx5nj8emwbyf7y9vcf48ab",
    "decision": "charge",
    "customerType": "b2c",
    "country": "DE",
    "lines": [
      {
        "id": "1",
        "description": "Genno credits",
        "quantity": 1,
        "treatment": "charge",
        "net": {
          "amount": "84033613",
          "currency": "EUR"
        },
        "tax": {
          "amount": "15966387",
          "currency": "EUR"
        },
        "gross": {
          "amount": "100000000",
          "currency": "EUR"
        },
        "ratePpm": "190000",
        "jurisdictionId": "DE",
        "jurisdictionName": "Germany",
        "taxName": "VAT",
        "regimeId": "EU_OSS_NON_UNION",
        "pendingRegistration": false,
        "taxBehavior": "inclusive"
      }
    ],
    "totals": {
      "net": {
        "amount": "84033613",
        "currency": "EUR"
      },
      "tax": {
        "amount": "15966387",
        "currency": "EUR"
      },
      "gross": {
        "amount": "100000000",
        "currency": "EUR"
      }
    },
    "inclusive": true,
    "reverseCharge": false,
    "reverseChargeWording": null,
    "validUntil": "2026-10-14T10:30:00.000Z",
    "unverifiedRules": false
  },
  "blocked": null,
  "waitlist": null,
  "payment": {
    "started": true,
    "intent": "payment",
    "component": "fake",
    "publishableKey": null,
    "paymentMethod": null,
    "upToDate": true
  },
  "legal": {
    "termsAccepted": false,
    "immediatePerformanceRequired": true,
    "immediatePerformanceText": "I want the service to start now, and I understand that I lose my right to withdraw once it has started."
  },
  "successUrl": null,
  "cancelUrl": "https://shop.example/cart",
  "expiresAt": "2026-10-15T10:00:00.000Z",
  "locale": {
    "preferred": [],
    "brand": ["en"]
  }
}

checkout_hosted_submit_details

Submit checkout details. Operation checkout.hosted.submit_details · Brand level · permission checkout:write · risk tier write · since M4

The hosted page's first step: the customer's email, country and, for a business, the company name, tax ID and address. The tax ID is checked with its register (VIES, HMRC, the Swiss UID register). Then the tax engine quotes the sale from the location evidence: the billing country, the IP country the page captured, and the card's country once a payment method is chosen (spec §13.2).

  • A sale Ownrecord can tax is quoted (a new quote version; valid for 30 minutes): the customer, their evidence set and the quote are stored.
  • A sale it can't tax with confidence is paused (spec §1.3): the session becomes blocked with the reason and checkout.session.blocked is emitted; the page offers the waitlist and, where it helps, buying as a business. Nothing about the customer is stored then.

Submitting again (other details, or after the quote expired) quotes again. Public: the hosted page calls it with the session key.

Annotations: readOnlyHint: false · destructiveHint: false · idempotentHint: false · openWorldHint: true

Arguments

ArgumentTypeRequiredDescription
sessionIdID (cs_…)yesThe checkout session's ID (cs_…).
keystringnoThe session key from the hosted URL (?key=…). Required without an API key; signed-in callers with checkout:write don't need it.
emailstringyesThe customer's email: receipts and invoices go there. (at most 254 characters)
namestringnoThe customer's name. (1–200 characters)
countrystringyesThe country the customer lives in (pre-filled from the IP address).
subdivisionstringnoThe state or region, where the regime needs it (US).
businessobjectnoBuying for a business: company name, tax ID and billing address (spec §13.2).
evidenceTokenstringnoThe IP-country evidence the hosted page captured (signed by the server; opaque to clients). (at most 1000 characters)
promotionCodestring or nullnoSubscription sessions: a promotion code to apply (null or empty removes the applied one).
quantitiesarray of objectnoNew quantities of line items created with adjustableQuantity. (at most 20 items)
localeone of en, de, fr, hr, it, esnoThe language the customer sees the page in (en, de, fr, hr, it, es). The session keeps it when it has no language yet: the customer, the invoice and the emails use it.
entity_idID (ent_…)noOptional: the brand's legal entity (ent_…); brand_id alone is enough.
brand_idID (brd_…)noThe brand to act on (brd_…), inside your API key's reach. Needed with an organization or entity key; a brand key acts on its own brand.
idempotency_keystringnoA unique string for this change. Retrying with the same key and arguments never acts twice. When left out, the server generates one and returns it in the result's idempotency_key. (1–255 characters)
  • Brand: pass brand_id with an organization or entity key; a brand key acts on its own brand.
  • Idempotency: the result returns the idempotency_key used, yours or one the server generated. Retry with it: a call with the same key and arguments never acts twice (keys are kept for 24 hours).
  • Dry run: not supported. dry_run: true fails with dry_run_not_supported.

Errors

Examples

A consumer in Germany

Arguments:

JSON
{
  "sessionId": "cs_01m4tx5nj8emwbyf7y9vcf48aa",
  "key": "Zk3tq8Vb2xQ9mN4rP7sL1yH6cJ0wE5aD-uT_fG8hK2o",
  "email": "anna@example.com",
  "country": "DE",
  "brand_id": "brd_01jbx4m3v8e9t0s6k2c5n7q1wz",
  "idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}

Result output:

JSON
{
  "id": "cs_01m4tx5nj8emwbyf7y9vcf48aa",
  "object": "checkout.hosted_session",
  "livemode": false,
  "status": "open",
  "mode": "payment",
  "currency": "EUR",
  "brand": {
    "slug": "genno",
    "name": "Genno",
    "primaryColor": null,
    "termsUrl": "https://genno.example/terms",
    "privacyUrl": "https://genno.example/privacy",
    "supportEmail": null
  },
  "seller": {
    "legalName": "Etna Labs AG",
    "address": "Dammstrasse 16, 6300 Zug, Switzerland",
    "taxId": "CHE-181.927.786 MWST"
  },
  "lineItems": [
    {
      "id": "1",
      "description": "Genno credits",
      "quantity": 1,
      "amount": {
        "amount": "100000000",
        "currency": "EUR"
      },
      "recurring": null,
      "adjustableQuantity": null,
      "discount": null
    }
  ],
  "subscription": null,
  "topup": null,
  "setup": null,
  "collectBusinessDetails": "auto",
  "prefill": {
    "email": "anna@example.com",
    "name": null,
    "country": "DE",
    "subdivision": null,
    "business": null
  },
  "quote": {
    "id": "tq_01m4tx5nj8emwbyf7y9vcf48ab",
    "decision": "charge",
    "customerType": "b2c",
    "country": "DE",
    "lines": [
      {
        "id": "1",
        "description": "Genno credits",
        "quantity": 1,
        "treatment": "charge",
        "net": {
          "amount": "84033613",
          "currency": "EUR"
        },
        "tax": {
          "amount": "15966387",
          "currency": "EUR"
        },
        "gross": {
          "amount": "100000000",
          "currency": "EUR"
        },
        "ratePpm": "190000",
        "jurisdictionId": "DE",
        "jurisdictionName": "Germany",
        "taxName": "VAT",
        "regimeId": "EU_OSS_NON_UNION",
        "pendingRegistration": false,
        "taxBehavior": "inclusive"
      }
    ],
    "totals": {
      "net": {
        "amount": "84033613",
        "currency": "EUR"
      },
      "tax": {
        "amount": "15966387",
        "currency": "EUR"
      },
      "gross": {
        "amount": "100000000",
        "currency": "EUR"
      }
    },
    "inclusive": true,
    "reverseCharge": false,
    "reverseChargeWording": null,
    "validUntil": "2026-10-14T10:30:00.000Z",
    "unverifiedRules": false
  },
  "blocked": null,
  "waitlist": null,
  "payment": {
    "started": false,
    "intent": null,
    "component": null,
    "publishableKey": null,
    "paymentMethod": null,
    "upToDate": false
  },
  "legal": {
    "termsAccepted": false,
    "immediatePerformanceRequired": true,
    "immediatePerformanceText": "I want the service to start now, and I understand that I lose my right to withdraw once it has started."
  },
  "successUrl": null,
  "cancelUrl": "https://shop.example/cart",
  "expiresAt": "2026-10-15T10:00:00.000Z",
  "locale": {
    "preferred": [],
    "brand": ["en"]
  }
}

A consumer where the seller can't sell yet

The UK needs a registration before the first consumer sale: the waitlist is offered.

Arguments:

JSON
{
  "sessionId": "cs_01m4tx5nj8emwbyf7y9vcf48aa",
  "key": "Zk3tq8Vb2xQ9mN4rP7sL1yH6cJ0wE5aD-uT_fG8hK2o",
  "email": "oliver@example.com",
  "country": "GB",
  "brand_id": "brd_01jbx4m3v8e9t0s6k2c5n7q1wz",
  "idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}

Result output:

JSON
{
  "id": "cs_01m4tx5nj8emwbyf7y9vcf48aa",
  "object": "checkout.hosted_session",
  "livemode": false,
  "status": "blocked",
  "mode": "payment",
  "currency": "EUR",
  "brand": {
    "slug": "genno",
    "name": "Genno",
    "primaryColor": null,
    "termsUrl": "https://genno.example/terms",
    "privacyUrl": "https://genno.example/privacy",
    "supportEmail": null
  },
  "seller": {
    "legalName": "Etna Labs AG",
    "address": "Dammstrasse 16, 6300 Zug, Switzerland",
    "taxId": "CHE-181.927.786 MWST"
  },
  "lineItems": [
    {
      "id": "1",
      "description": "Genno credits",
      "quantity": 1,
      "amount": {
        "amount": "100000000",
        "currency": "EUR"
      },
      "recurring": null,
      "adjustableQuantity": null,
      "discount": null
    }
  ],
  "subscription": null,
  "topup": null,
  "setup": null,
  "collectBusinessDetails": "auto",
  "prefill": {
    "email": "oliver@example.com",
    "name": null,
    "country": "GB",
    "subdivision": null,
    "business": null
  },
  "quote": null,
  "blocked": {
    "reason": "registration_required",
    "country": "GB",
    "countryName": "United Kingdom",
    "waitlistOffered": true,
    "businessOffered": true
  },
  "waitlist": null,
  "payment": {
    "started": false,
    "intent": null,
    "component": null,
    "publishableKey": null,
    "paymentMethod": null,
    "upToDate": false
  },
  "legal": {
    "termsAccepted": false,
    "immediatePerformanceRequired": true,
    "immediatePerformanceText": "I want the service to start now, and I understand that I lose my right to withdraw once it has started."
  },
  "successUrl": null,
  "cancelUrl": "https://shop.example/cart",
  "expiresAt": "2026-10-15T10:00:00.000Z",
  "locale": {
    "preferred": [],
    "brand": ["en"]
  }
}

checkout_sessions_create

Create a checkout session. Operation checkout.sessions.create · Brand level · permission checkout:write · risk tier write · since M4

Creates a hosted checkout and returns its url: send the customer there. The page collects the customer's details, quotes the tax (spec §9), takes the payment and shows the receipt; the sale is recorded only when the processor confirms it (webhook).

  • payment: one-time prices and credit packs.
  • subscription: recurring prices (spec §16.2). The first invoice is paid in the checkout and the card is saved for renewals; with a trial (subscriptionData.trialDays, default the prices' own) the card is only saved, or not asked for at all with subscriptionData.trialRequiresPaymentMethod: false. Lines can let the customer change the quantity (adjustableQuantity), and allowPromotionCodes adds a promotion code field.
  • topup: credits for an existing customer's wallet (spec §14.3, customer required): one credit pack, a fixed pack or a custom amount within the pack's bounds. The buyer must use the customer's email; a customer who has paid before is taxed as an existing customer. The wallet gets the purchased credits (the amount before tax, or the amount paid under the brand's gross credit basis) and the pack's bonus credits.
  • setup: no line items: the customer saves a card for a customer (customer required).
  • Line items: 1 to 20 prices of one currency, by ID or lookup key, with a quantity (1 to 1,000) or, for a custom-amount price, the amount in integer micros. Prices become immutable once a session uses them.
  • Customer: an existing customer, or an email to pre-fill. New buyers become customers when they're quoted.
  • Expiry: 24 hours by default (30 minutes to 24 hours with expiresAt). Test sessions show a test banner.

The URL carries a session key: treat it like the session itself and give it only to the customer.

Annotations: readOnlyHint: false · destructiveHint: false · idempotentHint: false · openWorldHint: false

Arguments

ArgumentTypeRequiredDescription
modeone of payment, subscription, topup, setupnopayment: one-time prices and credit packs; subscription: recurring prices, starting a subscription; topup: one credit pack (a fixed pack or a custom amount) added to an existing customer's wallet; setup: save a payment method of an existing customer, nothing is charged. (default "payment")
lineItemsarray of objectnoWhat the customer buys: 1 to 20 prices of one currency (none in setup mode). (at most 20 items)
customerID (cus_…)noAn existing customer of the brand (cus_…); required in setup and topup mode.
customerEmailstringnoPre-fills the email on the hosted page (ignored with customer). (at most 254 characters)
successUrlstringnoWhere the customer goes after paying; ?cs_id={session ID} is added. Required except in setup mode (#435, #474). (at most 2000 characters)
cancelUrlstringnoWhere the hosted page's back link goes. (at most 2000 characters)
localestringnoThe customer's language (invoices use it when supported).
collectBusinessDetailsone of auto, required, nevernoauto: offer “Buying for a business?”; required: business customers only; never: consumers only. (default "auto")
expiresAtdate-time (ISO 8601)noWhen the session expires: 30 minutes to 24 hours from now (default 24 hours).
allowPromotionCodesbooleannoSubscription sessions: offer a promotion code field on the hosted page.
promotionCodestringnoSubscription sessions: a promotion code applied for the customer. (1–50 characters)
subscriptionDataobjectnoSubscription sessions: the trial and the new subscription's metadata.
currencystringnoSetup sessions: the currency the saved method will pay in (default: the entity's).
metadataobjectnoYour own key-value pairs, returned with the session and in its events (e.g. your order ID).
entity_idID (ent_…)noOptional: the brand's legal entity (ent_…); brand_id alone is enough.
brand_idID (brd_…)noThe brand to act on (brd_…), inside your API key's reach. Needed with an organization or entity key; a brand key acts on its own brand.
idempotency_keystringnoA unique string for this change. Retrying with the same key and arguments never acts twice. When left out, the server generates one and returns it in the result's idempotency_key. (1–255 characters)
dry_runbooleannotrue: check permissions and rules and compute the result, then roll everything back. Nothing is saved. (default false)
  • Brand: pass brand_id with an organization or entity key; a brand key acts on its own brand.
  • Idempotency: the result returns the idempotency_key used, yours or one the server generated. Retry with it: a call with the same key and arguments never acts twice (keys are kept for 24 hours).
  • Dry run: supported. dry_run: true checks permissions and rules and computes the result, then rolls everything back.

Errors

Examples

A credit pack by lookup key

The customer's email is pre-filled on the hosted page.

Arguments:

JSON
{
  "lineItems": [
    {
      "lookupKey": "credits_100",
      "quantity": 1
    }
  ],
  "customerEmail": "anna@example.com",
  "successUrl": "https://shop.example/thanks",
  "cancelUrl": "https://shop.example/cart",
  "metadata": {
    "order": "ord_1042"
  },
  "brand_id": "brd_01jbx4m3v8e9t0s6k2c5n7q1wz",
  "idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}

Result output:

JSON
{
  "id": "cs_01m4tx5nj8emwbyf7y9vcf48aa",
  "object": "checkout.session",
  "livemode": false,
  "entityId": "ent_01m4tx5nj8emwbyf7y9vcf47x2",
  "brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
  "mode": "payment",
  "status": "open",
  "url": "https://ownrecord.io/c/genno/cs_01m4tx5nj8emwbyf7y9vcf48aa?key=Zk3tq8Vb2xQ9mN4rP7sL1yH6cJ0wE5aD-uT_fG8hK2o",
  "lineItems": [
    {
      "id": "1",
      "priceId": "price_01m4tx5nj8emwbyf7y9vcf48ad",
      "productId": "prod_01m4tx5nj8emwbyf7y9vcf48ae",
      "priceType": "credit_pack",
      "recurring": null,
      "adjustableQuantity": null,
      "discount": null,
      "description": "Genno credits",
      "quantity": 1,
      "customAmount": null,
      "amount": {
        "amount": "100000000",
        "currency": "EUR"
      },
      "taxBehavior": "inclusive"
    }
  ],
  "currency": "EUR",
  "customerId": null,
  "customerEmail": "anna@example.com",
  "successUrl": "https://shop.example/thanks",
  "cancelUrl": "https://shop.example/cart",
  "locale": null,
  "collectBusinessDetails": "auto",
  "allowPromotionCodes": false,
  "promotionCodeId": null,
  "subscriptionData": null,
  "taxQuoteId": null,
  "totals": null,
  "blockedReason": null,
  "waitlistEntryId": null,
  "paymentId": null,
  "invoiceId": null,
  "subscriptionId": null,
  "paymentMethodId": null,
  "expiresAt": "2026-10-15T10:00:00.000Z",
  "completedAt": null,
  "createdAt": "2026-10-14T10:00:00.000Z",
  "metadata": {
    "order": "ord_1042"
  }
}

A top-up of a customer's wallet

€40 of a custom-amount credit pack for an existing customer (spec §14.3).

Arguments:

JSON
{
  "mode": "topup",
  "customer": "cus_01m4tx5nj8emwbyf7y9vcf48ac",
  "lineItems": [
    {
      "lookupKey": "credits_custom",
      "customAmount": {
        "amount": "40000000",
        "currency": "EUR"
      }
    }
  ],
  "successUrl": "https://shop.example/wallet",
  "brand_id": "brd_01jbx4m3v8e9t0s6k2c5n7q1wz",
  "idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}

Result output:

JSON
{
  "id": "cs_01m4tx5nj8emwbyf7y9vcf48aa",
  "object": "checkout.session",
  "livemode": false,
  "entityId": "ent_01m4tx5nj8emwbyf7y9vcf47x2",
  "brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
  "mode": "topup",
  "status": "open",
  "url": "https://ownrecord.io/c/genno/cs_01m4tx5nj8emwbyf7y9vcf48aa?key=Zk3tq8Vb2xQ9mN4rP7sL1yH6cJ0wE5aD-uT_fG8hK2o",
  "lineItems": [
    {
      "id": "1",
      "priceId": "price_01m4tx5nj8emwbyf7y9vcf48ad",
      "productId": "prod_01m4tx5nj8emwbyf7y9vcf48ae",
      "priceType": "credit_pack",
      "recurring": null,
      "adjustableQuantity": null,
      "discount": null,
      "description": "Genno credits",
      "quantity": 1,
      "customAmount": {
        "amount": "40000000",
        "currency": "EUR"
      },
      "amount": {
        "amount": "40000000",
        "currency": "EUR"
      },
      "taxBehavior": "inclusive"
    }
  ],
  "currency": "EUR",
  "customerId": "cus_01m4tx5nj8emwbyf7y9vcf48ac",
  "customerEmail": null,
  "successUrl": "https://shop.example/wallet",
  "cancelUrl": null,
  "locale": null,
  "collectBusinessDetails": "auto",
  "allowPromotionCodes": false,
  "promotionCodeId": null,
  "subscriptionData": null,
  "taxQuoteId": null,
  "totals": null,
  "blockedReason": null,
  "waitlistEntryId": null,
  "paymentId": null,
  "invoiceId": null,
  "subscriptionId": null,
  "paymentMethodId": null,
  "expiresAt": "2026-10-15T10:00:00.000Z",
  "completedAt": null,
  "createdAt": "2026-10-14T10:00:00.000Z",
  "metadata": {}
}

checkout_sessions_expire

Expire a checkout session. Operation checkout.sessions.expire · Brand level · permission checkout:write · risk tier write · since M4

Ends an open or blocked checkout session now, so its link stops working (for example when the cart changed). Emits checkout.session.expired. Expiring an expired session changes nothing. A session that is paid, or whose payment is being processed, can't be expired (checkout_session_not_open).

Annotations: readOnlyHint: false · destructiveHint: true · idempotentHint: true · openWorldHint: false

Arguments

ArgumentTypeRequiredDescription
idID (cs_…)yesThe checkout session's ID (cs_…).
entity_idID (ent_…)noOptional: the brand's legal entity (ent_…); brand_id alone is enough.
brand_idID (brd_…)noThe brand to act on (brd_…), inside your API key's reach. Needed with an organization or entity key; a brand key acts on its own brand.
idempotency_keystringnoA unique string for this change. Retrying with the same key and arguments never acts twice. When left out, the server generates one and returns it in the result's idempotency_key. (1–255 characters)
dry_runbooleannotrue: check permissions and rules and compute the result, then roll everything back. Nothing is saved. (default false)
  • Brand: pass brand_id with an organization or entity key; a brand key acts on its own brand.
  • Idempotency: the result returns the idempotency_key used, yours or one the server generated. Retry with it: a call with the same key and arguments never acts twice (keys are kept for 24 hours).
  • Dry run: supported. dry_run: true checks permissions and rules and computes the result, then rolls everything back.

Errors

  • resource_not_found: No such checkout session for this brand and mode, or (on the hosted page) the session key is missing or wrong.
  • checkout_session_not_open: The session is complete, expired, or a payment for it is being processed (details.status).

Example

Expire an open session

Arguments:

JSON
{
  "id": "cs_01m4tx5nj8emwbyf7y9vcf48aa",
  "brand_id": "brd_01jbx4m3v8e9t0s6k2c5n7q1wz",
  "idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}

Result output:

JSON
{
  "id": "cs_01m4tx5nj8emwbyf7y9vcf48aa",
  "object": "checkout.session",
  "livemode": false,
  "entityId": "ent_01m4tx5nj8emwbyf7y9vcf47x2",
  "brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
  "mode": "payment",
  "status": "expired",
  "url": null,
  "lineItems": [
    {
      "id": "1",
      "priceId": "price_01m4tx5nj8emwbyf7y9vcf48ad",
      "productId": "prod_01m4tx5nj8emwbyf7y9vcf48ae",
      "priceType": "credit_pack",
      "recurring": null,
      "adjustableQuantity": null,
      "discount": null,
      "description": "Genno credits",
      "quantity": 1,
      "customAmount": null,
      "amount": {
        "amount": "100000000",
        "currency": "EUR"
      },
      "taxBehavior": "inclusive"
    }
  ],
  "currency": "EUR",
  "customerId": null,
  "customerEmail": "anna@example.com",
  "successUrl": "https://shop.example/thanks",
  "cancelUrl": "https://shop.example/cart",
  "locale": null,
  "collectBusinessDetails": "auto",
  "allowPromotionCodes": false,
  "promotionCodeId": null,
  "subscriptionData": null,
  "taxQuoteId": null,
  "totals": null,
  "blockedReason": null,
  "waitlistEntryId": null,
  "paymentId": null,
  "invoiceId": null,
  "subscriptionId": null,
  "paymentMethodId": null,
  "expiresAt": "2026-10-15T10:00:00.000Z",
  "completedAt": null,
  "createdAt": "2026-10-14T10:00:00.000Z",
  "metadata": {
    "order": "ord_1042"
  }
}

checkout_sessions_get

Get a checkout session. Operation checkout.sessions.get · Brand level · permission checkout:read · risk tier read · since M4

Returns a checkout session of the brand in the mode of the request: its status (open, blocked, processing, complete, expired), line items, the current quote's totals and, once paid, the payment and the invoice. A session past its expiry reads as expired even before the expiry job has run.

Use it after the customer returns to your success URL (?cs_id=…): fulfil your side when the status is complete, or listen for checkout.session.completed.

Annotations: readOnlyHint: true · destructiveHint: false · idempotentHint: true · openWorldHint: false

Arguments

ArgumentTypeRequiredDescription
idID (cs_…)yesThe checkout session's ID (cs_…).
entity_idID (ent_…)noOptional: the brand's legal entity (ent_…); brand_id alone is enough.
brand_idID (brd_…)noThe brand to act on (brd_…), inside your API key's reach. Needed with an organization or entity key; a brand key acts on its own brand.
  • Brand: pass brand_id with an organization or entity key; a brand key acts on its own brand.
  • Read-only: changes nothing; idempotency_key is ignored.

Errors

  • resource_not_found: No such checkout session for this brand and mode, or (on the hosted page) the session key is missing or wrong.

Example

A paid session

Arguments:

JSON
{
  "id": "cs_01m4tx5nj8emwbyf7y9vcf48aa",
  "brand_id": "brd_01jbx4m3v8e9t0s6k2c5n7q1wz"
}

Result output:

JSON
{
  "id": "cs_01m4tx5nj8emwbyf7y9vcf48aa",
  "object": "checkout.session",
  "livemode": false,
  "entityId": "ent_01m4tx5nj8emwbyf7y9vcf47x2",
  "brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
  "mode": "payment",
  "status": "complete",
  "url": null,
  "lineItems": [
    {
      "id": "1",
      "priceId": "price_01m4tx5nj8emwbyf7y9vcf48ad",
      "productId": "prod_01m4tx5nj8emwbyf7y9vcf48ae",
      "priceType": "credit_pack",
      "recurring": null,
      "adjustableQuantity": null,
      "discount": null,
      "description": "Genno credits",
      "quantity": 1,
      "customAmount": null,
      "amount": {
        "amount": "100000000",
        "currency": "EUR"
      },
      "taxBehavior": "inclusive"
    }
  ],
  "currency": "EUR",
  "customerId": "cus_01m4tx5nj8emwbyf7y9vcf48ac",
  "customerEmail": "anna@example.com",
  "successUrl": "https://shop.example/thanks",
  "cancelUrl": "https://shop.example/cart",
  "locale": null,
  "collectBusinessDetails": "auto",
  "allowPromotionCodes": false,
  "promotionCodeId": null,
  "subscriptionData": null,
  "taxQuoteId": "tq_01m4tx5nj8emwbyf7y9vcf48ab",
  "totals": {
    "net": {
      "amount": "84033613",
      "currency": "EUR"
    },
    "tax": {
      "amount": "15966387",
      "currency": "EUR"
    },
    "gross": {
      "amount": "100000000",
      "currency": "EUR"
    }
  },
  "blockedReason": null,
  "waitlistEntryId": null,
  "paymentId": "pay_01m4tx5nj8emwbyf7y9vcf48af",
  "invoiceId": "inv_01m4tx5nj8emwbyf7y9vcf48ag",
  "subscriptionId": null,
  "paymentMethodId": null,
  "expiresAt": "2026-10-15T10:00:00.000Z",
  "completedAt": "2026-10-14T10:03:12.000Z",
  "createdAt": "2026-10-14T10:00:00.000Z",
  "metadata": {
    "order": "ord_1042"
  }
}