Skip to main content
The Checkout Sessions API creates and retrieves individual payment attempts. Each session generates a unique Ethereum deposit address and a corresponding crypto amount derived from a live ETH/USD price feed. Sessions expire after a configurable TTL — once expired, any late payment is captured as a paid_late event but may require manual reconciliation. You can create sessions in two modes: link mode, which ties the session to an existing payment link and inherits its price, or ad-hoc mode, which lets you specify a custom fiat amount inline without a payment link.
Always supply an Idempotency-Key when creating sessions in server-side order flows to prevent duplicate charges if your request is retried.

The CheckoutSession object

id
string
Unique identifier for the checkout session. Format: UUID.
object
string
Always "checkout_session".
The ID of the payment link this session was created from. null for ad-hoc sessions.
status
string
Current payment status. One of:
ValueDescription
pendingWaiting for a blockchain transaction to be detected.
detectedA transaction has been seen in the mempool but is not yet confirmed.
paidPayment received and confirmed in full.
underpaidA confirmed transaction was received, but for less than the required amount.
overpaidA confirmed transaction was received for more than the required amount.
expiredThe session TTL elapsed before payment was received.
paid_latePayment arrived after the session expired.
failedAn unrecoverable error occurred during payment processing.
address
string
The Ethereum address the customer must send funds to. Unique per session.
amount
object
The crypto amount the customer must send.
fiat
object
The original fiat price this session was priced at.
ethPriceUsd
string
The ETH/USD exchange rate used to calculate amount.wei at session creation time, e.g. "3318.50".
expiresAt
string
ISO 8601 timestamp after which the session is considered expired and the address will no longer accept new payments.
paidAt
string | null
ISO 8601 timestamp of when the payment was confirmed. null until the session reaches a paid state.
txHash
string | null
The Ethereum transaction hash of the payment. null until a transaction is detected.
chainId
number
The EVM chain ID on which the deposit address is valid, e.g. 1 for Ethereum mainnet.
metadata
object | null
Arbitrary key-value pairs you attached at session creation, e.g. { "orderId": "99" }. Useful for reconciliation. null if not set.
successUrl
string | null
URL to redirect to after a successful payment. Overrides the parent link’s successUrl if set.
cancelUrl
string | null
URL to redirect to if the customer cancels. Overrides the parent link’s cancelUrl if set.
returnUrl
string | null
Generic return URL used when neither success nor cancel URLs apply.
customerEmail
string | null
Email address of the customer, used to look up or create a customer record. null if not provided.
livemode
boolean
true if this session was created with a live-mode API key; false for test mode.
checkoutUrl
string
The fully-qualified URL of the hosted checkout page, e.g. https://your-domain.com/checkout/cs_01HABC. Send customers here to complete payment.
createdAt
string
ISO 8601 timestamp of when the session was created.
updatedAt
string
ISO 8601 timestamp of the most recent status change.

POST /checkout_sessions

Creates a new checkout session. Returns the session object with a 201 status on success. Required scope: sessions:write Use link mode when you want to associate the session with an existing payment link. The fiat amount and currency are pulled directly from the link.
The ID of the payment link to create this session from. The link must exist and have active: true.
customerEmail
string
Email address of the customer. Used to associate the session with a customer record and populate the checkout form.
metadata
object
Up to 50 key-value pairs you want to attach for reconciliation. Values must be strings or numbers.
successUrl
string
Override the link’s successUrl for this specific session.
cancelUrl
string
Override the link’s cancelUrl for this specific session.
returnUrl
string
A generic return URL for when no specific success or cancel URL applies.

Ad-hoc mode

