Skip to main content
POST
Create a short-lived, single-use session tied to one merchant, customer, and order. The response gives you a session_token + iframe_url for the frontend — embed the iframe via the SDK or open the hosted checkout directly. POST /v1/sessions · Authenticated with your secret key.

Which flow?

Omit mandate_setup (or send intent: "checkout"). The session collects a card and charges immediately.

Mandate setup

Mandate creation is part of the Session APIs — this endpoint is how mandates are created. Send a mandate_setup block (see Body) with intent: "mandate_setup" and the session becomes authorize-only: the response carries an iframe_url where the owner approves once with their passkey. Completing setup does not issue payment credentials. Once the mandate is active, charge it with Charge a Mandate within its approved terms — no further passkey needed. The mandate_setup field reference below covers recurring_frequency, merchant_scope, max_charges, and valid_until; see Mandates for the concept and guardrails.
Choosing a card source. Omit card to let the cardholder select or enter a card in the collection surface. Send card.card_id to pre-select an already-enrolled card, or card.vault_ref_id (a Skyflow UUID) for the vault-ref flow. Send exactly one — if both are present, card_id wins. After collection, Get Payment Result returns the card bound to each transaction as transactions[].card_id.

Body

string
required
Unique identifier for the customer in your system (1–255 chars). Required for merchant (secret-key) sessions — omitting it returns 400 VAL_2001.
string
required
Customer email. Required for merchant sessions. Must be a valid email address.
string
required
Total order amount as a decimal string with up to 2 decimals, e.g. "49.99". Need not equal the sum of line items (it may include tax, shipping, and fees). This value becomes the authorized amount cap.
string
required
ISO 4217 code — 3 uppercase letters — and must be a supported currency. Supported: USD, EUR, GBP, INR, CAD, AUD, JPY, SGD, AED, HKD, MXN, BRL, CHF, CNY, NZD, SEK, NOK, DKK, ZAR, THB, KRW, PLN, TWD, PHP, IDR, MYR, CZK, ILS, CLP, ARS, COP, PEN, SAR, QAR, KWD, BHD, OMR, EGP, NGN, KES, GHS, TZS, UGX, PKR, BDT, LKR, VND, MMK, NPR. Other codes are rejected.This is your pricing currency and is independent of the card’s issuing country: there is no requirement that it match country_code_iso2 (the merchant’s location) or the cardholder’s country. A US-issued card can pay an INR-denominated session; the card network settles the cross-currency conversion. Price in whatever currency your product uses — you don’t need to re-denominate.
object
required
What is being bought. Two modes — pick one:
  • From a quote — send quote: true and the opaque quote_id (qte_…) returned when the quote was created. Merchant and product details come from that quote, so nothing else is needed.
  • Custom — omit quote (or send false) and describe the merchant and products yourself in custom.
string
default:"full_checkout"
full_checkout (hosted redirect) or embedding (mount the iframe via the SDK). Read by the frontend to choose the surface.
string
For hosted checkout: the URL Prava redirects the cardholder to after they finish. Must use https, max 2048 chars. Optional for all integration types.
object
Pre-select a card. Send one of the two fields below (see the note above).
object
Turns the session into mandate setup (authorize-only). See the Mandate setup tab above.
string
Customer phone number.
string
Customer country — 2 uppercase ISO 3166-1 letters.
string
Your external order reference id, max 255 chars.
string
Human-readable description of the order.
object
Optional, sandbox-only payment success simulation for quote-backed checkout. The exact shape is { "stage": "payment", "outcome": "success" }; both fields are required and additional fields are rejected. Custom checkout, production, and mandate-setup sessions cannot use it. Normal card collection and verification still run. An eligible terminal payment result can complete the sandbox lifecycle while observed_result retains the actual outcome. See Sandbox simulation.

Response

string
Unique session identifier.
string
JWT authenticating client-side SDK calls within this session.
string
Secure card-collection (or, for mandate setup, passkey-approval) surface.
string
Internal order identifier.
string
ISO 8601 timestamp when the session expires.

Notes

  • Sessions are short-lived and single-use, tied to a specific merchant, customer, and order.
  • session_token and iframe_url are used on the frontend: embedded via the SDK, or opened directly for hosted checkout.
  • Sessions can be revoked before use via POST /v1/sessions/:id/revoke.

Error responses

Authorizations

Authorization
string
header
required

Your secret key: sk_test_* (sandbox) or sk_live_* (production).

Body

application/json
user_id
string
required

Unique identifier for the customer in your system

Required string length: 1 - 255
user_email
string<email>
required

Customer's email address

Maximum string length: 320
total_amount
string
required

Total order amount in decimal format (e.g. "49.99")

Minimum string length: 1
Pattern: ^\d+(\.\d{1,2})?$
currency
string
required

ISO 4217 currency code — exactly 3 uppercase letters, and one of Prava's supported currencies (e.g. USD, EUR, GBP, INR) - other codes are rejected

Required string length: 3
Pattern: ^[A-Z]{3}$
purchase_context
Custom checkout · object
required

What is being bought. Two modes — send exactly one: quote: true + quote_id (session built from an existing quote), or custom (describe the merchant and products yourself).

user_phone
string

Customer's phone number

user_country_code_iso2
string

Customer's country — 2 uppercase ISO 3166-1 letters

Required string length: 2
Pattern: ^[A-Z]{2}$
external_order_ref
string

Your external order reference ID

Maximum string length: 255
description
string

Human-readable description of the order

integration_type
enum<string>
default:full_checkout

How the card is collected. full_checkout = hosted redirect; embedding = mount the iframe via the SDK.

Available options:
full_checkout,
embedding
callback_url
string<uri>

For hosted checkout: the https URL Prava redirects the cardholder to after they finish. Optional for all integration types.

Maximum string length: 2048
Pattern: ^https://
card
object

Pre-select a card. Send card_id OR vault_ref_id; if both are sent, card_id wins.

mandate_setup
object

Turns the session into mandate setup (authorize-only). Absent = standard checkout.

sandbox_simulation
object

Sandbox-only success simulation for quote-backed payment sessions. Fixed at session creation; production, custom checkout, and mandate setup reject this option. Normal card collection and verification still run. See Testing in Sandbox.

Response

Session created

session_id
string

Unique session identifier

session_token
string

JWT to authenticate client-side SDK operations within this session

iframe_url
string

URL for the secure card collection surface

order_id
string

Internal order identifier

expires_at
string<date-time>

ISO 8601 timestamp when the session expires