Create a checkout session
Returns a `checkout_url` to redirect the customer to. A cart with one recurring product starts a subscription; otherwise it takes a one-time payment. Sessions expire after 24 hours. Use it whenever a customer is ready to pay: the card is collected on Utopia's own page, so your server never handles card details. Every item must be in the same currency (`MIXED_CURRENCIES` otherwise), a subscription cart holds that one recurring product and nothing else (`INVALID_CART`), and a saved product must be `active` (`PRODUCT_NOT_ACTIVE`) and priced above zero (`INVALID_PRICE`). List each product once and raise its `quantity` rather than repeating it. Items priced inline are always one-time. An expired session reads as `expired` and has no `checkout_url` left to send anyone to. Send `Idempotency-Key` so a retried request returns the first session instead of creating a second one. A test key sees only test-mode products and creates only test-mode sessions.
Returns a checkout_url to redirect the customer to. A cart with one recurring product starts a subscription; otherwise it takes a one-time payment. Sessions expire after 24 hours.
Use it whenever a customer is ready to pay: the card is collected on Utopia's own page, so your server never handles card details. Every item must be in the same currency (MIXED_CURRENCIES otherwise), a subscription cart holds that one recurring product and nothing else (INVALID_CART), and a saved product must be active (PRODUCT_NOT_ACTIVE) and priced above zero (INVALID_PRICE). List each product once and raise its quantity rather than repeating it. Items priced inline are always one-time.
An expired session reads as expired and has no checkout_url left to send anyone to. Send Idempotency-Key so a retried request returns the first session instead of creating a second one. A test key sees only test-mode products and creates only test-mode sessions.
Authorization
secretKey Your secret key: sk_live_… or sk_test_….
In: header
Header Parameters
Retrying with the same key returns the first response instead of creating a duplicate. 1 to 255 printable ASCII characters (INVALID_IDEMPOTENCY_KEY otherwise), remembered for 24 hours per key's merchant and mode. A replayed answer carries idempotent-replayed: true. The same key with a different body is refused with 422 IDEMPOTENCY_KEY_REUSED; while the first request is still running, 409 IDEMPOTENCY_KEY_IN_USE. A request that failed with a 5xx is not remembered, so it can simply be retried.
length <= 255Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
application/json
application/json
curl -X POST "https://example.com/checkout_sessions" \ -H "Content-Type: application/json" \ -d '{ "product_cart": [ { "product_id": "pdt_3f2b8c1e9a4d4e7b8c2a1d5e6f7a8b9c", "quantity": 1 } ], "customer": { "email": "nour.alabbas@example.com", "name": "Nour Al Abbas" }, "return_url": "https://your-store.example/thank-you", "metadata": { "order_id": "1001" } }'{ "object": "checkout_session", "session_id": "cks_9b1e44a0c3d24f6e8a7b5c2d1e0f9a8b", "kind": "payment", "status": "open", "checkout_url": "https://utopia-payments.com/checkout/cks_9b1e44a0c3d24f6e8a7b5c2d1e0f9a8b", "total_amount": 34900, "currency": "AED", "product_cart": [ { "product_id": "pdt_3f2b8c1e9a4d4e7b8c2a1d5e6f7a8b9c", "name": "Pro course", "quantity": 1, "unit_amount": 34900 } ], "customer": { "name": "Nour Al Abbas", "email": "nour.alabbas@example.com", "phone_number": null }, "return_url": "https://your-store.example/thank-you", "payment_id": null, "subscription_id": null, "metadata": { "order_id": "1001" }, "livemode": true, "created_at": "2026-09-14T09:55:00.000Z", "expires_at": "2026-09-15T09:55:00.000Z", "completed_at": null}API reference
Every endpoint, parameter and response of the Utopia Payments API.
Retrieve a checkout session GET
Returns one checkout session: its current status, the cart as it was priced, and the `payment_id` or `subscription_id` it produced once the customer paid. Read it when a customer comes back to your `return_url`, or to recover a checkout link that is still open. `checkout_url` is filled in only while the session is `open`, and a session past its 24 hours reads as `expired`. Only sessions created by the key's merchant and mode are visible.