Use ad-hoc mode to create a one-off session with a custom fiat amount, without a payment link.
amount
object
required
The fiat price for this session.
customerEmail
string
Email address of the customer.
metadata
object
Arbitrary key-value pairs for reconciliation.
successUrl
string
HTTPS URL to redirect to after payment.
cancelUrl
string
HTTPS URL to redirect to on cancellation.
returnUrl
string
Generic return URL.
curl -X POST https://your-domain.com/api/v1/checkout_sessions \
  -H "Authorization: Bearer ck_test_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-99-v1" \
  -d '{
    "linkId": "pl_01HXYZ",
    "customerEmail": "[email protected]",
    "metadata": { "orderId": "99" }
  }'
const session = await client.checkoutSessions.create({
  linkId: "pl_01HXYZ",
  customerEmail: "[email protected]",
  metadata: { orderId: "99" },
}, { idempotencyKey: "order-99-v1" });

Example request — ad-hoc mode

curl -X POST https://your-domain.com/api/v1/checkout_sessions \
  -H "Authorization: Bearer ck_test_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-100-v1" \
  -d '{
    "amount": { "value": "149.99", "currency": "USD" },
    "successUrl": "https://example.com/ok",
    "metadata": { "orderId": "100" }
  }'
const session = await client.checkoutSessions.create({
  amount: { value: "149.99", currency: "USD" },
  successUrl: "https://example.com/ok",
  metadata: { orderId: "100" },
}, { idempotencyKey: "order-100-v1" });

Example response 201

{
  "id": "cs_01HABC",
  "object": "checkout_session",
  "linkId": null,
  "status": "pending",
  "address": "0x742d35Cc6634C0532925a3b844Bc454e4438f44e",
  "amount": {
    "wei": "45230000000000000",
    "eth": "0.04523"
  },
  "fiat": {
    "amount": "149.99",
    "currency": "USD"
  },
  "ethPriceUsd": "3318.50",
  "expiresAt": "2024-01-15T10:05:00.000Z",
  "paidAt": null,
  "txHash": null,
  "chainId": 1,
  "metadata": { "orderId": "100" },
  "successUrl": "https://example.com/ok",
  "cancelUrl": null,
  "returnUrl": null,
  "customerEmail": null,
  "livemode": false,
  "checkoutUrl": "https://your-domain.com/checkout/cs_01HABC",
  "createdAt": "2024-01-15T10:00:00.000Z",
  "updatedAt": "2024-01-15T10:00:00.000Z"
}

GET /checkout_sessions

Returns a cursor-paginated list of checkout sessions ordered by creation time, most recent first. Required scope: sessions:read

Query parameters

limit
integer
Number of results to return. Between 1 and 100. Defaults to 25.
starting_after
string
A session id used as a pagination cursor. Returns sessions created before this one.
status
string
Filter by session status. One of pending, detected, paid, underpaid, overpaid, expired, paid_late, or failed.
Filter sessions to those created from a specific payment link ID.
createdAfter
string
ISO 8601 datetime. Only return sessions created at or after this time.
createdBefore
string
ISO 8601 datetime. Only return sessions created at or before this time.

Example request

curl "https://your-domain.com/api/v1/checkout_sessions?status=paid&limit=25" \
  -H "Authorization: Bearer ck_test_YOUR_KEY"
const { data, hasMore, nextCursor } = await client.checkoutSessions.list({
  status: "paid",
  limit: 25,
});

Example response 200

{
  "data": [ { "id": "cs_01HABC", "object": "checkout_session", "status": "paid", "..." : "..." } ],
  "hasMore": true,
  "nextCursor": "cs_01HAAA"
}

GET /checkout_sessions/{id}

Retrieves a single checkout session by its ID. Required scope: sessions:read

Path parameters

id
string
required
The ID of the checkout session to retrieve.

Example request

curl https://your-domain.com/api/v1/checkout_sessions/cs_01HABC \
  -H "Authorization: Bearer ck_test_YOUR_KEY"
const session = await client.checkoutSessions.retrieve("cs_01HABC");
To receive real-time status updates instead of polling, register a webhook endpoint and listen for session.* events. See the Webhook Endpoints API for details.