← Documentation

Platform capabilities

Choose the parts your game needs: static hosting works without a backend or SDK. Platform account features remain in the host UI; game services are exposed through scoped SDK APIs.

Publishing and discovery

  • Create a game page with title, summary, Markdown description, cover, screenshots and genre tags. Upload static HTML, JavaScript, CSS, WASM and engine data through a folder or ZIP in the dashboard, or an exported folder through the CLI.
  • Builds are immutable, isolated origins. Uploads create drafts; publish explicitly after previewing. Publish an earlier retained build to roll back the browser client. Build rollback does not rewind databases, private objects or server code.
  • Public games enter discovery after publication. Unlisted games are available by link. Private games and draft previews require owner or named-tester access. A shared link is not an access grant.
  • Web engine exports can declare entrypoint, engine/version, threaded execution and startup mode. Unity and Godot integrations have separate installation instructions; no Unreal integration or web-export compiler is currently supplied.

Publishing quickstart · Engine plugins and supported exports

Server, database and object storage

An optional, on-demand Node.js backend runs in a game-isolated Fly Firecracker Machine. Use npm bundle-compatible dependencies and your own timers, rooms, matchmaking rules, small persistent world or HTTP handlers. There is one process per game in v1, not one per match.

One game-scoped D1 database holds structured player or world data; a private R2 namespace holds larger assets, snapshots, replays and uploads shared across worlds. Inkwell’s own account/control data is separate. Neither D1 nor private R2 is directly exposed to browser games.

Generic networking provides reliable messages, optional unreliable delivery, actions and HTTP. Transport capability reporting distinguishes native datagrams from fallback. The internal server tunnel uses TCP; no end-to-end UDP or automatic simulation/prediction is promised.

Connected players—including idle players—retain a backend. After the last player leaves or their lease expires, a five-minute grace period precedes shutdown. Save durable changes during play, then restore on startup. Timers are not an always-on scheduled-job service.

Game secrets can be entered in the dashboard or imported from an env file with the CLI. Values stay in the per-game Fly secret vault and appear in server process.env on a subsequent boot; lists reveal names only. Public outbound requests are allowed. Do not upload secret files or put credentials in client bundles.

Server and save examples · Server API · D1/R2 API

Game services

  • Game chat: default and creator-defined channels, bounded history, reconnect/catch-up, directed in-game recipients, server announcements, removal and clearing. Game chat is not a platform DM or an authorization boundary for rooms.
  • Leaderboards: named boards, ascending/descending scores, keep-best/forced updates, global/friends/nearby/selected-player queries, public titles and creator write/read policies.
  • Achievements: persistent account unlocks, progress linked to stats, translated titles/descriptions, hidden milestones, icons, notifications, completion summaries and visible cross-game reads.
  • Stats: integer, float and average-rate values; bounds, increment and server-write policies; aggregates and history. These are platform game-service records, separate from your custom D1 tables.
  • Offline support: opt-in cached stat/achievement reads and queued supported writes on the platform origin. Not asset downloading or a general offline queue for every API.
  • Player identity and presence: safe public profiles, guest status, current player counts and friends playing this game. Backend presence reads the same current-game roster without a viewer-specific friends list.

Guests can play and use supported chat/backend features; persistent account achievements and leaderboard submissions require sign-in. Browser actions remain subject to the game’s policies. Backend-only writes make the server the authority, not an automatic anti-cheat system.

Social and sharing

Platform players can favourite games, write reviews, follow creators, request/accept/remove friends, exchange friend-only direct messages, receive notifications, block accounts and report content. These actions operate in the platform UI and authenticated account API, not as unrestricted iframe SDK permissions.

Share on a game page or play page provides the canonical game-page link. It does not include private preview credentials, per-session tokens or creator-specific world state. Browser clipboard restrictions can require manually copying the selected link.

Friend invitations connect the platform-owned friend picker, notification delivery, recipient-only acceptance and optional creator context hooks. The default opens the published game; an invite never grants access to a private game. See the invitation contract and verify matching SDK/platform release availability before using newly integrated hooks.

Creator analytics

The creator dashboard combines session/play activity, game completion, loading signals, SDK custom events and optional aggregate browser performance samples. Use this to inspect engagement and startup/runtime problems. Private analytics require the game owner’s approved creator session or key.

GET /api/v1/games/:slug/analytics?days=30 reads creator analytics. Game SDK events are scoped by the host session; never use telemetry as proof of legitimate scores or entitlement. Performance collection is opt-in and does not upload raw traces, resource URLs or hardware fingerprints.

Event API · Performance API

Identity, access and moderation

Game management, deployments, private analytics and key creation require approved creator access. Private game and draft access is enforced by the platform gateway, not merely a hidden URL. Named testers can preview without receiving deployment or secret access.

Players can manage their public profile/avatar, account settings, data export and account deletion. Account blocks and moderation restrictions are enforced by platform services. A creator must still enforce authorization inside their own backend and validate user-generated content.

