API reference
Every endpoint, its auth scope, and a request/response example. Most games use the @triggair/sdk client instead of raw HTTP — this is the underlying contract. Machine-readable: /openapi.json (OpenAPI 3.1). Auth scopes: a publishable key goes in X-Triggair-Key; a player token and the developer/operator sessions go in Authorization: Bearer.
Players
/v1/players/anonymous publishable key Mint an anonymous player token
Exchanges a stable device id for a 24h player token. The player is created on first use. This is what the SDK's tg.login() calls; every player-scoped call sends the returned token as `Authorization: Bearer`.
{
"device_id": "a-stable-device-uuid",
"turnstile_token": "optional-if-challenge-on"
} {
"player_id": "p_1a2b3c",
"token": "eyJ…",
"expires_in": 86400
} /v1/players/recover publishable key Recover a player on a new device
Consumes a recovery code (from /v1/players/me/recovery-code) to rebind the same player to a new device, returning a fresh token.
{
"code": "RECOVERY-CODE",
"device_id": "new-device-uuid"
} {
"player_id": "p_1a2b3c",
"token": "eyJ…",
"expires_in": 86400
} /v1/players/me player token Get the current player
{
"player_id": "p_1a2b3c",
"display_name": null,
"created_at": "2026-07-01T00:00:00Z"
} /v1/players/me/recovery-code player token Mint a cross-device recovery code
Returns a single-use code the player saves/shares once; redeem it later with /v1/players/recover on another device.
{
"code": "RECOVERY-CODE",
"expires_at": "2026-08-01T00:00:00Z"
} /v1/players/me/moderation player token Get the caller's own ban/mute status
The player's active bans and restrictions (shadow actions are hidden from self-view).
{
"banned": false,
"restrictions": []
} /v1/players/me/stats player token Get the player's own stats
{
"stats": [
{
"key": "kills",
"value": 12
}
]
} /v1/players/me/stats player token Update stats (set / increment)
Applies one or more stat operations atomically. Stats back leaderboards, achievements, and segment targeting.
{
"ops": [
{
"key": "kills",
"op": "increment",
"value": 1
}
]
} {
"stats": [
{
"key": "kills",
"value": 13
}
]
} /v1/players/me player token Update the player's profile (e.g. display name)
{
"display_name": "AceRunner"
} {
"player_id": "p_1a2b3c",
"display_name": "AceRunner"
} /v1/players player token Look up players (public fields)
-
ids(query) — Comma-separated player ids.
{
"players": [
{
"player_id": "p_9",
"display_name": "Rival"
}
]
} /v1/players/:id player token Get another player's public profile
-
id(path) — Player id.
{
"player_id": "p_9",
"display_name": "Rival"
} Saves
/v1/saves player token List the player's save slots
{
"saves": [
{
"slot": "slot1",
"version": 3,
"updated_at": "2026-07-01T00:00:00Z"
}
]
} /v1/saves/:slot player token Read a save slot
-
slot(path) — Slot name (game-defined).
{
"slot": "slot1",
"data": {
"level": 4,
"coins": 120
},
"version": 3
} /v1/saves/:slot player token Write a save slot
Last-write-wins by default. Send `If-Match: <version>` for optimistic concurrency — a stale version returns 409 save_conflict. Returns 201 on first write, 200 on update.
-
slot(path) — Slot name.
{
"data": {
"level": 5,
"coins": 90
}
} {
"slot": "slot1",
"data": {
"level": 5,
"coins": 90
},
"version": 4
} /v1/saves/:slot player token Delete a save slot
-
slot(path) — Slot name.
null Leaderboards
/v1/leaderboards/:board/scores player token Submit a score
Submits a score to a configured board. The board's aggregation (best/last/sum) and period (all-time/daily/weekly) are set by the developer; the response reports the player's kept score for the current period.
-
board(path) — Board key.
{
"score": 9000
} {
"ok": true,
"best_score": 9000,
"period_key": "2026-07"
} /v1/leaderboards/:board/top player token Read the top entries
-
board(path) — Board key. -
limit(query) — Max entries (default 10).
{
"board": "high_scores",
"period_key": "2026-07",
"entries": [
{
"rank": 1,
"player_id": "p_9",
"score": 12000
}
]
} /v1/leaderboards/:board/around-me player token Read entries around the player
-
board(path) — Board key.
{
"board": "high_scores",
"period_key": "2026-07",
"me": {
"rank": 42,
"score": 8000
},
"entries": []
} /v1/leaderboards/:board/friends player token Read the friends-only board
-
board(path) — Board key.
{
"board": "high_scores",
"period_key": "2026-07",
"me": {
"rank": 2,
"score": 8000
},
"entries": []
} Achievements
/v1/achievements player token List achievements + the caller's progress
Definitions plus this player's progress; secret achievements are hidden until unlocked.
{
"achievements": [
{
"key": "first_win",
"unlocked": true,
"progress": 1,
"target": 1
}
]
} /v1/achievements/:key/progress player token Report achievement progress
The server clamps progress, unlocks exactly once, and escrows any reward into the inbox. The client reports progress but never grants the reward.
-
key(path) — Achievement key.
{
"amount": 1
} {
"key": "first_win",
"unlocked": true,
"progress": 1
} Daily
/v1/daily player token Get daily-reward status
{
"claimable": true,
"streak": 3,
"next_claim_at": "2026-07-11T00:00:00Z"
} /v1/daily/claim player token Claim today's reward
Server-day gated; the reward is escrowed into the inbox. Re-claiming the same day → 409 conflict.
{
"claimed": true,
"streak": 4
} Inbox
/v1/inbox player token List inbox items
-
limit(query) — Max items.
{
"items": [
{
"id": "in_1",
"kind": "reward",
"claimable": true,
"read": false
}
]
} /v1/inbox/:id/read player token Mark an inbox item read
-
id(path) — Inbox item id.
{
"ok": true
} /v1/inbox/:id/claim player token Claim an inbox item's reward
The single hardened grant path — exactly-once (idempotent per item). Grants currency, items, or stat rewards.
-
id(path) — Inbox item id.
{
"claimed": true,
"granted": {
"currency": [
{
"code": "gold",
"amount": 100
}
]
}
} Social
/v1/friends player token List friends
{
"friends": [
{
"player_id": "p_9",
"display_name": "Rival",
"state": "accepted"
}
]
} /v1/friends/requests player token List incoming friend requests
{
"requests": [
{
"player_id": "p_7",
"display_name": "Newcomer"
}
]
} /v1/friends/:id player token Send or accept a friend request
-
id(path) — The other player's id.
{
"state": "pending"
} /v1/friends/:id player token Remove a friend / cancel a request
-
id(path) — The other player's id.
null /v1/friends/:id/block player token Block a player
-
id(path) — The player to block.
{
"blocked": true
} /v1/share player token Mint a share / invite link
Creates a short code carrying an opaque context blob (a level, a challenge, a referral). Resolve it with GET /v1/share/:code on the recipient's device.
{
"context": {
"level": 7
},
"expires_in_seconds": 604800
} {
"code": "SH4RE",
"expires_at": "2026-07-18T00:00:00Z"
} /v1/share/:code player token Resolve a share link
-
code(path) — Share code.
{
"context": {
"level": 7
},
"from": "p_1a2b3c"
} Moderation
/v1/moderate/check player token Pre-check text before submit
Runs the same moderation the write paths use, so you can validate a chosen name/message without a round-trip failure. Stateless (writes nothing).
{
"surface": "username",
"text": "player name to check"
} {
"verdict": "mask",
"masked_text": "player ****",
"categories": [
"profanity"
],
"severity": 2
} /v1/reports player token Report a player / message / UGC
{
"target_type": "player",
"target_id": "p_9",
"reason": "harassment",
"note": "optional"
} {
"id": "cr_1",
"state": "open"
} /v1/appeals player token Appeal a ban
{
"ban_id": "bn_1",
"body": "why the ban should be lifted"
} {
"id": "ap_1",
"state": "pending"
} Compliance
/v1/players/me/age player token Set the player's age bracket
Neutral age screen. A birth year is mapped to a bracket and DISCARDED (no DOB stored). Returns the compliance view with the gated-feature map.
{
"birth_year": 2013
} {
"bracket": "13_15",
"consent_state": "pending",
"gated": {
"open_chat": true,
"lootbox": true
}
} /v1/players/me/compliance player token Get the compliance view (bracket + gated map)
{
"bracket": "13_15",
"consent_state": "pending",
"gated": {
"open_chat": true
}
} /v1/compliance/policy publishable key Get the game's gate policy (pre-token)
pk-only so the client can pre-disable regulated UI before a player token exists.
{
"gates": {
"open_chat": "13_15",
"lootbox": "adult"
},
"coppa_mode": false,
"default_jurisdiction": "US"
} /v1/players/me/consent/request player token Request parental consent (emails the parent)
{
"parent_email": "parent@example.com"
} {
"id": "pc_1",
"state": "pending",
"expires_at": "2026-07-24T00:00:00Z"
} /v1/players/me/consent player token Get the player's consent record
{
"consent": {
"id": "pc_1",
"state": "pending"
}
} /v1/consent/:token no auth Parent consent landing page (HTML)
The signed link a parent receives by email; renders Approve/Decline. No pk/token — the signed token IS the credential.
-
token(path) — Signed consent token from the email.
/v1/consent/:token/decide no auth Record the parent's decision
-
token(path) — Signed consent token.
{
"grant": true,
"note": "optional"
} {
"state": "granted"
} Crashes
/v1/crashes player token Report a crash
Grouped server-side by a normalized-stack fingerprint into a handful of issues with a crash-free-users %.
{
"message": "TypeError: x is undefined",
"stack": "at play (game.js:42)",
"platform": "web",
"appVersion": "1.4.0"
} {
"ok": true,
"group_id": "cg_1"
} RNG
/v1/rng/:stream player token Deterministic server-seeded random values
A verifiable per-player, per-period stream — the same request returns the same values, so loot/crit rolls can't be client-forged.
-
stream(path) — Stream name (e.g. 'loot'). -
count(query) — How many values.
{
"stream": "loot",
"period_key": "2026-07",
"values": [
0.42,
0.88
]
} Realtime
/v1/realtime/rooms/:room player token Join a realtime room (WebSocket upgrade)
A WebSocket upgrade. Because a browser WS can't send headers, the pk + player token go in the query (?key=&token=). Presence + broadcast; chat is moderated in transit. Rooms named team:<id> / match:<id> require membership. Use tg.realtime.join(room) from the SDK.
-
room(path) — Room name; team:/match: prefixes enforce membership. -
key(query) — Publishable key (query, since a WS can't set headers). -
token(query) — Player token.
Economy
/v1/wallet player token Get all currency balances
{
"balances": [
{
"currency": "gold",
"amount": 250
}
]
} /v1/wallet/history player token Get currency transaction history
-
limit(query) — Max lines.
{
"lines": [
{
"currency": "gold",
"delta": -100,
"reason": "store_buy",
"created_at": "2026-07-01T00:00:00Z"
}
]
} /v1/wallet/:currency player token Get one currency's balance
-
currency(path) — Currency code.
{
"currency": "gold",
"amount": 250
} /v1/stores player token List stores
{
"stores": [
{
"key": "main_store",
"name": "Shop"
}
]
} /v1/stores/:key player token Get a store's listings
-
key(path) — Store key.
{
"key": "main_store",
"listings": [
{
"id": "l_1",
"item": "sword",
"price": {
"gold": 100
}
}
]
} /v1/stores/:key/buy player token Buy a store listing
Server-authoritative price + balance check; idempotent (pass idem). Fails with insufficient_funds / out_of_stock / store_limit_reached.
-
key(path) — Store key.
{
"listing_id": "l_1",
"idem": "uuid"
} {
"ok": true,
"granted": {
"items": [
{
"item": "sword",
"qty": 1
}
]
}
} /v1/inventory player token List the player's inventory
{
"items": [
{
"item": "sword",
"qty": 1,
"equipped": true
}
]
} /v1/inventory/:item/consume player token Consume an item
-
item(path) — Item id.
{
"qty": 1,
"idem": "uuid"
} {
"ok": true,
"remaining": 0
} /v1/inventory/:item/equip player token Equip an item
-
item(path) — Item id.
{
"ok": true,
"equipped": true
} /v1/inventory/:item/unequip player token Unequip an item
-
item(path) — Item id.
{
"ok": true,
"equipped": false
} /v1/loot/:key/odds player token Get a loot box's disclosed odds
-
key(path) — Loot box key.
{
"key": "bronze_box",
"odds": [
{
"item": "common",
"weight": 0.9
},
{
"item": "rare",
"weight": 0.1
}
]
} /v1/loot/:key/open player token Open a loot box
Server-rolled (verifiable RNG), idempotent. loot_not_enabled if the box isn't configured; age-gated where required.
-
key(path) — Loot box key.
{
"idem": "uuid"
} {
"rolled": [
{
"item": "rare",
"qty": 1
}
]
} /v1/energy player token List energy meters
{
"meters": [
{
"meter": "stamina",
"current": 4,
"max": 5,
"refill_at": "2026-07-10T01:00:00Z"
}
]
} /v1/energy/:meter player token Get one energy meter
-
meter(path) — Meter name.
{
"meter": "stamina",
"current": 4,
"max": 5
} /v1/energy/:meter/spend player token Spend energy
out_of_energy if the balance is insufficient. Idempotent.
-
meter(path) — Meter name.
{
"amount": 1,
"idem": "uuid"
} {
"meter": "stamina",
"current": 3
} /v1/energy/:meter/refill player token Refill energy (e.g. with a currency)
-
meter(path) — Meter name.
{
"idem": "uuid"
} {
"meter": "stamina",
"current": 5
} Teams
/v1/teams player token Create a team
{
"name": "Alpha Squad",
"tag": "ALPHA",
"privacy": "open"
} {
"id": "tm_1",
"name": "Alpha Squad",
"tag": "ALPHA"
} /v1/teams player token List / search teams
-
q(query) — Search query.
{
"teams": [
{
"id": "tm_1",
"name": "Alpha Squad",
"member_count": 4
}
]
} /v1/teams/mine player token Get the caller's team
{
"team": {
"id": "tm_1",
"role": "owner"
}
} /v1/teams/leaderboards/:board player token Team leaderboard
-
board(path) — Board key.
{
"entries": [
{
"team_id": "tm_1",
"score": 5000
}
]
} /v1/teams/:id player token Get a team + members
-
id(path) — Team id.
{
"id": "tm_1",
"name": "Alpha Squad",
"members": [
{
"player_id": "p_1",
"role": "owner"
}
]
} /v1/teams/:id/join player token Join a team (open teams)
-
id(path) — Team id.
{
"ok": true,
"role": "member"
} /v1/teams/:id/leave player token Leave a team
-
id(path) — Team id.
{
"ok": true
} /v1/teams/:id/members/:pid/kick player token Kick a member (admin/owner)
-
id(path) — Team id. -
pid(path) — Member player id.
{
"ok": true
} /v1/teams/:id/members/:pid/role player token Change a member's role
-
id(path) — Team id. -
pid(path) — Member player id.
{
"role": "admin"
} {
"ok": true
} /v1/teams/:id/transfer player token Transfer ownership
-
id(path) — Team id.
{
"to": "p_2"
} {
"ok": true
} /v1/teams/:id/disband player token Disband a team (owner)
-
id(path) — Team id.
{
"ok": true
} /v1/teams/mine/invites player token List the caller's team invites
{
"invites": [
{
"id": "ti_1",
"team_id": "tm_1"
}
]
} /v1/teams/:id/invites player token Invite a player
-
id(path) — Team id.
{
"player_id": "p_7"
} {
"id": "ti_1",
"state": "pending"
} /v1/teams/invites/:iid/accept player token Accept an invite
-
iid(path) — Invite id.
{
"ok": true
} /v1/teams/invites/:iid/reject player token Reject an invite
-
iid(path) — Invite id.
{
"ok": true
} /v1/teams/:id/requests player token Request to join (closed teams)
-
id(path) — Team id.
{
"id": "tr_1",
"state": "pending"
} /v1/teams/:id/requests player token List join requests (admin)
-
id(path) — Team id.
{
"requests": [
{
"id": "tr_1",
"player_id": "p_7"
}
]
} /v1/teams/:id/requests/:rid/approve player token Approve a join request
-
id(path) — Team id. -
rid(path) — Request id.
{
"ok": true
} /v1/teams/:id/requests/:rid/reject player token Reject a join request
-
id(path) — Team id. -
rid(path) — Request id.
{
"ok": true
} /v1/teams/:id/members/:pid/ban player token Ban a member from the team
-
id(path) — Team id. -
pid(path) — Player id.
{
"ok": true
} /v1/teams/:id/members/:pid/unban player token Unban a player
-
id(path) — Team id. -
pid(path) — Player id.
{
"ok": true
} /v1/teams/:id/bans player token List team bans
-
id(path) — Team id.
{
"bans": [
{
"player_id": "p_9"
}
]
} Competition
/v1/tournaments player token List tournaments
{
"tournaments": [
{
"id": "to_1",
"title": "Weekend Cup",
"state": "live"
}
]
} /v1/tournaments/mine player token Tournaments the player has joined
{
"tournaments": []
} /v1/tournaments/:id player token Get a tournament
-
id(path) — Tournament id.
{
"id": "to_1",
"title": "Weekend Cup",
"starts_at": "2026-07-12T00:00:00Z"
} /v1/tournaments/:id/standings player token Get tournament standings
-
id(path) — Tournament id.
{
"entries": [
{
"rank": 1,
"player_id": "p_9",
"score": 12000
}
]
} /v1/tournaments/:id/join player token Join a tournament
tournament_not_open if entry is closed; may require an entry fee.
-
id(path) — Tournament id.
{
"ok": true
} /v1/tournaments/:id/me player token The player's tournament entry
-
id(path) — Tournament id.
{
"rank": 42,
"score": 8000
} /v1/leagues/:key/join player token Join a league
-
key(path) — League key.
{
"division": "bronze",
"tier": 3
} /v1/leagues/:key/me player token The player's league standing
-
key(path) — League key.
{
"division": "bronze",
"tier": 3,
"rank": 5
} /v1/leagues/:key/divisions/:tier/top player token Top of a league division
-
key(path) — League key. -
tier(path) — Division tier.
{
"entries": [
{
"rank": 1,
"player_id": "p_9"
}
]
} /v1/boards/:board/submit player token Submit to a keyed board (team / UGC / custom entity)
-
board(path) — Keyed board key.
{
"entity_id": "tm_1",
"score": 5000
} {
"ok": true,
"best_score": 5000
} /v1/boards/:board/top player token Top entries of a keyed board
-
board(path) — Keyed board key.
{
"entries": [
{
"rank": 1,
"entity_id": "tm_1",
"score": 5000
}
]
} /v1/boards/:board/entries/:entity_id player token One entity's keyed-board entry
-
board(path) — Keyed board key. -
entity_id(path) — Entity id (team/UGC/…).
{
"entity_id": "tm_1",
"score": 5000,
"rank": 1
} Progression
/v1/quests player token List quests + the caller's progress
{
"quests": [
{
"key": "daily_login",
"progress": 1,
"target": 1,
"claimable": true
}
]
} /v1/quests/:key/claim player token Claim a completed quest's reward
quest_not_complete if objectives aren't met; the reward is escrowed into the inbox.
-
key(path) — Quest key.
{
"claimed": true
} /v1/battle-pass/:season player token Get battle-pass tiers + the caller's progress
-
season(path) — Season key.
{
"season": "s1",
"tier": 4,
"xp": 1200,
"premium": false
} /v1/battle-pass/:season/claim player token Claim a battle-pass tier reward
tier_not_earned if not reached; premium_required for a premium lane without the pass.
-
season(path) — Season key.
{
"tier": 4,
"lane": "free"
} {
"claimed": true
} /v1/progression player token Get XP / level curve progress
{
"level": 7,
"xp": 3400,
"next_level_xp": 4000
} Storage
/v1/storage/:collection player token List keys in the player's collection
-
collection(path) — Collection key.
{
"keys": [
"settings",
"deck"
]
} /v1/storage/:collection/:key player token Read a collection entry
-
collection(path) — Collection key. -
key(path) — Entry key.
{
"key": "settings",
"data": {
"sfx": true
},
"version": 2
} /v1/storage/:collection/:key player token Write a collection entry
Optional If-Match for OCC (storage_conflict on a stale version).
-
collection(path) — Collection key. -
key(path) — Entry key.
{
"data": {
"sfx": false
}
} {
"key": "settings",
"version": 3
} /v1/storage/:collection/:key player token Delete a collection entry
-
collection(path) — Collection key. -
key(path) — Entry key.
null /v1/storage/:collection/:key/mutate player token Atomic server-side mutation of an entry
Apply structured ops (e.g. list append, counter add) server-side to avoid read-modify-write races.
-
collection(path) — Collection key. -
key(path) — Entry key.
{
"ops": [
{
"op": "append",
"path": "deck",
"value": "card_9"
}
]
} {
"key": "deck",
"version": 5
} /v1/storage/shared/:collection/:key player token Read a shared (game-wide) entry
-
collection(path) — Collection key. -
key(path) — Entry key.
{
"key": "motd",
"data": {
"text": "Welcome!"
}
} /v1/storage/shared/:collection/:key player token Write a shared entry (per the collection's write policy)
-
collection(path) — Collection key. -
key(path) — Entry key.
{
"data": {
"text": "Welcome!"
}
} {
"key": "motd",
"version": 1
} /v1/storage/team/:teamId/:collection player token List a team collection's keys (members only)
-
teamId(path) — Team id. -
collection(path) — Collection key.
{
"keys": [
"roster"
]
} /v1/storage/team/:teamId/:collection/:key player token Read a team entry
-
teamId(path) — Team id. -
collection(path) — Collection key. -
key(path) — Entry key.
{
"key": "roster",
"data": {}
} /v1/storage/team/:teamId/:collection/:key player token Write a team entry (members only)
-
teamId(path) — Team id. -
collection(path) — Collection key. -
key(path) — Entry key.
{
"data": {}
} {
"key": "roster",
"version": 1
} /v1/storage/team/:teamId/:collection/:key player token Delete a team entry
-
teamId(path) — Team id. -
collection(path) — Collection key. -
key(path) — Entry key.
null UGC
/v1/ugc player token Browse published content
-
sort(query) — e.g. top, new.
{
"items": [
{
"id": "ug_1",
"title": "My Level",
"plays": 42,
"rating": 4.5
}
]
} /v1/ugc/mine player token List the caller's content
{
"items": [
{
"id": "ug_1",
"title": "My Level",
"status": "published"
}
]
} /v1/ugc player token Create a draft
Title/content are moderated. Publish it with POST /v1/ugc/:id/submit.
{
"title": "My Level",
"data": {
"grid": []
}
} {
"id": "ug_1",
"status": "draft"
} /v1/ugc/:id player token Get a content item
-
id(path) — Content id.
{
"id": "ug_1",
"title": "My Level",
"data": {},
"author": "p_1"
} /v1/ugc/:id player token Update a draft
-
id(path) — Content id.
{
"title": "My Level v2"
} {
"id": "ug_1"
} /v1/ugc/:id player token Delete content
-
id(path) — Content id.
null /v1/ugc/:id/submit player token Publish a draft
-
id(path) — Content id.
{
"id": "ug_1",
"status": "published"
} /v1/ugc/:id/play player token Record a play
-
id(path) — Content id.
{
"ok": true
} /v1/ugc/:id/lineage player token Get remix lineage (attribution)
-
id(path) — Content id.
{
"ancestors": [
{
"id": "ug_0",
"author": "p_0"
}
]
} /v1/ugc/:id/remix player token Remix content (forks with attribution)
-
id(path) — Source content id.
{
"title": "My Remix"
} {
"id": "ug_2",
"remixed_from": "ug_1"
} /v1/ugc/:id/rate player token Rate content
-
id(path) — Content id.
{
"rating": 5
} {
"ok": true,
"rating": 4.6
} /v1/ugc/:id/like player token Like content
-
id(path) — Content id.
{
"ok": true,
"likes": 13
} /v1/ugc/:id/like player token Unlike content
-
id(path) — Content id.
{
"ok": true,
"likes": 12
} Async
/v1/async player token Create a turn-based match
No realtime/Durable Object needed — turns are submitted over HTTP with server-enforced turn order + OCC.
{
"type": "chess",
"opponents": [
"p_9"
]
} {
"match": {
"id": "am_1",
"state": {},
"turn": "p_1a2b3c"
}
} /v1/async/mine player token List the player's active matches
{
"matches": [
{
"id": "am_1",
"type": "chess",
"turn": "p_9"
}
]
} /v1/async/:id player token Get a match (participants only)
-
id(path) — Match id.
{
"match": {
"id": "am_1",
"state": {},
"turn_number": 4
}
} /v1/async/:id/turn player token Submit a turn
Rejected with not_your_turn out of order, or async_conflict on a stale version (send the version you read).
-
id(path) — Match id.
{
"state": {
"board": []
},
"version": 4,
"end": false
} {
"match": {
"id": "am_1",
"turn_number": 5
}
} /v1/async/:id/forfeit player token Forfeit a match
-
id(path) — Match id.
{
"match": {
"id": "am_1",
"status": "complete",
"winner": "p_9"
}
} LiveOps
/v1/config publishable key Get the game's published config blob
The developer's key→value tuning blob (server-controlled, no client deploy to change).
{
"config": {
"spawn_rate": 1.5,
"event_banner": "summer"
},
"version": 12
} /v1/flags player token Get feature flags resolved for the player
Each flag resolves per the player's segments, with a break-glass kill switch honoured.
{
"flags": {
"new_hud": true,
"checkout_v2": "variant_b"
}
} /v1/flags/:key player token Get one resolved flag value
-
key(path) — Flag key.
{
"key": "new_hud",
"value": true
} /v1/liveops/events/live player token Get currently-live events
{
"events": [
{
"key": "summer_fest",
"ends_at": "2026-08-01T00:00:00Z"
}
]
} /v1/players/me/segments player token Get the player's segment memberships
{
"segments": [
"whales",
"new_players"
]
} Analytics
/v1/events player token Ingest analytics events
Usually called via the SDK's durable outbox (tg.track), which coalesces + retries. Counts only — no per-player PII.
{
"events": [
{
"name": "level_complete",
"count": 1
}
]
} {
"accepted": 1
} Dev · Games
/v1/dev/games developer session Create a game
{
"name": "Neon Drift"
} {
"id": "g_1",
"name": "Neon Drift",
"tier": "shared",
"env": "prod"
} /v1/dev/games developer session List your games
{
"games": [
{
"id": "g_1",
"name": "Neon Drift",
"status": "active"
}
]
} /v1/dev/games/:id developer session Get a game
-
id(path) — Game id.
{
"id": "g_1",
"name": "Neon Drift",
"allowed_origins": [
"https://mygame.com"
]
} /v1/dev/games/:id developer session Update a game (name, CORS allowlist, pause)
Set allowed_origins (CORS) — an empty list is open to any origin. status paused takes the game offline.
-
id(path) — Game id.
{
"allowed_origins": [
"https://mygame.com"
],
"status": "active"
} {
"id": "g_1",
"allowed_origins": [
"https://mygame.com"
]
} /v1/dev/games/:id developer session Delete a game (and its keys/data)
-
id(path) — Game id.
null Dev · Keys
/v1/dev/games/:id/keys developer session Issue an API key
The full secret is returned ONCE. tg_pk_ (publishable) is safe in clients; tg_sk_ (secret) is server-only.
-
id(path) — Game id.
{
"kind": "publishable"
} {
"id": "key_1",
"prefix": "tg_pk_ab12",
"key": "tg_pk_ab12…full-shown-once",
"note": "Store this now — it won't be shown again."
} /v1/dev/games/:id/keys developer session List key metadata (never the secret)
-
id(path) — Game id.
{
"keys": [
{
"id": "key_1",
"kind": "publishable",
"prefix": "tg_pk_ab12",
"last_used_at": "2026-07-01T00:00:00Z",
"revoked_at": null
}
]
} /v1/dev/games/:id/keys/:keyId/rotate developer session Rotate a key (revoke + mint a replacement)
-
id(path) — Game id. -
keyId(path) — Key id.
{
"id": "key_2",
"key": "tg_pk_cd34…full-shown-once"
} /v1/dev/games/:id/keys/:keyId developer session Revoke a key
-
id(path) — Game id. -
keyId(path) — Key id.
null