Tài liệu Public API

Các API ẩn danh của Portal dưới /api/public: những gì trang player và game được gọi mà không cần tài khoản quản trị. Sinh từ contract của Portal API nên luôn khớp với route đang chạy.
Quy ước
  • Gọi các path trên origin của player; endpoint cho game SDK được phục vụ trên origin của game.
  • Lỗi có dạng { "error": { "code", "message" } }. Xử lý theo code; message có thể thay đổi.
  • Request thay đổi dữ liệu phải gửi header x-gameportal-csrf: 1.
  • Cookie khách là HttpOnly và được cấp tự động; script không đọc được.
01

Guest profile

GET/api/public/player
Get or create the guest profile. Creates a guest identity on first call and sets the HttpOnly guest cookie (gp_guest locally, __Host-gp_guest over HTTPS; SameSite=Strict, one year). Response is no-store.
Xác thựcplayer session cookie, else guest cookie (issued automatically when missing)
Giới hạn tần suất30/minute
Phản hồi
200{ player: GuestPlayer }
The guest profile.
Lỗi
429 RATE_LIMITED500 INTERNAL_ERROR
PATCH/api/public/player
Set the nickname or skip the prompt. nickname: null keeps the generated name and only marks the first-play prompt complete. Besides the CSRF header, the Origin header must equal the player origin.
Xác thựcplayer session cookie, else guest cookie (issued automatically when missing)
Header CSRFx-gameportal-csrf: 1
Giới hạn tần suất10/minute
Phản hồi
200{ player: GuestPlayer }
The updated profile.
Lỗi
400 INVALID_REQUEST401 GUEST_REQUIRED403 CSRF_REJECTED413 PAYLOAD_TOO_LARGE429 RATE_LIMITED500 INTERNAL_ERROR
Body application/json
TrườngKiểuBắt buộcGhi chú
nicknamestring | nullcó1 to 32 chars; No control characters, no leading or trailing whitespace.
02

Account

POST/api/public/player/register
Register a player account and sign in. ADR-025. When the guest cookie belongs to a guest no account owns yet, the new account owns that guest's player ID (scores and storage carry over); otherwise the account gets a new player ID. Sets the player session cookie. identifier is a Vietnamese mobile (stored as 0 + 9 digits) or an email (stored lower-cased). fullName 2–50 letters. Password 8–128 characters, never trimmed. The Origin header must equal the player origin. Response is no-store.
Xác thựcplayer session cookie, else guest cookie (issued automatically when missing)
Header CSRFx-gameportal-csrf: 1
Giới hạn tần suất5/minute
Phản hồi
201PlayerSignIn
Registered and signed in.
Lỗi
400 INVALID_REQUEST400 INVALID_ACCOUNT_INPUT403 CSRF_REJECTED409 IDENTIFIER_TAKEN413 PAYLOAD_TOO_LARGE429 RATE_LIMITED500 INTERNAL_ERROR
Body application/json PlayerRegisterInput
TrườngKiểuBắt buộcGhi chú
identifierstringcó1 to 254 chars; Vietnamese mobile or email.
fullNamestringcó1 to 200 chars
passwordstringcó1 to 256 chars; 8–128 characters after validation.
gender"undisclosed" | "male" | "female"có
acceptedPolicytruecó
POST/api/public/player/login
Sign in to a player account. Sets the player session cookie. The device's guest is not linked or merged: only play after this login counts for the account. The Origin header must equal the player origin. Response is no-store.
Xác thựcnone
Header CSRFx-gameportal-csrf: 1
Giới hạn tần suất10/minute
Phản hồi
200PlayerSignIn
Signed in.
Lỗi
400 INVALID_REQUEST401 INVALID_CREDENTIALS403 CSRF_REJECTED413 PAYLOAD_TOO_LARGE429 RATE_LIMITED500 INTERNAL_ERROR
Body application/json
TrườngKiểuBắt buộcGhi chú
identifierstringcó1 to 254 chars; Phone number or email.
passwordstringcó1 to 256 chars
PATCH/api/public/player/account
Update the personal profile. Only the fields sent change: fullName (2–50 letters), phone (a Vietnamese mobile, stored as 0 + 9 digits; a contact number, never the login identifier), birthDate (YYYY-MM-DD, 1900-01-01 to today), gender. null clears phone / birthDate. The login identifier and the display name cannot be changed here. The Origin header must equal the player origin. Response is no-store.
Xác thựcplayer session cookie (gp_player_session)
Header CSRFx-gameportal-csrf: 1
Giới hạn tần suất10/minute
Phản hồi
200{ account: PlayerAccount }
The updated account.
Lỗi
400 INVALID_REQUEST400 INVALID_ACCOUNT_INPUT401 ACCOUNT_REQUIRED403 CSRF_REJECTED413 PAYLOAD_TOO_LARGE429 RATE_LIMITED500 INTERNAL_ERROR
Body application/json
TrườngKiểuBắt buộcGhi chú
fullNamestringkhông1 to 200 chars
phonestring | nullkhông1 to 20 chars
birthDatestring | nullkhôngpattern ^\d{4}-\d{2}-\d{2}$
gender"undisclosed" | "male" | "female"không
POST/api/public/player/logout
Sign out. Ends the session and clears its cookie; succeeds without a session. The browser then plays as a guest again (a new one when its guest was linked to the account).
Xác thựcplayer session cookie (gp_player_session)
Header CSRFx-gameportal-csrf: 1
Giới hạn tần suất10/minute
Phản hồi
204
Signed out.
Lỗi
403 CSRF_REJECTED429 RATE_LIMITED500 INTERNAL_ERROR
03

