ZenXGames

Hosted game platform

One game contract.
Any app.

Launch versioned HTML5 games with verified players, direct modes, realtime rooms, cross-device progress, scores, and signed results. The API is publisher-neutral—social apps, learning products, communities, portals, and native apps all use the same contract.

Platform API 0.1 Protocol 1.0 12 active games

Stable by design

The same contract from portal to native app

01

No contract means standalone

A direct public URL keeps the game's complete menus, navigation, solo play, and browser state.

02

Backend-owned intent

Your trusted server selects the game, experience, roster, seats, bot policy, and callbacks.

03

One launch per player

Every human receives a short-lived URL bound to their own match seat and game version.

04

Capability driven

The live catalog—not a hardcoded app menu—decides which games support each profile.

Quickstart

Create a private two-player launch

Your backend calls ZenXGames. Mobile and web clients never receive the publisher API key.

1Host clientrequests a game
2Publisher backendverifies the roster
3ZenXGamessigns each launch
4Game WebViewopens the assigned URL
POST /v1/matches
curl https://games.zenxgames.com/v1/matches \
  -H 'Content-Type: application/json' \
  -H 'X-API-Key: zenx_srv_REDACTED' \
  -H 'Idempotency-Key: session-8841-pool-1' \
  --data '{
    "gameId": "pool-master",
    "experience": "private",
    "externalRoomId": "session-8841",
    "seatCount": 2,
    "players": [
      { "id": "usr_7b81", "name": "Maya" },
      { "id": "usr_f192", "name": "Noah" }
    ],
    "allowBots": false,
    "gameConfig": {
      "modeMenu": {
        "source": "api",
        "playerCount": 2,
        "lockPlayerCount": true,
        "offeredModes": [
          { "id": "versus_2p", "label": "2 Players", "players": 2, "default": true }
        ],
        "autoSelectWhenSingle": true,
        "returnLabel": "Done"
      }
    },
    "callbacks": {
      "matchResultUrl": "https://api.publisher.example/zenx/results"
    }
  }'
Deliver exactly one launch.The response contains one signed URL per human. Return only the URL whose playerId belongs to the authenticated caller.

Launch profiles

One endpoint, five product experiences

Profiles are normal request compositions. They are not tied to a chat, call, room type, or customer application.

Live

Standalone web

Open the versioned catalog URL without a launch token. The full game is unchanged.

No API request
Live

Practice

One verified human. The manifest selects native solo play or a computer challenger.

experience: practice
VSLive by game

Private duel

Two frozen human seats, ready barrier, direct approved mode, authoritative result.

experience: private
Capability

Group session

A shared board or same-challenge race for the exact roster, when the manifest supports its capacity.

seatCount: roster.length
Live

Matchmaking

Queue one player, prefer humans, then use bot fallback only where the game permits it.

experience: matchmaking

Direct-start presentation

Configure the experience before the game is revealed

The host does not inject scripts or manually click through a game menu. A signed gameConfig.modeMenu narrows the title to the exact allowed experience.

Embedded mode restriction
{
  "modeMenu": {
    "source": "api",
    "playerCount": 2,
    "lockPlayerCount": true,
    "offeredModes": [{
      "id": "race_2p",
      "label": "2 Players",
      "players": 2,
      "default": true
    }],
    "blockedModes": [
      "single", "bot", "online"
    ],
    "autoSelectWhenSingle": true,
    "returnLabel": "Done"
  }
}
offeredModes

The complete allow-list. Use IDs returned by the game capability.

blockedModes

A defensive deny-list for aliases already present in a native bundle.

autoSelectWhenSingle

Skips the chooser only when exactly one approved mode remains.

returnLabel

Labels the platform-owned result/return action. The host handles go_home.

Omit it for the public website.An absent modeMenu is a contractual instruction to leave the original full game UI untouched.

Signed launches

Identity and game state stay server trusted

Create-match response
{
  "match": {
    "matchId": "m_01J…",
    "roomId": "r_01J…",
    "gameId": "pool-master",
    "gameVersion": "0.1.10",
    "protocolVersion": "1.0.0",
    "status": "waiting"
  },
  "launches": [{
    "playerId": "usr_7b81",
    "token": "REDACTED",
    "url": "https://games.zenxgames.com/…"
  }]
}
  • URLs are short-lived bearer credentials.
  • Do not log, share, prefetch, or persist them.
  • Never accept a client-selected player ID.
  • Pin client bytes and authoritative rules by version.
  • Retry ambiguous creates with the same idempotency key.
  • Use GET /v1/launch/resolve only with the assigned token.

