An unofficial command-line interface for the RevenueCat API v2. Manage projects, customers, subscriptions, purchases, entitlements, products, offerings, metrics, webhooks, and more from your terminal.
Includes analysis commands for correlating Apple Search Ads attribution with RevenueCat revenue data.
Pure Go (minimal deps), built-in caching, rate limiting, and multiple output formats.
Documentation:
- Command reference (generated):
docs/commands/rc.md - Usage notes:
docs/USAGE.md
git clone https://github.com/SaadBelfqih/rc-cli.git
cd rc-cli
make installThis installs rc to $(go env GOBIN) (or $(go env GOPATH)/bin if GOBIN is unset).
Or build locally:
make build
./rc --helpRequires Go 1.25+.
rc configureThis prompts for your RevenueCat API credentials and saves them to ~/.aads/rc-cli.yaml:
api_key: "sk_xxxxxxxxxxxxxxxxxxxxxxxx"
project_id: "proj_xxxxxxxxxxxxxxxxxxxxxxxx"rc config set api_key sk_xxxxxxxxxxxxxxxxxxxxxxxx
rc config set project_id proj_xxxxxxxxxxxxxxxxxxxxxxxxAll config values can be overridden with environment variables:
| Variable | Description |
|---|---|
RC_API_KEY |
RevenueCat v2 secret API key |
RC_PROJECT_ID |
RevenueCat project ID |
- Go to RevenueCat Dashboard > Project Settings > API Keys
- Generate a v2 secret API key (starts with
sk_) - Note your Project ID from the project settings page
All commands accept --project-id to override the configured project:
rc customers list --project-id proj_xxx-o, --output string Output format: json, table, yaml (default "json")
-v, --verbose Verbose HTTP request/response logging
--project-id string Override project ID from config
rc projects list
rc projects create --from-json '{"name":"My New Project"}'
rc projects get --id proj_xxx
rc apps list
rc apps get --id app_xxx
rc apps create --from-json '{"name":"My App","type":"app_store","app_store":{"bundle_id":"com.example.app"}}'
rc apps update --id app_xxx --from-json '{"name":"Updated Name"}'
rc apps delete --id app_xxx
rc apps public-api-keys --id app_xxx
rc apps storekit-config --id app_xxxrc customers list
rc customers list --starting-after cust_xxx --limit 50
rc customers get --id cust_xxx
rc customers get --id cust_xxx --expand attributes
rc customers create --from-json '{"id":"user_123"}'
rc customers delete --id cust_xxx
# Customer sub-resources
rc customers subscriptions --customer-id cust_xxx
rc customers purchases --customer-id cust_xxx
rc customers active-entitlements --customer-id cust_xxx
rc customers aliases --customer-id cust_xxx
rc customers attributes --customer-id cust_xxx
# Customer actions
rc customers grant-entitlement --customer-id cust_xxx --from-json '{"entitlement_id":"ent_xxx"}'
rc customers revoke-entitlement --customer-id cust_xxx --from-json '{"entitlement_id":"ent_xxx"}'
rc customers assign-offering --customer-id cust_xxx --from-json '{"offering_id":"ofr_xxx"}'
rc customers set-attributes --customer-id cust_xxx --from-json '{"attributes":[{"key":"$email","value":"user@example.com"}]}'
rc customers transfer --customer-id cust_xxx --from-json '{"target_customer_id":"cust_yyy"}'
# Customer virtual currencies
rc customers virtual-currencies balances --customer-id cust_xxx
rc customers virtual-currencies create-transaction --customer-id cust_xxx --from-json '{"adjustments":{"GLD":100}}'
rc customers virtual-currencies update-balance --customer-id cust_xxx --from-json '{"adjustments":{"GLD":500}}'
# Blocked customers (beta)
rc customers blocked-customers list
rc customers blocked-customers add --id cust_xxx
rc customers blocked-customers remove --id cust_xxxrc subscriptions list --store-id "com.app.monthly"
rc subscriptions get --id sub_xxx
rc subscriptions cancel --id sub_xxx
rc subscriptions refund --id sub_xxx
rc subscriptions entitlements --id sub_xxx
rc subscriptions management-url --id sub_xxx
rc subscriptions transactions --id sub_xxx
rc subscriptions refund-transaction --id sub_xxx --transaction-id "GPA.000-000-000-000"rc purchases list --store-id "1000000123456789"
rc purchases get --id pch_xxx
rc purchases refund --id pch_xxx
rc purchases entitlements --id pch_xxxrc entitlements list
rc entitlements get --id ent_xxx
rc entitlements create --from-json '{"lookup_key":"premium"}'
rc entitlements update --id ent_xxx --from-json '{"display_name":"Premium Access"}'
rc entitlements delete --id ent_xxx
# Entitlement product associations
rc entitlements products --id ent_xxx
rc entitlements attach-products --id ent_xxx --from-json '{"products":["prod_xxx"]}'
rc entitlements detach-products --id ent_xxx --from-json '{"products":["prod_xxx"]}'rc products list
rc products list --app-id app_xxx
rc products get --id prod_xxx
rc products create --from-json '{"store_identifier":"com.app.premium","app_id":"app_xxx","type":"subscription"}'
rc products delete --id prod_xxx
rc products create-in-store --id prod_xxx --from-json '{"store_information":{"duration":"ONE_MONTH","subscription_group_name":"Premium"}}'rc offerings list
rc offerings get --id ofr_xxx
rc offerings create --from-json '{"lookup_key":"default"}'
rc offerings update --id ofr_xxx --from-json '{"display_name":"Default"}'
rc offerings delete --id ofr_xxx
rc packages list --offering-id ofr_xxx
rc packages get --id pkg_xxx
rc packages create --offering-id ofr_xxx --from-json '{"lookup_key":"monthly"}'
rc packages update --id pkg_xxx --from-json '{"display_name":"Monthly"}'
rc packages delete --id pkg_xxx
# Package product associations
rc packages products --id pkg_xxx
rc packages attach-products --id pkg_xxx --from-json '{"products":["prod_xxx"]}'
rc packages detach-products --id pkg_xxx --from-json '{"products":["prod_xxx"]}'rc metrics overview
rc metrics overview --currency USD
rc metrics chart --name revenue
rc metrics chart --name mrr --resolution 2 --start-date 2025-01-01 --end-date 2025-12-31
rc metrics chart --name churn --currency USD --segment country
rc metrics chart-options --name revenueResolution values: 0 (day), 1 (week), 2 (month), 3 (quarter), 4 (year).
Available chart names: actives, actives_movement, actives_new, arr, churn, cohort_explorer, conversion_to_paying, customers_active, customers_new, ltv_per_customer, ltv_per_paying_customer, mrr, mrr_movement, refund_rate, revenue, subscription_retention, subscription_status, trial_conversion_rate, trials, trials_movement, trials_new.
rc virtual-currencies list
rc virtual-currencies get --code GLD
rc virtual-currencies create --from-json '{"code":"GLD","name":"Gold"}'
rc virtual-currencies update --code GLD --from-json '{"name":"Gold Coins"}'
rc virtual-currencies delete --code GLDrc paywalls create --from-json '{"offering_id":"ofr_xxx"}'rc invoices list --customer-id cust_xxx
rc invoices get-file --customer-id cust_xxx --id inv_xxxrc webhooks list
rc webhooks get --id wh_xxx
rc webhooks create --from-json '{"url":"https://example.com/webhook"}'
rc webhooks update --id wh_xxx --from-json '{"url":"https://example.com/webhook2"}'
rc webhooks delete --id wh_xxxThese commands iterate through customers, extract Apple Search Ads attribution, and correlate it with revenue data.
Show which Apple Search Ads keywords generate the most revenue.
rc keyword-revenue
rc keyword-revenue --min-revenue 10
rc keyword-revenue --sort subscribers
rc keyword-revenue --sort conversion_rate
rc keyword-revenue --top 20
rc keyword-revenue --limit 500 # limit customers processed (faster, for testing)
rc keyword-revenue --refresh # ignore cache
rc keyword-revenue -o tableOutput fields:
| Field | Description |
|---|---|
keyword |
Normalized ASA keyword |
total_revenue_usd |
Total revenue from all subscriptions and purchases |
subscribers |
Number of active subscribers attributed to this keyword |
trials |
Number of trialing users attributed to this keyword |
conversion_rate |
Percentage of users who converted from trial to subscriber |
avg_ltv_usd |
Average lifetime value per subscriber |
Campaign & ad group revenue breakdown from RevenueCat data.
rc campaign-roi
rc campaign-roi --campaign 12345
rc campaign-roi --sort avg_ltv
rc campaign-roi --sort subscribers
rc campaign-roi -o tableOutput fields:
| Field | Description |
|---|---|
campaign_id |
Apple Search Ads campaign ID |
ad_group_id |
Apple Search Ads ad group ID |
keyword |
Normalized ASA keyword |
subscribers |
Number of active subscribers |
total_revenue_usd |
Total revenue in USD |
avg_ltv_usd |
Average lifetime value per subscriber |
rc configure # Interactive setup
rc config show # Show current config
rc config set api_key sk_xxx
rc config set project_id proj_xxx
rc versionCommands that accept --from-json support three input modes:
# Inline JSON
rc customers create --from-json '{"id":"user_123"}'
# From file
rc customers create --from-json @customer.json
# From stdin
cat customer.json | rc customers create --from-json @-The CLI wraps the full RevenueCat REST API v2 with typed service methods:
| Resource | Operations |
|---|---|
| Projects | list, create, get |
| Apps | list, get, create, update, delete, public-api-keys, storekit-config |
| Customers | list, get, create, delete, subscriptions, purchases, active-entitlements, aliases, attributes, set-attributes, assign-offering, grant-entitlement, revoke-entitlement, transfer |
| Blocked Customers | list, add, remove (beta) |
| Customer Virtual Currencies | balances, create-transaction, update-balance |
| Subscriptions | list, get, cancel, refund, entitlements, management-url, transactions, refund-transaction |
| Purchases | list, get, refund, entitlements |
| Entitlements | list, get, create, update, delete, products, attach-products, detach-products |
| Products | list, get, create, delete, create-in-store |
| Offerings | list, get, create, update, delete |
| Packages | list, get, create, update, delete, products, attach-products, detach-products |
| Virtual Currencies | list, get, create, update, delete |
| Paywalls | create |
| Invoices | list, get-file |
| Metrics | overview, chart, chart-options |
| Webhooks | list, get, create, update, delete |
RevenueCat API (api.revenuecat.com/v2)
|
+-- List customers (paginated, 100 per page)
| |
| +-- For each customer:
| +-- Fetch with expanded attributes
| +-- Extract ASA attribution ($keyword, $campaign, $adGroup)
| +-- Skip if no ASA attribution (saves API calls)
| +-- Fetch production subscriptions
| +-- Fetch production purchases
| +-- Calculate total revenue, trial/subscriber status
|
+-- Cache results to ~/.aads/rc_cache.json (1 hour TTL)
|
+-- Aggregate by keyword or campaign/adgroup/keyword
|
+-- Output as JSON, table, or YAML
| Attribution | Keys checked (in order) |
|---|---|
| Keyword | $keyword, $searchAdsKeyword, $search_ads_keyword, keyword |
| Campaign ID | $campaign, $searchAdsCampaignId, $search_ads_campaign_id, campaign_id |
| Ad Group ID | $adGroup, $searchAdsAdGroupId, $search_ads_ad_group_id, ad_group_id |
Customer data for the analysis commands is cached to ~/.aads/rc_cache.json with a 1-hour TTL.
- Cache is only saved for full fetches (not when
--limitis used) - Cache is invalidated when the project ID changes
- Use
--refreshto force a re-fetch - Cache is shared between
keyword-revenueandcampaign-roi
Built-in rate limiter at 450 requests/minute for customer iteration. The CLI also handles HTTP 429 responses by respecting the Retry-After header.
rc-cli/
├── main.go
├── go.mod
├── Makefile
├── cmd/ # Cobra commands
│ ├── root.go # Root cmd, global flags, output helpers
│ ├── configure.go # Interactive credential setup
│ ├── config.go # config show/set commands
│ ├── version.go
│ ├── projects.go # projects + apps
│ ├── customers.go # customers CRUD + actions
│ ├── subscriptions.go # subscriptions
│ ├── purchases.go # purchases
│ ├── entitlements.go # entitlements + product associations
│ ├── products.go # products
│ ├── offerings.go # offerings + packages
│ ├── metrics.go # metrics + charts
│ ├── webhooks.go # webhooks
│ ├── virtual_currencies.go # virtual currencies + customer VC commands
│ ├── paywalls.go # paywalls
│ ├── invoices.go # invoices
│ ├── blocked_customers.go # blocked customers (beta)
│ ├── keyword_revenue.go # ASA keyword-revenue analysis
│ └── campaign_roi.go # ASA campaign-roi analysis
├── internal/
│ ├── api/ # RevenueCat HTTP client + services
│ │ ├── client.go # HTTP client, rate limit retry, service factories
│ │ ├── projects.go # ProjectService, AppService
│ │ ├── customers.go # CustomerService
│ │ ├── subscriptions.go # SubscriptionService
│ │ ├── purchases.go # PurchaseService
│ │ ├── entitlements.go # EntitlementService
│ │ ├── products.go # ProductService
│ │ ├── offerings.go # OfferingService, PackageService
│ │ ├── metrics.go # MetricsService
│ │ ├── webhooks.go # WebhookService
│ │ ├── virtual_currencies.go # VirtualCurrencyService
│ │ ├── paywalls.go # PaywallService
│ │ ├── iterate.go # Customer iteration orchestrator (ASA analysis)
│ │ └── cache.go # Local JSON cache
│ ├── types/
│ │ └── types.go # API types, output rows
│ ├── config/
│ │ └── config.go # ~/.aads/rc-cli.yaml + env vars
│ └── output/
│ ├── output.go # Format dispatcher
│ ├── json.go
│ ├── table.go
│ └── yaml.go
├── docs/
│ ├── USAGE.md
│ └── commands/ # Generated command reference
└── tools/
└── gendocs/ # Command doc generator
| Package | Purpose |
|---|---|
github.com/spf13/cobra |
CLI framework |
gopkg.in/yaml.v3 |
Config + YAML output |
No external HTTP client, table, or API client libraries.
This is an unofficial CLI tool and is not affiliated with, endorsed by, or associated with RevenueCat Inc. or Apple Inc. It runs on your computer or server and only communicates with RevenueCat's public API. You are responsible for how you use it.
MIT. See LICENSE.