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.
01Guest profile
GET
/api/public/playerGet 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ực | player session cookie, else guest cookie (issued automatically when missing) |
|---|---|
| Giới hạn tần suất | 30/minute |
| Phản hồi | 200 { player: GuestPlayer }The guest profile. |
| Lỗi | 429 RATE_LIMITED500 INTERNAL_ERROR |
PATCH
/api/public/playerSet 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ực | player session cookie, else guest cookie (issued automatically when missing) |
|---|---|
| Header CSRF | x-gameportal-csrf: 1 |
| Giới hạn tần suất | 10/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/json02Account
POST
/api/public/player/registerRegister 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ực | player session cookie, else guest cookie (issued automatically when missing) |
|---|---|
| Header CSRF | x-gameportal-csrf: 1 |
| Giới hạn tần suất | 5/minute |
| Phản hồi | 201 PlayerSignInRegistered 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 PlayerRegisterInputPOST
/api/public/player/loginSign 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ực | none |
|---|---|
| Header CSRF | x-gameportal-csrf: 1 |
| Giới hạn tần suất | 10/minute |
| Phản hồi | 200 PlayerSignInSigned in. |
| Lỗi | 400 INVALID_REQUEST401 INVALID_CREDENTIALS403 CSRF_REJECTED413 PAYLOAD_TOO_LARGE429 RATE_LIMITED500 INTERNAL_ERROR |
Body
application/jsonPATCH
/api/public/player/accountUpdate 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ực | player session cookie (gp_player_session) |
|---|---|
| Header CSRF | x-gameportal-csrf: 1 |
| Giới hạn tần suất | 10/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/jsonPOST
/api/public/player/logoutSign 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ực | player session cookie (gp_player_session) |
|---|---|
| Header CSRF | x-gameportal-csrf: 1 |
| Giới hạn tần suất | 10/minute |
| Phản hồi | 204 Signed out. |
| Lỗi | 403 CSRF_REJECTED429 RATE_LIMITED500 INTERNAL_ERROR |
03Catalog
GET
/api/public/catalogList playable games. Only games with an eligible active PRODUCTION release are listed.
Cache-Control: public, max-age=30.| Xác thực | none |
|---|---|
| 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ố
GET
/api/public/catalog/{slug}Get a playable game by slug.
| Xác thực | none |
|---|---|
| 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ố
04Profile data
GET
/api/public/player/favoritesList 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ực | player session cookie (gp_player_session), required |
|---|---|
| Giới hạn tần suất | 60/minute |
| Phản hồi | 200 PlayerFavoritesPageOne page of favourites. |
| Lỗi | 400 INVALID_REQUEST400 INVALID_QUERY401 ACCOUNT_REQUIRED429 RATE_LIMITED500 INTERNAL_ERROR |
Tham số
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ực | player session cookie (gp_player_session), required |
|---|---|
| Giới hạn tần suất | 60/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ố
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ực | player session cookie (gp_player_session), required |
|---|---|
| Header CSRF | x-gameportal-csrf: 1 |
| Giới hạn tần suất | 30/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ố
DELETE
/api/public/player/favorites/{slug}Remove a favourite game. Idempotent. The
Origin header must equal the player origin.| Xác thực | player session cookie (gp_player_session), required |
|---|---|
| Header CSRF | x-gameportal-csrf: 1 |
| Giới hạn tần suất | 30/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ố
GET
/api/public/player/historyList 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ực | player session cookie (gp_player_session), required |
|---|---|
| Giới hạn tần suất | 60/minute |
| Phản hồi | 200 PlayerHistoryPageOne page of plays. |
| Lỗi | 400 INVALID_REQUEST400 INVALID_QUERY401 ACCOUNT_REQUIRED429 RATE_LIMITED500 INTERNAL_ERROR |
Tham số
GET
/api/public/player/statsGet 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ực | player session cookie (gp_player_session), required |
|---|---|
| Giới hạn tần suất | 60/minute |
| Phản hồi | 200 PlayerStatsThe statistics. |
| Lỗi | 400 INVALID_REQUEST400 INVALID_QUERY401 ACCOUNT_REQUIRED429 RATE_LIMITED500 INTERNAL_ERROR |
Tham số
05Launch
POST
/api/public/games/{gameId}/launch-identityCreate 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ực | player session cookie, else guest cookie (issued automatically when missing) |
|---|---|
| Header CSRF | x-gameportal-csrf: 1 |
| Giới hạn tần suất | 30/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ố
06News
GET
/api/public/newsList published news. PUBLISHED articles only, newest first.
Cache-Control: public, max-age=30.| Xác thực | none |
|---|---|
| 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ố
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ực | none |
|---|---|
| Phản hồi | 200 { article: PublicNewsArticle }The article. |
| Lỗi | 400 INVALID_REQUEST404 NEWS_UNAVAILABLE500 INTERNAL_ERROR |
Tham số
07Guides
GET
/api/public/guidesList 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ực | none |
|---|---|
| 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ố
GET
/api/public/guides/{slug}Get a published guide by slug. Content, table of contents and metadata for the guide page.
| Xác thực | none |
|---|---|
| Phản hồi | 200 { guide: PublicGuideArticle }The guide. |
| Lỗi | 400 INVALID_REQUEST404 GUIDE_UNAVAILABLE500 INTERNAL_ERROR |
Tham số
08Game categories
GET
/api/public/game-categoriesList enabled game categories.
Cache-Control: public, max-age=60. Categories are not linked to games yet.| Xác thực | none |
|---|---|
| Phản hồi | 200 { categories: PublicGameCategory[] }All enabled categories. |
| Lỗi | 400 INVALID_REQUEST500 INTERNAL_ERROR |
Tham số
GET
/api/public/game-categories/{slug}Get an enabled game category by slug.
| Xác thực | none |
|---|---|
| Phản hồi | 200 { category: PublicGameCategory }The category. |
| Lỗi | 400 INVALID_REQUEST404 CATEGORY_UNAVAILABLE500 INTERNAL_ERROR |
Tham số
09Support pages
GET
/api/public/supportsList the support menu. Enabled pages in
sortOrder. Cache-Control: public, max-age=60.| Xác thực | none |
|---|---|
| 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ực | none |
|---|---|
| Phản hồi | 200 { support: PublicSupportPage }The page. |
| Lỗi | 400 INVALID_REQUEST404 SUPPORT_UNAVAILABLE500 INTERNAL_ERROR |
Tham số
10SDK
GET
/api/public/games/{gameId}/configGet 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ực | none |
|---|---|
| Phản hồi | 200 { config: GameConfig }The configuration. |
| Lỗi | 400 INVALID_REQUEST404 GAME_CONFIG_NOT_FOUND500 INTERNAL_ERROR |
Tham số
POST
/api/public/games/{gameId}/eventsIngest 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ực | Authorization: Bearer <Nakama session token> |
|---|---|
| Giới hạn tần suất | 60/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ố
Body
application/json GameEvent11Schema
ErrorError envelope used by every Portal API error response.
GuestPlayerPlayerAccountPlayerSignInPlayerRegisterInputPublicGamePlayerFavoritesPagePlayerHistoryPagePlayerStatsPublicGameDetailGuestLaunchHeadingPublicNewsSummaryPublicNewsArticlePublicGuideSummaryPublicGuideArticlePublicGameCategoryPublicSupportPageGameConfigGameEvent