Client SDK

One event envelope across web, Android, iOS, and Flutter

Browser game API
const launch = await window.ZenXGame.ready;
const me = launch.player;
const players = window.ZenXGame.getPlayers();
const configuration = window.ZenXGame.getConfiguration();

window.ZenXGame.on("STATE", state => renderStandings(state.players));
window.ZenXGames.setState({
  state: "playing",
  metadata: { level: 12, checkpoint: "round-2" }
});
window.ZenXGames.setState({
  state: "over", score: 8400, leaderboard: "weekly"
});
game_loadedmatch_foundmatch_not_found match_startmatch_playinground_over match_overmatch_resultscore_submitted progress_savedgo_homeerror

Browser parent

window.postMessage(event, origin)

Android

AndroidBridge.getGameEvents(json)

Flutter channel

AndroidBridge.postMessage(json)

iOS WebKit

gameState.postMessage(json)

Client events improve the immediate UI but can be duplicated, delayed, or lost if the operating system destroys a WebView. Use the signed server result for durable business actions.

Server callbacks

Verify every result before applying it

Signed request headers
X-ZenX-Event: match_result
X-ZenX-Delivery: dlv_01J…
X-ZenX-Timestamp: 1789430400000
X-ZenX-Signature: v1=<base64url-hmac>

signature_input =
  timestamp + "." + raw_request_body
  1. Read the raw body.Do not re-serialize parsed JSON before verification.
  2. Check freshness.Reject a timestamp outside your allowed clock window.
  3. Compare safely.Recompute HMAC-SHA256 with the callback secret and compare in constant time.
  4. Deduplicate.Claim the delivery ID and match transition exactly once.
  5. Return 2xx after durability.Non-2xx deliveries are retried with backoff.

One-to-one economics

Winner, publisher host, and platform share one conserved stake

Preview The contract is defined for future publisher wallets; Platform API 0.1 does not yet accept live settlement instructions.

DebitLoserCommitted stake
Atomic split100%Integer conserved
Winner player share Host publisher share ZenXGames platform share
Planned request extension
{
  "settlement": {
    "profileId": "duel-standard-v1",
    "stake": {
      "currency": "publisher.credit",
      "amount": 20
    }
  }
}
  • Only the authoritative result can name winner and loser.
  • Percentages and beneficiaries come from a server-owned profile.
  • Winner credit + host credit + platform credit equals loser debit.
  • Draw, no-contest, cancellation, forfeit, and shortfall rules are frozen before acceptance.
  • Settlement is atomic, idempotent per match, and fully auditable.
  • Group-session economics are intentionally deferred to a separate contract.

Mobile WebViews

App-like on every screen without squeezing the game

Contain the surface

Fit the catalog's portrait or landscape frame inside available bounds. Never use cover/fill for the game board.

Allow-list navigation

Keep game navigation on games.zenxgames.com and open outside links externally.

Cache static bytes

Persist immutable versioned assets, but never launch URLs, tokens, API responses, or user-specific HTML.

Close cleanly

Call window.ZenXGame.close() before destroying the WebView, then use destruction as the fallback.

Availability

Generic API, versioned game capabilities

A platform feature can be live while an individual title remains closed for that profile. Always read the current catalog.

Live

Platform foundation

Signed player launches, practice derivation, private rooms, matchmaking, realtime transport, progress, scores, events, and signed callbacks.

Per game

Direct private play

Enable only when embeddedPlay.enabled is true and one offered mode matches the exact human seat count.

Per game

Computer challenger

Enable only when supportsBots is true. Native solo games do not need a fake opponent.

Per game

Exact-roster groups

Read groupPlay for the 2–4 player capacity, scoring order, and whether the title uses one shared board, a synchronized challenge, or signed parallel practice.

Preview

Duel settlement

The generic three-beneficiary contract is specified but not a live wallet endpoint in API 0.1.

Closed by default.An empty private-mode capability means unavailable, even when the game's public menu visually contains multiplayer choices.

Security checklist

Keep trust outside the game bundle

Reference

Build against the published contract

The OpenAPI file describes the live API. The integration contract explains profile composition, WebView behavior, callbacks, and availability boundaries.