Skip to content

HTTP API

Base URL: https://api.flitzy.app. Every request needs a deploy token:

Terminal window
curl -H "Authorization: Bearer $FLITZY_TOKEN" https://api.flitzy.app/v1/apps

Responses are JSON. Errors look like {"error": "…", "hint": "…"}, sometimes with a code such as app_limit_reached. Rate limits are in Limits.

GET /v1/me Who the token belongs to, with its tokens.
GET /v1/usage Plan, apps used and allowed, per-app limits, databases, rate limits.
POST /v1/me/tokens {name, expiresInDays?} → new token, shown once.
DELETE /v1/me/tokens/:id Revoke a token.
GET /v1/org/tokens All tokens of the organization (its admins).
DELETE /v1/org/tokens/:id Revoke one of them.
GET /v1/billing Plan (free or pro), subscription status, renewal date, the plan table.
POST /v1/billing/checkout {url} of a Stripe Checkout page for Pro. Account owner or organization admins.
POST /v1/billing/portal {url} of the Stripe customer portal.

Limit errors that Pro lifts (app_limit_reached, database_limit_reached, plan_required) carry plan and, on Free, upgradeUrl.

GET /v1/apps Apps with URL, health and last deploy.
GET /v1/apps/:name Status: health, problem, pods, events, volume, last deploys.
DELETE /v1/apps/:name Delete the app.
POST /v1/apps/:name/deploys Upload a .tar.gz of the folder as the body → 202 {id, url, statusUrl}. Query: port, volume=1, link=db1,db2, private=1|0.
GET /v1/apps/:name/deploys?limit= Deploy history.
GET /v1/deploys/:id One deploy with status and log; poll it until live or failed.
GET /v1/apps/:name/logs?tail= Recent output.
GET /v1/apps/:name/logs?follow=1&tail=&since= Live logs as Server-Sent Events (below).
GET /v1/apps/:name/metrics CPU and memory with share of the limits.
GET /v1/apps/:name/env {keys}: variable names.
PATCH /v1/apps/:name/env {set: {K: "v"}, unset: ["K"]}, restarts the app.
DELETE /v1/apps/:name/volume Delete the volume and its data.
PUT /v1/apps/:name/access {private: true|false}: only the team can open the app (private apps). GET /v1/apps and GET /v1/apps/:name show private.
POST /v1/access/grant {app, return} → {redirect}: one-time sign-in link to a private app for a member of its team (used by the dashboard).

See Selling in your app.

GET /v1/connect/status The team’s Stripe account: status (not_connected, onboarding_incomplete, pending_verification, active), feePercent.
POST /v1/connect/onboard {country?} → {url}: Stripe onboarding (team admins).
POST /v1/connect/dashboard {url}: the seller’s Stripe dashboard.
GET /v1/apps/:name/monetization Paywall, price, customers.
PUT /v1/apps/:name/monetization {price, interval: month|year|once, currency?, name?, rotateSecret?}: sell access; injects FLITZY_APP_PAYWALL_*.
DELETE /v1/apps/:name/monetization Stop selling.

Called by the app itself, without a Flitzy token (base: FLITZY_APP_PAYWALL_URL):

POST …/checkout {ref?, email?, success_url?, cancel_url?} → {url} Stripe Checkout. Works from the browser.
GET …/sessions/:session_id {paid, ref, email} after the redirect back.
GET …/access?ref=… or ?email=… Authorization: Bearer $FLITZY_APP_PAYWALL_SECRET → {active, status, currentPeriodEnd}.
POST …/portal {ref|email, return_url?} with the secret → {url}: customer manages or cancels.
GET /v1/apps/:name/domains Domains with status pending, issuing, active or error.
POST /v1/apps/:name/domains {domain} → DNS instructions.
POST /v1/apps/:name/domains/:domain/verify Check DNS and go live.
DELETE /v1/apps/:name/domains/:domain
GET /v1/databases Databases with status and links; connection strings masked.
POST /v1/databases {name, type: "postgres" | "redis"} → 201.
GET /v1/databases/:name Status and linked apps.
GET /v1/databases/:name/connection Full connection string (recorded in the activity log).
POST /v1/databases/:name/links {app, envName?}: set the variable in the app and restart it.
DELETE /v1/databases/:name/links/:app
DELETE /v1/databases/:name Delete with all data.

GET /v1/audit?app=&action=&result=&before=&limit= → {events, next}, newest first. result takes a list such as denied,failed; pass next as before for the next page.

GET /v1/apps/:name/logs?follow=1 answers with text/event-stream:

Event Data
attach Now streaming a container; newPod after a deploy, restarts after a crash.
log {lines: [{t, text}]}. t is an RFC 3339 timestamp with nanoseconds.
status The container is not running: state, reason, exit code, hint.
end The server closes the stream (after 30 minutes).

To resume after a disconnect, reconnect with since=<t of the last line>; lines are neither repeated nor skipped. A : ping comment every 15 seconds keeps proxies from closing the stream.