CLI Reference

Every superwall command — create, dev, push, promote, publish — with flags, auth, and the checks that run before anything ships.

The CLI has git semantics on purpose: push saves, promote ships. Every push mints a sealed version; nothing users see changes until promote points production at it. This page is the command reference — Push, promote & publish explains the model.

superwall create                  # scaffold superwall/ inside your app
superwall dev                     # studio on http://localhost:6100
superwall push                    # build + version. Production untouched.
superwall promote                 # point production at the latest push
superwall publish                 # push + promote in one step
superwall publish -m "Q3 test"    # record why

The scaffolded package scripts mirror these (dev, push, promote, ship).

Auth

Run superwall login once interactively. In CI, set SUPERWALL_API_KEY (an sk_… key) — the project's .env is the usual home for it. dev needs no login.

superwall create

Scaffolds a complete project: the directory skeleton, a starter paywall, dependencies installed, your Superwall app connected, and a git init if needed.

FlagWhat it does
--example <name>Start from an example instead of the default starter.

superwall dev

Hosts the studio for the project — or several at once with a glob (superwall dev examples/*). Regenerates superwall.d.ts first, so route and product types are always current.

FlagWhat it does
--port, -pPort, default 6100 — moves to the next free port if taken.
--hostBind address, for previewing from another device.

Project problems (stray files in app/, duplicate routes) print as warnings here — the same ones that block a push, so fix them as they appear.

superwall push

Builds every paywall, versions the changed ones, and leaves production alone. Re-running with nothing changed is a no-op.

FlagWhat it does
--id <id>Limit to one paywall; repeatable.
--rename <old>=<new>Declare a directory rename so CI can resolve it.
-m <note>Record why, shown with the version in the dashboard.

A push refuses — before anything is written — when:

  • a selected paywall has diagnostics (publishing is immutable; fix first),
  • a product in config.ts doesn't exist on the dashboard (every variable on it would be undefined on device),
  • a directory rename is unresolved (below).

The first push binds each paywall — creating it on Superwall if needed — and records the binding in superwall.lock; commit that file. After that, push always updates the same paywall; no IDs ever appear in your code.

Every push also snapshots your superwall/ source, so the dashboard can show and diff the code each version was built from. .env, node_modules/, and gitignored files never leave the machine.

Renames

Renaming a paywall directory is detected, never guessed. Interactively, push asks whether the unfamiliar directory is a rename (keeping the live paywall attached) or a new paywall. In CI, declare it — anything unresolved stops the push rather than creating a duplicate:

superwall push --rename plus-upgrade=pro-upgrade

Deleting a paywall directory never blocks a push — the dashboard paywall keeps serving, and restoring the directory re-binds it.

superwall promote

Points production at a pushed version. Promote never rebuilds — it only moves the live pointer.

FlagWhat it does
--id <id>Limit to one paywall.
--version, -v <n>Pick a specific version (with a single --id) — which is also the rollback.
superwall promote --id plus-upgrade --version 5
# → Rolled back version 7 → 5

superwall publish

Push + promote in one step. Takes -m <note>. Also warns about other paywalls that are pushed-but-not-live, so nothing ships half-forgotten.

Before pushing: create the products

A push refuses if a config.ts names a product the dashboard doesn't have. The fix is a command away — the same CLI writes products directly:

superwall entitlements list --json                 # grab the NUMERIC entitlement id
superwall products create pro_3999_year \
  --project <id> --app <id> \
  --name "Annual" --price 39.99 --period year \
  --trial-days 7 --entitlement <numeric-id> --json
  • --entitlement takes the numeric id (55688), not the identifier (pro) — the identifier fails with a decode error.
  • Pass --project explicitly when your account has several, or the command errors with "Multiple projects found".
  • --price is major units (39.99); --period is day|week|month|year; --trial-days sets the intro offer.
  • --dry-run confirms the target before writing anything.

Two gates worth checking early

  • Headless paywalls must be enabled on the application — otherwise every push fails with "Headless paywalls are not enabled for this application". It's a server-side feature flag; check with superwall apps list --json and look for headless_paywalls in features_enabled. Contact us to have it turned on.
  • One broken surface blocks the whole push. A leftover scaffold aimed at a nonexistent product stops everything — push what you built with repeated --id flags instead of touching unrelated directories.

For the full error-message-to-fix table, see Troubleshooting.

How is this guide?

On this page