Core concepts
Everything in Open Play revolves around a few concepts: the environment that data belongs to, the modules that turn features on and off, two kinds of API key, the player’s session, and the plugin that carries game-specific logic. Read this page once; the other pages assume you know these words.
Studio, game, environment
Open Play uses a three-level hierarchy. In the panel you manage this tree on the Studios and games screen (visible only to the super admin).
| Level | Meaning | Note |
|---|---|---|
| Studio | The organization that holds your games together | A server can have more than one studio |
| Game | A single product | When a new game is created, the dev and prod environments are opened automatically |
| Environment | An isolated copy of the game: dev, prod, and staging if you want it | Players, characters, wallets, and keys belong to an environment |
The environment is the data boundary. A player, character, wallet, or key in one environment is not visible from another environment. Every API call runs against a single environment:
- In calls made with an API key, the environment comes from the key; you do not send an extra header.
- In calls made with a player session, you declare the environment with the
x-crx-env: <environment-id>header. The ID is a UUID. The SDKs send it from theenvironmentIdsetting.
Note
Today the panel does not show the environment ID (UUID) in a readable field. Ask your operator team for the ID, or read it from the
environmentIdfield in the response to theGET /v1/panel/modulesrequest that the Game settings › Modules tab makes in a panel session. This gap is on record.
For the panel steps, see Quickstart and Game settings.
Modules
Most features are modules: characters, economy, items, trading, store, rewards, social, chat, competition, notifications, webhooks, scenes, plugins (13 modules). Modules are turned on and off per environment; at installation the wizard has you choose a starter set, and afterwards you use the Game settings › Modules tab (super admin only).
- The endpoints of a disabled module do not work: HTTP
404with the body{"code":"module_disabled","message":"…","module":"<name>"}. A caller with invalid credentials gets401and cannot find out that the module is disabled. - Disabling does not delete data, it only stops the surface; when you enable it again the data is still there.
- Some modules depend on others (for example
tradingrelies oneconomyanditems), and a module that an active plugin needs cannot be disabled. - Core surfaces (player sign-in, content groups, API keys) are not modules and cannot be disabled.
For error details, see Errors.
API keys: server and client
An API key is a secret string bound to an environment, sent with the Authorization: Bearer header. Its format:
crx_live_<prefix>_<secret>
The panel shows only the crx_live_<prefix> part (the prefix); the secret is shown once, at the moment it is created and cannot be recovered. If you lose it, you create a new key or rotate the key: the old secret becomes invalid and the new one is shown once.
| Server key | Client key | |
|---|---|---|
| Where is it used? | Your game server, your backend code | The game client (browser, mobile) |
| Can it be embedded? | No, keep it secret | Yes |
| What can it do? | All operations: creating definitions, granting money, minting items, registering webhooks, administration | Only permitted, non-sensitive operations |
| Example | the add_xp command, granting money, minting items | reading a character, the set_flag command |
The exact rule changes per endpoint and is tested per endpoint in code. Which endpoint accepts which key type is listed in the endpoint reference. If the key type is insufficient, the call gets 403.
To create a key in the panel: Game settings › API keys › New API key (see API keys). When you create one, you enter a name, the type (Server key or Client key), the validity period, and a note written to the audit log (8–500 characters).
Warning
Advanced settings (scope labels, permissions, extra information) are for record-keeping only today; they do not restrict what the key can access. Only the key type determines access. Do not treat a server key as “restricted”.
For managing keys and secret values, see Security.
Player session
Players talk to the server not with an API key but with their own sessions. A session is opened in these ways: guest sign-in, email and password, Google. On a successful sign-in the server writes a session cookie (__Secure-crx.session) and a refresh cookie (__Secure-crx.refresh); the same tokens are also returned in the response body, so clients without cookies (the Unity native build, command-line tools) can use Authorization: Bearer <session-token>.
Every request made with a player session carries the x-crx-env header. In a cookie-based (browser) session, state-changing requests additionally require CSRF protection (the x-csrf-token header). The SDKs manage these details for you; with raw REST you implement them yourself:
The player session can also be carried to your game server: the player’s short-lived access JWT (EdDSA) is verified offline with a shared JWKS. See Server-side verification.
Plugin
A plugin is a package compiled into the server that carries game-specific server logic (commands, queries, realtime modules). Plugin calls are made under /v1/plugins/{plugin}/...; state-changing commands carry an idempotency key and, if the schema requires it, a version check with expectedVersion. A plugin’s schema is an artifact (<plugin>.plugin.schema.json), and the TypeScript/Unity bindings are generated from this schema.
Note
Loading third-party plugins (from the panel or the API) is not supported today. Plugins come with the Open Play server release. See Plugins overview.
Common call rules
The same three rules apply to many endpoints; you will find the details in the reference pages:
- Idempotency-Key: for state-changing commands, the same key and the same body replay the result; the same key with a different body returns
422. See Idempotency and concurrency. - If-Match / expectedVersion: by declaring the version of the resource that you read, you catch a concurrent write conflict (
409). - Numbers: large integers (
i64) becomebigintin JavaScript; in the plugin protocol they are carried as decimal strings. See Numbers and encoding.
For short definitions of terms, see the Glossary.