Reference
Going live
The route from a sandbox key to a live one: what to prove, what to agree, and what changes when the tenant switches.
The sequence
Work in this order. It is the one that fails cheapest, because everything it surfaces costs a test run rather than a customer's money.
- Build the whole flow against the sandbox: quote, reserve, order, position, exit, settlement.
- Trigger every failure mode on the Errors page deliberately and handle each one, including killing your own process mid-order and recovering it by
clientOrderId. - Run a settlement consumer through a full cycle, void included, and prove it is safe to run twice.
- Reconcile a period and prove it balances.
- Agree the commercial terms below.
- Swap the key.
The sandbox is not a lesser environment
It is the same pipeline, the same tables and the same code, with the fill produced locally and the tenant flagged. Everything you prove there about idempotency, recovery, settlement and error handling transfers unchanged.
What to prove before you swap the key
Every one of these is reachable in the sandbox. Run them there.
Pricing and display
- Render the quote's
executionPriceon every ticket. No surface anywhere renders a reference probability as a price. - Where no executable price is published, show no price and disable the controls. Never fall back to the reference.
- Read
priceBasis. Display areference-basis quote as an estimate, or not at all. - Carry prices at the precision you received them. No rounding to whole cents anywhere in the path from response to display.
Money
- Act on
operatorMoneyandoperatorExitMoney, never on the float fields beside them. Parse amounts as decimal strings and never through a float. - Assert both identities before posting:
authorizationAmount = actualDebit + releaseAmountandactualDebit = tradeAmount + platformFee + venueFee. Exactly, not to a tolerance. - Release the non-zero
releaseAmounta partial fill returns. Debiting the full stake keeps money that is not yours to keep. - Credit
sellProceedson a sell and never debit. A nulloperatorMoneyis not a reason to fall back to the entry shape. - Reserve the stake on your wallet before the quote, not after the order.
Orders and recovery
- Derive every
clientOrderIdfrom the reservation in your own ledger, and reuse it on every retry. - Hold the authorization on
409 reconciliation_requiredand poll. No branch anywhere releases on it, and no branch re-quotes on it. - Exercise the recovery path: kill the process mid-order, find the order again with
GET /api/v1/orders?externalUserId=&clientOrderId=, then read thatorderIdback withGET /api/v1/orders/{id}. - Switch your wallet on
settlementState, not onstatus. The list and the single-order routes carry the same value from the same function; a branch that treats a missing field as"settled"releases a hold it must keep, so refuse to act on a row without it. - Handle the refusals that depend on your configuration rather than the market:
over_wager_limitandover_period_limit(the limits you set per account or per player),over_tenant_exposure(waitretryAfterMs),market_not_offered, andstake_exceeds_stale_limit, which caps the stake on an aging or stale price and names the largest stake it would take inmaxStake. - Handle the live-account refusals:
503 trading_paused(your trading pause),503 order_lane_unavailableand503 live_execution_unavailable(wait and retry), and on a cash out422 below_venue_minimum,422 insufficient_position(offersellableContracts) and403 sell_not_available. Treat an order withdrawn before sending (statuscancelled, for example over a live cap) like any other cancellation: apply its release. - If you serve players in more than one jurisdiction, send each player's country with
PUT /api/v1/users/{id}/jurisdiction(or in the embed session) before their first quote. Where jurisdiction enforcement is active for your account, a player with no asserted country is refused. - Re-quote and re-confirm with the player on a
409. Never retry a422unchanged. - Handle
partially_filled.filledQuantity, not the quote'scontracts, is what the player holds.
Settlement and operations
- Key the settlement consumer on the settlement
idorpositionId, advance its cursor only after a successful credit, and make it safe to run twice. - Credit a void from
voidCredit(a refund with the fee included, or a split payout with the fee kept), and run a full settlement cycle including a void end to end. - Read
GET /api/v1/reconciliationon a nightly close and alert on anycriticalfinding. - Read
simulatedand surface it somewhere your operations team can see it. - Back off with jitter on
429and5xx, and readRateLimit-Remainingwherever it arrives. One thing it will not tell you: a second per-tenant ceiling counts every key you hold together and is not reported on any header. Keep a retry path rather than a purely predictive one. - Store keys in a secret manager and rehearse the rotation path.
- If you use webhooks, register every endpoint, verify a signed delivery end to end, and rehearse a signing-secret rotation: it replaces the old secret at once. Keep polling the reconciliation feed regardless.
- Narrow scopes per credential. A read-only integration key does not carry
orders:write.
What we need from you, and what you receive
Both lists are kept in one place, with the reason for every item and where it is entered: the Partner onboarding checklist, which is also the last section of the Parity Integration Packet. In short, we need your tenant name, jurisdictions, the markets to offer, commercial terms, display currency and language, account limits, the origins that will frame the embed and its look, your webhook endpoints and events, the keys and scopes you want, your wallet endpoint if you use an operator-backed book, the people who need account access, and your technical contacts. You receive a sandbox tenant and host, a test key and later a live key (each shown once), a signing secret per webhook endpoint (shown once), the embed URL, account access for your team, and this documentation.
What is agreed with people, not in code
Part of a launch is a conversation rather than a contract shape. Settle these for your account, before the key changes: the custody structure, including per-user versus omnibus accounts; the regulatory perimeter you operate inside; how KYC and AML responsibility divides between you and Parity; and the commercial terms.
Parity holds no player funds, and that does not change at launch
You own your customers' cash ledger. Parity returns exact instructions against it, authorizationAmount, actualDebit, releaseAmount, sellProceeds, settlementCredit and voidCredit, and never a balance of theirs. That shape is identical in the sandbox, which is why what you build there is what you run.
What changes when the key changes
A tenant starts in sandbox mode. Parity moves it to live as a managed step once the readiness checks on your tenant have no blocking item and the terms are agreed, and you then receive sk_live_ keys. At go-live Parity also enables live transmission for your account, confirms the collateral arrangement where Parity executes for you, and sets the live policy caps on your tenant; each order is then armed as it executes.
- Sandbox keys are minted
pk_test_and live keyssk_live_. Mode is a property of the operator record, so no header or parameter moves a caller across the boundary. - The balance, ledger, funding and sandbox test-control routes answer
403 sandbox_onlyfor a live tenant. They model a Parity-held balance, which is the wrong model for a live operator: your own wallet is the authority on what a player may stake. - Every other route behaves identically in both modes, against the same tables and the same code, with two exceptions. A live cash out is checked when it is quoted (sized in contracts, on the hundredth-of-a-contract grid, at least the market's minimum and no more than is free to sell), and a live fill carries the venue's own fee inside the stake. Otherwise what differs is what happens after an order is cleared to execute: see below.
simulatedis on every quote, order and settlement payload, and tells you whether a fill was produced locally.
Ask what is armed before you point real customers at it
A sandbox order produces a fill immediately. A live order does not: it is recorded, reserved against, and cleared to execute, and it is transmitted to a venue once live transmission is enabled for your account and that specific order has been armed. Arming is a deliberate per-order act, not something an order acquires by being placed. Until both are true the order sits at pending_venue_execution with transmissionState: not_transmitted.
Nothing is lost there: no order was sent, the order is still cancellable, and its release instruction is exact. But it is not a state that clears on its own, and it is the one thing about live mode that your sandbox run cannot show you. Confirm with Parity, in writing, what live transmission is enabled for your account as part of this checklist, before the key changes.
The mechanics of each of those live on Environments.

