Skip to main content

Player

Player operations run in the browser. Send Content-Type and X-Game-Platform-ID, use the platform's configured domain so the browser Origin matches it, and set credentials: 'include' on every request.

Do not send the platform API key from the browser. After login, the API sets an HttpOnly session cookie; browser JavaScript must neither read nor create it.

Load the authentication configuration​

The response exposes only the public provider identifiers required to start login. Provider secrets are not returned in the browser context.

fragment PlatformAuthConfig on AuthConfig {
id
name
description
xsollaConfig {
loginProjectId
}
googleConfig {
clientID
}
yandexConfig {
clientID
}
vkIdConfig {
clientID
}
configs {
web {
implementation
activeService
}
}
}

query PlayerAuthConfiguration {
result: PlatformFetchGamePlatform {
__typename
... on Problem {
message
}
... on GamePlatform {
isMultipleAuthConfigUsed
authConfig {
...PlatformAuthConfig
}
allAuthConfigs {
...PlatformAuthConfig
}
}
}
}

Successful response shape:

{
"data": {
"result": {
"__typename": "GamePlatform",
"isMultipleAuthConfigUsed": false,
"authConfig": {
"id": "configured-auth-id",
"name": "Google login",
"description": "Sign in with Google",
"googleConfig": {
"clientID": "public-oauth-client-id"
},
"configs": {
"web": {
"implementation": "EXTERNAL",
"activeService": "GOOGLE"
}
}
},
"allAuthConfigs": []
}
}
}

When isMultipleAuthConfigUsed is true, let the player choose one of allAuthConfigs and pass its id as authConfigId during login. Otherwise use authConfig.

Log in​

Complete the OAuth flow for one of the authentication providers configured on the platform, then exchange the resulting short-lived provider token with GamePush.

Provider setup and callback requirements are described in Third-Party Authentication. Return here for the platform-specific token exchange and session cookie flow.

mutation LoginPlayer($input: LoginPlayerOnGamePlatformInput!) {
result: LoginPlayerOnGamePlatform(input: $input) {
__typename
... on Problem {
message
}
... on LoginPlayerOnGamePlatformResult {
isNewUser
}
}
}

Variables:

{
"input": {
"gamePlatformID": 42,
"token": "SHORT_LIVED_PROVIDER_TOKEN",
"tokenType": "AccessToken",
"redirectUri": "https://games.example.com/auth/callback",
"authConfigId": "configured-auth-id"
}
}

Use a real, short-lived provider token at runtime; do not log or commit it. tokenType accepts AccessToken or ExchangeToken as required by the selected provider.

Successful response:

{
"data": {
"result": {
"__typename": "LoginPlayerOnGamePlatformResult",
"isNewUser": false
}
}
}

To end the session, keep the same browser headers and cookie settings:

mutation LogoutPlayer {
result: LogoutPlayerOnGamePlatform {
__typename
... on Problem {
message
}
... on Success {
success
}
}
}
{
"data": {
"result": {
"__typename": "Success",
"success": true
}
}
}

Read and update the profile​

query CurrentPlatformPlayer($input: GetGamePlatformPlayerInput!) {
result: GetGamePlatformPlayer(input: $input) {
__typename
... on Problem {
message
}
... on GamePlatformPlayer {
id
gamePlatformID
name
avatar
balance
autoSkipAds
credentials {
login
type
}
vip {
productTag
enabled
disableGameAds
disablePlatformAds
currencyAccrual
bonusCurrency
endTime
}
playedGames
}
}
}

Variables:

{
"input": {}
}

Successful response shape:

{
"data": {
"result": {
"__typename": "GamePlatformPlayer",
"id": 9001,
"gamePlatformID": 42,
"name": "Player",
"avatar": "https://cdn.example.com/avatar.webp",
"balance": "1200",
"autoSkipAds": false,
"credentials": {
"login": "player@example.com",
"type": "EMAIL"
},
"vip": {
"productTag": "vip-month",
"enabled": true,
"disableGameAds": true,
"disablePlatformAds": true,
"currencyAccrual": 100,
"bonusCurrency": 50,
"endTime": "2026-09-01T00:00:00Z"
},
"playedGames": [101, 102]
}
}
}

Pass projectId in the input only when the profile must be prepared for a particular game.

mutation UpdatePlatformPlayer($input: UpdatePlayerProfileOnGamePlatformInput!) {
result: UpdatePlayerProfileOnGamePlatform(input: $input) {
__typename
... on Problem {
message
}
... on GamePlatformPlayer {
id
name
avatar
autoSkipAds
}
}
}

Variables and successful response:

{
"input": {
"name": "New name",
"avatarURL": "https://cdn.example.com/new-avatar.webp",
"autoSkipAds": false
}
}
{
"data": {
"result": {
"__typename": "GamePlatformPlayer",
"id": 9001,
"name": "New name",
"avatar": "https://cdn.example.com/new-avatar.webp",
"autoSkipAds": false
}
}
}

Build “My games”​

Read playedGames from the profile, then resolve those IDs to cards. An empty ID list produces an empty list.

