HTTP API
Create games, push versions and read creator analytics from any language with a Studio API key.
The HTTP API is how a script, a CI job or a tool you build creates games and pushes versions without the Studio. Every route is rooted at https://remix.gg/api/v1 and authenticated with a Studio API key. The API console is where you create keys, and it shows live request and response examples.
Authentication
Create a key on the API console and pass it as a bearer token:
Authorization: Bearer sk_live_your_api_key_here
Content-Type: application/json
A key acts as you. Keep it out of client-side code and out of game code.
Rate Limit
All requests made with one key share a 60-request token bucket that refills at one request per second. A 429 response includes Retry-After.
Games
GET /games
Lists the games you own.
{
"games": [
{
"id": "cm3abc123",
"name": "My Awesome Game",
"appImageUrl": "https://…/app-icon.webp",
"createdAt": "2025-10-23T10:30:00.000Z",
"updatedAt": "2025-10-23T11:45:00.000Z",
"liveVersionId": "cm3xyz456"
}
]
}
POST /games
Creates a game from a complete HTML document.
| Body field | Required | Meaning |
|---|---|---|
name | yes | 5 to 25 characters, unique for your account. |
code | yes | The whole HTML document. |
presentation | no | The remix.json presentation block; target labels the game mobile or desktop. |
lifecycle, levelCount | no | "scored", "levels" or "custom", and the level total (5 to 99) for level games. |
leaderboards, achievements | no | The declaration blocks from remix.json, synced the same way a CLI publish syncs them. |
curl -X POST "https://remix.gg/api/v1/games" \
-H "Authorization: Bearer sk_live_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"name": "My Awesome Game",
"code": "<!doctype html>…",
"presentation": { "target": "mobile" },
"lifecycle": "scored",
"leaderboards": [{ "key": "best-taps", "name": "Best Taps", "operator": "best" }]
}'
Responds 201 with { "game": { "id", "name", "createdAt" } } plus leaderboardSync and achievementSync blocks listing what was created, updated, disabled or ignored, with warnings. A duplicate name is a 400.
An achievement icon is kept only when it is the URL of an image already hosted with this game; Remix Desktop and the CLI host files under assets/ when they publish. Any other value shows the default badge and returns a warning.
POST /games/:id/versions
Uploads a new version of the game's code. Uploads overwrite the latest unpublished version; if the latest version is already live, a new draft is created. Every upload clears the previous version's checks, so the new code is checked again before it can launch.
| Body field | Required | Meaning |
|---|---|---|
code | yes | The whole HTML document for this version, up to 2 MB. |
presentation, levelCount | no | As on create; lifecycle is read on create only. A desktop game's type is read from the build at each launch; a launched Levels game stays Levels and its level count cannot shrink. |
leaderboards, achievements | no | The declaration blocks from remix.json; immutable fields on existing keys are ignored with a warning. |
Responds 201 with { "success": true, "version": { "id", "title", "createdAt" } } plus the same sync blocks as create.
Analytics
Both routes require the key of the game's creator and accept optional start_date and end_date query parameters in YYYY-MM-DD (UTC, inclusive).
GET /games/:id/leaderboard
The top 100 unique players on the game's main score board, ranked by best score. With dates, it lists the players whose best score was set in that range.
{
"game_id": "cm3abc123",
"period": { "start_date": "2026-04-01", "end_date": "2026-04-30" },
"leaderboard": [
{ "rank": 1, "score": 12800, "achieved_at": "2026-04-15T12:30:00.000Z",
"user": { "id": "user_123", "username": "player_one", "pfp": "https://…" } }
]
}
GET /games/:id/scores
Aggregate play activity, overall and per platform.
{
"game_id": "cm3abc123",
"period": { "start_date": null, "end_date": null },
"metrics": {
"plays": 180,
"qualified_plays": 142,
"completed_plays": 96,
"total_seconds": 12450
},
"platforms": [
{
"platform": "web",
"plays": 180,
"qualified_plays": 142,
"completed_plays": 96,
"total_seconds": 12450
}
]
}
Errors
Every error is { "error": string } with an optional details. 401 is a missing or invalid key, 403 is a key that does not own the game, an account without API access, or a suspended account, 404 is an unknown game, 400 is a malformed body or query, 429 is the rate limit.