Import a game
POST /api/developer/projects/import/ — upload a build and get a play link.
POST /api/developer/projects/import/
Content-Type: multipart/form-dataAnonymous by default. Send a login token (Authorization: Bearer rbk_...) with the games:write scope to publish straight into the person's account. A login that isn't approved yet returns login_pending (403); one that was revoked or expired returns login_inactive (401).
Fields
| Field | Details |
|---|---|
bundle | Required. One browser-ready ZIP with index.html at its root. 10 MiB compressed, 50 MiB expanded, 500 entries including folders. Holds the text files, and the media too unless a session carries it. |
upload_id, upload_token | Optional, sent together: the media of a new-game upload session. |
title | 1–255 characters. name is accepted as an alias if it matches. |
description | Plain text, up to 4,000 characters. |
thumbnail | A separate PNG or JPEG, at most 2 MiB and 4096 pixels a side. Re-encoded to strip metadata. |
context | A JSON string with the fields below. Private to Rosebud. |
Without a title the game is called “Uploaded game”.
Context
All optional. Keep prompts, conversations, personal details, local paths and environment variables out of it.
| Field | Values |
|---|---|
agent_client | codex, claude-code, gemini-cli, cursor, other, unknown |
agent_version | At most 80 characters |
model_provider | openai, anthropic, google, other, unknown |
model | At most 100 characters |
use_case | learning, game-jam, prototype, portfolio, classroom, client-work, commercial, other |
framework | vanilla, phaser, three, other, unknown |
discovery_source | docs, search, github, recommendation, existing-user, other, unknown |
Response
HTTP 201, anonymous:
{
"project_id": "6f1d2c8e-...",
"play_url": "https://rosebud.ai/play/moon-garden",
"claim_url": "https://rosebud.ai/claim#<secret>",
"claim_expires_at": "2026-10-27T19:04:11Z",
"content_version": "9f2c41e0b7..."
}HTTP 201, with a login token:
{
"project_id": "6f1d2c8e-...",
"play_url": "https://rosebud.ai/play/moon-garden",
"editor_url": "https://rosebud.ai/edit/6f1d2c8e-...",
"content_version": "9f2c41e0b7...",
"claimed": true,
"owner": "sam",
"agent_token": "<agent_token>",
"connection_expires_at": "2027-01-25T18:04:11Z"
}The claim_url and agent_token are private. The agent_token is the game's update connection, already approved; use it with releases. If Rosebud publishes the game but can't add it to the account, the response falls back to the anonymous shape, so the person can still claim it.
A login token also answers key_expired (401), insufficient_scope (403, with required_scope) and invalid_key (401). See Agent logins.
Expiry
Unclaimed games expire one hour after import. At claim_expires_at the game, code and asset URLs return HTTP 410 game_expired; cleanup then permanently deletes them and they return HTTP 404. There's no late claim.
Every import creates a new game. Retrying after a lost response can create a second one.