query MyGames($input: FetchGamesOnGamePlatformByIdsInput!, $lang: Lang) {
result: FetchGamesOnGamePlatformByIds(input: $input) {
__typename
... on Problem {
message
}
... on GameViewsList {
count
items {
id
name(lang: $lang)
icon(lang: $lang)
cover(lang: $lang)
platformUrl(lang: $lang)
rating
}
}
}
}
{
"lang": "EN",
"input": {
"gamePlatformId": 42,
"gameIds": [101, 102],
"targetOS": "Desktop"
}
}
{
"data": {
"result": {
"__typename": "GameViewsList",
"count": 2,
"items": [
{
"id": 101,
"name": "Example Game",
"platformUrl": "https://games.example.com/game/example-game",
"rating": 8.4
}
]
}
}
}

Record a game after it starts:

mutation AddPlayedGame($input: AddGameToPlayedOnGamePlatformInput!) {
result: AddGameToPlayedOnGamePlatform(input: $input) {
__typename
... on Problem {
message
}
... on Success {
success
}
}
}
{
"input": {
"gameViewId": 101
}
}
{
"data": {
"result": {
"__typename": "Success",
"success": true
}
}
}

Remove one game or import a local list into an empty player profile with these operations:

mutation RemovePlayedGame(
$input: RemoveGameFromPlayedOnGamePlatformInput!
) {
result: RemoveGameFromPlayedOnGamePlatform(input: $input) {
__typename
... on Problem {
message
}
... on Success {
success
}
}
}

mutation SyncPlayedGames($input: SyncPlayedGamesOnGamePlatformInput!) {
result: SyncPlayedGamesOnGamePlatform(input: $input) {
__typename
... on Problem {
message
}
... on Success {
success
}
}
}

Variables for RemovePlayedGame:

{
"input": {
"gameViewId": 101
}
}

Variables for SyncPlayedGames:

{
"input": {
"gameViewIds": [101, 102]
}
}

Both successful mutations return {"__typename":"Success","success":true}. SyncPlayedGamesOnGamePlatform is intended for importing a guest's locally saved games after the player first signs up. It saves at most the first 25 published games only when the server-side playedGames list is empty. If that list already contains games, the mutation returns success without changing it. It does not replace an existing list; use the add and remove mutations for later changes.

Purchase platform currency or benefits​

Render available bundles from productsList in the Platform query. Start a purchase only after the player has signed in.

The shared product and purchase concepts are described in Purchases. The operations below cover the platform-specific bundle purchase, provider payload, and status check.

mutation PurchasePlatformBundle($input: PurchaseGamePlatformCurrencyBundleInput!) {
result: PurchaseGamePlatformCurrencyBundle(input: $input) {
__typename
... on Problem {
message
}
... on PlayerPurchaseOutput {
product {
id
tag
type
price(platform: PARTNER)
currency
}
purchase {
_id
orderStatus
payload
}
}
}
}
{
"input": {
"productId": 15,
"lang": "EN"
}
}
{
"data": {
"result": {
"__typename": "PlayerPurchaseOutput",
"product": {
"id": 15,
"tag": "coins-1000",
"type": "CURRENCY_BUNDLE",
"price": 4.99,
"currency": "USD"
},
"purchase": {
"_id": "purchase-id",
"orderStatus": "NEW",
"payload": {
"token": "SHORT_LIVED_PAYMENT_TOKEN"
}
}
}
}
}

Read paymentsConfig.configs.web.activeService from the Platform query and handle payload according to that service:

activeServiceReturned payloadSite action
XSOLLA{ "token": "..." }Open Xsolla Pay Station at https://secure.xsolla.com/paystation4/?token=<token>.
ROBOKASSA{ "url": "https://..." }Open the returned checkout URL in the payment interface or redirect the player to it.
STRIPE{ "url": "https://..." }Open the returned Stripe Checkout URL in the payment interface or redirect the player to it.

Provider-side setup is described in Xsolla, Robokassa, and Stripe. Use activeService to select the integration instead of inferring it from arbitrary payload fields. Treat payment tokens and URLs as short-lived data: do not log or persist them.

The browser must not mark a purchase as paid. After the provider flow completes, poll the purchase by ID and use orderStatus as the source of truth:

query PlatformPurchase($input: GetGamePlatformPurchaseInput!) {
result: GetGamePlatformPurchase(input: $input) {
__typename
... on Problem {
message
}
... on PlayerPurchase {
_id
orderStatus
payload
product {
id
type
price(platform: PARTNER)
}
}
}
}
{
"input": {
"purchaseId": "purchase-id"
}
}
{
"data": {
"result": {
"__typename": "PlayerPurchase",
"_id": "purchase-id",
"orderStatus": "PAID",
"payload": {
"token": "SHORT_LIVED_PAYMENT_TOKEN"
},
"product": {
"id": 15,
"type": "CURRENCY_BUNDLE",
"price": 4.99
}
}
}
}

For an in-game product paid from the platform balance, use the product, project, and provider returned by the game API:

mutation PurchaseGameProduct($input: PurchaseProductOnGamePlatformInput!) {
result: PurchaseProductOnGamePlatform(input: $input) {
__typename
... on Problem {
message
}
... on PlayerPurchase {
_id
projectId
productId
orderStatus
product {
id
name(lang: EN)
price(platform: PARTNER)
}
}
}
}
{
"input": {
"productId": 301,
"projectId": 501,
"provider": "GAMEPUSH"
}
}
{
"data": {
"result": {
"__typename": "PlayerPurchase",
"_id": "game-purchase-id",
"projectId": 501,
"productId": 301,
"orderStatus": "PAID",
"product": {
"id": 301,
"name": "Starter pack",
"price": 500
}
}
}
}

Always treat orderStatus from the API as the source of truth; never mark a purchase as paid only because the browser returned from a payment page.