CherrySub CLI
Install the CLI, automate store setup, migrate catalogs and purchases, and manage profiles.
Download this chapterOn this page
CherrySub CLI signs you in, chooses your project and app, and provisions store
credentials locally. It uses the same account permissions as the dashboard.
The preview defaults to staging (https://api-staging.cherrysub.com).
Install
macOS / Linux (arm64 or amd64), without Go or Node.js:
curl -fsSL https://api-staging.cherrysub.com/cli/install.sh -o /tmp/cherrysub-install.sh
sh /tmp/cherrysub-install.sh
export PATH="$HOME/.local/bin:$PATH"
cherrysub --versionThe installer verifies the archive's SHA-256 checksum before installing. It
requires no sudo. CHERRYSUB_INSTALL_DIR changes the destination. Add that
directory to your shell's PATH for future terminal sessions.
Windows: download amd64
or arm64,
verify against checksums.txt,
and extract cherrysub.exe to a directory on PATH.
Repository contributors can run go install ./cmd/cherrysub from the checkout.
python3 scripts/build-cli.py produces all six platform archives and checksums.
First connection
cherrysub auth login
cherrysub setup apple
# or:
cherrysub setup google --oauth-client ./google-desktop-client.jsonThe CLI prompts for missing project/app selections and remembers your choice.
If you have several projects, --project UUID selects one explicitly. Pass the
app UUID after apple or google to connect a particular app. The dashboard's
Integrations page provides the command with both identifiers filled in.
An existing app credential is kept unless you pass --rotate. Shared deployment
credentials can be replaced with an app credential. Old store keys are never
automatically revoked, including during rotation.
cherrysub projects list
cherrysub projects use PROJECT_UUID
cherrysub apps list
cherrysub apps use APP_UUID
cherrysub setup apple APP_UUID --dry-run --json
cherrysub stores status APP_UUID --json--dry-run checks CherrySub access and prints a plan. It does not sign in to a
store or create/upload keys. It can update the CLI session's selected project.
Apple automation
setup apple performs local Apple Account sign-in, trusted-device or SMS 2FA,
team selection, a bundle-ID lookup, and In-App Purchase key access checks. After
you confirm the app and team, it creates and downloads an In-App Purchase key
and sends it directly to CherrySub. Passwords and Apple session cookies are not
stored. The key exists only in process memory before upload.
Use an Apple role allowed to create In-App Purchase keys. The app must already exist in App Store Connect with the bundle ID configured in CherrySub. Account agreements or Apple's key limits may need attention in App Store Connect. This uses Apple's web-session endpoints, which can change independently of the public API. File import is available if interactive sign-in is unavailable.
cherrysub setup apple APP_UUID --sms
cherrysub setup apple APP_UUID --team-id 123456 --rotate
cherrysub setup apple APP_UUID --key-file ./SubscriptionKey_ABC123DEFG.p8 --issuer-id ISSUER_UUIDKey ID is detected from SubscriptionKey_ID.p8 (also AuthKey_ID.p8) or supplied
with --key-id. Use an In-App Purchase key, not an App Store Connect API key.
The key format alone cannot distinguish them.
Google automation
Google browser authorization needs a Desktop app OAuth client belonging to
your organization. A CherrySub-owned verified OAuth client is not bundled in
this preview. Create one at Google Cloud credentials,
configure its audience/test users as required by Google, download the client
JSON, and supply --oauth-client. This is an OAuth client file, distinct from
the service-account key the setup command will create.
cherrysub setup google APP_UUID \
--oauth-client ./google-desktop-client.json \
--cloud-project my-google-project \
--developer-account https://play.google.com/console/u/0/developers/1234567890123456789/app-listSign in as someone who can enable services, create service accounts/keys in that Cloud project, and manage Play users. The command:
- Uses browser OAuth with PKCE and a loopback callback.
- Enables IAM and Android Publisher APIs on the selected existing Cloud project.
- Creates or reuses an app-specific
cherrysub-*service account. - Grants the package's app information, financial data, and order/subscription permissions.
- Creates a JSON key in memory and uploads it to CherrySub.
The temporary Play account-level bootstrap permission is removed even when package access fails; a cleanup failure is reported. Existing users' permissions are preserved. Organization policies blocking key creation are surfaced; the CLI does not change those policies. Google OAuth tokens never go to CherrySub.
Existing service-account key:
cherrysub setup google APP_UUID --service-account ./service-account.jsonScripting and profiles
Use --json --no-input --yes with explicit identifiers for unattended setup.
Errors go to stderr and return a nonzero exit status. Store credentials are
never included in JSON output. auth login --password-stdin --email EMAIL
accepts a password via stdin without a password command-line argument.
Supported secret environment variables:
CHERRYSUB_PASSWORD: CherrySub sign-in only.CHERRYSUB_APPLE_PASSWORD,CHERRYSUB_APPLE_2FA_CODE: local Apple sign-in.CHERRYSUB_GOOGLE_ACCESS_TOKEN: existing user OAuth access token withcloud-platformandandroidpublisherscopes; alternative to browser sign-in.CHERRYSUB_GOOGLE_CLIENT_ID,CHERRYSUB_GOOGLE_CLIENT_SECRET: alternative to the Desktop OAuth client JSON file.
CHERRYSUB_EMAIL and CHERRYSUB_APPLE_ID supply account emails. Avoid shell
tracing and putting secret values directly into shell history.
Sessions are private files (0600 on macOS/Linux) in the OS user config directory
under cherrysub/. The containing directory is 0700. On Windows use your private
user profile directory with its normal account ACLs. CHERRYSUB_CONFIG_DIR
overrides the directory. Passwords/store credentials are never saved there.
cherrysub --profile self-hosted --api-url https://api.example.com auth login
cherrysub --profile self-hosted setup apple APP_UUID
cherrysub auth status
cherrysub auth logoutA signed-in profile cannot be retargeted to another API. Use another profile.
The CLI rejects credential-bearing redirects and non-HTTPS origins (except
literal loopback IPs for development). Profile locks serialize session-scoped
project selection; concurrent jobs should sign in to separate profiles. After
a hard crash, remove the reported .lock file only when no command is running.
Create new resources:
cherrysub projects create --name "My project"
cherrysub apps create --name "My app" --bundle-id com.example.app --keys-out ./sdk-keys.jsonApp creation saves the one-time SDK keys to a new private file. It never overwrites an existing file or prints the secret key.
After setup / recovery
credential_saved means CherrySub accepted and encrypted the credential. It
does not mean a live purchase or all store permissions have been verified.
Notifications (Apple server notifications / Google RTDN) remain a separate
step. Use the dashboard setup guide and make a sandbox purchase to verify the
complete flow. New Google permissions may need time to propagate.
If upload fails after key creation, the CLI reports the new key's ID, retains
old keys, and exits nonzero. Check stores status before retrying because a
network timeout can occur after the server commits. Revoke an unused new key
in the store console if needed. Newly created Apple keys cannot be downloaded
again. CLI tests use local Apple/Google/API fixtures; live account provisioning
is performed only when an operator runs setup with their own account.
Each CLI archive includes THIRD_PARTY_NOTICES.md for the MIT-licensed
RevenueCat CLI components adapted for local
store provisioning.
Catalog and purchase migration
The CLI reads RevenueCat configuration locally, imports portable CSV/JSON files, and lists connected App Store or Google Play products. Every catalog command previews by default; use --apply to apply a reviewed plan. A verified owner/admin session and the selected CherrySub project scope catalog operations.
cherrysub migrate revenuecat APP_ID --source-project RC_PROJECT_ID
cherrysub migrate revenuecat APP_ID --source-project RC_PROJECT_ID --apply
cherrysub migrate store google APP_ID --product premium,credits --apply
cherrysub migrate file ./catalog.json APP_ID --apply
cherrysub migrate history APP_IDRevenueCat needs a V2 secret key with project-configuration read permissions. Enter it at the masked prompt or use CHERRYSUB_REVENUECAT_API_KEY in automation. --source-app resolves ambiguous source-app matches. --output saves a new private JSON catalog that can be reviewed in the dashboard. --activate-current explicitly selects the source's current offering; leaving it out preserves the destination selection.
The distinct purchase command uses a CherrySub app secret and normal verified receipt ingestion. CHERRYSUB_APP_SECRET selects the app regardless of the dashboard project/app selection. It does not use the hosted session cookie. Preview checks the file locally; applying verifies each purchase server-side and may emit normal webhooks.
cherrysub migrate purchases --template > purchases.csv
cherrysub migrate purchases ./purchases.csv
cherrysub migrate purchases ./purchases.csv --apply --checkpoint ./progress.jsonl
cherrysub migrate purchases ./purchases.csv --apply --resume --checkpoint ./progress.jsonlUse real StoreKit 2 JWS transactions or Google purchase tokens and retain exact App User IDs. Checkpoints bind the file, API origin, and app secret and contain no plaintext receipt/token or user identity. Completed records are skipped on resume. Do not modify the input file to fix a rejected row while reusing its checkpoint; use a separate corrected file and checkpoint. The complete migration guide covers source formats, Google base-plan policy, limits, failure recovery, and cutover validation.