Skip to content

Config Workflow

The CLI is how billing.config.ts moves from your repo into Guapocado.

The usual loop is:

Terminal window
npx guap init
npx guap login
npx guap plan --test
npx guap push --test

Production uses the same config file:

Terminal window
npx guap plan --live
npx guap push --live
Terminal window
npx guap init

Creates a starter billing.config.ts.

If the file already exists, the CLI should not overwrite your billing model without you explicitly changing it.

Terminal window
npx guap login

A single guap login authorizes one workspace (organization) and mints both a test and a live server key, so you can push --test and push --live without logging in twice. Keys stay environment-scoped (a test key can’t touch live). In the browser approval page you pick which workspace to authorize.

The CLI stores credentials per workspace in:

.guapocado/credentials.json

Use test while developing. Use live only when you are intentionally syncing real billing state.

If you belong to multiple workspaces, switch between them locally:

Terminal window
npx guap workspace list # show logged-in workspaces (● = active)
npx guap workspace select # interactive picker (↑/↓ + enter)

push/pull/plan operate against the active workspace’s keys.

By default the CLI looks for your billing config in the current directory (billing.config.ts, billing.config.json, guapocado.billing.json, or guapocado.billing.yaml). In a monorepo the config often lives elsewhere, so plan, push, generate, and listen accept --config (alias -c):

Terminal window
npx guap push --test --config ./packages/billing/billing.config.ts
npx guap plan --test -c ./packages/billing # a directory works too

The value may be a config file or the directory that contains one.

Terminal window
npx guap plan --test

Plan pulls the remote config for the selected environment and shows what would change.

Run plan before push. Treat it like a database migration preview.

Terminal window
npx guap push --test

Push validates the local config and syncs it to Guapocado.

If Stripe is connected for that environment, Guapocado syncs products and prices from your product definitions.

Stripe prices are immutable — you cannot edit a price in place. When you change an amount, currency, or billing frequency and push, Guapocado creates a new Stripe price and deactivates the old one.

New checkouts use the new price immediately.

Existing subscribers are not automatically moved to the new price. Their subscription continues at the price they signed up on. This is intentional — silently repricing active subscribers would be unexpected and potentially violate payment agreements.

If you want to move existing subscribers to the new price, you need to migrate them explicitly. You can do this from the Guapocado dashboard (subscriber list → change plan) or via the API. Doing it in bulk requires iterating your active subscribers and calling the subscription change endpoint for each.

The same applies to overage and expansion prices: if you change the unit cost, only new overage opt-ins and new seat purchases use the updated price. Customers already on overage or with purchased expansion keep their existing subscription items at the original rate.

Terminal window
npx guap pull --test

Pull reads the remote config. Use it to inspect what Guapocado currently has for an environment.

Your repo should still be the source of truth. Pull is for inspection and recovery, not the normal editing flow.

Terminal window
npx guap generate

Generate reads billing.config.ts and writes local integration artifacts.

For local read-model mode, generate Drizzle tables:

Terminal window
npx guap generate --tables --orm drizzle --db sqlite
npx guap generate --tables --orm drizzle --db pg
npx guap generate --tables --orm drizzle --db mysql

You can store defaults in config:

generate: {
tables: {
enabled: true,
orm: "drizzle",
db: "sqlite",
output: "src/db/guapocado.ts",
},
},

Then a plain npx guap generate uses those defaults.

listen is for local webhook development.

Terminal window
npx guap listen --test --dev --to http://localhost:3000/api/guap-webhook

Use it when your config declares a test dev relay receiver:

webhooks: {
devTunnel: true,
forwarding: [
{
key: "local",
path: "/api/guap-webhook",
events: "*",
integration: "custom",
autoRegister: true,
},
],
}

The dev relay is test-only.

Both environments use the hosted API:

https://api.guapocado.dev

The key and CLI flag decide the environment.

Terminal window
npx guap push --test
npx guap push --live

For a normal plan change:

  1. Edit billing.config.ts.
  2. Run npx guap plan --test.
  3. Push to test.
  4. Test checkout and runtime checks.
  5. Open a pull request with the config change.
  6. After merge, run npx guap plan --live.
  7. Push to live.

This keeps product billing changes reviewable before they affect customers.