CLI Reference

Command-line tool for managing SaaS billing configurations as code

CLI Reference

The Raterunner CLI lets you manage your billing configuration as code. Define pricing plans, entitlements, and promotions in YAML, then sync them to payment providers like Stripe.

Installation

Homebrew (macOS/Linux)

brew install raterunner/tap/raterunner

Download Binary

Download the latest release from GitHub Releases.

Available builds:

PlatformArchitectureFile
macOSIntelraterunner_VERSION_darwin_amd64.tar.gz
macOSApple Siliconraterunner_VERSION_darwin_arm64.tar.gz
Linuxx64raterunner_VERSION_linux_amd64.tar.gz
LinuxARM64raterunner_VERSION_linux_arm64.tar.gz
Windowsx64raterunner_VERSION_windows_amd64.zip
WindowsARM64raterunner_VERSION_windows_arm64.zip
# Example: macOS Apple Silicon
curl -sL https://github.com/raterunner/cli/releases/download/v0.0.1/raterunner_0.0.1_darwin_arm64.tar.gz | tar xz
sudo mv raterunner /usr/local/bin/

Linux Packages

Available on GitHub Releases:

  • .deb — Debian, Ubuntu
  • .rpm — RHEL, Fedora, CentOS
  • .apk — Alpine
# Debian/Ubuntu
curl -sLO https://github.com/raterunner/cli/releases/download/v0.0.1/raterunner_0.0.1_linux_amd64.deb
sudo dpkg -i raterunner_0.0.1_linux_amd64.deb

Go Install

go install github.com/raterunner/cli/cmd/raterunner@latest

Build from Source

git clone https://github.com/raterunner/cli.git
cd cli
make build
sudo mv bin/raterunner /usr/local/bin/

Verify Installation

raterunner --version

Quick Start

1. Initialize a project

raterunner init

This creates a raterunner/ directory with a sample billing.yaml:

your-project/
└── raterunner/
    └── billing.yaml

2. Edit billing.yaml

Customize the generated configuration:

# raterunner/billing.yaml
version: 1
providers:
  - stripe

entitlements:
  seats:
    type: int
    unit: seat
  api_calls:
    type: int
    unit: call

plans:
  - id: free
    name: Free Plan
    prices:
      monthly: { amount: 0 }
    limits:
      seats: 1
      api_calls: 1000

  - id: pro
    name: Pro Plan
    trial_days: 14
    prices:
      monthly: { amount: 2900 }
      yearly: { amount: 29000 }
    limits:
      seats: 10
      api_calls: 50000

  - id: pro_lifetime
    name: Pro Lifetime
    billing_model: one_time
    prices:
      one_time: { amount: 7900 }
    limits:
      seats: 10
      api_calls: 50000

Note: Plans with billing_model: one_time create Stripe Payment Intents instead of Subscriptions. Use the one_time price key instead of monthly/yearly.

3. Validate the configuration

raterunner validate raterunner/billing.yaml

4. Preview changes (dry run)

export STRIPE_SANDBOX_KEY=sk_test_...
raterunner apply --env sandbox --dry-run raterunner/billing.yaml

5. Apply to Stripe

raterunner apply --env sandbox raterunner/billing.yaml

After applying, Raterunner creates a provider file with Stripe IDs:

your-project/
└── raterunner/
    ├── billing.yaml           # Your billing configuration
    └── stripe_sandbox.yaml    # Generated: Stripe IDs

Commands

init

Initialize a new billing configuration with example plans.

raterunner init              # Creates raterunner/billing.yaml
raterunner init ./my-app     # Creates my-app/raterunner/billing.yaml
raterunner init --force      # Overwrite existing files

The generated billing.yaml includes:

  • Free, Pro, and Enterprise plan templates
  • Example entitlements (projects, API calls, support)
  • Comments with documentation links

validate

Validate a billing or provider configuration against the JSON Schema.

