An instant backend, before anyone signs up
An agent can make a Flatstack backend for someone who has no account yet: a sandbox. It is a real project, with a D1 database, functions, sign-in for the app’s users, file storage and hosting at a flatstack.app address, and it lasts 24 hours. The person you’re building for keeps it by opening its claim link: they sign up and pay, or sign in to an account they already have. Nothing is lost when they do. A sandbox nobody claims is deleted.
This isn’t a free tier. A sandbox is small, it never sends email, and only one person can ever keep it, by paying for a plan or adding it to the one they have.
Making one
Over MCP, connect to the sandbox endpoint. It needs no sign-in:
claude mcp add --transport http flatstack-sandbox https://api.flatstack.dev/mcp/sandbox
Then call create_sandbox. Over HTTP it’s one unauthenticated request:
curl -X POST https://api.flatstack.dev/v1/sandboxes \
-H 'content-type: application/json' \
-d '{ "template": "starter", "ref": "<referral code>" }'
From the CLI, without signing in: npx @flatstackdev/cli sandbox create --json.
Both fields are optional. template is one of starter, next, astro or react-router and is recorded on the sandbox. ref is a referral code; it goes into checkout when the sandbox is claimed. The answer, 201:
{
"sandbox": true,
"sandboxId": "sbx_…",
"projectId": "prj_…",
"url": "https://sandbox-k3v9q2x7mf.flatstack.app",
"token": "fs_dep_…",
"claimUrl": "https://flatstack.dev/claim?token=fs_clm_…",
"expiresAt": "2026-11-01T12:00:00.000Z",
"status": "ready",
"limits": { "requests": 100000, "functionCpuMs": 200000, "databaseStorageBytes": 104857600, "…": "…" },
"mcp": "https://api.flatstack.dev/mcp/sandbox",
"warnings": []
}
token is shown once. Keep it for the rest of the session and don’t show it to anyone. claimUrl is for the person: give it to them as soon as there’s something worth keeping.
Building in it
The token reaches the sandbox’s own project and nothing else. With it you can:
MCP tool (on /mcp/sandbox) |
API route |
|---|---|
deploy |
POST /v1/projects/{projectId}/deploys, and /assets, /assets/missing for site files |
get_deploy_status |
GET /v1/projects/{projectId}/deploys, …/deploys/{deployId} |
apply_schema |
POST /v1/projects/{projectId}/migrations |
run_security_scan |
POST /v1/projects/{projectId}/scan |
set_env, set_secret |
PUT /v1/projects/{projectId}/env/{key}, …/secrets/{key} |
get_logs |
GET /v1/projects/{projectId}/logs |
search_docs |
GET /v1/docs/search |
GET /v1/sandbox: the sandbox’s expiry, limits and usage so far |
On the sandbox endpoint, send the token as Authorization: Bearer fs_dep_…, or, if your client can’t change its headers mid-session, as the token argument of each tool. You don’t need projectId there: the token names the sandbox. From the CLI, FLATSTACK_TOKEN=<token> flatstack deploy --project <projectId>.
Every other route and tool refuses the token with 403 forbidden, and so does the main /mcp endpoint. run_sql and list_tables aren’t there yet; they arrive with the SQL tools.
Limits
| Limit | Value |
|---|---|
| Projects | 1, D1 only |
| Requests | 100,000 |
| Function CPU | 200,000 ms |
| Database storage | 100 MB |
| File storage | 500 MB |
| End users | 1,000 |
| Realtime connections | 10 |
| Vector records | 5,000 |
| logged, never sent | |
| AI gateway, branch environments, custom domains, backups | none |
| Logs | kept 1 day |
| CPU per request, cron interval | as Hobby |
The usage limits cover the sandbox’s whole 24 hours, not a month. Past one, the sandbox is capped the way an account is (requests get 429 requests_capped, writes that add data get 507), never billed. Results on the sandbox endpoint warn at 80%, and in the last two hours they say when the sandbox will be deleted.
Email your app sends is written to the sandbox’s email log and never delivered, to anyone.
How many
Three sandboxes an hour and ten a day from one address (an IPv4 address, or an IPv6 /64), and the same from one agent: its network, User-Agent and MCP client together. The fourth in an hour gets 429 sandbox_rate_limited, with details.limit (ip or fingerprint) and details.window (hour or day). Only keyed hashes of the address and the fingerprint are kept.
Keeping it
When the person opens the claim link:
- Without an account, they sign up, choose a plan and pay. Once Stripe confirms the payment, the account is created and the sandbox moves into it as its first project, in an active slot. The referral code goes into checkout with it. If the 24 hours ran out while they were paying, they still get the account they paid for, without the sandbox.
- With an account, one click on Keep it moves the sandbox in as a parked project. They need a role that can create projects (owner, admin or developer). Promote it to an active slot when it needs the full plan. If every parked slot is taken, it lands archived instead: its database, users and files are kept in an archive for 12 months, it isn’t served, and it takes no slot. Restore it once a slot is free.
Agents signed in to an account can claim for the person with claim_sandbox on the main /mcp endpoint, or flatstack sandbox claim <claim link>, which both call POST /v1/sandboxes/claim with { "claim": "<claim link or fs_clm_ token>" }.
Either way the project keeps its ID, address, database, files, deploys, variables and secrets, and takes the account’s limits from then on. The sandbox token stops working; the account’s members and tokens take over.
The response’s state says where it landed: active, parked or archived. A claim can fail with:
410 sandbox_expired: the 24 hours are over and the sandbox has been, or is about to be, deleted.409 conflict: someone else already claimed it.
Signed in, you don’t need a sandbox
create_sandbox on the main /mcp endpoint, POST /v1/sandboxes with a token, and flatstack sandbox create when signed in make a parked project in your account instead: no 24-hour clock, the account’s limits, nothing to claim. With no parked slot free it fails with 403 parked_slots_full, which lists the parked projects you could remove.
What’s deleted, and when
An unclaimed sandbox is deleted within a minute of its expiresAt: its Worker, database, hostname, token and every row. Sandboxes never appear in an account’s project list, slot counts, usage or setup checklist; Flatstack’s own admin panel counts them.
As Markdown: agents/sandbox.md