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.
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.
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.
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.
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.
| Surface | Use it for | Authority |
|---|---|---|
| Catalog, public creator/game pages, limits | Discovery and public metadata | Public reads, subject to visibility and rate limits |
| Account and social API | Your profile, friends, notifications and content actions | Authenticated account; some routes session-only |
| Game/build/backend management | Owned games, uploads, publication, testers, server deployment and secrets | Approved 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/chat | Manage the owned game’s service definitions/data | Approved creator key/session; operation policies still apply |
/api/v1/game-services/presence | Current-game online count and bounded public roster | Runtime credential only; browser presence uses its separate host bridge |
/api/v1/games/:slug/invites and recipient acceptance | Player-confirmed friend invitation notifications | Signed-in account session only, with friendship/access checks; no creator send authority |
/api/v1/game-services/* | Runtime leaderboards, achievements, stats and chat | Scoped runtime credential or host-mediated browser session |
/api/v1/runtime/database/query, storage/object, storage | Private D1 queries and R2 objects | Game backend runtime only; prefer the storage SDK |
| Backend connect/fetch, analytics sessions/events, realtime tokens | Player-frame integration | Host-managed protocols; use the SDK, do not mint tickets in games |
| GitHub exchange/callback/webhook, internal and admin paths | Deployment identity, provider events, runtime orchestration, moderation | Dedicated 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 |
|---|---|
apiRequestsPerMinute | 120 |
writesPerMinute | 30 |
gamesCreatedPerUtcDay | 10 |
deploymentsPerUtcDay | 100 |
maxBuildBytes | 1,073,741,824 |
maxBuildFiles | 10,000 |
maxBuildFileBytes | 1,073,741,824 |
maxBuildUploadBatchBytes | 33,554,432 |
maxBuildUploadBatchFiles | 20 |
maxBuildUploadEnvelopeBytes | 37,748,736 |
retainedBuildsPerGame | 5 |
maxStoredBuildBytesPerAccount | 5,368,709,120 |
maxPageImagesPerGame | 8 |
maxPageImageBytes | 5,242,880 |
maxPageImageBytesPerGame | 26,214,400 |
maxPageImageBytesPerAccount | 262,144,000 |
maxGenreTags | 5 |
maxShortDescriptionLength | 240 |
maxMarkdownLength | 20,000 |
maxReviewLength | 4,000 |
maxCurrentApiKeysPerAccount | 10 |
maxBackendBundleBytes | 10,485,760 |
retainedBackendDeploymentsPerGame | 5 |
maxStoredBackendBytesPerCreator | 524,288,000 |
maxBackendConnections | 10,000 |
backendIdleGraceSeconds | 300 |
backendConnectionLeaseSeconds | 45 |
backendPlayerLeaseSeconds | 90 |
backendRuntimeTokenDays | 30 |
backendConnectionTicketSeconds | 30 |
maxBackendSecretsPerGame | 50 |
maxBackendSecretNameLength | 128 |
maxBackendSecretValueBytes | 65,536 |
maxBackendSecretsPayloadBytes | 262,144 |
maxBackendSecretsBytesPerGame | 262,144 |
maxBackendHttpBodyBytes | 8,388,608 |
maxBackendHttpEnvelopeBytes | 12,582,912 |
maxDatabaseStatementsPerBatch | 20 |
maxDatabaseStatementBytes | 100,000 |
maxDatabaseParametersPerStatement | 100 |
maxDatabaseResponseBytes | 5,242,880 |
maxGameObjectBytes | 104,857,600 |
maxWorldStorageBytes | 524,288,000 |
maxGameStorageBytes | 1,073,741,824 |
maxCreatorStorageBytes | 5,368,709,120 |
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.