raterunner validate raterunner/billing.yaml
raterunner validate raterunner/stripe_sandbox.yaml

Validates:

  • Schema compliance
  • Required fields
  • Valid references (entitlements, plan IDs)
  • Pricing model correctness

apply

Sync billing configuration to Stripe. Creates products, prices, coupons, and promotion codes.

# Preview changes (no writes to Stripe)
raterunner apply --env sandbox --dry-run raterunner/billing.yaml

# Apply changes to sandbox
raterunner apply --env sandbox raterunner/billing.yaml

# Apply to production
raterunner apply --env production raterunner/billing.yaml

# Output diff as JSON
raterunner apply --env sandbox --dry-run --json raterunner/billing.yaml

Options:

OptionDescription
--envTarget environment: sandbox or production
--dry-runPreview changes without applying
--jsonOutput diff as JSON
--forceForce application, skip confirmation

What it does:

Stripe APIPurpose
POST /v1/productsCreate products for plans and addons
POST /v1/pricesCreate prices (flat, per-unit, tiered)
POST /v1/couponsCreate discount coupons
POST /v1/promotion_codesCreate promotion codes
POST /v1/prices/{id}Archive old prices when amounts change

Output file:

After successful apply, creates stripe_sandbox.yaml or stripe_production.yaml:

# raterunner/stripe_sandbox.yaml (auto-generated)
provider: stripe
environment: sandbox
synced_at: "2026-01-15T10:30:00Z"
plans:
  free:
    product_id: prod_ABC123
    prices:
      monthly: price_XYZ789
  pro:
    product_id: prod_DEF456
    prices:
      monthly: price_UVW012
      yearly: price_RST345

import

Import existing Stripe products/prices to YAML files. Useful for migrating existing Stripe setup to Raterunner.

raterunner import --env sandbox --output raterunner/billing.yaml

Creates:

  • raterunner/billing.yaml — billing configuration
  • raterunner/stripe_sandbox.yaml — provider ID mappings

What it reads:

Stripe APIPurpose
GET /v1/productsFetch all products
GET /v1/pricesFetch all prices

truncate

Archive all products and prices in Stripe sandbox. Sandbox only — refuses to run against production.

raterunner truncate           # Interactive confirmation
raterunner truncate --confirm # Skip confirmation (for CI/CD)

What it does:

Stripe APIPurpose
POST /v1/prices/{id}Archive prices (set active: false)
POST /v1/products/{id}Archive products (set active: false)
DELETE /v1/coupons/{id}Delete coupons

config

Manage CLI settings.

raterunner config set quiet true   # Enable quiet mode
raterunner config get quiet        # Get current value
raterunner config list             # List all settings
raterunner config path             # Show config file path

Global Flags

FlagDescription
--quiet, -qSuppress non-essential output (errors still shown)
--help, -hShow help
--version, -vShow version

Environment Variables

VariableDescription
STRIPE_SANDBOX_KEYStripe test API key (sk_test_...)
STRIPE_PRODUCTION_KEYStripe live API key (sk_live_...)

Set them in your shell:

export STRIPE_SANDBOX_KEY=sk_test_...
export STRIPE_PRODUCTION_KEY=sk_live_...

Or use a .env file (the CLI does not automatically load .env — use source or a tool like direnv):

# .env
STRIPE_SANDBOX_KEY=sk_test_...
STRIPE_PRODUCTION_KEY=sk_live_...

File Structure

A typical Raterunner setup:

your-project/
├── raterunner/
│   ├── billing.yaml           # Source of truth: plans, prices, entitlements
│   ├── stripe_sandbox.yaml    # Auto-generated: Stripe IDs for sandbox
│   └── stripe_production.yaml # Auto-generated: Stripe IDs for production
└── ... your app code
FilePurposeCommitted to Git?
billing.yamlYour billing configuration (plans, prices, entitlements)Yes
stripe_sandbox.yamlStripe IDs for test environmentYes
stripe_production.yamlStripe IDs for live environmentYes

