Session API

A session is a single checkout: a fixed ZKZ amount, a dedicated receiving wallet, and a 5-minute window to pay. The API runs on your treasury node. Create sessions server-side with your site key — it must never reach the browser.

Create a session

POST/v1/sessions — site-key auth. An Idempotency-Key header makes retries safe: the same key + same body replays the original response; a different body returns 409.

const res = await fetch("https://<your-node-host>/v1/sessions", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${SITE_KEY}`,   // sk_… — server-side only
    "Content-Type": "application/json",
    "Idempotency-Key": "order_8842-create-1",
  },
  body: JSON.stringify({
    amount: "125",            // decimal STRING — never a number
    order_id: "order_8842",
    mode: "redirect",        // "redirect" | "embed"
    success_url: "https://shop.example/thanks",
    cancel_url: "https://shop.example/cart",
  }),
});
const session = await res.json();

The response carries a session_id (sess_…, your durable order reference), a token (cs_…), the checkout_url, the receiver_pubkey, and expires_at. Status is always open on creation.

Session status

A session's status is always exactly one of four values, and once it leaves open it is terminal:

StatusMeaning
openCreated, not yet paid (includes queued-at-capacity sessions).
paidSettlement confirmed — the payment object is present.
expiredThe 5-minute window elapsed with no valid payment.
cancelledCancelled via the API before payment.

Retrieve a session

GET/v1/sessions/:session_id — site-key auth. For fulfilment, prefer webhooks over polling — payment.succeeded is the reliable trigger.

Amounts are decimal strings everywhere — never parseFloat/Number them. There is no sandbox: every session moves real ZKZ.

Full API reference →   Integration docs →