Skip to main content
The ledger CLI keeps your catalog in your repository, as ledger.config.ts or ledger.catalog.json. You change pricing by editing the file, review the change in a pull request, and publish it with ledger push. Setup walks through the first run. Install it with npm install --save-dev integrateledger-cli and run npx ledger, or run npx integrateledger-cli without installing. It needs Node 22.18 or later, or Bun.

The config file

ledger.config.ts
  • The fields are the API’s, as on Catalog. defineCatalog, plan, feature and creditPack only add types.
  • The file holds the whole catalog. Items you remove from it are archived when you push.
  • There’s no environment: the API key chooses it, so one file serves Sandbox and Live.
  • ledger.catalog.json holds the same catalog in the POST /v1/catalog body’s shape, where packs are addOns. It’s what the onboarding skill writes, and the default for projects without a package.json. If it names an environment, the key must match it.

What a push changes

Pushing an unchanged file changes nothing and retries any Stripe sync that hasn’t finished. In CI, run ledger diff --exit-code on pull requests and ledger push --live --yes after merge, as in Deploy.

Commands

Flags

API keys

The key’s prefix is its environment: ledger_test_ for Sandbox, ledger_live_ for Live. The CLI uses the first key for the selected environment from:
  1. LEDGER_API_KEY
  2. .ledger/credentials.json (from ledger login)
  3. LEDGER_API_KEY in .env.local, then .env
A key for the other environment is skipped, so a Live key in your shell never publishes without --live. The key needs the catalog:read and catalog:write actions, and for migrate also customers:read, customers:write and billing:write. The CLI never prints it.

Exit codes

JSON output

With --json, diff prints:
  • kind is plan, feature or credit_pack; action is add, update or archive.
  • Effect codes: new_plan_version, stripe_product_and_price, stripe_price, stripe_overage_product, stripe_none, subscribers_keep_plan, in_place, purchase_pending_risk, archived.
  • push adds the API’s changed and stripeSync (synced, pending, failed, awaiting_connection).
  • pull prints { environment, organizationId, path, counts, wrote }; init prints { path, format, source, environment, counts, skills } with source workspace or template; skills prints { skills, linkCommand }, each skill with { name, path, status } and status written, updated or unchanged.
  • Errors print { "error": { "code", "message", "issues"? } }, where issues lists { path, message } with paths like plans.1.monthlyPriceCents. Codes include invalid_config, no_api_key, confirmation_required, local_changes, config_not_found, unauthorized and purchase_pending.