The game iframe receives restricted capabilities on a distinct immutable origin. It does not receive account cookies or private identity data. Use server-provided game identity to own saves; usernames and presence routing IDs alone are not credentials.

Administrator review and moderation endpoints are not creator APIs. SDK access cannot grant administrator privileges, contact-list access, platform DMs or cross-game writes.

Deployment automation

Deploy with the CLI npm package using a developer key, or connect a GitHub repository to a game and configure the branch and exact Actions workflow. The workflow builds and exchanges GitHub OIDC identity for short-lived scoped deployment access; connecting the repository does not install the workflow file.

Production jobs can publish explicitly. Preview jobs create browser drafts and do not replace the live backend. Backend changes may wait for the active server to stop, so keep browser/server protocol changes compatible. A branch selection is deployment configuration, not automatic multi-world server provisioning.

CLI and secrets commands · GitHub workflow example

API audiences and authentication

The account and creator endpoint index covers the host-facing API. A developer key does not replace every signed-in operation; routes such as account settings, key management and GitHub linking require a session.

API audiences and capability boundaries
SurfaceUse it forAuthority
Catalog, public creator/game pages, limitsDiscovery and public metadataPublic reads, subject to visibility and rate limits
Account and social APIYour profile, friends, notifications and content actionsAuthenticated account; some routes session-only
Game/build/backend managementOwned games, uploads, publication, testers, server deployment and secretsApproved creator/owner; deployment tokens are further scoped
/api/v1/games/:slug/leaderboards, /api/v1/games/:slug/achievements (also stats via service: 'stats'), and /api/v1/games/:slug/chatManage the owned game’s service definitions/dataApproved creator key/session; operation policies still apply
/api/v1/game-services/presenceCurrent-game online count and bounded public rosterRuntime credential only; browser presence uses its separate host bridge
/api/v1/games/:slug/invites and recipient acceptancePlayer-confirmed friend invitation notificationsSigned-in account session only, with friendship/access checks; no creator send authority
/api/v1/game-services/*Runtime leaderboards, achievements, stats and chatScoped runtime credential or host-mediated browser session
/api/v1/runtime/database/query, storage/object, storagePrivate D1 queries and R2 objectsGame backend runtime only; prefer the storage SDK
Backend connect/fetch, analytics sessions/events, realtime tokensPlayer-frame integrationHost-managed protocols; use the SDK, do not mint tickets in games
GitHub exchange/callback/webhook, internal and admin pathsDeployment identity, provider events, runtime orchestration, moderationDedicated signed/provider/internal/admin authentication; not general creator APIs

Validation errors use an error field and, where available, a code. SDK game-service failures expose GameServiceError; storage uses RuntimeServiceError. Treat 401 as authentication required, 403 as denied, 404 as absent or inaccessible, 409 as a conflict and 429 as a rate limit. Do not blindly retry a write after an uncertain response without an idempotency strategy.

Machine-readable limits

These values are rendered from the platform’s own limits definition, not a separately maintained table. The live limits endpoint returns the deployment’s values. Game-service-specific limits are documented on the chat, leaderboard and achievement pages. Capacity limits are not performance guarantees.

Limit key (unit is part of the name)Value
apiRequestsPerMinute120
writesPerMinute30
gamesCreatedPerUtcDay10
deploymentsPerUtcDay100
maxBuildBytes1,073,741,824
maxBuildFiles10,000
maxBuildFileBytes1,073,741,824
maxBuildUploadBatchBytes33,554,432
maxBuildUploadBatchFiles20
maxBuildUploadEnvelopeBytes37,748,736
retainedBuildsPerGame5
maxStoredBuildBytesPerAccount5,368,709,120
maxPageImagesPerGame8
maxPageImageBytes5,242,880
maxPageImageBytesPerGame26,214,400
maxPageImageBytesPerAccount262,144,000
maxGenreTags5
maxShortDescriptionLength240
maxMarkdownLength20,000
maxReviewLength4,000
maxCurrentApiKeysPerAccount10
maxBackendBundleBytes10,485,760
retainedBackendDeploymentsPerGame5
maxStoredBackendBytesPerCreator524,288,000
maxBackendConnections10,000
backendIdleGraceSeconds300
backendConnectionLeaseSeconds45
backendPlayerLeaseSeconds90
backendRuntimeTokenDays30
backendConnectionTicketSeconds30
maxBackendSecretsPerGame50
maxBackendSecretNameLength128
maxBackendSecretValueBytes65,536
maxBackendSecretsPayloadBytes262,144
maxBackendSecretsBytesPerGame262,144
maxBackendHttpBodyBytes8,388,608
maxBackendHttpEnvelopeBytes12,582,912
maxDatabaseStatementsPerBatch20
maxDatabaseStatementBytes100,000
maxDatabaseParametersPerStatement100
maxDatabaseResponseBytes5,242,880
maxGameObjectBytes104,857,600
maxWorldStorageBytes524,288,000
maxGameStorageBytes1,073,741,824
maxCreatorStorageBytes5,368,709,120