# Test mode & live mode > What differs between sandbox and production, and the checklist for going live. Source: https://casinoapipro.com/docs/test-and-live Every account starts in test mode. Test and live are separate credentials, separate data and separate money — there is no flag that turns one into the other by accident. ## What differs | Name | Type | Meaning | | --- | --- | --- | | `Credentials` | ck_test_ / ck_live_ | Prefixed so you can tell at a glance which environment a log line came from. | | `Money` | play / real | Test credentials cannot move real money under any circumstances. | | `Wallet` | separate records | Each environment has its own wallet integration. Test mode can use the built-in play-money wallet or your staging one; live uses whatever you configured for live, and never falls back. | | `Games` | same | Identical engine, identical mathematics, identical versions. Only the money differs. | | `Data` | separate | Players, sessions, rounds, transactions, free bets and your API request log all belong to one environment. A test player is not a live player even under the same player_id, and nothing you see in one mode is ever from the other. | | `Rate limit` | same | Your planu2019s requests-per-minute budget, identical in both. Test traffic is not given a looser allowance, so a load test in sandbox measures the limit you will actually meet. | | `Players` | capped in sandbox | Sandbox allows `100` distinct players on the free plan; live is uncapped. Sandbox is for building and testing, and a hundred is far more than any integration needs — the limit exists so that a free account cannot quietly be run as a real casino. Paid plans have no sandbox cap, because live is already available to them. If you are genuinely load-testing and need more, ask and we will raise it for your account. | > **Nothing crosses between them** > > The separation is enforced per request, not per screen. A sandbox credential cannot read a live round, a live one cannot read a sandbox round, and the dashboard filters every list — including the API request log — on the mode you are in. There is no endpoint that returns both and no parameter that widens one to the other: a credential carries its environment in its token and cannot ask for the other. > **The engine is the same code** > > Sandbox is not a simulator. Rounds are computed by the same versioned engine, with the same provable-fairness commitments, and settled through the same idempotent state machine. A result you get in test is the result you would have got live. ## One host, two kinds of key There is no separate sandbox hostname. Every request in both environments goes to `https://api.casinoapipro.com`, and the key you exchange for a token is what puts you in one environment or the other. Nothing else in your integration changes between them — not the host, not a header, not a query parameter. ```http https://api.casinoapipro.com ck_test_… → sandbox https://api.casinoapipro.com ck_live_… → live ``` The token you get back carries the environment, and every route reads it from there. A live token cannot see sandbox data and a test token cannot move real money; there is no flag that turns one into the other. > **The health endpoint says nothing about your account** > > `GET /health` returns `status`, `version` and `uptime_seconds` — it is unauthenticated and tells you the platform is up, not what you are entitled to. Read your own state from the dashboard or [the account endpoints](/docs/account) instead. ## Going live Issuing live credentials is self-service: you generate them in the dashboard the moment your plan is active. There is no approval queue and nothing to wait for on our side. What is worth doing first is proving the parts that are expensive to get wrong in production. - Configure a live wallet integration. It is a separate record from your sandbox one. Until it exists, live money calls fail with `WALLET_NOT_CONFIGURED` — deliberately, rather than falling back to the play-money wallet. This is the single commonest thing missed on the first live bet. - Prove your wallet is idempotent — replay the same `transactionId` and confirm one movement. - Prove your retry path — make the sandbox wallet time out and confirm you recover without double-debiting. - Prove your reversal path — refund a bet and confirm you match on `referenceTransactionId`, not on the reversal's own id. See [the wallet contract](/docs/wallet). - Verify webhook signatures against the raw body, and confirm you deduplicate on event id. - Swap the credentials. > **Keep the test credentials working** > > The commonest post-launch incident is a change shipped straight to live because the sandbox integration was retired. Keep it, and point your staging environment at it.