Going live
Going live is a change of workspace state, not a code change. Your integration keeps the same base
URL and the same code; you swap a cpk_test_ key for a cpk_live_ one.
The approval gate
Section titled “The approval gate”- Submit KYB. Business details, documents, and the structured identity of the people behind the business, all from the dashboard’s Settings.
- Complete the structured identity. Go-live requires at least one UBO, and every UBO and director must have their deep fields filled in. These are required at go-live, not at the first onboarding screen, so an account can look complete and still be blocked here.
- Wait for KYB approval. A workspace cannot be enabled while its KYB is anything other than
APPROVED. Attempting it returns422with a message naming the current status. - An operator enables live mode. This is not a self-service action.
- Create a
cpk_live_key and swap it in. Same base URL, same code, same signing recipe.
If step 2 or 3 is incomplete, the go-live call fails with 422 and tells you which of the two it
was: an incomplete identity names the people and the missing fields; a KYB that is not approved
names the status it is in.
What does not carry over from the Sandbox
Section titled “What does not carry over from the Sandbox”Sandbox and Live share the code path, but resources are per network, and knowing that in advance is what makes go-live day uneventful. To re-create on the Live side:
- API keys. A
cpk_test_key can never touch mainnet. Mint yourcpk_live_key from the dashboard, with the least-privilege scopes your integration actually uses. - Webhook endpoints. Endpoints are registered per network, each with its own secret. Register your production endpoints with a live key (or from the dashboard in Live mode) and store the new secrets; your sandbox endpoints will not receive live events.
- Wallets and customers. Sandbox wallets live on the testnets. Your production wallets are created fresh with the live key: same requests, same code.
- Withdrawal security. The allowlist, its beneficiaries and the withdrawal limits are Live-side configuration, on the dashboard’s Security page. Nothing you did in Sandbox pre-configures them.
Read this before your first live withdrawal
Section titled “Read this before your first live withdrawal”A live workspace starts with the withdrawal allowlist ON. That is deliberate: it is secure by default, and it is the single most common first-day surprise.
The practical consequence is that your first live withdrawal is not a straight API call. The destination has to be on the allowlist first, and adding a beneficiary is a protected action rather than an ordinary write, with a cooling-off delay (24 h by default) before the new address becomes usable. Larger withdrawals are additionally held for a second member’s approval, according to the policy on your workspace.
Plan for it: add your first beneficiaries on go-live day, before you need them, so the cooling-off has elapsed by the time your first real withdrawal is due.
This differs from the Sandbox on purpose. Sandbox keys are not granted withdrawal scopes, precisely so that you do not learn a withdrawal flow that has no allowlist to satisfy and then meet these controls for the first time in production.
Before your first real customer
Section titled “Before your first real customer”A checklist worth walking through once, seriously, before real money flows:
- Branch on
code, never onerrortext. The message wording can change; the code is the contract. See Error codes. - Credit on
DEPOSIT_CONFIRMEDonly, and readrequired_confirmationsoff the deposit instead of hard-coding a threshold. - Verify every webhook signature and deduplicate on the delivery id, which is stable across retries. Recipe and contract in Webhooks.
- Send an
Idempotency-Keyon mutating POSTs, so a network timeout never turns into a double action. - Guard the live secret. Store it in your secret manager, never in code or logs; consider the key’s optional IP allowlist and expiry.
- Test your production webhook endpoint end to end before the first customer does it for you.
What does not change
Section titled “What does not change”- The base URL is the same. There is no separate live host.
- The signing recipe is identical.
operationIdvalues, and therefore your SDK method names, are unchanged.- The network is taken from the key:
cpk_test_is testnet,cpk_live_is mainnet. You do not send it.