neowire Publisher API
Download spec

neowire Publisher APIv1.0.0

Base URLhttps://api.neowire.ai
AppBearerTokenHTTP bearer
Authorization: Bearer <token>

Applied per endpoint.

The server-to-server API a publisher's backend calls to register its users.

Error handling#

Every endpoint declares a default response carrying this envelope (7 operations). Endpoint-specific status codes are listed with each endpoint.

errorstring
codestring

Machine-readable error code; omitted when the error has none.

Errorapplication/json
{
  "error": "string",
  "code": "string"
}
Jump to an endpoint

Endpoints7

POST/s2s/v1/user/{id}/auth#authUser

Authenticate a user and mint a bearer token

AppBearerTokenHTTP Bearer

Service-to-service endpoint called by an app backend (e.g. airperks-api) with its app token. Creates the user named by the path id on first call, upserts their demographics and currency-conversion settings, then returns a short-lived JWT the caller passes to the client as a bearer token for the /v1/* endpoints.

Status Code Meaning
400 invalid_timezone timezone is not a valid IANA timezone name.
400 too_many_friend_ids friend_user_ids resolves to more than 100 friends.
400 currency_not_configured currency is not one of the app's configured currencies.
409 username_taken Another user of this app already uses this username.

Path parameters

idstringrequired

External user id: the app's own identifier for the user, whose first authentication creates them.

  • example user1
string
  • example user1
  • ≤ 128 chars
  • pattern ^[a-zA-Z0-9._-]+$

Request bodyrequiredapplication/json

inherited from S2SUserFields
countrystringrequired
  • example US
  • 2 … 2 chars
languagestringrequired
  • example en
  • 2 … 2 chars
ageintegerrequired
  • 0 … 150
genderstringrequired
  • male
  • female
  • other
timezonestringrequired

IANA timezone name (e.g. "America/Chicago").

  • example America/Chicago
  • ≤ 64 chars
should_reward_userbooleanrequired

Whether the caller has determined this user is eligible to earn rewards. Stored on the user record and consulted by the feed endpoints.

currencystringrequired

Identifier of the user's local currency for displayed earnings. Any currency identifier is accepted, including custom, non-ISO codes (e.g. an app's own virtual currency) — it is not required to be an ISO 4217 code. Where the app configures currencies, it must be one of them (currency_not_configured otherwise); the matching configuration decides how the client renders amounts.

  • example USD
  • ≤ 10 chars
currency_factorstringrequired

Decimal multiplier applied to USD earnings to display them in the user's local currency (local = usd * currency_factor).

  • example 1.0
usernamestring

Unique handle within the calling app. When provided it is stored; when omitted the existing stored value is kept. There is no way to clear it back to empty.

  • pattern ^[a-z0-9-_.]{1,30}$
picture_urlstring

Profile picture URL. When provided it is stored; when omitted the existing stored value is kept. There is no way to clear it back to empty.

  • ≤ 200 chars
  • pattern ^https://\S+$
friend_user_idsarray of string

The full set of the user's friends' external user ids (empty allowed). When present the stored friend list is replaced with this set; when absent it is left untouched. Ids of unknown users, and the user's own id, are dropped.

  • ≤ 100 items
ad_bidnumber · double | null

Optional client-reported ad bid. Consumed only when the user is first created: it is stored for analytics and resolves the reward factor persisted on the user. Omitted or sent on a later auth for an existing user, it is ignored and the factor stays at its default (1.0).

Responses

200User authenticated; bearer token issuedS2SUserAuthResponseapplication/json
tokenstringrequired

JWT bearer token for the /v1/* endpoints.

expires_atstring · date-timerequired
defaultGeneric ErrorError handling ↑
PATCH/s2s/v1/user/{id}#patchUser

Partially update a user's stored profile

AppBearerTokenHTTP Bearer

Service-to-service endpoint called by an app backend with its app token. Updates only the provided fields on the user named by the path id; omitted fields keep their stored values. When friend_user_ids is present (even as an empty array) the user's friend list is replaced with the given set; ids that match no existing user of the calling app are dropped silently. ad_bid and the reward factor derived from it are frozen at user creation and cannot be changed here.

Status Code Meaning
400 invalid_timezone timezone is not a valid IANA timezone name.
400 too_many_friend_ids friend_user_ids resolves to more than 100 friends.
400 currency_not_configured currency is not one of the app's configured currencies.
404 user_not_found No user with this id exists for the calling app.
409 username_taken Another user of this app already uses this username.

Path parameters

idstringrequired

External user id: the app's own identifier for the user, whose first authentication creates them.

  • example user1
string
  • example user1
  • ≤ 128 chars
  • pattern ^[a-zA-Z0-9._-]+$

Request bodyrequiredapplication/json

countrystring
  • example US
  • 2 … 2 chars
languagestring
  • example en
  • 2 … 2 chars
ageinteger
  • 0 … 150
genderstring
  • male
  • female
  • other
timezonestring

IANA timezone name (e.g. "America/Chicago").

  • example America/Chicago
  • ≤ 64 chars
should_reward_userboolean

Whether the caller has determined this user is eligible to earn rewards. Stored on the user record and consulted by the feed endpoints.

currencystring

Identifier of the user's local currency for displayed earnings. Any currency identifier is accepted, including custom, non-ISO codes (e.g. an app's own virtual currency) — it is not required to be an ISO 4217 code. Where the app configures currencies, it must be one of them (currency_not_configured otherwise); the matching configuration decides how the client renders amounts.

  • example USD
  • ≤ 10 chars
currency_factorstring

Decimal multiplier applied to USD earnings to display them in the user's local currency (local = usd * currency_factor).

  • example 1.0
usernamestring

Unique handle within the calling app. When provided it is stored; when omitted the existing stored value is kept. There is no way to clear it back to empty.

  • pattern ^[a-z0-9-_.]{1,30}$
picture_urlstring

Profile picture URL. When provided it is stored; when omitted the existing stored value is kept. There is no way to clear it back to empty.

  • ≤ 200 chars
  • pattern ^https://\S+$
friend_user_idsarray of string

The full set of the user's friends' external user ids (empty allowed). When present the stored friend list is replaced with this set; when absent it is left untouched. Ids of unknown users, and the user's own id, are dropped.

  • ≤ 100 items

Responses

200User updated

No response body.

defaultGeneric ErrorError handling ↑
DELETE/s2s/v1/user/{id}#deleteUser

Delete a user

AppBearerTokenHTTP Bearer
Code Status Meaning
user_not_found 404 No live user of this app matches the path id (unknown or already deleted).

Path parameters

idstringrequired

External user id: the app's own identifier for the user, whose first authentication creates them.

  • example user1
string
  • example user1
  • ≤ 128 chars
  • pattern ^[a-zA-Z0-9._-]+$

Responses

200User deleted

No response body.

defaultGeneric ErrorError handling ↑
GET/s2s/v1/user/{id}/games#getUserGameActivity

Read a user's game activity

AppBearerTokenHTTP Bearer

Service-to-service endpoint called by an app backend with its app token. Returns one user's whole minigame history, resolved for that user: display names translated into their language, rewards converted to their currency, and mission goals carrying their progress. A game only visible to test users is included only for a test user, and a deleted game is never included.

Every collection is always present and may be empty, so a user who has never played reports five empty arrays rather than an error.

Status Code Meaning
404 user_not_found No live user with this id exists for the app.

Path parameters

idstringrequired

External user id: the app's own identifier for the user, whose first authentication creates them.

  • example user1
string
  • example user1
  • ≤ 128 chars
  • pattern ^[a-zA-Z0-9._-]+$

Responses

200The user's game activityS2SUserGameActivityResponseapplication/json
completed_eventsarray of S2SGameCompletedEventrequired

The events the user has completed, most recent first.

game_idstringrequired

The game slug (e.g. "apex-layers").

game_namestringrequired

The game's display name.

game_typestring S2SGameTyperequired
event_idstringrequired

The event's internal name (e.g. "level-50").

event_namestringrequired

The event's display name in the user's language, falling back to English and then to its internal name.

reward_user_currencystringrequired

The reward the user actually received for this event, as a decimal string in their currency.

completed_atstring · date-timerequired
progressarray of S2SGameProgressrequired

Derived per-game state, one entry per game the user has played, most recently played first.

game_idstringrequired

The game slug (e.g. "apex-layers").

game_namestringrequired
game_typestring S2SGameTyperequired
best_scoreintegerrequired

The user's best metric value across all their rounds of this game: the highest level for a level game, the highest score for a highscore game.

play_countintegerrequired

How many rounds the user has played of this game.

total_playtime_secondsintegerrequired

Total seconds the user has spent in this game.

last_played_atstring · date-timerequired
eventsarray of S2SGameEventStaterequired

Every event of the version the user is on for this game, in the order shown to the client. Completed events carry a non-null completed_at.

Show definition ↓
playsarray of S2SGamePlayrequired

The user's most recent rounds, newest first, capped at the last 10. One entry per round rather than per submission, so a round continued after a second life appears once.

game_idstringrequired

The game slug (e.g. "apex-layers").

game_namestringrequired
game_typestring S2SGameTyperequired
scoreintegerrequired

The metric value reached in this round, 0 when the user did not score.

playtime_secondsintegerrequired

How many seconds the round lasted, summed over its submissions.

played_atstring · date-timerequired

When the round began.

joinable_missionsarray of S2SGameMissionOfferrequired

The missions the user could join right now by playing the corresponding game. A mission moves to mission_participations as soon as they join it.

game_idstringrequired

The game slug (e.g. "apex-layers").

game_namestringrequired
game_typestring S2SGameTyperequired
mission_idstringrequired

The mission's internal name (e.g. "daily-grind").

mission_namestringrequired

The mission's display name in the user's language, falling back to English and then to its internal name.

goalsarray of S2SGameMissionGoalrequired

The mission's goals in the order shown to the client, all at zero progress since the user has not joined yet.

Show definition ↓
reward_user_currencystringrequired

What completing every goal would pay if the user joined now, as a decimal string in their currency.

joinable_untilstring · date-time | nullrequired

When the mission stops being joinable, or null when open-ended.

mission_participationsarray of S2SGameMissionParticipationrequired

The user's ongoing mission windows plus every past one whose window ended within the last 14 days, most recent first.

game_idstringrequired

The game slug (e.g. "apex-layers").

game_namestringrequired
game_typestring S2SGameTyperequired
mission_idstringrequired

The mission's internal name (e.g. "daily-grind").

mission_namestringrequired

The mission's display name in the user's language, falling back to English and then to its internal name.

statusstring S2SGameMissionStatusrequired
goalsarray of S2SGameMissionGoalrequired

The goals of the mission version the user joined, in the order shown to the client, carrying their progress.

Show definition ↓
reward_user_currencystringrequired

The reward received on completion, as a decimal string in the user's currency. Zero unless status is completed.

joined_atstring · date-timerequired

When the user joined, i.e. their first counting play.

resets_atstring · date-timerequired

When the mission window ends, or ended for a past participation.

defaultGeneric ErrorError handling ↑
GET/s2s/v1/shares/{id}#getShare

Resolve a share id to media metadata

AppBearerTokenHTTP Bearer

Resolves one share id to its media metadata plus the sharer's external user id. Only shares belonging to the calling app resolve.

Status Code Meaning
404 share_not_found Unknown id, another app's share, or the media has been deleted.

Path parameters

idstringrequired

The share id to resolve.

string
  • ≤ 32 chars

Responses

200Resolved shareS2SShareapplication/json
idstringrequired

The share id.

sharer_uidstringrequired

External user id of the user who created the share.

mediaShareMediarequired
oneOfone of 3 variants, selected by type

type = "video" ShareVideoMedia

typestringrequired
  • = "video"discriminator
idstringrequired
creator_tagstringrequired
creator_namestringrequired
thumbnail_urlstringrequired

type = "comic" ShareComicMedia

typestringrequired
  • = "comic"discriminator
idstringrequired
titlestringrequired
descriptionstringrequired
cover_urlstringrequired

type = "game" ShareGameMedia

typestringrequired
  • = "game"discriminator
idstringrequired
namestringrequired
icon_urlstringrequired
banner_image_urlstringrequired
scoreinteger | nullrequired

Score the sharer attached to the share, or null.

defaultGeneric ErrorError handling ↑
POST/s2s/v1/shares/{id}#getShares

Resolve share ids to media metadata (batch)

AppBearerTokenHTTP Bearer

Batch counterpart of GET/s2s/v1/shares/{id}, resolving the request body's ids in one call. The path id must be the literal _.

Only shares belonging to the calling app are returned; ids that are unknown, belong to another app, or whose media has been deleted are omitted from the response (so the result may be shorter than the request, and in any order).

Path parameters

idstringrequired

Must be _; the ids to resolve come from the request body.

string

Request bodyrequiredapplication/json

idsarray of stringrequired

The share ids to resolve.

  • 1 … 50 items

Responses

200Resolved sharesS2SGetSharesResponseapplication/json
sharesarray of S2SSharerequired

Resolved shares, one per successfully resolved id. Unknown, wrong-app or deleted-media ids are omitted, so this may be shorter than the requested id list and in any order.

idstringrequired

The share id.

sharer_uidstringrequired

External user id of the user who created the share.

defaultGeneric ErrorError handling ↑
PATCH/s2s/v1/ads/{id}#fillServerAd

Fill ad slots with server-reported revenue

AppBearerTokenHTTP Bearer

Server-to-server counterpart of the client PATCH/v1/ads/{id} fill, called by an app backend with its app token. Attaches server-reported revenue (server_data, currently currency + bid) to ad slots owned by the calling app.

When id is a slot uuid the body fills that single slot via server_data. When id is the literal _ the body's items array fills many slots at once; items must be non-empty and server_data must be omitted in that case. The batch is atomic: any validation error fails the whole request and nothing is written. Slots that don't exist for the app (or were already server-filled) are silently skipped.

Path parameters

idstringrequired

A slot uuid, or _ to fill a batch via the request body's items.

string

Request bodyrequiredapplication/json

server_dataS2SServerAdData
currencystringrequired

Currency identifier for the bid. Any currency identifier is accepted, including custom, non-ISO codes — it is not required to be an ISO 4217 code.

  • ≤ 10 chars
bidstringrequired

Bid amount as a decimal string (e.g. "1.25").

itemsarray of S2SFillServerAdItem

Per-slot fills, used when the path id is _.

  • ≤ 500 items
idstring · uuidrequired

The slot id to fill.

Responses

204Slots filled

No response body.

defaultGeneric ErrorError handling ↑

Schemas

S2SUserFieldsobject

The user profile an app backend owns, every field optional: the body of PATCH/s2s/v1/user/{id}, and the base S2SUserAuthRequest extends with the fields it requires.

countrystring
  • example US
  • 2 … 2 chars
languagestring
  • example en
  • 2 … 2 chars
ageinteger
  • 0 … 150
genderstring
  • male
  • female
  • other
timezonestring

IANA timezone name (e.g. "America/Chicago").

  • example America/Chicago
  • ≤ 64 chars
should_reward_userboolean

Whether the caller has determined this user is eligible to earn rewards. Stored on the user record and consulted by the feed endpoints.

currencystring

Identifier of the user's local currency for displayed earnings. Any currency identifier is accepted, including custom, non-ISO codes (e.g. an app's own virtual currency) — it is not required to be an ISO 4217 code. Where the app configures currencies, it must be one of them (currency_not_configured otherwise); the matching configuration decides how the client renders amounts.

  • example USD
  • ≤ 10 chars
currency_factorstring

Decimal multiplier applied to USD earnings to display them in the user's local currency (local = usd * currency_factor).

  • example 1.0
usernamestring

Unique handle within the calling app. When provided it is stored; when omitted the existing stored value is kept. There is no way to clear it back to empty.

  • pattern ^[a-z0-9-_.]{1,30}$
picture_urlstring

Profile picture URL. When provided it is stored; when omitted the existing stored value is kept. There is no way to clear it back to empty.

  • ≤ 200 chars
  • pattern ^https://\S+$
friend_user_idsarray of string

The full set of the user's friends' external user ids (empty allowed). When present the stored friend list is replaced with this set; when absent it is left untouched. Ids of unknown users, and the user's own id, are dropped.

  • ≤ 100 items
S2SUserFieldsapplication/json
{
  "country": "US",
  "language": "en",
  "age": 0,
  "gender": "male",
  "timezone": "America/Chicago",
  "should_reward_user": true,
  "currency": "USD",
  "currency_factor": "1.0",
  "username": "string",
  "picture_url": "string",
  "friend_user_ids": [
    "string"
  ]
}

The user profile an app backend owns, every field optional: the body of PATCH /s2s/v1/user/{id}, and the base S2SUserAuthRequest extends with the fields it requires.

S2SUserAuthRequestallOf
inherited from S2SUserFields
countrystringrequired
  • example US
  • 2 … 2 chars
languagestringrequired
  • example en
  • 2 … 2 chars
ageintegerrequired
  • 0 … 150
genderstringrequired
  • male
  • female
  • other
timezonestringrequired

IANA timezone name (e.g. "America/Chicago").

  • example America/Chicago
  • ≤ 64 chars
should_reward_userbooleanrequired

Whether the caller has determined this user is eligible to earn rewards. Stored on the user record and consulted by the feed endpoints.

currencystringrequired

Identifier of the user's local currency for displayed earnings. Any currency identifier is accepted, including custom, non-ISO codes (e.g. an app's own virtual currency) — it is not required to be an ISO 4217 code. Where the app configures currencies, it must be one of them (currency_not_configured otherwise); the matching configuration decides how the client renders amounts.

  • example USD
  • ≤ 10 chars
currency_factorstringrequired

Decimal multiplier applied to USD earnings to display them in the user's local currency (local = usd * currency_factor).

  • example 1.0
usernamestring

Unique handle within the calling app. When provided it is stored; when omitted the existing stored value is kept. There is no way to clear it back to empty.

  • pattern ^[a-z0-9-_.]{1,30}$
picture_urlstring

Profile picture URL. When provided it is stored; when omitted the existing stored value is kept. There is no way to clear it back to empty.

  • ≤ 200 chars
  • pattern ^https://\S+$
friend_user_idsarray of string

The full set of the user's friends' external user ids (empty allowed). When present the stored friend list is replaced with this set; when absent it is left untouched. Ids of unknown users, and the user's own id, are dropped.

  • ≤ 100 items
ad_bidnumber · double | null

Optional client-reported ad bid. Consumed only when the user is first created: it is stored for analytics and resolves the reward factor persisted on the user. Omitted or sent on a later auth for an existing user, it is ignored and the factor stays at its default (1.0).

S2SUserAuthRequestapplication/json
{
  "country": "US",
  "language": "en",
  "age": 0,
  "gender": "male",
  "timezone": "America/Chicago",
  "should_reward_user": true,
  "currency": "USD",
  "currency_factor": "1.0",
  "username": "string",
  "picture_url": "string",
  "friend_user_ids": [
    "string"
  ],
  "ad_bid": 0
}
S2SUserAuthResponseobject
tokenstringrequired

JWT bearer token for the /v1/* endpoints.

expires_atstring · date-timerequired
S2SUserAuthResponseapplication/json
{
  "token": "string",
  "expires_at": "2026-08-09T12:00:00Z"
}
S2SGetSharesRequestobject
idsarray of stringrequired

The share ids to resolve.

  • 1 … 50 items
S2SGetSharesRequestapplication/json
{
  "ids": [
    "string"
  ]
}
S2SGetSharesResponseobject
sharesarray of S2SSharerequired

Resolved shares, one per successfully resolved id. Unknown, wrong-app or deleted-media ids are omitted, so this may be shorter than the requested id list and in any order.

idstringrequired

The share id.

sharer_uidstringrequired

External user id of the user who created the share.

mediaShareMediarequired
oneOfone of 3 variants, selected by type

type = "video" ShareVideoMedia

typestringrequired
  • = "video"discriminator
idstringrequired
creator_tagstringrequired
creator_namestringrequired
thumbnail_urlstringrequired

type = "comic" ShareComicMedia

typestringrequired
  • = "comic"discriminator
idstringrequired
titlestringrequired
descriptionstringrequired
cover_urlstringrequired

type = "game" ShareGameMedia

typestringrequired
  • = "game"discriminator
idstringrequired
namestringrequired
icon_urlstringrequired
banner_image_urlstringrequired
scoreinteger | nullrequired

Score the sharer attached to the share, or null.

S2SGetSharesResponseapplication/json
{
  "shares": [
    {
      "id": "string",
      "sharer_uid": "string",
      "media": {
        "type": "video",
        "id": "string",
        "creator_tag": "string",
        "creator_name": "string",
        "thumbnail_url": "string"
      }
    }
  ]
}

Showing the video variant.

S2SShareobject
idstringrequired

The share id.

sharer_uidstringrequired

External user id of the user who created the share.

mediaShareMediarequired
oneOfone of 3 variants, selected by type

type = "video" ShareVideoMedia

typestringrequired
  • = "video"discriminator
idstringrequired
creator_tagstringrequired
creator_namestringrequired
thumbnail_urlstringrequired

type = "comic" ShareComicMedia

typestringrequired
  • = "comic"discriminator
idstringrequired
titlestringrequired
descriptionstringrequired
cover_urlstringrequired

type = "game" ShareGameMedia

typestringrequired
  • = "game"discriminator
idstringrequired
namestringrequired
icon_urlstringrequired
banner_image_urlstringrequired
scoreinteger | nullrequired

Score the sharer attached to the share, or null.

S2SShareapplication/json
{
  "id": "string",
  "sharer_uid": "string",
  "media": {
    "type": "video",
    "id": "string",
    "creator_tag": "string",
    "creator_name": "string",
    "thumbnail_url": "string"
  }
}

Showing the video variant.

S2SFillServerAdRequestobject

Body for PATCH/s2s/v1/ads/{id}. Set server_data to fill the single slot named in the path; set items to fill a batch when the path id is _.

server_dataS2SServerAdData
currencystringrequired

Currency identifier for the bid. Any currency identifier is accepted, including custom, non-ISO codes — it is not required to be an ISO 4217 code.

  • ≤ 10 chars
bidstringrequired

Bid amount as a decimal string (e.g. "1.25").

itemsarray of S2SFillServerAdItem

Per-slot fills, used when the path id is _.

  • ≤ 500 items
idstring · uuidrequired

The slot id to fill.

server_dataS2SServerAdDatarequired
currencystringrequired

Currency identifier for the bid. Any currency identifier is accepted, including custom, non-ISO codes — it is not required to be an ISO 4217 code.

  • ≤ 10 chars
bidstringrequired

Bid amount as a decimal string (e.g. "1.25").

S2SFillServerAdRequestapplication/json
{
  "server_data": {
    "currency": "string",
    "bid": "string"
  },
  "items": [
    {
      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "server_data": {
        "currency": "string",
        "bid": "string"
      }
    }
  ]
}

Body for PATCH /s2s/v1/ads/{id}. Set server_data to fill the single slot named in the path; set items to fill a batch when the path id is _.

S2SFillServerAdItemobject
idstring · uuidrequired

The slot id to fill.

server_dataS2SServerAdDatarequired
currencystringrequired

Currency identifier for the bid. Any currency identifier is accepted, including custom, non-ISO codes — it is not required to be an ISO 4217 code.

  • ≤ 10 chars
bidstringrequired

Bid amount as a decimal string (e.g. "1.25").

S2SFillServerAdItemapplication/json
{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "server_data": {
    "currency": "string",
    "bid": "string"
  }
}
S2SServerAdDataobject

Server-reported ad revenue for a slot.

currencystringrequired

Currency identifier for the bid. Any currency identifier is accepted, including custom, non-ISO codes — it is not required to be an ISO 4217 code.

  • ≤ 10 chars
bidstringrequired

Bid amount as a decimal string (e.g. "1.25").

S2SServerAdDataapplication/json
{
  "currency": "string",
  "bid": "string"
}
S2SUserGameActivityResponseobject
completed_eventsarray of S2SGameCompletedEventrequired

The events the user has completed, most recent first.

game_idstringrequired

The game slug (e.g. "apex-layers").

game_namestringrequired

The game's display name.

game_typestring S2SGameTyperequired
event_idstringrequired

The event's internal name (e.g. "level-50").

event_namestringrequired

The event's display name in the user's language, falling back to English and then to its internal name.

reward_user_currencystringrequired

The reward the user actually received for this event, as a decimal string in their currency.

completed_atstring · date-timerequired
progressarray of S2SGameProgressrequired

Derived per-game state, one entry per game the user has played, most recently played first.

game_idstringrequired

The game slug (e.g. "apex-layers").

game_namestringrequired
game_typestring S2SGameTyperequired
best_scoreintegerrequired

The user's best metric value across all their rounds of this game: the highest level for a level game, the highest score for a highscore game.

play_countintegerrequired

How many rounds the user has played of this game.

total_playtime_secondsintegerrequired

Total seconds the user has spent in this game.

last_played_atstring · date-timerequired
eventsarray of S2SGameEventStaterequired

Every event of the version the user is on for this game, in the order shown to the client. Completed events carry a non-null completed_at.

event_idstringrequired

The event's internal name (e.g. "level-50").

event_namestringrequired

The event's display name in the user's language, falling back to English and then to its internal name.

reward_user_currencystringrequired

The reward completing this event pays, as a decimal string in the user's currency. This is the prospective amount derived from the event's configuration, so it can differ from what a completed event actually paid — read S2SGameCompletedEvent.reward_user_currency for that.

completed_atstring · date-time | nullrequired

When the user completed this event, or null if they have not.

playsarray of S2SGamePlayrequired

The user's most recent rounds, newest first, capped at the last 10. One entry per round rather than per submission, so a round continued after a second life appears once.

game_idstringrequired

The game slug (e.g. "apex-layers").

game_namestringrequired
game_typestring S2SGameTyperequired
scoreintegerrequired

The metric value reached in this round, 0 when the user did not score.

playtime_secondsintegerrequired

How many seconds the round lasted, summed over its submissions.

played_atstring · date-timerequired

When the round began.

joinable_missionsarray of S2SGameMissionOfferrequired

The missions the user could join right now by playing the corresponding game. A mission moves to mission_participations as soon as they join it.

game_idstringrequired

The game slug (e.g. "apex-layers").

game_namestringrequired
game_typestring S2SGameTyperequired
mission_idstringrequired

The mission's internal name (e.g. "daily-grind").

mission_namestringrequired

The mission's display name in the user's language, falling back to English and then to its internal name.

goalsarray of S2SGameMissionGoalrequired

The mission's goals in the order shown to the client, all at zero progress since the user has not joined yet.

goal_idstringrequired

The goal's internal name (e.g. "complete-levels").

goal_namestringrequired

The goal's display name in the user's language, falling back to English and then to its internal name.

valuenumber · doublerequired

The user's progress toward threshold, 0 while unjoined.

thresholdnumber · doublerequired

The value at which the goal completes. Frozen when the user joins, so it does not move with a later config change.

completedbooleanrequired
reward_user_currencystringrequired

What completing every goal would pay if the user joined now, as a decimal string in their currency.

joinable_untilstring · date-time | nullrequired

When the mission stops being joinable, or null when open-ended.

mission_participationsarray of S2SGameMissionParticipationrequired

The user's ongoing mission windows plus every past one whose window ended within the last 14 days, most recent first.

game_idstringrequired

The game slug (e.g. "apex-layers").

game_namestringrequired
game_typestring S2SGameTyperequired
mission_idstringrequired

The mission's internal name (e.g. "daily-grind").

mission_namestringrequired

The mission's display name in the user's language, falling back to English and then to its internal name.

statusstring S2SGameMissionStatusrequired
goalsarray of S2SGameMissionGoalrequired

The goals of the mission version the user joined, in the order shown to the client, carrying their progress.

goal_idstringrequired

The goal's internal name (e.g. "complete-levels").

goal_namestringrequired

The goal's display name in the user's language, falling back to English and then to its internal name.

valuenumber · doublerequired

The user's progress toward threshold, 0 while unjoined.

thresholdnumber · doublerequired

The value at which the goal completes. Frozen when the user joins, so it does not move with a later config change.

completedbooleanrequired
reward_user_currencystringrequired

The reward received on completion, as a decimal string in the user's currency. Zero unless status is completed.

joined_atstring · date-timerequired

When the user joined, i.e. their first counting play.

resets_atstring · date-timerequired

When the mission window ends, or ended for a past participation.

S2SUserGameActivityResponseapplication/json
{
  "completed_events": [
    {
      "game_id": "string",
      "game_name": "string",
      "game_type": "level",
      "event_id": "string",
      "event_name": "string",
      "reward_user_currency": "string",
      "completed_at": "2026-08-09T12:00:00Z"
    }
  ],
  "progress": [
    {
      "game_id": "string",
      "game_name": "string",
      "game_type": "level",
      "best_score": 0,
      "play_count": 0,
      "total_playtime_seconds": 0,
      "last_played_at": "2026-08-09T12:00:00Z",
      "events": [
        {
          "event_id": "string",
          "event_name": "string",
          "reward_user_currency": "string",
          "completed_at": "2026-08-09T12:00:00Z"
        }
      ]
    }
  ],
  "plays": [
    {
      "game_id": "string",
      "game_name": "string",
      "game_type": "level",
      "score": 0,
      "playtime_seconds": 0,
      "played_at": "2026-08-09T12:00:00Z"
    }
  ],
  "joinable_missions": [
    {
      "game_id": "string",
      "game_name": "string",
      "game_type": "level",
      "mission_id": "string",
      "mission_name": "string",
      "goals": [
        {
          "goal_id": "string",
          "goal_name": "string",
          "value": 0,
          "threshold": 0,
          "completed": true
        }
      ],
      "reward_user_currency": "string",
      "joinable_until": "2026-08-09T12:00:00Z"
    }
  ],
  "mission_participations": [
    {
      "game_id": "string",
      "game_name": "string",
      "game_type": "level",
      "mission_id": "string",
      "mission_name": "string",
      "status": "ongoing",
      "goals": [
        {
          "goal_id": "string",
          "goal_name": "string",
          "value": 0,
          "threshold": 0,
          "completed": true
        }
      ],
      "reward_user_currency": "string",
      "joined_at": "2026-08-09T12:00:00Z",
      "resets_at": "2026-08-09T12:00:00Z"
    }
  ]
}
S2SGameTypeenum
string
  • level
  • highscore
S2SGameTypeapplication/json
"level"
S2SGameCompletedEventobject
game_idstringrequired

The game slug (e.g. "apex-layers").

game_namestringrequired

The game's display name.

game_typestring S2SGameTyperequired
event_idstringrequired

The event's internal name (e.g. "level-50").

event_namestringrequired

The event's display name in the user's language, falling back to English and then to its internal name.

reward_user_currencystringrequired

The reward the user actually received for this event, as a decimal string in their currency.

completed_atstring · date-timerequired
S2SGameCompletedEventapplication/json
{
  "game_id": "string",
  "game_name": "string",
  "game_type": "level",
  "event_id": "string",
  "event_name": "string",
  "reward_user_currency": "string",
  "completed_at": "2026-08-09T12:00:00Z"
}
S2SGameProgressobject
game_idstringrequired

The game slug (e.g. "apex-layers").

game_namestringrequired
game_typestring S2SGameTyperequired
best_scoreintegerrequired

The user's best metric value across all their rounds of this game: the highest level for a level game, the highest score for a highscore game.

play_countintegerrequired

How many rounds the user has played of this game.

total_playtime_secondsintegerrequired

Total seconds the user has spent in this game.

last_played_atstring · date-timerequired
eventsarray of S2SGameEventStaterequired

Every event of the version the user is on for this game, in the order shown to the client. Completed events carry a non-null completed_at.

event_idstringrequired

The event's internal name (e.g. "level-50").

event_namestringrequired

The event's display name in the user's language, falling back to English and then to its internal name.

reward_user_currencystringrequired

The reward completing this event pays, as a decimal string in the user's currency. This is the prospective amount derived from the event's configuration, so it can differ from what a completed event actually paid — read S2SGameCompletedEvent.reward_user_currency for that.

completed_atstring · date-time | nullrequired

When the user completed this event, or null if they have not.

S2SGameProgressapplication/json
{
  "game_id": "string",
  "game_name": "string",
  "game_type": "level",
  "best_score": 0,
  "play_count": 0,
  "total_playtime_seconds": 0,
  "last_played_at": "2026-08-09T12:00:00Z",
  "events": [
    {
      "event_id": "string",
      "event_name": "string",
      "reward_user_currency": "string",
      "completed_at": "2026-08-09T12:00:00Z"
    }
  ]
}
S2SGameEventStateobject
event_idstringrequired

The event's internal name (e.g. "level-50").

event_namestringrequired

The event's display name in the user's language, falling back to English and then to its internal name.

reward_user_currencystringrequired

The reward completing this event pays, as a decimal string in the user's currency. This is the prospective amount derived from the event's configuration, so it can differ from what a completed event actually paid — read S2SGameCompletedEvent.reward_user_currency for that.

completed_atstring · date-time | nullrequired

When the user completed this event, or null if they have not.

S2SGameEventStateapplication/json
{
  "event_id": "string",
  "event_name": "string",
  "reward_user_currency": "string",
  "completed_at": "2026-08-09T12:00:00Z"
}
S2SGamePlayobject
game_idstringrequired

The game slug (e.g. "apex-layers").

game_namestringrequired
game_typestring S2SGameTyperequired
scoreintegerrequired

The metric value reached in this round, 0 when the user did not score.

playtime_secondsintegerrequired

How many seconds the round lasted, summed over its submissions.

played_atstring · date-timerequired

When the round began.

S2SGamePlayapplication/json
{
  "game_id": "string",
  "game_name": "string",
  "game_type": "level",
  "score": 0,
  "playtime_seconds": 0,
  "played_at": "2026-08-09T12:00:00Z"
}
S2SGameMissionOfferobject
game_idstringrequired

The game slug (e.g. "apex-layers").

game_namestringrequired
game_typestring S2SGameTyperequired
mission_idstringrequired

The mission's internal name (e.g. "daily-grind").

mission_namestringrequired

The mission's display name in the user's language, falling back to English and then to its internal name.

goalsarray of S2SGameMissionGoalrequired

The mission's goals in the order shown to the client, all at zero progress since the user has not joined yet.

goal_idstringrequired

The goal's internal name (e.g. "complete-levels").

goal_namestringrequired

The goal's display name in the user's language, falling back to English and then to its internal name.

valuenumber · doublerequired

The user's progress toward threshold, 0 while unjoined.

thresholdnumber · doublerequired

The value at which the goal completes. Frozen when the user joins, so it does not move with a later config change.

completedbooleanrequired
reward_user_currencystringrequired

What completing every goal would pay if the user joined now, as a decimal string in their currency.

joinable_untilstring · date-time | nullrequired

When the mission stops being joinable, or null when open-ended.

S2SGameMissionOfferapplication/json
{
  "game_id": "string",
  "game_name": "string",
  "game_type": "level",
  "mission_id": "string",
  "mission_name": "string",
  "goals": [
    {
      "goal_id": "string",
      "goal_name": "string",
      "value": 0,
      "threshold": 0,
      "completed": true
    }
  ],
  "reward_user_currency": "string",
  "joinable_until": "2026-08-09T12:00:00Z"
}
S2SGameMissionStatusenum

Where a joined mission window stands. There is no not_started: a mission the user has not joined is reported in joinable_missions instead.

string
  • ongoing
  • completed
  • failed
S2SGameMissionStatusapplication/json
"ongoing"
S2SGameMissionParticipationobject
game_idstringrequired

The game slug (e.g. "apex-layers").

game_namestringrequired
game_typestring S2SGameTyperequired
mission_idstringrequired

The mission's internal name (e.g. "daily-grind").

mission_namestringrequired

The mission's display name in the user's language, falling back to English and then to its internal name.

statusstring S2SGameMissionStatusrequired
goalsarray of S2SGameMissionGoalrequired

The goals of the mission version the user joined, in the order shown to the client, carrying their progress.

goal_idstringrequired

The goal's internal name (e.g. "complete-levels").

goal_namestringrequired

The goal's display name in the user's language, falling back to English and then to its internal name.

valuenumber · doublerequired

The user's progress toward threshold, 0 while unjoined.

thresholdnumber · doublerequired

The value at which the goal completes. Frozen when the user joins, so it does not move with a later config change.

completedbooleanrequired
reward_user_currencystringrequired

The reward received on completion, as a decimal string in the user's currency. Zero unless status is completed.

joined_atstring · date-timerequired

When the user joined, i.e. their first counting play.

resets_atstring · date-timerequired

When the mission window ends, or ended for a past participation.

S2SGameMissionParticipationapplication/json
{
  "game_id": "string",
  "game_name": "string",
  "game_type": "level",
  "mission_id": "string",
  "mission_name": "string",
  "status": "ongoing",
  "goals": [
    {
      "goal_id": "string",
      "goal_name": "string",
      "value": 0,
      "threshold": 0,
      "completed": true
    }
  ],
  "reward_user_currency": "string",
  "joined_at": "2026-08-09T12:00:00Z",
  "resets_at": "2026-08-09T12:00:00Z"
}
S2SGameMissionGoalobject
goal_idstringrequired

The goal's internal name (e.g. "complete-levels").

goal_namestringrequired

The goal's display name in the user's language, falling back to English and then to its internal name.

valuenumber · doublerequired

The user's progress toward threshold, 0 while unjoined.

thresholdnumber · doublerequired

The value at which the goal completes. Frozen when the user joins, so it does not move with a later config change.

completedbooleanrequired
S2SGameMissionGoalapplication/json
{
  "goal_id": "string",
  "goal_name": "string",
  "value": 0,
  "threshold": 0,
  "completed": true
}
RewardDisplayIconobject

Render the amount with the icon at icon_url on the given side of it.

typestringrequired
  • = "icon"
icon_urlstringrequired
positionstring RewardDisplayPositionrequired
RewardDisplayIconapplication/json
{
  "type": "icon",
  "icon_url": "string",
  "position": "left"
}
RewardDisplayPlainobject

Render the amount with symbol on the given side of it, e.g. "$1.50".

typestringrequired
  • = "plain"
symbolstringrequired
positionstring RewardDisplayPositionrequired
RewardDisplayPlainapplication/json
{
  "type": "plain",
  "symbol": "string",
  "position": "left"
}
ComicPartPageobject
page_typestringrequired
  • = "page"
indexintegerrequired

The index of the page in the part.

video_urlstringrequired
ComicPartPageapplication/json
{
  "page_type": "page",
  "index": 0,
  "video_url": "string"
}
ComicPartPageAdallOf
page_typestringrequired
  • = "ad"
inherited from Ad
slot_idstring · uuidrequired

The ad slot's id. Use it to fill the slot via PATCH/v1/ads/{id}.

typestringrequired
  • offer
  • external
lock_secondsintegerrequired

How long the ad is locked before it can be skipped.

external_sub_typestring | nullrequired

Sub-type of an external ad; null for non-external ads.

  • native
  • interstitial
  • rewarded
ComicPartPageAdapplication/json
{
  "page_type": "ad",
  "slot_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "type": "offer",
  "lock_seconds": 0,
  "external_sub_type": "native"
}
ShareVideoMediaobject
typestringrequired
  • = "video"
idstringrequired
creator_tagstringrequired
creator_namestringrequired
thumbnail_urlstringrequired
ShareVideoMediaapplication/json
{
  "type": "video",
  "id": "string",
  "creator_tag": "string",
  "creator_name": "string",
  "thumbnail_url": "string"
}
ShareComicMediaobject
typestringrequired
  • = "comic"
idstringrequired
titlestringrequired
descriptionstringrequired
cover_urlstringrequired
ShareComicMediaapplication/json
{
  "type": "comic",
  "id": "string",
  "title": "string",
  "description": "string",
  "cover_url": "string"
}
ShareGameMediaobject
typestringrequired
  • = "game"
idstringrequired
namestringrequired
icon_urlstringrequired
banner_image_urlstringrequired
scoreinteger | nullrequired

Score the sharer attached to the share, or null.

ShareGameMediaapplication/json
{
  "type": "game",
  "id": "string",
  "name": "string",
  "icon_url": "string",
  "banner_image_url": "string",
  "score": 0
}
ShareMediaoneOf · 3

The shared media, discriminated by type.

oneOfone of 3 variants, selected by type

type = "video" ShareVideoMedia

typestringrequired
  • = "video"discriminator
idstringrequired
creator_tagstringrequired
creator_namestringrequired
thumbnail_urlstringrequired

type = "comic" ShareComicMedia

typestringrequired
  • = "comic"discriminator
idstringrequired
titlestringrequired
descriptionstringrequired
cover_urlstringrequired

type = "game" ShareGameMedia

typestringrequired
  • = "game"discriminator
idstringrequired
namestringrequired
icon_urlstringrequired
banner_image_urlstringrequired
scoreinteger | nullrequired

Score the sharer attached to the share, or null.

ShareMediaapplication/json
{
  "type": "video",
  "id": "string",
  "creator_tag": "string",
  "creator_name": "string",
  "thumbnail_url": "string"
}

Showing the video variant.

Errorobject
errorstring
codestring

Machine-readable error code; omitted when the error has none.

Errorapplication/json
{
  "error": "string",
  "code": "string"
}
VideoFriendLikeallOf
inherited from Friend
uidstringrequired

The friend's external user id (app-scoped public identifier).

usernamestring | nullrequired

The friend's username; null when unset.

picture_urlstring | nullrequired

The friend's profile picture URL; null when unset.

liked_atstring · date-timerequired

When the friend liked the video.

VideoFriendLikeapplication/json
{
  "uid": "string",
  "username": "string",
  "picture_url": "string",
  "liked_at": "2026-08-09T12:00:00Z"
}
Friendobject

A compact projection of a friend user.

uidstringrequired

The friend's external user id (app-scoped public identifier).

usernamestring | nullrequired

The friend's username; null when unset.

picture_urlstring | nullrequired

The friend's profile picture URL; null when unset.

Friendapplication/json
{
  "uid": "string",
  "username": "string",
  "picture_url": "string"
}
RewardDisplayPositionenum

Which side of the amount the icon or symbol goes on.

string
  • left
  • right
RewardDisplayPositionapplication/json
"left"
GameCategoryenum

Game category slug.

string
  • arcade
  • board-card
  • casual
  • entertainment
  • puzzle
  • role-playing
  • strategy
  • other
GameCategoryapplication/json
"arcade"
GameTypeenum
string
  • level
  • highscore
GameTypeapplication/json
"level"
GameEventobject
idstring · uuidrequired
translationsmap<string, string>required
«key»string
sort_orderintegerrequired
rewardRewardrequired
totalstringrequired

total = bonus + base

bonusstringrequired
basestringrequired
displayoneOf · 2 variantsrequired

How the client should render the amounts, as configured for the user's currency. Falls back to a leading "$" where the app configures no rendering for that currency, and wherever there is no user to read a currency from, such as the public games catalog.

oneOfone of 2 variants, selected by type

type = "icon" RewardDisplayIcon

typestringrequired
  • = "icon"discriminator
icon_urlstringrequired
positionstring RewardDisplayPositionrequired

type = "plain" RewardDisplayPlain

typestringrequired
  • = "plain"discriminator
symbolstringrequired
positionstring RewardDisplayPositionrequired
threshold_typestringrequired
  • level
  • highscore
  • games_played
  • counter
  • gauge
  • set
blocked_bystring · uuid | nullrequired

public_id of the event that must be completed first, or null.

marks_endgamebooleanrequired

Whether completing this event marks the user as having reached the endgame. At most one event per version sets this.

completed_atstring · date-time | nullrequired
GameEventapplication/json
{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "translations": {
    "key": "string"
  },
  "sort_order": 0,
  "reward": {
    "total": "string",
    "bonus": "string",
    "base": "string",
    "display": {
      "type": "icon",
      "icon_url": "string",
      "position": "left"
    }
  },
  "threshold_type": "level",
  "blocked_by": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "marks_endgame": true,
  "completed_at": "2026-08-09T12:00:00Z"
}

Showing the icon variant.

GameMissionobject
idstring · uuidrequired
translationsmap<string, string>required
«key»string
rewardRewardrequired
totalstringrequired

total = bonus + base

bonusstringrequired
basestringrequired
displayoneOf · 2 variantsrequired

How the client should render the amounts, as configured for the user's currency. Falls back to a leading "$" where the app configures no rendering for that currency, and wherever there is no user to read a currency from, such as the public games catalog.

oneOfone of 2 variants, selected by type

type = "icon" RewardDisplayIcon

typestringrequired
  • = "icon"discriminator
icon_urlstringrequired
positionstring RewardDisplayPositionrequired

type = "plain" RewardDisplayPlain

typestringrequired
  • = "plain"discriminator
symbolstringrequired
positionstring RewardDisplayPositionrequired
statusstringrequired
  • not_started
  • ongoing
  • completed
joinable_untilstring · date-time | nullrequired

Until when the mission can be started, or null when unbounded.

minutes_to_completeintegerrequired

Minutes the user has to complete the mission: the full cadence window (1440 for daily) before starting, the remainder until the mission resets once started.

goalsarray of GameMissionGoalrequired
translationsmap<string, string>required
«key»string
valuenumber · doublerequired

The user's current progress toward the goal.

thresholdnumber · doublerequired

The value at which the goal completes.

completedbooleanrequired
GameMissionapplication/json
{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "translations": {
    "key": "string"
  },
  "reward": {
    "total": "string",
    "bonus": "string",
    "base": "string",
    "display": {
      "type": "icon",
      "icon_url": "string",
      "position": "left"
    }
  },
  "status": "not_started",
  "joinable_until": "2026-08-09T12:00:00Z",
  "minutes_to_complete": 0,
  "goals": [
    {
      "translations": {
        "key": "string"
      },
      "value": 0,
      "threshold": 0,
      "completed": true
    }
  ]
}

Showing the icon variant.

GameStatemap

The user's current game state keyed by value name: the latest snapshot, or every configured value at its zero state when the user has not played yet. Which field of each value is populated follows the value's configured type.

«key»GameStateValue
totalinteger · int64

A counter's or gauge's current total. Both only ever move by whole increments, so this is a whole number - exact across the full int64 range, of which a client reading it into a double can represent up to 2^53.

numbernumber · double

A number value's current value.

stringstring

A string value's current value.

booleanboolean

A boolean value's current value.

setarray of string

A set value's current elements, sorted. Always present (and empty when nothing is held) for set values.

listarray of any

A list value's current items in order, each shaped by the item schema configured for the value. Always present (and empty when nothing is held) for list values.

GameStateapplication/json
{
  "key": {
    "total": 0,
    "number": 0,
    "string": "string",
    "boolean": true,
    "set": [
      "string"
    ],
    "list": []
  }
}
GameFriendHighscoreallOf
inherited from Friend
uidstringrequired

The friend's external user id (app-scoped public identifier).

usernamestring | nullrequired

The friend's username; null when unset.

picture_urlstring | nullrequired

The friend's profile picture URL; null when unset.

highscoreintegerrequired

The friend's best result for this game (highest level for level games, highest score for highscore games).

GameFriendHighscoreapplication/json
{
  "uid": "string",
  "username": "string",
  "picture_url": "string",
  "highscore": 0
}
GameSectionenum

Which block of the games tab a game belongs to, for rendering the section headers, in the order the sections appear: test holds the test-user-only games and reaches test users only, continue_playing the games the user is part-way through, discover the rest. Responses that rank nothing for a specific user — a single game, the public catalog, a game injected into the feed — report discover.

string
  • test
  • continue_playing
  • discover
GameSectionapplication/json
"test"
Rewardobject
totalstringrequired

total = bonus + base

bonusstringrequired
basestringrequired
displayoneOf · 2 variantsrequired

How the client should render the amounts, as configured for the user's currency. Falls back to a leading "$" where the app configures no rendering for that currency, and wherever there is no user to read a currency from, such as the public games catalog.

oneOfone of 2 variants, selected by type

type = "icon" RewardDisplayIcon

typestringrequired
  • = "icon"discriminator
icon_urlstringrequired
positionstring RewardDisplayPositionrequired

type = "plain" RewardDisplayPlain

typestringrequired
  • = "plain"discriminator
symbolstringrequired
positionstring RewardDisplayPositionrequired
Rewardapplication/json
{
  "total": "string",
  "bonus": "string",
  "base": "string",
  "display": {
    "type": "icon",
    "icon_url": "string",
    "position": "left"
  }
}

Showing the icon variant.

GameMissionGoalobject
translationsmap<string, string>required
«key»string
valuenumber · doublerequired

The user's current progress toward the goal.

thresholdnumber · doublerequired

The value at which the goal completes.

completedbooleanrequired
GameMissionGoalapplication/json
{
  "translations": {
    "key": "string"
  },
  "value": 0,
  "threshold": 0,
  "completed": true
}
GameStateValueobject

One state value. Exactly one field carries the value, chosen by the type it is configured as: total for counter and gauge values, number for number values, string/boolean/set/list for the others. The fields that do not apply are omitted.

totalinteger · int64

A counter's or gauge's current total. Both only ever move by whole increments, so this is a whole number - exact across the full int64 range, of which a client reading it into a double can represent up to 2^53.

numbernumber · double

A number value's current value.

stringstring

A string value's current value.

booleanboolean

A boolean value's current value.

setarray of string

A set value's current elements, sorted. Always present (and empty when nothing is held) for set values.

listarray of any

A list value's current items in order, each shaped by the item schema configured for the value. Always present (and empty when nothing is held) for list values.

GameStateValueapplication/json
{
  "total": 0,
  "number": 0,
  "string": "string",
  "boolean": true,
  "set": [
    "string"
  ],
  "list": []
}

One state value. Exactly one field carries the value, chosen by the type it is configured as: total for counter and gauge values, number for number values, string/boolean/set/list for the others. The fields that do not apply are omitted.

ComicPartobject
indexintegerrequired

The index of the part in the comic.

versionstringrequired

The version of the part.

titlestringrequired
descriptionstringrequired
unlockedbooleanrequired

Whether the part is unlocked (already read, or the single next readable part). When false, music_url and pages are null. Pages are only ever populated by GET /v1/comics/{comic_id}/parts/{part_index}, so an unlocked part still has null pages in the list/detail/feed views.

finished_reading_atstring · date-time | nullrequired

The timestamp the user finished reading the part.

rewardRewardrequired
totalstringrequired

total = bonus + base

bonusstringrequired
basestringrequired
displayoneOf · 2 variantsrequired

How the client should render the amounts, as configured for the user's currency. Falls back to a leading "$" where the app configures no rendering for that currency, and wherever there is no user to read a currency from, such as the public games catalog.

oneOfone of 2 variants, selected by type

type = "icon" RewardDisplayIcon

typestringrequired
  • = "icon"discriminator
icon_urlstringrequired
positionstring RewardDisplayPositionrequired

type = "plain" RewardDisplayPlain

typestringrequired
  • = "plain"discriminator
symbolstringrequired
positionstring RewardDisplayPositionrequired
cover_urlstringrequired
music_urlstring | nullrequired

The URL of the music for the part. Null if the part is locked.

pagesarray of ComicPartPagesItem | nullrequired

The pages and ads of the part. Only populated by GET /v1/comics/{comic_id}/parts/{part_index} (the full part view); null in the list/detail/feed views and for locked parts.

oneOfone of 2 variants, selected by page_type

page_type = "page" ComicPartPage

page_typestringrequired
  • = "page"discriminator
indexintegerrequired

The index of the page in the part.

video_urlstringrequired

page_type = "ad" ComicPartPageAd

page_typestringrequired
  • = "ad"discriminator
inherited from Ad
slot_idstring · uuidrequired

The ad slot's id. Use it to fill the slot via PATCH/v1/ads/{id}.

typestringrequired
  • offer
  • external
lock_secondsintegerrequired

How long the ad is locked before it can be skipped.

external_sub_typestring | nullrequired

Sub-type of an external ad; null for non-external ads.

  • native
  • interstitial
  • rewarded
rating_countinteger · int64required

Number of 1-5 star ratings submitted for this part. Reported as 0 (together with rating_avg) until the part has collected at least 5 ratings, so early, unrepresentative scores are hidden.

rating_avgnumber · doublerequired

Average star rating (1.0-5.0), truncated to one decimal place. Reported as 0 until the part has collected at least 5 ratings (see rating_count).

read_time_avgnumber · doublerequired

Median time, in seconds, users spent reading this part (reads over one hour are excluded as outliers). 0 when the part has not been read yet.

ComicPartapplication/json
{
  "index": 0,
  "version": "string",
  "title": "string",
  "description": "string",
  "unlocked": true,
  "finished_reading_at": "2026-08-09T12:00:00Z",
  "reward": {
    "total": "string",
    "bonus": "string",
    "base": "string",
    "display": {
      "type": "icon",
      "icon_url": "string",
      "position": "left"
    }
  },
  "cover_url": "string",
  "music_url": "string",
  "pages": [
    {
      "page_type": "page",
      "index": 0,
      "video_url": "string"
    },
    {
      "page_type": "ad",
      "slot_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "type": "offer",
      "lock_seconds": 0,
      "external_sub_type": "native"
    }
  ],
  "rating_count": 0,
  "rating_avg": 0,
  "read_time_avg": 0
}

Showing all 2 variants of the union.

ComicFriendReadingProgressallOf
inherited from Friend
uidstringrequired

The friend's external user id (app-scoped public identifier).

usernamestring | nullrequired

The friend's username; null when unset.

picture_urlstring | nullrequired

The friend's profile picture URL; null when unset.

last_read_part_indexintegerrequired

The highest part index the friend has read in this comic.

ComicFriendReadingProgressapplication/json
{
  "uid": "string",
  "username": "string",
  "picture_url": "string",
  "last_read_part_index": 0
}
ComicPartPagesItemoneOf · 2
oneOfone of 2 variants, selected by page_type

page_type = "page" ComicPartPage

page_typestringrequired
  • = "page"discriminator
indexintegerrequired

The index of the page in the part.

video_urlstringrequired

page_type = "ad" ComicPartPageAd

page_typestringrequired
  • = "ad"discriminator
inherited from Ad
slot_idstring · uuidrequired

The ad slot's id. Use it to fill the slot via PATCH/v1/ads/{id}.

typestringrequired
  • offer
  • external
lock_secondsintegerrequired

How long the ad is locked before it can be skipped.

external_sub_typestring | nullrequired

Sub-type of an external ad; null for non-external ads.

  • native
  • interstitial
  • rewarded
ComicPartPagesItemapplication/json
{
  "page_type": "page",
  "index": 0,
  "video_url": "string"
}

Showing the page variant.

Adobject
slot_idstring · uuidrequired

The ad slot's id. Use it to fill the slot via PATCH/v1/ads/{id}.

typestringrequired
  • offer
  • external
lock_secondsintegerrequired

How long the ad is locked before it can be skipped.

external_sub_typestring | nullrequired

Sub-type of an external ad; null for non-external ads.

  • native
  • interstitial
  • rewarded
Adapplication/json
{
  "slot_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "type": "offer",
  "lock_seconds": 0,
  "external_sub_type": "native"
}