Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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).

LevelMeaningNote
StudioThe organization that holds your games togetherA server can have more than one studio
GameA single productWhen a new game is created, the dev and prod environments are opened automatically
EnvironmentAn isolated copy of the game: dev, prod, and staging if you want itPlayers, 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 the environmentId setting.

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 environmentId field in the response to the GET /v1/panel/modules request 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 404 with the body {"code":"module_disabled","message":"…","module":"<name>"}. A caller with invalid credentials gets 401 and 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 trading relies on economy and items), 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 keyClient key
Where is it used?Your game server, your backend codeThe game client (browser, mobile)
Can it be embedded?No, keep it secretYes
What can it do?All operations: creating definitions, granting money, minting items, registering webhooks, administrationOnly permitted, non-sensitive operations
Examplethe add_xp command, granting money, minting itemsreading 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) become bigint in JavaScript; in the plugin protocol they are carried as decimal strings. See Numbers and encoding.

For short definitions of terms, see the Glossary.