This page lists the problems you will encounter in integration as a symptom, cause, fix triple. Find the symptom from the error code or the status code. For the full code tables, see the error reference.
Note
When reporting a problem, include: the path and method called, the status code and body (with secret values removed), the request time (UTC), and on plugin endpoints the x-request-id/requestId. The server does not leak error detail outward; this information speeds up the investigation.
The Authorization: Bearer crx_live_… header is missing or its format is wrong; the key was revoked, disabled, or expired; the key belongs to another environment
Check the header and the key; look at the key’s state and environment in the panel (API keys). The server does not distinguish “wrong key” from “revoked”
Server call 403 permission denied
You are calling a server endpoint with a client key
Use a server key (endpoints: the endpoints marked “Server key”)
Player call 401
The x-crx-env header is missing or not a UUID; the session is missing, expired, or revoked; the environment does not match
Add the header; refresh the session or sign in again. A banned account also looks like 401 (no distinction is made)
Player 403 permission denied (POST)
The CSRF pair is missing/does not match; the token was already used; Origin is not allowed
See the CSRF rows below
403 and {"code":"account_banned"} at sign-in
The account is banned
Show the player a suspension screen; do not build a retry loop; do not open a new guest
The session ends earlier than expected
No request was made for 30 days; or the 180-day absolute ceiling was reached; the password changed (all sessions drop); “single active session” is on in the environment and a sign-in was made from another device
Build a sign-in-again flow; the behavior is on the security page
The session cookie is never set in the browser
You are working over HTTP (Secure + the __Secure- prefix); the API is on another domain (the cookie becomes third-party, SameSite=Lax); the browser blocks cookies
The x-csrf-token header or the __Secure-crx.csrf cookie is not being sent
Get a token with GET /v1/auth/csrf; send the cookie and the header together. The SDK does this automatically
The first POST passes, the second 403
The CSRF token is single-use and renewed with every successful response; you did not store the response’s new value, or you sent two requests in parallel with the same token
Use the new x-csrf-token and Set-Cookie value in each response; put modifying requests in a queue
403 only in the browser, works in curl
Origin is not in the environment’s allowed origins; a navigation request with Sec-Fetch-Site: cross-site
Define the game’s domain as an environment domain (Game settings: environments); call the API from the same origin
A “CORS policy” error in the browser console
The game’s domain is in no environment’s domain list or the global allowed list (the server sends no CORS to that origin); or the origin is not https://<domain> (http, a port, null)
Add the domain as an environment domain (Game settings: environments); if that is not possible, set up a same-origin reverse proxy. Do not add extra CORS headers to your proxy
On a clan, group, or tournament endpoint the key is not a UUID
Generate a UUID v4
400If-Match error
*, W/"3", a negative or non-numeric value
Send the exact version number (3 or "3")
409 version conflict
The resource changed after you read it
Re-read, repeat with the new version
409 idempotent request in progress
The request with the same key is still being processed
Repeat shortly with the same key
422 idempotency mismatch
You used the same key with a different body
A new key for every different operation; do not change the body when repeating the same operation (remember that the key is unique across the environment)
422 unprocessable: …
A business rule rejection (balance, stock, limit)
Read the state and show it to the user; do not repeat the same request
410
The key’s 24-hour record retention expired
Read the state and, if the operation was not applied, restart it with a new key
413
The body is above 2 MiB
Shrink the body; for images use the image upload endpoint
429
Rate limit or rule budget
Wait and repeat with the same key; for the rule budget simplify the rule
503 and Retry-After: 30
The environment’s placement is temporarily unavailable
Wait for Retry-After and repeat
A big number is corrupted (9007199254740992 instead of 9007199254740993)
You read the JSON with JSON.parse; int64 did not fit in a JS number
Use the SDK’s bigint reading or lossless-json (numbers)
An SDK error of type Contract
The response does not conform to the schema the SDK knows (the server is newer) or the response is above 2 MiB
The plugin is not enabled in the environment (read-only, draining, disabled) or the environment’s plugin version does not match the server’s; CSRF/Origin rejection
Look at the plugin’s state and version in the panel (Plugins)
400 and invalid_argument (“x-crx-schema-version is required”)
The x-crx-schema-version header is missing or the schema version is wrong; the payload does not conform to the schema; the same parameter twice in a query
Verify the operation’s schemaVersion value and the input schema from the schema document
404 and not_found
The plugin ID or the message type is wrong; you confused the message type with the operation name
Write the requestMessageType value in the schema document into the path
409idempotency_in_flight
The command with the same key is being processed
retryable: true; wait and repeat with the same key
422unprocessable + reason
A plugin business rule rejection
reason is a plugin-specific code; see the plugin’s documentation; repeating does not help
The command result is uncertain
The network dropped
Query with …/result?idempotency_key=… or repeat with the same key (calling plugins)
SDK upgrade_required (plugin_binding_mismatch)
The binding’s pin does not match the expectation you hold or the document on the server
Get the current document and regenerate the binding (bindings)
Cannot find module '@open-play/sdk/player' in the generated binding
The generator writes the import with the name @open-play/sdk; the published package’s name is @ferdiunal/open-play-ts
Define an alias in package.json: "@open-play/sdk": "npm:@ferdiunal/open-play-ts@<version>"
crx plugins generate error: CRX TYPES FAIL
The digest does not match, the output file already exists, the output folder does not exist, or there is a symbolic link in the path
Match the digest with the schemaSha256 in the document; delete the existing output; create the folder
The endpoint is not registered, was deleted, or is disabled; the event type is not in the subscription list; the webhooks module is disabled (deliveries wait in place, data is not deleted); the endpoint is not publicly reachable
Sync the clock with NTP; keep the window at 5 minutes
The same event arrived twice
Delivery is at-least-once
Deduplicate with X-Crx-Event-Id
Deliveries are failed
No 2xx was received in 10 attempts
Fix the receiver error. The panel’s deliveries are only for monitoring (there is no resend/replay action); make up for the effect of missed events by reading the relevant resource with REST