request_id, timestamps, and request/response payloads.
Operator API errors
| HTTP Status | Likely cause | Resolution |
|---|---|---|
401 | Missing or malformed Authorization header. | Verify the header format is exactly Authorization: ApiKey ps_<your_api_key>. Check your HTTP client is not stripping it on redirects. |
403 | API key is valid but not authorized for the resource. | Confirm the key belongs to the correct operator account. Contact support if the issue persists. |
404 | Resource not found (e.g. unknown gameId on /operator/launch). | Re-fetch the catalog from /operator/games to confirm the ID is still enabled. |
400 | Malformed JSON or missing required field. | Validate the request body against the endpoint schema. |
429 | Rate limit exceeded. | Back off and retry with exponential delay. |
5xx | Transient PlayStarters error. | Retry with exponential back-off. Contact support if it persists. |
Authentication issues
- Header format. Must be
Authorization: ApiKey ps_<your_api_key>— notBearer, notToken. - Environment match. Make sure you are calling the base URL that matches your key (sandbox vs production).
- Key rotation. If the key may have been leaked, contact PlayStarters to rotate it. Old keys are invalidated immediately on rotation.
Game launch issues
/operator/launch returns a URL but the game does not load
- Confirm the
gameUrlis loaded immediately. Launch URLs are short-lived. - Open the URL in an iframe with the correct
allowattributes (autoplay, fullscreen) or in a new window. - Check the browser console and network tab for CSP, mixed-content (HTTP vs HTTPS), or cross-origin issues on your site.
- PlayStarters calls your wallet endpoint with
type: "BALANCE"immediately after the game opens. Check your endpoint logs for that request. - Verify your endpoint returns
{ "balance": <number> }with HTTP200. A non-200response, a malformed body, or a missingbalancefield will surface as0(or a generic error) in the game. - Confirm the
currencyyou passed to/operator/launchmatches the currency of the balance your endpoint returns.
Seamless Wallet callback issues
Player charged twice for the same spin- Your endpoint is not idempotent. Implement deduplication on
request_id— see Idempotency.
WIN or VOID arrives for an unknown parent_transaction_id
- Don’t fail the request. Log it for investigation and respond
200 OKwith the player’s current balance. Failing the request causes retries and reconciliation drift.
- Check whether your endpoint is returning
400 { "msg": "Insufficient user credit" }only for genuinely insufficient balances. Returning400for transient errors (DB timeouts, etc.) will incorrectly block the game.
Going-live checklist
Before switching from sandbox to production:
- ✅ Production Operator API key stored as an environment variable.
- ✅ Production wallet key stored as an environment variable; your wallet endpoint validates the
Authorization: Bearerheader. - ✅ Base URL switched from sandbox to production for all Operator API calls.
- ✅ Wallet endpoint reachable from PlayStarters with valid TLS.
- ✅ Idempotency on
request_idverified with a duplicate-request test. - ✅ End-to-end flow tested: launch →
BALANCE→BET→WIN→VOIDwith reconciled balances on both sides.
If you’ve followed this guide and the issue persists, submit a support ticket. Include your operator ID, the affected endpoint, the
request_id, the timestamp (with timezone), and the request/response payloads with secrets redacted.