Skip to content
ShortPlay Developer Docs

Zip format, versions, and rollback

What your zip needs to contain

The upload flow, endpoint by endpoint

  1. POST /v1/uploads/init — start an upload for a game (title + hook + tag); returns an uploadId and a uploadUrl to PUT your zip to. Rate-limited to 10 uploads per account per hour (api/src/upload.ts:64, api/src/upload-routes.ts:268-329).
  2. PUT /v1/uploads/:id/bundle — stream your zip body to that URL (api/src/upload-routes.ts:335-367).
  3. POST /v1/uploads/:id/complete — send your confirmed manifest (+ title/hook/tag); the bundle is validated (zip structure, index.html presence, size) and a draft game/version row is created. Nothing is published yet (api/src/upload-routes.ts:374-).
  4. POST /v1/games/:id/publish — promotes a draft (or a specific version, via { "version": N } in the body) to live. This is the only step that makes a game appear in the feed, and only after the next pool-rebuild cron. Publish also enforces a completeness gate: a game with no hook or no genre tag set in Details is refused with 422 details_required — the feed never shows an incomplete listing (api/src/upload-routes.ts:612-786).

Versions

Every upload after the first becomes a new version on the game's ladder — versions are immutable once promoted, and only one version is ever live at a time. You can:

Release notes

Each version can carry release notes (max 2000 characters, api/src/upload-routes.ts:1586 MAX_RELEASE_NOTES_LEN), attached at completion time and surfaced back in the version-history response. They're free text — a changelog line for players or your own record, not machine-parsed.