TL;DR
An app your agent built becomes something other people use when it has seven things: sign-in that decides who gets in, data that survives a deploy, a stable URL and domain, a version that stays up, logs, a way back from a bad deploy, and keys for programs that call it. floo supplies each one from floo.app.toml and the CLI, for a tool your team opens every morning and for an app your customers use.
- Who gets in is a config line. Invite-only sign-in at floo's gateway, or public. Invited people need no seat and no account with the tool you built in.
- Each environment has its own data. Dev and prod get separate Postgres databases, and migrations run before traffic moves.
- Recovery is a command, not a rebuild. A rollback took 16 seconds in our test.
- Customer self-sign-up is coming. Today, customers get in by invitation or through a public app.
Agents have made the app the cheap part. Cursor, Claude Code, and Codex will each build a working dashboard, portal, or tool from a paragraph. What decides whether anyone else uses it is everything around the code: who can open it, where the data lives, what happens when a deploy goes wrong.
Cursor's own launch of Cursor Apps on November 5 made the same point: most of what people build "never make it off of localhost." Its answer runs apps behind Cursor sign-in for your Cursor team, or as public links where an admin allows them. This post is about the general case, for an app built with any agent, opened by your team, by people outside it, and by customers.
We ran sign-in, Postgres, a scheduled job, logs, rollback, and a prod release on a real app the same day; how to deploy an app you built in Cursor has the commands and outputs. The rest follows floo's docs, linked at the end.
Who gets in?
The first question is always access, and the answer differs by who the app is for.
A tool for your team. One line in floo.app.toml:
[app]
access_mode = "accounts"
floo's gateway puts an invite-only sign-in page in front of every request. A request without a session never reaches your code; in our test app's request log, every unsigned request got 401 from the gateway, not from the app. Your code reads who is calling from headers the gateway adds, X-Floo-User-Email and X-Floo-User-Role among them, so the agent writes no login page, session store, or auth library. Invite people by email:
floo apps invite teammate@example.com --role member --app my-app
They do not need an account with the tool you built in, and app users do not use floo builder seats. Removing a member ends their access on the next request. See App sign-in.
An app for a few customers or clients. The same invite-only mode works for people outside your company: a client portal for six accounts, a report a partner checks weekly, a demo for one prospect. Each person you invite gets in; nobody else does.
An app for anyone. access_mode = "public" serves it to everyone, and [[routes]] can mix the two, for example a public landing page with an invite-only /admin. If a public app needs its own customer accounts today, the app handles that sign-in itself. Customer self-sign-up through floo's gateway is coming; it is not available yet, and neither is SAML or OIDC sign-in for app users.
Where does the data live?
An app people rely on keeps their data across deploys. Declare Postgres in the same file:
[managed.default]
type = "postgres"
floo creates a database for each environment and injects DATABASE_URL. Dev and prod never share one, so trying a change in dev cannot touch what customers see. Add migrate_command under the service and each deploy runs migrations with the new image before traffic moves; a failed migration stops the deploy and the old version keeps serving. floo keeps change history for managed Postgres and runs restores on request (backups). The data is in a normal Postgres database your code queries directly, not in a store tied to the tool that wrote the app. See Postgres.
What is the URL, and can it be our domain?
Every app gets a getfloo.app URL on its first deploy, and a second one for prod when you first release. For customers you usually want your own host. Declare it:
[domains."portal.example.com"]
service = "web"
The next prod release creates the domain, and floo domains show portal.example.com --app my-app prints the two DNS records to publish: a CNAME to edge.getfloo.com for traffic and an _acme-challenge record for the certificate. floo checks every minute and turns the host on when both resolve. The app's access mode applies on the custom domain too, so an invite-only app stays invite-only there. See Custom domains.
Will it be up when someone opens it?
An internal tool that takes ten seconds to wake up stops getting opened. floo sends each service in dev and prod a small request every five minutes, so instances do not sit idle long enough to stop (cold starts). A deploy starts the new version and checks it before moving traffic, so a version that fails to boot never takes requests.
Then there is finding out when something breaks. Once you turn it on, floo watches for failed deploys and runtime errors that repeat, and POSTs each one, with its context, to a webhook: your agent, an on-call bot, or an incident pipeline (agent webhooks). floo analytics my-app reports traffic, error rate, and latency after a deploy.
What happened, and when?
When someone says "it's broken", you need the logs before you need a theory:
floo logs query --app my-app --since 1h --error
floo logs query --app my-app --cron daily-report --env prod
floo logs query --app my-app --requests
The first is your app's output, the second a scheduled job's, the third every request the gateway handled with its status and latency. floo logs tail streams them. Logs are kept for 7 days. An agent reads the same output as JSON with --json, which is how it debugs without asking you to paste a screenshot. See Logs.
How do we go back?
Every deploy is a commit, and floo deploys list --app my-app --json shows which commit is live in each environment. When a bad version gets through:
floo deploys rollback my-app <deploy-id> --yes
It re-points traffic at the earlier image without running migrations. In our test it took 16 seconds, and the earlier version was serving again. Dev and prod are separate steps, too: pushes and floo deploy ship to dev, and prod changes only when you publish a release with floo releases promote or a GitHub release. See Releases and rollbacks.
How do other programs use it?
The app is rarely the end of the chain. An alerting agent files entries, a nightly script pulls a report, a customer's system posts orders. Each one gets its own app API key, limited to the routes you declare for it:
[[routes]]
path = "/"
access = "accounts"
service = "web"
[[routes]]
path = "/api"
access = "api_key"
scope = "api"
service = "web"
floo apps consumers create oncall-agent --app my-app
floo apps keys create oncall-agent-key --consumer oncall-agent --scope api --app my-app
The gateway checks the key, strips it before your code sees the request, and passes the consumer's identity instead, so every write is attributed to the program that made it. A key on the page route gets 401; it does not sign anyone in. Your own agent needs none of this: it calls the app with the floo API key it already signed in with, as you (call your app). See App API keys and how to give your agent its own key.
The whole list in one file
For a team tool or a customer app, the parts above add up to one reviewed file in the repository:
[app]
name = "my-app"
access_mode = "accounts"
[services.web]
type = "web"
path = "."
port = 3000
ingress = "public"
migrate_command = "node scripts/migrate.js"
[managed.default]
type = "postgres"
[cron.daily-report]
schedule = "0 9 * * *"
command = "node scripts/report.js"
service = "web"
[domains."portal.example.com"]
service = "web"
Because it is in git, a change to who can open the app or where it is served goes through the same review as the code. The agent that built the app can read and change it, and you can see exactly what it changed.
Where to start
- You have an app already. Deploy an app you built in Cursor works for any agent's output: add a Dockerfile and
floo.app.toml, runfloo deploy. - You are starting fresh. The templates are working apps with sign-in and Postgres in place, and how to build and deploy an internal tool with AI builds one from a single prompt.
- You are comparing options. The backend overview lists what floo supplies, and internal apps compares the ways to host tools for a team.
floo deploys and hosts apps built with AI. Your agent builds the app; floo runs it, watches it, and tells your agent when it breaks.
Sources
- Cursor: Build live apps in Cursor (November 5, 2026), Apps
- floo docs: app sign-in, team access, Postgres, backups, environments, custom domains, cold starts, agent webhooks, analytics and alerts, logs, releases and rollbacks, app API keys, call your app, config reference
Frequently asked questions
What does an app my agent built need before other people can use it?
Seven things: a way to decide who gets in, data that survives a deploy, a stable URL and usually your own domain, a version that stays up, logs when something breaks, a way back from a bad deploy, and keys for any program that calls it. On floo each one is a line in floo.app.toml or one CLI command.
Can people outside my company open an app hosted on floo?
Yes. An invite-only app opens for any email you invite, inside or outside your company, and invited app users do not use builder seats. A public app opens for anyone. Customer self-sign-up, where people create their own accounts in your app, is coming and is not available yet.
Do I need to write login code?
Not for invite-only access. Set access_mode = "accounts" and floo's gateway shows the sign-in page, checks membership on every request, and passes X-Floo-User-Email, X-Floo-User-Id, X-Floo-User-Name, and X-Floo-User-Role to your code. For a public app with your own customer accounts today, your app handles sign-in itself.
How does another agent or script call the app?
Give it an app API key. floo apps consumers create names the program, floo apps keys create --scope issues a key for routes declared with access = "api_key" and that scope, and the gateway strips the key before your code sees the request. Your own agent needs no app key: it calls the app with the floo API key it signed in with.
What happens if a deploy breaks the app?
A failed migration stops the deploy and the previous version keeps serving. If a bad version does go live, floo deploys rollback re-points traffic at an earlier deploy; in our test it took 16 seconds. floo can also POST failed deploys and repeating errors to a webhook so your agent hears about them.