Catalog

GET/api/public/catalog
List playable games. Only games with an eligible active PRODUCTION release are listed. Cache-Control: public, max-age=30.
Xác thựcnone
Phản hồi
200{ games: PublicGame[], hasMore: boolean, page: integer, pageSize: integer }
One page of games.
Lỗi
400 INVALID_REQUEST500 INTERNAL_ERROR
Tham số
TênVị tríKiểuGhi chú
pagequeryintegerat least 1; default 1
pageSizequeryinteger1 to 49; default 24
searchquerystringat most 80 chars
categoryquerystring1 to 60 chars; pattern ^[a-z0-9]+(?:-[a-z0-9]+)*$; Slug of an enabled game category.
enginequery"html" | "cocos" | "unity"
GET/api/public/catalog/{slug}
Get a playable game by slug.
Xác thựcnone
Phản hồi
200{ game: PublicGameDetail }
The game, including the publicId needed to launch it.
Lỗi
400 INVALID_REQUEST404 GAME_UNAVAILABLE500 INTERNAL_ERROR
Tham số
TênVị tríKiểuGhi chú
slugpathstring1 to 80 chars; pattern ^[a-z0-9]+(?:-[a-z0-9]+)*$
04

Profile data

GET/api/public/player/favorites
List the account's favourite games. Newest first; only games that are currently playable. Needs a player account: a guest gets 401 ACCOUNT_REQUIRED. Response is no-store.
Xác thựcplayer session cookie (gp_player_session), required
Giới hạn tần suất60/minute
Phản hồi
200PlayerFavoritesPage
One page of favourites.
Lỗi
400 INVALID_REQUEST400 INVALID_QUERY401 ACCOUNT_REQUIRED429 RATE_LIMITED500 INTERNAL_ERROR
Tham số
TênVị tríKiểuGhi chú
pagequeryinteger1 to 999999; default 1
pageSizequeryinteger1 to 49; default 18
GET/api/public/player/favorites/{slug}
Check whether a game is a favourite. The heart state on the play page. Response is no-store.
Xác thựcplayer session cookie (gp_player_session), required
Giới hạn tần suất60/minute
Phản hồi
200{ favorite: boolean }
The heart state.
Lỗi
400 INVALID_REQUEST400 INVALID_QUERY401 ACCOUNT_REQUIRED429 RATE_LIMITED500 INTERNAL_ERROR
Tham số
TênVị tríKiểuGhi chú
slugpathstring1 to 80 chars; pattern ^[a-z0-9]+(?:-[a-z0-9]+)*$
PUT/api/public/player/favorites/{slug}
Add a favourite game. Idempotent. At most 200 favourites per account. The Origin header must equal the player origin.
Xác thựcplayer session cookie (gp_player_session), required
Header CSRFx-gameportal-csrf: 1
Giới hạn tần suất30/minute
Phản hồi
204
The game is a favourite.
Lỗi
400 INVALID_REQUEST400 INVALID_QUERY401 ACCOUNT_REQUIRED403 CSRF_REJECTED404 GAME_NOT_FOUND409 FAVORITES_LIMIT429 RATE_LIMITED500 INTERNAL_ERROR
Tham số
TênVị tríKiểuGhi chú
slugpathstring1 to 80 chars; pattern ^[a-z0-9]+(?:-[a-z0-9]+)*$
DELETE/api/public/player/favorites/{slug}
Remove a favourite game. Idempotent. The Origin header must equal the player origin.
Xác thựcplayer session cookie (gp_player_session), required
Header CSRFx-gameportal-csrf: 1
Giới hạn tần suất30/minute
Phản hồi
204
The game is no longer a favourite.
Lỗi
400 INVALID_REQUEST400 INVALID_QUERY401 ACCOUNT_REQUIRED403 CSRF_REJECTED429 RATE_LIMITED500 INTERNAL_ERROR
Tham số
TênVị tríKiểuGhi chú
slugpathstring1 to 80 chars; pattern ^[a-z0-9]+(?:-[a-z0-9]+)*$
GET/api/public/player/history
List the account's play history. One entry per launch, newest first; only games that are currently playable are listed, and total counts only plays of those currently public games. Response is no-store.
Xác thựcplayer session cookie (gp_player_session), required
Giới hạn tần suất60/minute
Phản hồi
200PlayerHistoryPage
One page of plays.
Lỗi
400 INVALID_REQUEST400 INVALID_QUERY401 ACCOUNT_REQUIRED429 RATE_LIMITED500 INTERNAL_ERROR
Tham số
TênVị tríKiểuGhi chú
pagequeryinteger1 to 999999; default 1
pageSizequeryinteger1 to 49; default 18
GET/api/public/player/stats
Get the account's play statistics. Play time is measured from SDK game_start / game_end events (each session clamped to 240 minutes). Weeks run Monday to Sunday in Asia/Ho_Chi_Minh. When Nakama is unavailable the response is partial and playTime / achievements are null. Response is no-store.
Xác thựcplayer session cookie (gp_player_session), required
Giới hạn tần suất60/minute
Phản hồi
200PlayerStats
The statistics.
Lỗi
400 INVALID_REQUEST400 INVALID_QUERY401 ACCOUNT_REQUIRED429 RATE_LIMITED500 INTERNAL_ERROR
Tham số
TênVị tríKiểuGhi chú
weekStartquerystringdate; A Monday from 2026-01-01, not in the future. Default: this week.
05

