Skip to content
flypod
CLI reference

CLI reference

The flypod CLI deploys a static directory or file to a public URL with one command, then manages versions, rollbacks, and account ownership.

flypod is a zero-auth static-site deploy primitive. One command ships a directory or single file to a public URL. Logged in, deploys are permanent and owned; anonymous, they live 14 days.

Install

npx flypod

Or install globally:

npm i -g flypod

The binary is flypod. The first positional argument that names a subcommand is dispatched (a flag's value never counts, so flypod --site list update is update for the site list); otherwise the argument is treated as a deploy path. flypod deploy [path] is the same as flypod [path]. A bare word that is not a path but is close to a verb (flypod verisons) fails with unknown_command and names the verb you probably meant, rather than deploying a folder that does not exist.

An unknown flag is refused on every command, top-level or subcommand, with the code unknown_flag and exit 2 — nothing is silently ignored. A flag that takes a value and is given none fails with usage. --help never runs the command it is attached to: it prints help on stdout and exits 0 (under --json, as {"ok":true,"help":"…"}). Success exits 0; see Errors and exit codes for the rest.

Commands

Global flags

FlagDescription
--jsonEmit one line of machine-readable JSON on stdout, and nothing on stderr. Every command takes it.
-q, --quietPrint only the URL on stdout. Read by the deploy and by flypod update.
-h, --helpPrint usage on stdout and exit 0, without running the command. Every command takes it.
-v, --versionPrint the CLI version and exit (top level only).

Errors and exit codes

Every command fails the same way. In a terminal the reason is on a line starting with ✗, with the next step underneath it. With --json the failure is one line of JSON on stdout and nothing on stderr:

{ "ok": false, "code": "rate_limited", "error": "Too many requests from this network right now.", "fix": "Wait a minute and retry the same command.", "retry_after_s": 30 }

Branch on code: it is stable. error is prose and may change. fix, when present, is the literal next step. A failure that came from the server also carries its HTTP status.

The exit code follows code, never the command:

ExitMeaning
0Success.
1A runtime error to act on: no build directory, site gone, upload refused.
2Usage: the command line itself needs changing.
3Auth: not signed in, or the credential was refused.
4Retryable: rate limit, server error, network, or a login still pending.
CodeExitWhen
usage2A required argument is missing or malformed: a flag with no value, an invalid --mode, an ambiguous flypod rollback prefix.
unknown_command2A bare word close to a verb (flypod verisons), or a flypod comments verb that does not exist.
unknown_flag2A flag the command does not take.
interactive_login_required2flypod login --json: the browser step is handed back to the caller. See Account commands.
no_build_dir1The path does not exist, or no path was given and no build directory was detected.
no_files1The directory has no files to upload.
no_site1No site is linked to this folder and no --site was passed. On update, versions and rollback the JSON adds reason: never_linked, expired, gone, or other_folder (a folder above or below this one is linked; fix names the --site command).
no_such_version1flypod rollback: no version matches, or the live version is already the oldest.
not_found1The server returned 404 for something other than a site.
site_gone1The site expired or was deleted.
already_claimed1The site already belongs to another account.
invalid_upload1The server rejected the upload as malformed.
too_large1The upload is over the size or file-count cap. Against flypod.dev the CLI checks this before uploading.
blocked1Content screening refused the deploy.
challenge_required1The server wants a human challenge for this deploy. Signed-in deploys skip it: run flypod login and deploy again.
bad_request1Any other 4xx from the server.
login_expired1The sign-in code expired before it was confirmed.
unexpected1Anything not covered above.
not_signed_in3The command needs an account and there is no session.
unauthorized3The credential (your session, or a --token manage token) does not grant access to this site.
token_rejected3A deploy sent an account credential (FLYPOD_TOKEN or a saved login) and the server did not accept it, or flypod login --token was refused. It never falls back to an anonymous deploy.
no_token3flypod token: this machine holds no manage token for the site.
login_denied3The sign-in was denied in the browser.
rate_limited4Too many requests; retry_after_s says how long to wait when the server gave one.
server_error4The server returned a 5xx. flypod update has already retried it once (an update is safe to repeat); when flypod itself answered, the JSON carries a request_id to quote.
network4The server could not be reached, or something in between (a proxy, a firewall) refused the request before it got there.
authorization_pending4flypod login --device-code: the user has not confirmed within the 25 seconds it waits. The next flypod command finishes the sign-in once they do.
login_timeout4flypod login gave up waiting for the browser.

Environment variables

VariableDescription
FLYPOD_TOKENUse an account session token for this process (agents / CI). Takes precedence over a saved login.
DEPLOY_URLOverride the server base URL. Default https://flypod.dev. A saved login keeps the host it was made against, which wins over DEPLOY_URL.
FLYPOD_CONFIG_DIROverride the config directory.
FLYPOD_SOURCEOverride the surface the CLI reports to the server (cli, skill, library, ci, …). By default it is skill when the project has the flypod skill installed, otherwise cli.
FLYPOD_SHOW_TOKENSet (e.g. to 1) to restore the old inline manage_token line in deploy output. Off by default; prefer flypod token.
NO_COLORDisable colored output.
FORCE_COLORForce colored output.
DO_NOT_TRACKSet (to anything but 0 or false) to turn off the CLI's random install id, its agent, CI, launch and agent-instructions words, and its failure reports.
FLYPOD_TELEMETRY0, false, off or no turns off the same, for flypod alone.

The CLI counts deploys per install with a random id, says in one fixed word which coding agent ran it (claude_code, codex, cursor, gemini, opencode, other or none, read from variables those agents set: AI_AGENT, CLAUDECODE, CLAUDE_CODE_ENTRYPOINT, CURSOR_AGENT, GEMINI_CLI, CODEX_SANDBOX, CODEX_SANDBOX_NETWORK_DISABLED, CODEX_THREAD_ID, CODEX_MANAGED_BY_NPM; never the variables' values) and whether CI did (CI, GITHUB_ACTIONS), how it was launched (npx, bunx, pnpm_dlx, yarn_dlx, script, local, global or other, from the shape of its own script path and the package manager's npm_lifecycle_event, npm_command, npm_config_user_agent, npm_execpath), and whether the project's agent instructions name flypod (skill, agents_md, claude_md, cursor_rules, copilot, gemini_md or none: which kind of file, among AGENTS.md, CLAUDE.md, .cursorrules, .cursor/rules/*, .github/copilot-instructions.md and GEMINI.md in the project up to its repository root, has the word flypod in its first 32 KB), and when a command fails against flypod.dev it reports the error code and, for too_large, no_files and no_build_dir, the upload's shape (file count, kilobytes per kind of file, whether the folder has a package.json or a build folder); for no_site, which kind; for unauthorized, which kind of credential was refused, whether this machine knew the site, and whether it was named by the folder's link or --site. Never file names, paths or contents. Reports never print and give up after 1.5 s. The library (deploySite()) sends none of it.

Configuration files

flypod stores config in a per-user directory, never in your project repo. Override the location with FLYPOD_CONFIG_DIR.

PlatformDefault location
macOS~/Library/Application Support/flypod
Windows%APPDATA%/flypod
Linux$XDG_CONFIG_HOME/flypod (defaults to ~/.config/flypod)

These files are written with mode 0600:

  • session.json: the account session created by flypod login.
  • projects.json: the folder-to-site registry. LRU-capped at 64 entries; expired entries auto-prune.
  • pending-login.json: only while a flypod login --json waits for its person. A device code, not a credential, so the next command can finish the sign-in; worthless after ten minutes.
  • install.json: the random install id described above. Not written when DO_NOT_TRACK is set.

Config files are never placed in your project repo. Nothing flypod writes needs to be committed.

Authentication

Connect the CLI through browser device authorization:

flypod login

For a stateless agent or CI job, provide an existing account session token:

FLYPOD_TOKEN=<session_token> npx flypod ./dist

FLYPOD_TOKEN takes precedence over a saved login. With neither, the deploy is anonymous. A credential that is sent and not accepted fails with token_rejected; it never silently becomes an anonymous deploy. See Account commands.

On this page