HTTP API
Base URL: https://api.flitzy.app. Every request needs a deploy token:
curl -H "Authorization: Bearer $FLITZY_TOKEN" https://api.flitzy.app/v1/appsResponses are JSON. Errors look like {"error": "…", "hint": "…"}, sometimes with a code such as app_limit_reached. Rate limits are in Limits.
Account
Section titled “Account”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. |
Plan and billing
Section titled “Plan and billing”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). |
Selling
Section titled “Selling”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. |
Domains
Section titled “Domains”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 |
Databases
Section titled “Databases”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. |
Activity
Section titled “Activity”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.
Live logs
Section titled “Live logs”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.