Launch

POST/api/public/games/{gameId}/launch-identity
Create a single-use production launch. Issues a guest launch for the game's active production release and sets the guest cookie when the caller has none. The shell loads launch.url in the sandboxed iframe and passes launch.bootstrap to the SDK. Response is no-store.
Xác thựcplayer session cookie, else guest cookie (issued automatically when missing)
Header CSRFx-gameportal-csrf: 1
Giới hạn tần suất30/minute
Phản hồi
201{ launch: GuestLaunch }
The launch context.
Lỗi
400 INVALID_REQUEST403 CSRF_REJECTED404 GAME_UNAVAILABLE429 RATE_LIMITED500 INTERNAL_ERROR
Tham số
TênVị tríKiểuGhi chú
gameIdpathstringpattern ^game_[a-z0-9]{12,32}$; Public game ID.
06

News

GET/api/public/news
List published news. PUBLISHED articles only, newest first. Cache-Control: public, max-age=30.
Xác thựcnone
Phản hồi
200{ news: PublicNewsSummary[], hasMore: boolean, page: integer, pageSize: integer }
One page of articles.
Lỗi
400 INVALID_REQUEST500 INTERNAL_ERROR
Tham số
TênVị tríKiểuGhi chú
pagequeryinteger1 to 1000000; default 1
pageSizequeryinteger1 to 48; default 12
searchquerystringat most 80 chars
GET/api/public/news/{slug}
Get a published article by slug. Everything the article page needs: content, table of contents, reading time and SEO fields.
Xác thựcnone
Phản hồi
200{ article: PublicNewsArticle }
The article.
Lỗi
400 INVALID_REQUEST404 NEWS_UNAVAILABLE500 INTERNAL_ERROR
Tham số
TênVị tríKiểuGhi chú
slugpathstring1 to 120 chars; pattern ^[a-z0-9]+(?:-[a-z0-9]+)*$
07

Guides

