Merchant CLI
Install @refcampaign/cli and inspect RefCampaign merchant data from a terminal or CI job.
@refcampaign/cli is a read-only command-line client for merchant reporting. It reads campaigns, affiliates, conversions, commissions, and payouts; it does not change those resources.
Installation
The CLI requires Node.js 22, 23, or 24.
Install it globally:
npm install --global @refcampaign/cli
refcampaign --versionOr run the published package without a global install:
npx @refcampaign/cli --version
npx @refcampaign/cli status --jsonRun refcampaign --help or refcampaign <group> <command> --help to inspect the help shipped with your installed version. The examples below use the global executable.
Authentication
Create a merchant API key in Settings → API keys, then start the interactive login:
refcampaign auth loginThe prompt masks the key while you type. Login validates the key with RefCampaign before saving it to the operating-system keyring: Keychain on macOS, Secret Service on Linux, or Credential Manager on Windows. The CLI does not create a local credentials file. Surrounding whitespace is rejected.
Inspect or remove the keyring credential with:
refcampaign auth status
refcampaign auth status --json
refcampaign auth logoutauth status reports environment or keyring as the active source. auth logout removes only the keyring entry and is safe to repeat.
CI and environment priority
For CI, add REFCAMPAIGN_API_KEY as a masked, protected secret in the CI provider and expose it to the job environment. The CLI uses a non-empty REFCAMPAIGN_API_KEY before consulting the keyring, so headless jobs do not need an interactive login. Do not print the variable or write it to a repository file.
merchant-report:
script:
- refcampaign status --json
- refcampaign conversions summary --period 30d --jsonCommands and filters
Every resource command is read-only. --json and --csv are mutually exclusive. The global --debug option adds redacted diagnostic details to stderr.
| Command | Options |
|---|---|
refcampaign auth login | Interactive masked prompt; validates and saves the keyring credential |
refcampaign auth status | --json, --csv |
refcampaign auth logout | No command-specific options |
refcampaign status | --json, --csv |
refcampaign campaigns list | Common list options; --status DRAFT|ACTIVE|PAUSED|COMPLETED|ARCHIVED |
refcampaign campaigns get <id> | --json, --csv |
refcampaign affiliates list | Common list options; --status ACTIVE|APPROVED_UNASSIGNED|SUSPENDED|ARCHIVED; --campaign-id <id> |
refcampaign affiliates get <id> | --json, --csv |
refcampaign conversions list | Common list options; --campaign-id <id>; --affiliate-id <id>; --status PENDING|APPROVED|REFUNDED|REJECTED|DISPUTED; --from <date>; --to <date>; --min-amount <amount>; --max-amount <amount> |
refcampaign conversions summary | --period 7d|30d|mtd|ytd (default 30d); --group-by status|campaign; --campaign-id <id>; --json; --csv |
refcampaign commissions list | Common list options; --campaign-id <id>; --affiliate-id <id>; --status PENDING|APPROVED|PAID|REJECTED|PAYABLE|LOCKED|PAID_PENDING|DISPUTED; --from <date>; --to <date>; --min-amount <amount>; --max-amount <amount> |
refcampaign payouts list | Common list options; --affiliate-id <id>; --status PENDING|INVOICE_UPLOADED|PROCESSING|APPROVED|PAID|REJECTED|CANCELLED; --method PAYPAL|BANK_TRANSFER|WISE; --from <date>; --to <date> |
refcampaign payouts get <id> | --json, --csv |
Common list options are --limit <number> (1–100, default 50), --offset <number> (zero-based, default 0), --all, --json, and --csv. Amount filters accept non-negative decimals with at most two decimal places. Date filters accept a real ISO 8601 date such as 2026-07-01 or a timestamp with seconds and Z or a UTC offset.
Example queries:
refcampaign status
refcampaign campaigns list --status ACTIVE
refcampaign campaigns get camp_123 --json
refcampaign affiliates list --campaign-id camp_123 --all
refcampaign affiliates get aff_123 --json
refcampaign conversions list --status APPROVED --from 2026-07-01 --to 2026-07-31 --csv
refcampaign conversions summary --period 30d --group-by campaign --json
refcampaign commissions list --status PAYABLE --min-amount 10.00 --all
refcampaign payouts list --method BANK_TRANSFER --status PAID --json
refcampaign payouts get pay_123 --csvOutput contracts
The default output is a human-readable table. Dates in tables use the machine's locale and time zone. List tables print More records are available. Use --offset N to continue. when another page exists.
Machine-readable modes are stable for scripting:
--jsonemits one JSON document followed by a newline. Detail and summary commands use{ "data": ... }; list commands use{ "data": [...], "pagination": ... }.--csvemits one header row and CRLF-delimited records. Potential spreadsheet formulas in text cells are prefixed with an apostrophe. List and detail columns are the same fields shown below.- stdout contains successful command output only. Errors, retry notices, and
--debugdiagnostics go to stderr. Secrets are redacted from stderr.
| Command family | Table/CSV fields |
|---|---|
auth status | source, merchant, valid |
status | merchant, active campaigns, Stripe connected, Stripe mode |
| campaigns | id, name, status, commission rate/type, start, end |
| affiliates | id, display name, email, status, created |
| conversions | id, campaign, affiliate, amount/currency, commission/currency, status, created |
conversions summary | totals: count, revenue, commissions, period, range; optional status or campaign groups. CSV columns are scope,key,label,count,revenue,revenue_currency,commissions,commissions_currency,period,range_from,range_to |
| commissions | id, affiliate, campaign, amount/currency, status, created |
| payouts | id, affiliate, amount/currency, method, status, requested |
JSON list example:
refcampaign campaigns list --limit 1 --json{
"data": [
{
"id": "camp_123",
"name": "Partner program",
"description": null,
"status": "ACTIVE",
"commissionRate": 20,
"commissionType": "PERCENTAGE",
"startDate": "2026-07-01T00:00:00.000Z",
"endDate": null,
"createdAt": "2026-06-20T08:30:00.000Z"
}
],
"pagination": {
"total": 3,
"limit": 1,
"offset": 0,
"hasMore": true,
"page": 1,
"totalPages": 3
}
}CSV example:
refcampaign campaigns list --limit 1 --csvid,name,status,commission_rate,commission_type,start,end
camp_123,Partner program,ACTIVE,20,PERCENTAGE,2026-07-01T00:00:00.000Z,Pagination and retries
Without --all, a list command requests one page. Use the displayed next offset, or select another page explicitly with --limit and --offset. With --all, the CLI starts at the requested offset and follows every page until the API reports hasMore: false; JSON and CSV then contain the combined rows.
Each HTTP request has a 10-second timeout and at most three attempts. The CLI retries timeouts, transient DNS/connection failures, HTTP 429, and HTTP 5xx responses. It honors a valid Retry-After header; otherwise delays are approximately 1 second then 2 seconds plus up to 999 ms of jitter. Retry notices appear on stderr in an interactive terminal or when --debug is enabled. Other HTTP 4xx responses are not retried.
Advanced API URL override
REFCAMPAIGN_API_URL is an advanced, process-environment override for the API origin. The selected origin receives the Authorization: Bearer header, so it must be an endpoint you trust. The default is https://app.refcampaign.com. The value must be an origin root: a trailing / is accepted, but a username, password, path, query, or fragment is rejected. HTTPS is mandatory except when the host is exactly localhost, 127.0.0.1, or [::1]; ports are allowed. The CLI never persists this override. Never send a production key to an overridden origin.
Use the override only for a controlled non-production environment:
REFCAMPAIGN_API_URL=https://app.test.refcampaign.com refcampaign status --jsonExit codes
| Code | Meaning |
|---|---|
| 0 | Success, version, or help |
| 1 | API, network, timeout, incompatible-response, keyring, or unexpected failure |
| 2 | Invalid command, option, option combination, or local input |
| 3 | Missing, invalid, revoked, or insufficiently scoped credential; scripts may branch on exit code 3 |
Troubleshooting
No API key configured: runrefcampaign auth login, or exposeREFCAMPAIGN_API_KEYthrough the CI secret store.- Key reported as invalid or revoked: without printing its value, check directly whether
REFCAMPAIGN_API_KEYis defined in the shell or CI secret store. If it is defined, replace or unset it there;refcampaign auth loginchanges only the keyring and cannot override the environment source. IfREFCAMPAIGN_API_KEYis absent, the keyring is the relevant source: userefcampaign auth logoutto remove a stale stored entry when needed, thenrefcampaign auth loginto validate and save the replacement. Remove surrounding whitespace before submitting it. - Key missing the
readscope: generate an API key with thereadscope. Replace or unsetREFCAMPAIGN_API_KEYwhen the environment is the active source; otherwise runrefcampaign auth loginwith the replacement keyring credential. - Secure credential store unavailable: unlock the OS keyring and retry. On headless CI, use the environment secret instead.
- HTTP 429 or 5xx: the CLI already retries up to three total attempts. Wait and retry later if the final attempt fails.
- Request timed out or network request failed: verify DNS, proxy, firewall, and the selected API origin. Add the global
--debugoption for redacted diagnostics. - Invalid date, amount, page, or filter: run the exact command with
--help; usage failures return exit code 2. - Unexpected response shape: update
@refcampaign/cli; the CLI rejects responses that do not match its shipped contract.