> For the complete documentation index, see [llms.txt](https://wiki.playgama.com/playgama/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://wiki.playgama.com/playgama/mcp/tools.md).

# Tools reference

Your client discovers the Playgama MCP server's tools automatically once connected, and the authoritative list is what the server answers to `tools/list` — this page is for knowing what to ask for, and what each tool will and will not do.

A few rules hold everywhere:

* Every tool works on **your own games** only — the ones you see in the cabinet. An id that is not yours, or a deleted game, is refused the same way an unknown one is.
* Schemas are **strict**: an argument the tool does not declare is refused by name rather than silently dropped.
* Reads are marked read-only; **every write is annotated as destructive**, so your client asks for confirmation before running it.
* Business refusals (validation, ownership, a stale checksum) come back as readable results the agent can act on, not as protocol errors.

## Launch path

### get\_launch\_steps

The game's path to players, in order — `archive`, `bridge`, `covers`, `form`, `sandbox`, `share`, `traffic` — judged by the latest archive in the game's form (`archiveId`, `null` when there is none or it could not be read). It decides nothing on its own: each step carries what the tools that own it would answer. The agent starts with this read and reads it again after each step.

`current` is the first required step still holding the path — `null` when none is.

Each step in `steps`:

| Field          | Meaning                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `id`           | The step                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `state`        | Where the step is — see below                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `reason`       | Why it is not `DONE`, as the tool that owns it says it — e.g. `NOT_FOUND` from the Bridge SDK analysis, a `publish_sandbox` refusal reason or the `get_sandbox_traffic` verdict — or `null`                                                                                                                                                                                                                                                                                                |
| `required`     | Whether the step can hold the path. `form` and `share` are not required                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `nextTools`    | The tools that move the step. Every set that offers an archive upload, and the `bridge` step's own, starts with `get_game_checklist`. `traffic` in `TODO` lists `get_sandbox_share` before `start_sandbox_traffic` — the start takes the post links; with `reason: STALE_PENDING` the lost bonus run is re-queued by a start with the same links, no new post. Empty when it is `DONE` or `CABINET`, or when `blockedBy` names a step to finish first and the step itself is not `UNKNOWN` |
| `blockedBy`    | The step to finish first, kept only while that step holds the path and has tools to call; otherwise `null`                                                                                                                                                                                                                                                                                                                                                                                 |
| `askDeveloper` | `true` on `sandbox` and `traffic` — their effect cannot be taken back, so the agent asks the developer before acting                                                                                                                                                                                                                                                                                                                                                                       |
| `emptySlots`   | `covers` only: the slots with no usable cover (`square`, `portrait`, `landscape`); absent when the covers could not be read                                                                                                                                                                                                                                                                                                                                                                |

| `state`       | Holds the path | Meaning                                                                                                                                                                                                                                                                                                                                       |
| ------------- | -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `TODO`        | Yes            | Not done yet. The form is also `TODO` (`reason` `REJECTED` or `WAITING`) when moderation sent an unchanged form back                                                                                                                                                                                                                          |
| `IN_PROGRESS` | Yes            | Under way — the archive is not unpacked yet, the share bonus run is pending or live, or a traffic start is refused `RUN_IN_PROGRESS`; poll the tool in `nextTools`                                                                                                                                                                            |
| `DONE`        | No             | Nothing left to do. `traffic` is `DONE` only once the share bonus run finished; a free run without post links does not count                                                                                                                                                                                                                  |
| `FAILED`      | Yes            | The archive could not be used (`reason: UNPACK`) — upload a corrected zip                                                                                                                                                                                                                                                                     |
| `BLOCKED`     | Yes            | Refused — `reason` says why, `blockedBy` names the step to finish first when there is one                                                                                                                                                                                                                                                     |
| `UNKNOWN`     | Yes            | A source did not answer, and nothing else: `reason` is `<SOURCE>_UNAVAILABLE` (`ARCHIVES`, `COVERS`, `SUBMISSION`, `SANDBOX` or `TRAFFIC`) and `nextTools` is `get_launch_steps` — call it again. It is neither done nor not done. A step that would be `DONE` on top of such a step is `UNKNOWN` too; the rest of the path is still answered |
| `PARTIAL`     | No             | `covers` has one or two of its three slots filled                                                                                                                                                                                                                                                                                             |
| `OUTDATED`    | No             | The live sandbox is behind the latest archive or form (`reason: CHANGED`), or the two cannot be compared (`reason: CHANGE_UNKNOWN`) — publishing again brings it up to date                                                                                                                                                                   |
| `AVAILABLE`   | No             | `share` of a live sandbox — never `DONE`, since the link can always be shared once more                                                                                                                                                                                                                                                       |
| `WAITING`     | No             | `bridge` while the Bridge SDK analysis has not answered (`reason: PENDING`). It may never answer, so the path does not wait for it — but the agent does not publish until `bridge` is `DONE`: the Bridge SDK is required for every game, the sandbox included                                                                                 |
| `CABINET`     | No             | `traffic` refused `ORG_LIMIT` or `PAYMENT_REQUIRED`: the share bonus of the game or of the organization is used, and what is left — paid traffic — is bought in the cabinet. No tools                                                                                                                                                         |

| Parameter       | Type   | Required | Description                                 |
| --------------- | ------ | -------- | ------------------------------------------- |
| `applicationId` | string | Yes      | Game id, as returned by `list_applications` |

## Games

### list\_applications

Every named game on your account, newest first — `id`, `title`, `status` and `updatedAt`. Takes paging only: no status filter and no search, so the agent matches on the rows it gets back. The order is fixed and does not change when you edit a game, so paging visits every game exactly once.

Deleted games never appear here, and neither does a game whose title was never filled in — the cabinet does not list those either.

| Parameter | Type    | Required | Description           |
| --------- | ------- | -------- | --------------------- |
| `limit`   | integer | No       | 1–100. Default 20     |
| `skip`    | integer | No       | How many rows to skip |

### create\_application

Creates a new game as a draft, the way the cabinet's **New Game** page does, and answers its `id` — the id every other tool takes.

Titles are not unique, so after a call that failed without a clear answer the agent should check `list_applications` before creating again; a duplicate draft is deleted by a human in the cabinet.

| Parameter | Type   | Required | Description                                                                                                                                                                                                                                                               |
| --------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `title`   | string | Yes      | In English — Latin letters, digits, spaces and punctuation, up to 120 characters. Players and moderators see it as-is                                                                                                                                                     |
| `engine`  | enum   | Yes      | `unity`, `construct3`, `cocos-creator`, `defold`, `godot`, `gdevelop`, `game_maker`, `scratch`, `js` (plain JavaScript, no engine)                                                                                                                                        |
| `agent`   | enum   | No       | The coding agent the game was made with, the developer's own answer: `claude-code`, `codex`, `cursor`, `kimi-code`, `grok-build`, `workbuddy`, `other`, `none` (a game written without an agent). Cabinet field "What agent and model did you use for creating this game" |
| `model`   | enum   | No       | The model behind that agent: `claude-fable`, `claude-opus`, `claude-sonnet`, `claude-haiku`, `openai-astra`, `openai-sol`, `openai-luna`, `openai-terra`, `grok`, `kimi`, `other`                                                                                         |

### get\_application

The full saved form of one game, together with the metadata of its archives and media. File contents and download links are not part of this surface.

| Parameter       | Type   | Required | Description                                 |
| --------------- | ------ | -------- | ------------------------------------------- |
| `applicationId` | string | Yes      | Game id, as returned by `list_applications` |

### update\_application\_form

Saves form fields of a game. This is a **partial save**: a field left out keeps its stored value, so the agent sends only what it means to change. Enum arrays are replaced whole. Saving does not submit anything to moderation.

| Parameter              | Type    | Required | Cabinet field                                                                                                                                                                                      |
| ---------------------- | ------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `applicationId`        | string  | Yes      | —                                                                                                                                                                                                  |
| `title`                | string  | No       | Title                                                                                                                                                                                              |
| `description`          | string  | No       | Description                                                                                                                                                                                        |
| `howToPlayText`        | string  | No       | How to play                                                                                                                                                                                        |
| `engine`               | string  | No       | Game Engine                                                                                                                                                                                        |
| `link`                 | string  | No       | Link to the game if it is published elsewhere                                                                                                                                                      |
| `isHorizontal`         | boolean | No       | Screen Orientation — landscape                                                                                                                                                                     |
| `isVertical`           | boolean | No       | Screen Orientation — portrait                                                                                                                                                                      |
| `leaderboards`         | boolean | No       | Game Features — leaderboards                                                                                                                                                                       |
| `multiplayer`          | boolean | No       | Game Features — multiplayer                                                                                                                                                                        |
| `social`               | boolean | No       | Game Features — social                                                                                                                                                                             |
| `distributeEverywhere` | boolean | No       | Distribution — publish on all partner platforms                                                                                                                                                    |
| `excludedPlatforms`    | array   | No       | Distribution — platforms to exclude                                                                                                                                                                |
| `supportedLanguages`   | array   | No       | Game Languages                                                                                                                                                                                     |
| `supportedDevices`     | array   | No       | Supported Devices — `IOS`, `ANDROID`, `DESKTOP`                                                                                                                                                    |
| `agent`                | enum    | No       | What agent and model did you use for creating this game — the agent: `claude-code`, `codex`, `cursor`, `kimi-code`, `grok-build`, `workbuddy`, `other`, `none`                                     |
| `model`                | enum    | No       | The same field — the model behind that agent: `claude-fable`, `claude-opus`, `claude-sonnet`, `claude-haiku`, `openai-astra`, `openai-sol`, `openai-luna`, `openai-terra`, `grok`, `kimi`, `other` |

The accepted values of the enum arrays are published to your client in the tool schema, so the agent sees the current list without guessing. For what each field means to a moderator, see [Submitting a game](/playgama/submitting-a-game.md).

Covers, screenshots and archives are **not** form fields here: covers have their own tools, and other assets are not on this surface at all.

### get\_submission\_state

Whether the game can be submitted to moderation right now and, when it cannot, why: missing certification, a cooldown after a failed moderation, the state of the build being judged (the build check's own reason codes, or `ARCHIVE_CHECKING` while it runs), a banned organization, or nothing changed since the last submit.

The verdict is always about a build: name the archive you are asking about. There is no default.

Submitting itself is not available through MCP — a human does it in the cabinet.

| Parameter       | Type   | Required | Description                                                                                                                                                                           |
| --------------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `applicationId` | string | Yes      | Game id                                                                                                                                                                               |
| `archiveId`     | string | **Yes**  | The build the verdict judges — the archive a submit would freeze. `get_application` and `get_launch_steps` answer the game's archives; an archive of another game is refused with 404 |

### list\_moderation\_comments

The moderation correspondence on a game, newest first, grouped by moderation task. Read-only: replying to moderation is not part of this surface.

| Parameter       | Type   | Required | Description |
| --------------- | ------ | -------- | ----------- |
| `applicationId` | string | Yes      | Game id     |

## Game builds

Uploading a build is three steps, and the bytes never travel through MCP: the agent gets a presigned URL, performs the upload itself, then confirms.

{% hint style="info" %}
**start → PUT → confirm → poll.** The upload URL is valid for one hour and is signed for exactly the byte length and content type you declared, so the storage refuses anything else. Nothing is in the game's form until the confirm.
{% endhint %}

### start\_archive\_upload

Step 1 of 3. Creates an archive record for the game and answers `uploadUrl` and `headers` — PUT the zip to it with exactly those headers:

```bash
curl -T game.zip -H "Content-Type: application/zip" "<uploadUrl>"
```

The zip must meet the [Game checklist](/playgama/mcp/game-checklist.md): read it with `get_game_checklist` and check the game and the zip against each item before this call.

| Parameter       | Type    | Required | Description                                                                                                                                                                             |
| --------------- | ------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `applicationId` | string  | Yes      | Game id                                                                                                                                                                                 |
| `name`          | string  | Yes      | Up to 200 characters. Put the build version in it, e.g. `coin-town-1.4.2` — the form keeps every archive, and the version is how a human tells them apart. A trailing `.zip` is dropped |
| `contentSize`   | integer | Yes      | Exact size of the zip in bytes (`wc -c < game.zip`). At most 300 MB                                                                                                                     |

### confirm\_archive\_upload

Step 3 of 3: tells the cabinet the PUT has finished. The archive is added to the game's form and queued for unpacking and Bridge SDK analysis. Archives already in the form stay there — removing one is a human action in the cabinet.

Refused with 409 while nothing is stored at the upload URL. Safe to repeat: once processing has run, a repeat only answers the current state.

| Parameter       | Type   | Required | Description                           |
| --------------- | ------ | -------- | ------------------------------------- |
| `applicationId` | string | Yes      | Game id                               |
| `archiveId`     | string | Yes      | As answered by `start_archive_upload` |

### get\_archive\_status

The state of one archive. Unpacking and the build check take a minute or more, so the agent polls this until `state.status` is no longer `CHECKING`, or until `processing` is `FAILED` (upload a corrected zip — a broken zip is never checked).

| Field          | Meaning                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `state`        | The build check. `status` — `CHECKING` while it runs, then `PASSED`, `PROBLEM` or `NOT_CHECKED`; `reason` — the code; `message` — what is wrong and what to do, to be given to the developer word for word on `PROBLEM` or `NOT_CHECKED`. Only a `PASSED` build is published to the sandbox or submitted to moderation                                                                                                                                                                                                                                                                               |
| `processing`   | `PENDING` while the upload is unconfirmed or being unpacked; `DONE` once unpacked; `FAILED` if the zip could not be used                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `failedAt`     | `UNPACK` when `processing` is `FAILED`, otherwise `null`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `bridgeSdk`    | Whether that same check found the Playgama Bridge SDK in the build. `FOUND`; `NOT_FOUND` — the SDK was not detected: tell the developer and point them to the certification link from `get_archive_qa_tool_link` (its Build Startup section shows why the SDK did not initialize), and `get_bridge_sdk_docs` has the integration docs. The Bridge SDK is required for every game, the sandbox included: fix the integration and upload a new archive; `PENDING` — the check has not answered yet. Sandbox traffic is what needs `bridgeSdk: FOUND`; publishing and submitting are decided by `state` |
| `errorMessage` | Why it failed                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `inForm`       | Whether the archive is in the game's form                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `analysis`     | What the check measured — `bridgeVersion` and `bridgeEngine`, read from the same check `state` comes from; `null` when no check has run                                                                                                                                                                                                                                                                                                                                                                                                                                                              |

| Parameter       | Type   | Required | Description |
| --------------- | ------ | -------- | ----------- |
| `applicationId` | string | Yes      | Game id     |
| `archiveId`     | string | Yes      | Archive id  |

## Covers

The form has three cover slots, and each takes an image of exactly that size — resize before uploading:

| Slot        | Size        |
| ----------- | ----------- |
| `square`    | 800 × 800   |
| `portrait`  | 1080 × 1920 |
| `landscape` | 1920 × 1080 |

### start\_cover\_upload

Step 1 of 3, one slot per call. Answers `mediaId`, `uploadUrl` and `headers`:

```bash
curl -T cover.png -H "Content-Type: image/png" "<uploadUrl>"
```

| Parameter       | Type    | Required | Description                                                          |
| --------------- | ------- | -------- | -------------------------------------------------------------------- |
| `applicationId` | string  | Yes      | Game id                                                              |
| `cover`         | enum    | Yes      | `square`, `portrait`, `landscape`                                    |
| `format`        | enum    | Yes      | `png` or `jpeg` — checked against the bytes on confirm               |
| `contentSize`   | integer | Yes      | Exact size of the file in bytes (`wc -c < cover.png`). At most 10 MB |

### confirm\_cover\_upload

Step 3 of 3. The file is checked — it must be the format the upload was started as, exactly the size of its slot, and a complete, decodable image — and then put into the form **in place of** the cover that was there; `replaced` names what it took out.

Refused with 409 while nothing is stored at the upload URL, and with 422 when the file does not fit (with the reason — upload a corrected file with a new `start_cover_upload`). Safe to repeat: a confirmed cover only answers its state.

| Parameter       | Type   | Required | Description                         |
| --------------- | ------ | -------- | ----------------------------------- |
| `applicationId` | string | Yes      | Game id                             |
| `mediaId`       | string | Yes      | As answered by `start_cover_upload` |

## In-app catalog

{% hint style="warning" %}
`replace_in_app_products` is a **whole-state write**, not a patch: a product left out is deleted, and an empty list clears the catalog. The agent must call `list_in_app_products` first and pass its `checksum` back — if someone edited the catalog in the browser meanwhile, the call is refused instead of deleting their work.
{% endhint %}

### list\_in\_app\_products

The catalog of a game as currently saved, plus the `checksum` naming that exact state. Each product comes back in exactly the fields a replace accepts, so the answer can be sent straight back with one field changed.

| Parameter       | Type   | Required | Description |
| --------------- | ------ | -------- | ----------- |
| `applicationId` | string | Yes      | Game id     |

### replace\_in\_app\_products

Replaces the whole catalog with the list passed in. The form's "has in-game purchases" flag travels with it: leave `hasInGamePurchases` out and it follows whether the list is empty. Turning purchases on with an empty catalog is refused.

| Parameter            | Type    | Required | Description                                                               |
| -------------------- | ------- | -------- | ------------------------------------------------------------------------- |
| `applicationId`      | string  | Yes      | Game id                                                                   |
| `products`           | array   | Yes      | The complete catalog after the change                                     |
| `expectedChecksum`   | string  | Yes      | The `checksum` `list_in_app_products` answered — the state being replaced |
| `hasInGamePurchases` | boolean | No       | Defaults to whether `products` is non-empty                               |

Each product:

| Field         | Type   | Required | Description                      |
| ------------- | ------ | -------- | -------------------------------- |
| `productId`   | string | Yes      | Stable id, unique in the catalog |
| `title`       | string | Yes      | —                                |
| `description` | string | No       | —                                |
| `type`        | enum   | Yes      | `consumable` or `non_consumable` |
| `priceUsd`    | number | Yes      | Price in USD, at most 2 decimals |

## Leaderboards

Deleting a leaderboard is not available through MCP — it takes its scores with it and cannot be undone, so it stays a human action in the cabinet.

### list\_leaderboards

The leaderboards configured for a game.

| Parameter       | Type   | Required | Description |
| --------------- | ------ | -------- | ----------- |
| `applicationId` | string | Yes      | Game id     |

### create\_leaderboard

Adds a leaderboard to a game. `id` is the tag the game passes to the [Playgama Bridge SDK](/playgama/bridge-sdk/api/leaderboards.md).

| Parameter       | Type    | Required | Description                         |
| --------------- | ------- | -------- | ----------------------------------- |
| `applicationId` | string  | Yes      | Game id                             |
| `id`            | string  | Yes      | Leaderboard tag, e.g. `top_players` |
| `name`          | string  | Yes      | —                                   |
| `type`          | enum    | Yes      | `numeric` or `time`                 |
| `scoreOrder`    | enum    | No       | `desc` or `asc`                     |
| `decimals`      | integer | No       | —                                   |

### update\_leaderboard

Changes the name, type or score order of an existing leaderboard. At least one of them is required.

| Parameter       | Type   | Required | Description         |
| --------------- | ------ | -------- | ------------------- |
| `applicationId` | string | Yes      | Game id             |
| `leaderboardId` | string | Yes      | The leaderboard tag |
| `name`          | string | No       | —                   |
| `type`          | enum   | No       | `numeric` or `time` |
| `scoreOrder`    | enum   | No       | `desc` or `asc`     |

## QA Tool

Both tools hand out a link for you to open in a browser. Ask for the link every time rather than building it by hand — the cabinet's address depends on the deployment.

### get\_archive\_qa\_tool\_link

The link that opens an uploaded archive in the Playgama QA Tool, where you play the build inside the Bridge SDK harness and submit it to moderation. The page has something to show once the archive is unpacked (`processing` is `DONE`). With `mode: certification` the link opens the certification page instead — the one to hand out for an archive with `bridgeSdk: NOT_FOUND`: its Build Startup section shows why the Bridge SDK did not initialize, and `get_bridge_sdk_docs` has the integration docs. Opening it unlocks nothing; after the fix, upload a new archive.

Answers `url`, `processing`, `failedAt` and `bridgeSdk`, as `get_archive_status` does.

| Parameter       | Type   | Required | Description                                                                                            |
| --------------- | ------ | -------- | ------------------------------------------------------------------------------------------------------ |
| `applicationId` | string | Yes      | Game id                                                                                                |
| `archiveId`     | string | Yes      | Archive id                                                                                             |
| `mode`          | string | No       | `certification` — the only value; anything else is refused. Leave it out for the ordinary testing page |

### get\_local\_game\_qa\_tool\_link

A link that opens the QA Tool on a game you are serving yourself — typically a dev server on `localhost`. Use it to test before uploading anything.

| Parameter   | Type   | Required | Description                                                                                                                                                                    |
| ----------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `url`       | string | Yes      | Absolute http(s) URL of the game's index page, e.g. `http://localhost:5503/`                                                                                                   |
| `sessionId` | string | No       | Keys the QA Tool's `localStorage`: letters, digits, `-` and `_`, up to 64. Leave it out for a fresh environment every time; pass your own key to keep saved state between runs |

## Bridge SDK documentation

### get\_bridge\_sdk\_docs

The live [Playgama Bridge SDK](/playgama/bridge-sdk/getting-started.md) documentation from this wiki, for integrating the SDK — required in every game before its first upload, the sandbox included — and for fixing it when an archive answered `bridgeSdk: NOT_FOUND` or traffic was refused with `NO_BRIDGE`. It reads the wiki, not your games.

Without `page` it answers the index: `pages`, one `{ page, title, required, description? }` per page of the Bridge SDK section. With `page` it answers that page's `page`, `title`, `url` and `markdown`. With `engine` too, the markdown is cut to that engine's tabs when the page has tabs and one matches; `engineFilter` says which tabs the page had (`tabsFound`) and which were kept (`tabsKept`). An unknown `page` is refused with the list of valid ids.

| Parameter | Type   | Required | Description                                                                                                                                                                                                                                                                                   |
| --------- | ------ | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `page`    | string | No       | Page id from the index, e.g. `api/storage` or `api/advertisement/rewarded`. A link copied from a wiki page works as-is — with or without `.md`, with or without an anchor (the anchor is ignored; the whole page comes back). Up to 200 characters. Leave it out for the index                |
| `engine`  | string | No       | Engine or binding to keep code samples for, matched against the page's tab titles — e.g. `Plain JS`, `Unity`, `Construct 3`, `GDevelop`, `Godot` (matches both 3.x and 4.x), `GameMaker`, `Defold`, `Cocos Creator`, `Scratch`. Up to 200 characters. Leave it out to keep every engine's tab |

### get\_game\_checklist

The live [Game checklist](/playgama/mcp/game-checklist.md) from this wiki: what a game and its archive must meet to go up on Playgama — the required Bridge steps in order, the build requirements and tips. The agent reads it before integrating the Bridge SDK and before every `start_archive_upload`, checks the game and the zip against each item, fixes what fails before the upload, and tells you which items it could not check itself. It reads the wiki, not your games.

Without `page` it answers the checklist itself: `title`, `url`, `markdown`, and `pages` — the pages nested under the checklist, one `{ page, title, required, description? }` each (none yet). With `page` it answers that page's `page`, `title`, `url` and `markdown`. A link to a Bridge SDK page is not this tool's — pass it to `get_bridge_sdk_docs` as its `page`, as written; here it is refused with the list of valid ids.

| Parameter | Type   | Required | Description                                                                                                                                                                                                       |
| --------- | ------ | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `page`    | string | No       | Id of a nested page from `pages`. A link copied from the wiki works as-is — with or without `.md`, with or without an anchor (the anchor is ignored). Up to 200 characters. Leave it out for the checklist itself |

## Sandbox

A **sandbox** is a public page where anyone with the link plays the build you uploaded — no submit, no certification, no moderation, no partner platform. One sandbox per game, and its address never changes, so re-publishing keeps the players' saved progress.

{% hint style="danger" %}
`publish_sandbox` puts the game in front of anyone with the link **immediately**, and `start_sandbox_traffic` starts an ad campaign that sends players there and **cannot be undone**. They are the only writes on this surface whose effect is visible outside the cabinet, which is why each has a line of its own on the consent page you see when you connect an agent. Tell your agent to ask before calling either.
{% endhint %}

Publishing is refused when the archive failed to unpack, while it is unpacking, when its build check has not passed or has not answered yet, when the build runs a Playgama Bridge older than **2.2.0** or its version could not be read, when the game has no title, when the sandbox was blocked, and after **3 publications in a rolling hour**. `get_sandbox_state` gives the same verdict in advance.

### get\_sandbox\_state

What is on the game's sandbox right now: the link, the status (`ACTIVE` or `BLOCKED`) and the live revision — its archive, the title it was published under, and when. `site` is `null` when the game has never been published to a sandbox.

Pass `archiveId` and the answer also carries a `publish` verdict for that archive:

| Field            | Meaning                                                                                                                                                                                                     |
| ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `allowed`        | Whether `publish_sandbox` would go through                                                                                                                                                                  |
| `reason`         | When it would not: `ARCHIVE_FAILED`, `ARCHIVE_PENDING`, `BRIDGE_VERSION_OUTDATED`, `BRIDGE_VERSION_UNKNOWN`, `NO_TITLE`, `BLOCKED`, `RATE_LIMITED`, plus the build check's own codes and `ARCHIVE_CHECKING` |
| `message`        | The words of that refusal, the same ones the publish answers                                                                                                                                                |
| `changeStatus`   | `CHANGED` — publishing writes a new revision; `UNCHANGED` — the same thing is already live; `UNKNOWN` — cannot be told, and never refuses                                                                   |
| `archiveChanged` | Whether that archive differs from the one on the page                                                                                                                                                       |
| `failedAt`       | With `ARCHIVE_FAILED`: `UNPACK`                                                                                                                                                                             |

Upload the covers **before** publishing: the preview of a shared link is cached by whoever opens it first, and nobody can refresh it afterwards. A missing cover never refuses a publish; `get_launch_steps` names the empty slots in `emptySlots`.

This is also the check-up read after a publish whose answer never arrived: `UNCHANGED` means it landed, `CHANGED` means it did not.

| Parameter       | Type   | Required | Description                                                                      |
| --------------- | ------ | -------- | -------------------------------------------------------------------------------- |
| `applicationId` | string | Yes      | Game id                                                                          |
| `archiveId`     | string | No       | An archive of this game. When given, the answer also carries the publish verdict |

### get\_sandbox\_share

The ready post and share links for the game's **live** sandbox: `text`, the post (the live title and the link), and `links` — one per network, `x`, `threads`, `facebook`, `linkedin`, `reddit` — each with its `url` and `prefillsText`. Facebook takes only the link, so the developer pastes the text. `share` is `null` when the sandbox is not published or is blocked.

For the [share bonus](#sandbox-traffic), a post on any platform counts; these links are shortcuts.

Hand out the links as given — never build them by hand.

| Parameter       | Type   | Required | Description |
| --------------- | ------ | -------- | ----------- |
| `applicationId` | string | Yes      | Game id     |

### publish\_sandbox

Publishes an archive to the game's sandbox page. The archive must be in the game's form and unpacked (`get_archive_status` says `processing: DONE`), and the game must have a title. The archive must also have passed its build check (`state.status: PASSED` in `get_archive_status`): a `PROBLEM`, a `NOT_CHECKED` or a check still running is refused, and the refusal carries the check's own reason code and its message, which the agent relays word for word. The build must also run **Playgama Bridge 2.2.0 or newer**: an older one is refused with `BRIDGE_VERSION_OUTDATED`, and one whose version the check could not read with `BRIDGE_VERSION_UNKNOWN`. `get_sandbox_state` with the same `archiveId` answers those refusals before this call. The Playgama Bridge SDK is required for every game, the sandbox included, and a build it was not detected in does not pass the check: hand the developer the `get_archive_qa_tool_link` certification link, fix the integration with the docs from `get_bridge_sdk_docs` and upload a new archive.

Answers `outcome`: `PUBLISHED` — a new revision is live; `UNCHANGED` — the same archive and the same form were already published, nothing was written and the link is the same one. A repeat after a failed or lost answer is therefore safe: it never creates a second revision of the same thing.

Take the link from `url` in the answer and hand it to the developer — never build it by hand.

After a publish, the agent is told to call `get_sandbox_share` and offer the developer the post and links.

| Parameter       | Type   | Required | Description                                                                                                                                                                                 |
| --------------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `applicationId` | string | Yes      | Game id                                                                                                                                                                                     |
| `archiveId`     | string | Yes      | An archive of this game, in its form, unpacked and past its build check (`processing: DONE` and `state.status: PASSED`), built on Playgama Bridge 2.2.0 or newer (`analysis.bridgeVersion`) |

A refusal carries `reason`; `ARCHIVE_FAILED` also carries `failedAt`:

| `reason`                          | Status | What to do                                                                                                                                                                   |
| --------------------------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ARCHIVE_PENDING`                 | 409    | The archive is still being unpacked — poll `get_archive_status` and try again. If `get_archive_status` already says `DONE`, this archive cannot be served — upload it again  |
| `ARCHIVE_FAILED`                  | 409    | `failedAt: UNPACK` — the zip could not be used, upload a corrected one                                                                                                       |
| the build check's own reason code | 409    | The check reports a problem with the build, or could not check it. The refusal carries the check's `message`: relay it word for word, fix the build and upload a new archive |
| `ARCHIVE_CHECKING`                | 409    | The build check has not answered yet — poll `get_archive_status` until `state.status` leaves `CHECKING`                                                                      |
| `BRIDGE_VERSION_OUTDATED`         | 409    | The build runs a Playgama Bridge older than 2.2.0; the message names the version found. Update the SDK (`get_bridge_sdk_docs`) and upload a new archive                      |
| `BRIDGE_VERSION_UNKNOWN`          | 409    | The check could not read the build's Bridge version. Make sure the game uses Playgama Bridge 2.2.0 or newer and upload the archive again                                     |
| `NO_TITLE`                        | 422    | The game has no title                                                                                                                                                        |
| `BLOCKED`                         | 403    | The sandbox was blocked                                                                                                                                                      |
| `RATE_LIMITED`                    | 429    | 3 publications in the rolling hour already                                                                                                                                   |

## Sandbox traffic

A published sandbox is playable by anyone with the link, but nobody has the link yet. These two tools bring it players: one start creates an advertising campaign in the Playgama DSP, with banners cut from the game's covers, pointed at the sandbox page. The cabinet's game page has the same button in its Sandbox block.

**Free traffic is a share bonus.** The developer posts about the game on any platform, and `start_sandbox_traffic` takes one to three HTTPS links to those public posts in `postUrls` — one is enough, and more posts do not multiply the boost. `get_sandbox_share` has the ready post and share links. The bonus is once per game, for up to three games per organization over its lifetime; earlier free launches without sharing do not use it. Paid traffic is available in the cabinet; MCP does not purchase it.

The agent reads how long a boost serves and how many bonuses are left (`durationDays`, `remainingFreeRuns`) from the `offer` of `get_sandbox_traffic`, and describes a free boost without quoting `budgetUsd`.

Before a start can go through, the game needs a published sandbox, covers in the live revision, and a live build in which the Bridge SDK was found. `verdict` checks that eligibility, campaign capacity included; the start also validates the post links. Earlier free or paid campaigns can run alongside the share bonus.

### get\_sandbox\_traffic

Whether traffic can be brought to the game's sandbox right now, the package on offer, and the runs so far.

| Field     | Meaning                                                                                                                                                                                                                                                                                                                                                                            |
| --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `verdict` | `allowed` — whether the game is eligible now — and `reason` when it is false: the very refusal `start_sandbox_traffic` would give. Post links are not part of it; the start checks them                                                                                                                                                                                            |
| `offer`   | `kind` `FREE` while the game's share bonus is unused, `PAID` after; `available` — true only for a free bonus that can start now; `remainingFreeRuns` — share bonuses left to the organization, lifetime; `durationDays` — how long one free boost serves; `budgetUsd` — internal accounting, not a figure to quote; `priceUsd` (`null` for the free bonus) and `expectedGameplays` |
| `current` | The run in progress — `PENDING` while the campaign is being created, `RUNNING` while it serves — or `null`. It can be another campaign than the one the agent started                                                                                                                                                                                                              |
| `runs`    | The history, newest first                                                                                                                                                                                                                                                                                                                                                          |

Each run carries `id`, `kind`, `status` (`PENDING`, `RUNNING`, `FINISHED`, `FAILED`), `failureReason` when it failed, `postUrls` — the post links submitted with it, empty for earlier free runs without sharing and for paid runs — `creativeCount`, `budgetUsd`, `startsAt` and `endsAt`, and `spentRatio` — the share of the budget the DSP reports spent, 0 to 1, `null` until the DSP was first asked. `spentFinal` becomes true once the figure is no longer expected to change.

| `reason`           | What it means                                                                                                                                                                                                                                                        |
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `DSP_DISABLED`     | Traffic is not available on this deployment                                                                                                                                                                                                                          |
| `NO_SITE`          | The game was never published to its sandbox — call `publish_sandbox` first                                                                                                                                                                                           |
| `BLOCKED`          | The sandbox is blocked                                                                                                                                                                                                                                               |
| `NO_COVERS`        | The live revision has no covers — upload covers and publish again, the banners are cut from them                                                                                                                                                                     |
| `ANALYSIS_PENDING` | The analysis of the live build has not answered yet — ask again shortly                                                                                                                                                                                              |
| `NO_BRIDGE`        | The Playgama Bridge SDK was not detected by the analysis of the live build — traffic goes only to games the ad network can serve; `get_bridge_sdk_docs` has the integration docs. A build the SDK was detected in is not refused, whatever the analysis run ended as |
| `RUN_IN_PROGRESS`  | A share run is already pending or live, a paid launch is pending, or campaign capacity is full                                                                                                                                                                       |
| `PAYMENT_REQUIRED` | The game's share bonus is used — paid traffic is offered in the cabinet                                                                                                                                                                                              |
| `ORG_LIMIT`        | The organization has used its three share bonuses, lifetime; earlier free runs without sharing do not count                                                                                                                                                          |

| Parameter       | Type   | Required | Description |
| --------------- | ------ | -------- | ----------- |
| `applicationId` | string | Yes      | Game id     |

### start\_sandbox\_traffic

Starts the free boost. **It spends the run's budget over its window and cannot be undone** — ask the developer before calling it. The post links are posts the developer has already published: the agent asks the developer to paste their links and never invents one.

Answers `run`, the `PENDING` run with its `id` and the stored `postUrls`; the campaign is created in the background. Poll `get_sandbox_traffic`, find that `run.id` in `runs` and follow it until it leaves `PENDING` — `RUNNING`, or `FAILED` with `failureReason`; `current` may name another campaign. Starting again after a failed run is safe: a failed run gives the bonus back. Repeating the call while the run is pending or live answers `RUN_IN_PROGRESS` and creates nothing; a stale `PENDING` share run is requeued with the same id and post links, without another bonus.

| Parameter       | Type             | Required | Description                                                                                                                                                                                                                                                                                                                      |
| --------------- | ---------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `applicationId` | string           | Yes      | Game id                                                                                                                                                                                                                                                                                                                          |
| `postUrls`      | array of strings | Yes      | 1–3 different HTTPS links to public posts on any platform, at most 2048 characters each. Only the URL syntax and duplicates are checked. The developer publishes the post first; one is enough. Links are normalized and checked for syntax — a profile or a link from another network is refused; their content is not verified |

A refusal carries `reason`: the one `get_sandbox_traffic` shows in advance, or one of the post-link refusals, which the read cannot show. An array outside 1–3 items or a link over 2048 characters is refused by the input schema, and the exact same link twice by input validation, before these checks.

| `reason`           | Status | What to do                                                                                                       |
| ------------------ | ------ | ---------------------------------------------------------------------------------------------------------------- |
| `SHARE_REQUIRED`   | 422    | No post links — share the game and pass 1–3 public post links                                                    |
| `INVALID_POST_URL` | 422    | A link is not a valid HTTPS URL (no credentials or custom port), or the same link is given twice — fix the links |