GET/api/public/guides
List published guides. Enabled guides only. Default order: sortOrder, then title; sort=newest|az|za overrides (newest by publishedAt, az/za by title). category filters by game category slug (the category must be enabled); type is lower case. Cache-Control: public, max-age=60.
Xác thựcnone
Phản hồi
200{ guides: PublicGuideSummary[], hasMore: boolean, page: integer, pageSize: integer, total: integer }
One page of guides.
Lỗi
400 INVALID_REQUEST500 INTERNAL_ERROR
Tham số
TênVị tríKiểuGhi chú
pagequeryinteger1 to 1000000; default 1
pageSizequeryinteger1 to 48; default 12
searchquerystringat most 80 chars
gamequerystring1 to 80 chars; pattern ^[a-z0-9]+(?:-[a-z0-9]+)*$
categoryquerystring1 to 60 chars; pattern ^[a-z0-9]+(?:-[a-z0-9]+)*$
typequery"tips" | "guide" | "news" | "review"
featuredquerybooleanOnly featured (true) or only non-featured (false) guides.
sortquery"newest" | "az" | "za"
GET/api/public/guides/{slug}
Get a published guide by slug. Content, table of contents and metadata for the guide page.
Xác thựcnone
Phản hồi
200{ guide: PublicGuideArticle }
The guide.
Lỗi
400 INVALID_REQUEST404 GUIDE_UNAVAILABLE500 INTERNAL_ERROR
Tham số
TênVị tríKiểuGhi chú
slugpathstring1 to 120 chars; pattern ^[a-z0-9]+(?:-[a-z0-9]+)*$
08

Game categories

GET/api/public/game-categories
List enabled game categories. Cache-Control: public, max-age=60. Categories are not linked to games yet.
Xác thựcnone
Phản hồi
200{ categories: PublicGameCategory[] }
All enabled categories.
Lỗi
400 INVALID_REQUEST500 INTERNAL_ERROR
Tham số
TênVị tríKiểuGhi chú
hotquerybooleanFilter by the hot flag.
sortByquery"title" | "createdAt" | "updatedAt"default "title"
sortDirquery"asc" | "desc"default "asc"
GET/api/public/game-categories/{slug}
Get an enabled game category by slug.
Xác thựcnone
Phản hồi
200{ category: PublicGameCategory }
The category.
Lỗi
400 INVALID_REQUEST404 CATEGORY_UNAVAILABLE500 INTERNAL_ERROR
Tham số
TênVị tríKiểuGhi chú
slugpathstring1 to 60 chars; pattern ^[a-z0-9]+(?:-[a-z0-9]+)*$
09

Support pages

GET/api/public/supports
List the support menu. Enabled pages in sortOrder. Cache-Control: public, max-age=60.
Xác thựcnone
Phản hồi
200{ supports: PublicSupportMenuItem[] }
Menu entries.
Lỗi
500 INTERNAL_ERROR
GET/api/public/supports/{slug}
Get an enabled support page by slug.
Xác thựcnone
Phản hồi
200{ support: PublicSupportPage }
The page.
Lỗi
400 INVALID_REQUEST404 SUPPORT_UNAVAILABLE500 INTERNAL_ERROR
Tham số
TênVị tríKiểuGhi chú
slugpathstring1 to 120 chars; pattern ^[a-z0-9]+(?:-[a-z0-9]+)*$
10

SDK

GET/api/public/games/{gameId}/config
Get the SDK bootstrap configuration. Served on the game origin. Available for INTEGRATION and PUBLISHED games; disabled and unknown games share the same 404.
Xác thựcnone
Phản hồi
200{ config: GameConfig }
The configuration.
Lỗi
400 INVALID_REQUEST404 GAME_CONFIG_NOT_FOUND500 INTERNAL_ERROR
Tham số
TênVị tríKiểuGhi chú
gameIdpathstringpattern ^game_[a-z0-9]{12,32}$; Public game ID.
POST/api/public/games/{gameId}/events
Ingest an analytics event. Authenticated with the player's Nakama session token. Body limit 12 288 bytes; rate limit is per IP and session.
Xác thựcAuthorization: Bearer <Nakama session token>
Giới hạn tần suất60/minute
Phản hồi
202{ accepted: true, duplicate: boolean }
Accepted; duplicate is true when eventId was already stored.
Lỗi
400 INVALID_REQUEST401 EVENT_UNAUTHENTICATED404 GAME_NOT_FOUND413 PAYLOAD_TOO_LARGE422 INVALID_EVENT429 RATE_LIMITED500 INTERNAL_ERROR503 SESSION_VERIFICATION_UNAVAILABLE
Tham số
TênVị tríKiểuGhi chú
gameIdpathstringpattern ^game_[a-z0-9]{12,32}$; Public game ID.
Body application/json GameEvent
TrườngKiểuBắt buộcGhi chú
eventIdstringcóuuid; Idempotency key: a repeated eventId is reported as a duplicate.
sessionIdstringcóuuid
namestringcógame_ready | game_start | game_end | level_start | level_complete | level_fail, or custom:<name> matching ^custom:[a-z0-9][a-z0-9._-]{0,47}$.
propertiesobjectkhôngFlat map, at most 32 keys and 8192 bytes of JSON.
11