All files should be committed to Git — this gives you:

  • Full history of what plans existed at any point
  • Which Stripe objects were created for each environment
  • When syncs happened (synced_at timestamp)

CI/CD Integration

GitHub Actions: Validate on PR

name: Validate Pricing

on:
  pull_request:
    paths:
      - 'raterunner/billing.yaml'

jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install Raterunner
        run: |
          curl -sL https://github.com/raterunner/cli/releases/download/v0.0.1/raterunner_0.0.1_linux_amd64.tar.gz | tar xz
          sudo mv raterunner /usr/local/bin/

      - name: Validate configuration
        run: raterunner validate raterunner/billing.yaml

      - name: Preview changes
        run: raterunner apply --env sandbox --dry-run raterunner/billing.yaml
        env:
          STRIPE_SANDBOX_KEY: ${{ secrets.STRIPE_SANDBOX_KEY }}

GitHub Actions: Sync on Merge

name: Sync Pricing

on:
  push:
    branches: [main]
    paths:
      - 'raterunner/billing.yaml'

jobs:
  sync:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install Raterunner
        run: |
          curl -sL https://github.com/raterunner/cli/releases/download/v0.0.1/raterunner_0.0.1_linux_amd64.tar.gz | tar xz
          sudo mv raterunner /usr/local/bin/

      - name: Sync to sandbox
        run: raterunner apply --env sandbox raterunner/billing.yaml
        env:
          STRIPE_SANDBOX_KEY: ${{ secrets.STRIPE_SANDBOX_KEY }}

      - name: Commit provider file
        run: |
          git config user.name github-actions
          git config user.email github-actions@github.com
          git add raterunner/stripe_sandbox.yaml
          git diff --staged --quiet || git commit -m "Update Stripe sandbox IDs"
          git push

Sync to Production (Manual Trigger)

name: Deploy to Production

on:
  workflow_dispatch:
    inputs:
      confirm:
        description: 'Type "production" to confirm'
        required: true

jobs:
  deploy:
    runs-on: ubuntu-latest
    if: github.event.inputs.confirm == 'production'
    steps:
      - uses: actions/checkout@v4

      - name: Install Raterunner
        run: |
          curl -sL https://github.com/raterunner/cli/releases/download/v0.0.1/raterunner_0.0.1_linux_amd64.tar.gz | tar xz
          sudo mv raterunner /usr/local/bin/

      - name: Sync to production
        run: raterunner apply --env production raterunner/billing.yaml
        env:
          STRIPE_PRODUCTION_KEY: ${{ secrets.STRIPE_PRODUCTION_KEY }}

      - name: Commit provider file
        run: |
          git config user.name github-actions
          git config user.email github-actions@github.com
          git add raterunner/stripe_production.yaml
          git diff --staged --quiet || git commit -m "Update Stripe production IDs"
          git push

Workflow Example

Here's a typical workflow for managing pricing changes:

1. Make changes locally

Edit raterunner/billing.yaml to add a new plan or change prices.

2. Validate

raterunner validate raterunner/billing.yaml

3. Preview changes

raterunner apply --env sandbox --dry-run raterunner/billing.yaml

4. Test in sandbox

raterunner apply --env sandbox raterunner/billing.yaml

Test the changes in your Stripe test environment.

5. Create a PR

git checkout -b update-pricing
git add raterunner/
git commit -m "Update Pro plan pricing"
git push origin update-pricing

6. Review and merge

The PR review ensures pricing changes are intentional. After merge, CI automatically syncs to sandbox.

7. Deploy to production

After testing in sandbox, manually trigger the production deployment (or set up automatic deployment).

Current Status

Note: Raterunner currently supports Stripe only. Support for Paddle and Chargebee is planned.

Contact raterunner@akorchak.software for other provider needs.

On this page