Tools/Growth CLI

Growth CLI

Use growth-cli to manage contacts, campaigns, workflows, surveys, partners and payouts from the terminal.

growth-cli is an api2cli-generated command line client for Growth's organization-scoped public API. The active organization comes from the API key, not from a command argument.

Install

On this machine the CLI is built and linked with api2cli:

api2cli bundle growth
api2cli link growth

Authentication

An API key is scoped to one organization. Store one profile per organization and switch between them:

growth-cli auth set nsk_your_key --profile amencolors   # first profile becomes active
growth-cli auth set nsk_other_key --profile my-other-org
growth-cli auth list                                    # "*" marks the active profile
growth-cli auth use my-other-org                        # switch, persists across runs
growth-cli --profile amencolors auth test               # one-shot override

Resolution order: --profile flag, then GROWTH_PROFILE, then the profile saved by auth use, then default.

Environment variables are also supported:

GROWTH_API_KEY=nsk_your_key growth-cli org show
GROWTH_API_URL=http://localhost:3050/api/v1 growth-cli contacts list

GROWTH_API_KEY overrides every profile and makes --profile a no-op. auth list warns when it is set. Use it only in CI, where there is a single organization.

Contacts

growth-cli contacts list --status subscribed --limit 50
growth-cli contacts get [email protected]
growth-cli contacts identify --email [email protected] --tags signup --field utm_source=google
growth-cli contacts update [email protected] --email [email protected] --field plan=pro
growth-cli contacts sync --email [email protected] --event-key order_123 \
  --event-type purchase_paid --event-source stripe --tags customer
growth-cli contacts unsubscribe [email protected]

contacts sync applies the same merge as identify and additionally records a deduplicated lifecycle event: replaying the same --event-key is a no-op, which makes it safe to call from a webhook that retries.

Use identify for app-side events: it creates the contact when missing, adds tags without dropping existing ones, and merges custom fields. create is a sync command that replaces the whole tag set and the whole custom-field record — calling it on signup would wipe tags written by your freebie flow. See the Identify Email Contact API.

contacts delete is an alias for unsubscribe. It preserves contact history and send/event analytics.

Tags

growth-cli tags list
growth-cli tags add [email protected] --tags vip,newsletter
growth-cli tags remove [email protected] --tags vip

Adding a tag can trigger active tag-based workflows for subscribed contacts. tags add requires the contact to exist; use contacts identify when it may not.

Workflows

growth-cli workflows list --status active --trigger all
growth-cli workflows get <workflow-id> --export > onboarding.json
growth-cli workflows create --file onboarding.json
growth-cli workflows update <workflow-id> --file onboarding.json
growth-cli workflows publish <workflow-id>
growth-cli workflows delete <workflow-id>
growth-cli workflows trigger <workflow-id> --email [email protected] --tags freebie

workflows list shows only API request workflows unless you pass --trigger all.

create and update take a JSON document where a condition step carries its own yes / no child arrays; get --export prints that same shape, so a workflow round-trips: export, edit, update. update replaces the entire step tree — use publish / pause to change only the status.

Transactional

growth-cli transactional list
growth-cli transactional get freebie-kit --export > freebie-kit.json
growth-cli transactional create --file freebie-kit.json
growth-cli transactional update freebie-kit --file freebie-kit.json
growth-cli transactional archive freebie-kit
growth-cli transactional send welcome --email [email protected] --var firstName=Jane,plan=pro

tx is an alias for transactional. --var fills the template's @{variable} placeholders; --tags are merged onto the contact rather than replacing its tags.

create and update take one JSON document holding both the definition and its email content (slug, name, subject, contentBlocks); get --export prints that same shape, so a transactional round-trips: export, edit, update. update only writes the keys present in the file. See the Manage Transactional Emails API.

Campaigns

growth-cli campaigns list --status sent --limit 10
growth-cli campaigns create --name "August" --subject "What shipped" --markdown body.md --tags customers
growth-cli campaigns get <campaign-id> --export > august.json
growth-cli campaigns update <campaign-id> --file august.json
growth-cli campaigns send <campaign-id> --test [email protected]
growth-cli campaigns schedule <campaign-id> --at 2026-08-01T09:00
growth-cli campaigns analytics <campaign-id>

--markdown wraps a file in a single markdown block; pass --file with a JSON document to author the full contentBlocks array (headings, buttons, images, surveys). campaigns send without --test mails every subscribed contact matching the audience — there is no undo. See the Email Campaigns API.

Surveys

growth-cli surveys list
growth-cli surveys create --type nps --question "How likely are you to recommend us?"
growth-cli surveys responses <survey-id> --limit 100

The returned surveyId is what a survey content block references. See the Email Surveys API.

Affiliate Events

growth-cli affiliate click --ref partner-a --landing-url https://example.com
growth-cli affiliate signup --customer-key cus_123 --ref partner-a
growth-cli affiliate payment --customer-key cus_123 --amount 4900 --currency usd --source-id invoice_123

Partners, Promo Codes And Payouts

growth-cli affiliates create --name "Marie Dupont" --email [email protected]
growth-cli affiliates list --status active
growth-cli promo-codes create --code MARIE20 --percent 20 --affiliate <affiliate-id>
growth-cli promo-codes sync
growth-cli commissions list --status pending
growth-cli commissions approve <commission-id>
growth-cli affiliates payout <affiliate-id>
growth-cli payments summary

Paying a partner is a two-step flow: approve each pending commission, then run the payout, which transfers the approved total from the organization's connected Stripe balance. Amounts are in minor units. See the Affiliate Partners API, Affiliate Promo Codes API and Affiliate Revenue API.

Senders And Routing

growth-cli providers list
growth-cli providers test <provider-id>

growth-cli identities list
growth-cli identities create --provider <provider-id> --from "Acme <[email protected]>"
growth-cli identities create --provider <provider-id> --from [email protected] --from-name Acme --reply-to [email protected]
growth-cli identities delete <identity-id>

growth-cli routing show
growth-cli routing set --default --identity <identity-id>
growth-cli routing set --stream marketing --identity <identity-id>
growth-cli routing set --stream transactional --identity <identity-id>
growth-cli routing set --stream marketing --clear

Provider accounts are created in the Growth UI, where credentials are encrypted at rest — the CLI reads and tests them but never receives credentials back, not even masked.

providers test checks the stored credentials; for Amazon SES it also reports the 24-hour quota, the per-second send rate, whether sending is enabled and whether the account is still in the sandbox.

identities create is an upsert: re-posting the same address updates it, so the command is safe to rerun from a provisioning script. Routing resolves in this order: the stream's identity, then the default identity, then the platform sender. See Sending From Your Own Domain.

Output

All commands support:

growth-cli contacts list --json
growth-cli contacts list --format csv --fields email,status,tags

Use --profile or GROWTH_PROFILE to switch organizations. Use growth-cli org before imports or automation runs to confirm the active organization.

Sending from your Google account