Schema

Error
Error envelope used by every Portal API error response.
TrườngKiểuBắt buộcGhi chú
error{ code: string, message: string, field?: string, failed?: { src: string, reason: string }[] }có
GuestPlayer
TrườngKiểuBắt buộcGhi chú
playerIdstringcóPlatform player ID, shared by every game.
nicknamestringcóDisplay name; for a signed-in player it is the account's changeable name.
profileCompletebooleancóFalse until the guest submits or skips the first-play nickname prompt.
accountPlayerAccount | nullcó
PlayerAccount
TrườngKiểuBắt buộcGhi chú
identifierstringcóNormalized phone (0 + 9 digits) or lower-cased email.
fullNamestringcó
gender"undisclosed" | "male" | "female"có
createdAtstringcódate-time; When the account was registered.
phonestring | nullcóContact phone 0xxxxxxxxx, separate from the login identifier.
birthDatestring | nullcódate
PlayerSignIn
TrườngKiểuBắt buộcGhi chú
playerIdstringcó
accountPlayerAccountcó
PlayerRegisterInput
TrườngKiểuBắt buộcGhi chú
identifierstringcó1 to 254 chars; Vietnamese mobile or email.
fullNamestringcó1 to 200 chars
passwordstringcó1 to 256 chars; 8–128 characters after validation.
gender"undisclosed" | "male" | "female"có
acceptedPolicytruecó
PublicGame
TrườngKiểuBắt buộcGhi chú
categories{ slug: string, title: string }[]có
slugstringcó1 to 80 chars; pattern ^[a-z0-9]+(?:-[a-z0-9]+)*$
namestringcó
descriptionstring | nullcó
engine"html" | "cocos" | "unity"có
thumbnailUrlstringcóSame-origin path or URL; a default thumbnail when none was uploaded.
PlayerFavoritesPage
TrườngKiểuBắt buộcGhi chú
gamesPublicGame[]có
totalintegercó
pageintegercó
pageSizeintegercó
PlayerHistoryPage
TrườngKiểuBắt buộcGhi chú
entries{ game: PublicGame, playedAt: string }[]có
totalintegercóEvery play of the account, including games no longer public.
pageintegercó
pageSizeintegercó
PlayerStats
TrườngKiểuBắt buộcGhi chú
timeZone"Asia/Ho_Chi_Minh"có
partialbooleancóTrue when Nakama was unavailable: playTime and achievements are null.
inGameNamestringcóGuest nickname of the account's player identity.
gamesPlayedintegercóDistinct games with at least one play.
playTime{ todayMinutes: integer, dailyAverageMinutes: integer, totalMinutes: integer, minutesByDay: integer[] } | nullcó
weekly{ weekStart: string, weekEnd: string, launchesByDay: integer[] }có
mostPlayed{ game: PublicGame, launches: integer, lastPlayedAt: string }[]có
achievements{ game: PublicGame, score: integer, rank: integer, updatedAt: string }[] | nullcó
activities{ kind: "play", game: PublicGame, at: string }[]có
PublicGameDetail
TrườngKiểuBắt buộcGhi chú
categories{ slug: string, title: string }[]có
slugstringcó1 to 80 chars; pattern ^[a-z0-9]+(?:-[a-z0-9]+)*$
namestringcó
descriptionstring | nullcó
engine"html" | "cocos" | "unity"có
thumbnailUrlstringcóSame-origin path or URL; a default thumbnail when none was uploaded.
publicIdstringcópattern ^game_[a-z0-9]{12,32}$; Public game ID.
contentHtmlstring | nullcóat most 200000 chars; Game introduction: article HTML, sanitized on save; images are removed.
GuestLaunch
TrườngKiểuBắt buộcGhi chú
idstringcó
gameIdstringcópattern ^game_[a-z0-9]{12,32}$; Public game ID.
buildIdstringcópattern ^build_[a-z0-9]{16,32}$; Build ID.
releaseIdstringcópattern ^release_[a-z0-9]{16,32}$; Release ID.
playerIdstringcó
environment"PRODUCTION"có
createdAtstringcódate-time
urlstringcóuri; Active production release index.html on the game origin; load it in the sandboxed iframe.
bootstrap{ protocolVersion: 1, code: string, expiresAt: string, localFragmentUrl?: string }có
Heading
TrườngKiểuBắt buộcGhi chú
idstringcóAnchor id present in contentHtml.
level2 | 3 | 4có
textstringcó
PublicNewsSummary
TrườngKiểuBắt buộcGhi chú
publicIdstringcópattern ^news_[a-z0-9]{12,32}$; News article ID.
slugstringcó1 to 120 chars; pattern ^[a-z0-9]+(?:-[a-z0-9]+)*$
titlestringcó
excerptstring | nullcóThe written excerpt, or the start of the article text.
coverImageUrlstring | nullcóuri; Public URL of the thumbnail.
publishedAtstringcódate-time
PublicNewsArticle
TrườngKiểuBắt buộcGhi chú
publicIdstringcópattern ^news_[a-z0-9]{12,32}$; News article ID.
slugstringcó1 to 120 chars; pattern ^[a-z0-9]+(?:-[a-z0-9]+)*$
titlestringcó
excerptstring | nullcóThe written excerpt, or the start of the article text.
coverImageUrlstring | nullcóuri; Public URL of the thumbnail.
publishedAtstringcódate-time
contentHtmlstringcóSanitized HTML with heading anchors.
updatedAtstringcódate-time
readingTimeMinutesintegercó
headingsHeading[]có
seo{ title: string, description: string, imageUrl: string | null }có
PublicGuideSummary
TrườngKiểuBắt buộcGhi chú
slugstringcó1 to 120 chars; pattern ^[a-z0-9]+(?:-[a-z0-9]+)*$
titlestringcó
excerptstring | nullcó
thumbnailUrlstring | nullcóuri; Public URL of the thumbnail.
game{ slug: string, name: string } | nullcó
category{ slug: string, title: string } | nullcó
articleType"TIPS" | "GUIDE" | "NEWS" | "REVIEW"có
isFeaturedbooleancó
publishedAtstringcódate-time
updatedAtstringcódate-time
PublicGuideArticle
TrườngKiểuBắt buộcGhi chú
slugstringcó1 to 120 chars; pattern ^[a-z0-9]+(?:-[a-z0-9]+)*$
titlestringcó
excerptstring | nullcó
thumbnailUrlstring | nullcóuri; Public URL of the thumbnail.
game{ slug: string, name: string } | nullcó
category{ slug: string, title: string } | nullcó
articleType"TIPS" | "GUIDE" | "NEWS" | "REVIEW"có
isFeaturedbooleancó
publishedAtstringcódate-time
updatedAtstringcódate-time
contentHtmlstringcóSanitized HTML with heading anchors.
headingsHeading[]có
PublicGameCategory
TrườngKiểuBắt buộcGhi chú
slugstringcó1 to 60 chars; pattern ^[a-z0-9]+(?:-[a-z0-9]+)*$
titlestringcó
descriptionstring | nullcó
thumbnailUrlstring | nullcóuri
posterUrlstring | nullcóuri
isHotbooleancó
PublicSupportMenuItem
TrườngKiểuBắt buộcGhi chú
slugstringcó1 to 120 chars; pattern ^[a-z0-9]+(?:-[a-z0-9]+)*$
titlestringcó
PublicSupportPage
TrườngKiểuBắt buộcGhi chú
slugstringcó1 to 120 chars; pattern ^[a-z0-9]+(?:-[a-z0-9]+)*$
titlestringcó
contentHtmlstringcóSanitized HTML with heading anchors.
headingsHeading[]có
updatedAtstringcódate-time
GameConfig
TrườngKiểuBắt buộcGhi chú
schemaVersion1có
gameIdstringcópattern ^game_[a-z0-9]{12,32}$; Public game ID.
environment"local" | "staging" | "production"có
sdk{ minimumVersion: string, recommendedVersion: string }có
endpoints{ portalApiUrl: string, nakama: { host: string, port: integer, useSsl: boolean, serverKey: string } }có
capabilities("player" | "storage" | "leaderboard" | "game" | "analytics")[]có
GameEvent
TrườngKiểuBắt buộcGhi chú
eventIdstringcóuuid; Idempotency key: a repeated eventId is reported as a duplicate.
sessionIdstringcóuuid
namestringcógame_ready | game_start | game_end | level_start | level_complete | level_fail, or custom:<name> matching ^custom:[a-z0-9][a-z0-9._-]{0,47}$.
propertiesobjectkhôngFlat map, at most 32 keys and 8192 bytes of JSON.