Skip to main content
The Atoa CLI is a command-line tool for interacting with the Atoa payment API from your terminal. Create payments, manage customers, test webhooks, and inspect transactions — without leaving the shell, and without writing a script. It’s scriptable for CI/CD, automated test pipelines, support workflows, and one-off operations. Source code: github.com

Log in with your browser

atoa login opens the dashboard, you approve, done. No token to copy-paste.

Test webhooks locally

atoa webhooks trigger PAYMENTS_STATUS fires a fake event at your sandbox URL — no real payment needed.

Two credential types

Your browser login runs account commands; an SDK key runs payments/data commands.

Shell completion

TAB-completes commands, flags, profile names, and key IDs across bash, zsh, and PowerShell.

Prerequisites

  • Node.js 20 or later — verify with node --version
  • An Atoa merchant account and a desktop browser on the same machine (login is browser-based). No account yet? Run atoa signup, or see the Getting Started guide.

Installation

Verify the install:
The CLI stores credentials locally under ~/.atoa/auth/, readable only by your user account.

First-time setup

Pair the CLI with your Atoa account through your browser:
Your default browser opens the Atoa dashboard, you approve the request, and the CLI is logged in. If your account has multiple businesses, you pick one (or run atoa business use <id> afterwards). A profile is created, named after your business.
atoa login requires an interactive terminal (TTY) and a desktop browser on the same machine — there is no headless/CI login path (see CI / automation).
No account yet? atoa signup walks you through account creation (email + one-time code) and business onboarding — no prior login needed.

Confirm you’re logged in


The dual-credential model

The CLI holds two independent credential types per profile:
A single atoa login always creates the login session. The SDK key is optional — add it whenever you need the payments/data commands:
atoa keys create requires an admin role on the business. The apiSecret is stored locally under ~/.atoa/auth/, so the CLI picks it up automatically on later commands.

Which login does each command need?

The generic verbs atoa get/post/delete authenticate with the SDK key, not the browser session — they’re for calling the payments API directly, so atoa keys create must have been run first.

Environments and profiles

A single machine can hold credentials for many businesses (profiles) and both environments (sandbox + production). The CLI keeps them separate so you can’t accidentally run a production refund while testing locally.
SDK keys are per-env and not interchangeable — a sandbox key won’t work against production. Mint one per env with atoa keys create --env <env>.

Per-profile settings

CLI state is stored entirely under profiles. To change which env a profile defaults to, use atoa profile set. To wipe everything, use atoa reset.

Inspect state

Change the default env on a profile

The keys you can set:

Reset everything

atoa reset is destructive — it removes every profile and clears every stored credential for this CLI. Use --revoke only when you also want the server-side keys deactivated (e.g. when offboarding a shared device).

Core workflows

Create a payment

Returns a paymentRequestId, the customer-facing paymentLink, and a qrCodeUrl.

Check payment status (poll until terminal)

--poll keeps polling every 5 seconds until the status is no longer PENDING, up to 3 minutes.

List recent transactions

Refund a payment

Manage customers and saved cards


Account management

These run on your browser login — no SDK key needed.

Switch the active business

If your account owns several businesses, account commands operate on one at a time:

Manage login sessions

Every atoa login registers a device session server-side. Audit and revoke them:
Revoking the current device’s session logs this CLI out — you’ll need to atoa login again.

SDK key lifecycle


Team, onboarding & business setup

Staff and roles

atoa staff add and atoa staff invite are the same command under two names — both create the staff member and notify them.
Run atoa staff update or atoa roles update with no arguments on a terminal and the CLI prompts for each field with the current value already filled in — press Enter to keep it.
--permission takes permission ids, and atoa roles permissions is where they come from — every other view shows only names, so start there when scripting a role. Each row also carries a requires list, which is why a role can end up with more permissions than you asked for.
Some permissions depend on others. When you tick one, the CLI automatically adds the permissions it requires and prints which ones it added.

KYB (Know Your Business) verification

Card payments need a separate application, which stays blocked until KYB passes. Both link commands open the browser for you and print the URL as well, so there’s something to fall back on if no browser can be launched.

Bank accounts

Run atoa bank add with no flags on a terminal and it walks you through it — pick your bank, enter the details, confirm. Your first bank account is set as the primary automatically. The primary account is where Atoa settles your payments. Pass --setPrimary on a later account to move settlement to it — this also re-points any store currently linked to the previous account. If a one-time code is required, atoa bank add sends it and exits with code 9. Re-run the same command with --otp to complete it:

Stores

All stores subcommands need a browser login:

Google Business listing

Pair a store with its Google Business listing so reviews flow back to Atoa:
Search first, then link with a placeId from those results. The listing’s name and address are stored exactly as the CLI sends them and are never looked up from the id, so --placeId on its own exits with code 3 — the search is what supplies them. Pass the same --search text to both commands. Linking a store that already has a listing replaces it — there’s no warning, so check with --dryRun first. atoa google unlink reverses it.
atoa google search works on any account. link, unlink and locations need the Google Review add-on and exits with code 8 without it — atoa addons list shows your plan’s limits. Once the plan allows it, locations still exits with code 4 until the merchant connects their Google Business account, which happens in the dashboard rather than the CLI.

Direct Debit

Atoa collects your subscription fees by Direct Debit. A business can hold one mandate — once it’s active, setup refuses rather than creating a second one.
Run interactively and the CLI prefills the account holder name, email and billing address already on the business, and masks the account number it has on file — press Enter to keep it. To run it without a terminal, pass every field as a flag plus --acceptMandate:
Only --addressLine2 is optional. The name is the account holder’s own, not the business’s — the mandate is signed by an individual — and it’s capped at 20 characters here.
--acceptMandate is required and records the merchant’s agreement to the Direct Debit mandate terms: the request stores an affirmative acceptance with a timestamp. Without it the command exits with code 3 and creates nothing. Only pass it once the merchant has explicitly agreed, and tell them what they’re agreeing to.

Notification preferences

Each channel reads as on, off, or unavailable — Atoa doesn’t send every channel for every topic, and an unavailable channel can’t be switched on.

Add-on plans

A downgrade is refused while your usage exceeds the target plan’s limits. The CLI names which features are over the limit so you know what to reduce first.

Checkout branding and SMS sender name

Onboard a brand-new account

Every prompted value also has a flag, so signup can run with no terminal — useful in CI or from a script. The code goes to your inbox, so it takes two runs:
--acceptTerms records acceptance of the Privacy Policy and Terms of Service; --marketing is a separate opt-in. --startNew creates a second business rather than resuming an existing signup. --businessStructure is Limited Company or Charity. --industry and --monthlyTurnover are server-defined lists that vary by environment, so the values above are illustrative — pass the option’s name and, if it doesn’t match, the CLI exits with code 3 listing every valid one to choose from.
atoa signup is the one command that needs no prior login — it creates the account and logs you in as part of the flow.

Create a hosted checkout link (browser login; --storeId is required):
--amount is in GBP (e.g. 10.50 for £10.50), not pence.

Idempotency — duplicate-charge protection

The CLI auto-generates a fresh Idempotency-Key: <uuidv4> header on every POST/PUT/PATCH, so a network blip on the response never double-charges a customer. You don’t need to think about this for interactive use. For CI / scripted retries — where one logical operation may run more than once (a job restarts) — pass a stable --idempotencyKey so a re-run produces the same key and the server deduplicates:
Available on atoa payments create, atoa refunds create, atoa card-on-file charge, and the generic atoa post. Every other POST still sends an auto-generated key, so all retries are safe by default.

Trigger test webhook events

The CLI can fire a synthetic webhook payload at your registered sandbox URL — same shape as production — without you actually creating a real payment.
Atoa’s webhook service dispatches the body to whatever sandbox URL you registered with atoa webhooks create. Inspect the request on your endpoint (e.g. webhook.site) to verify your signature-check, routing logic, and response shape work end-to-end.

Supported events

Customising the dispatched body

Test triggers are sandbox-only by design. If you pass --env production, the CLI warns you and proceeds with your active profile’s sandbox key anyway — this prevents accidentally driving fake events at your live customers.

Using the CLI in CI

atoa login needs an interactive browser, so a CI runner cannot log in itself. Instead, provision credentials on a workstation once, then hand the files to the runner:
  1. On a workstation: atoa login, plus atoa keys create if the job hits SDK/data commands.
  2. Copy ~/.atoa/auth/ to a location the runner can read.
  3. Point the runner at it with ATOA_HOME (credentials live in $ATOA_HOME/.atoa/auth/).
Every command accepts --output json for machine-readable output (the default is a human-readable table) and --dryRun to resolve the request without sending it. --yes is required on destructive commands in a non-TTY context.
Passing --output does more than pick a format — it also puts the CLI into non-interactive mode, so no prompt is ever opened. A command that would have asked for a value reports the missing flag by name and exits with code 3 instead. This is what makes the CLI safe to drive from an AI agent: it never blocks on a prompt the agent cannot see, and a missing value comes back as a named flag the agent can supply on the next run.

Exit codes

The CLI uses POSIX-style exit codes so pipelines can branch on the failure mode:

Environment variables


Generic HTTP verbs

When you need to hit an endpoint the CLI doesn’t yet wrap (or you want full control over the request body), use the raw verbs. They authenticate with the SDK key, so run atoa keys create first:

How -d and --data work

These are two different ways to build the request body. Pick whichever fits the call: So atoa post /api/webhook/merchant --data @webhook.json reads webhook.json from the directory you ran the command in, takes its contents as the JSON request body, and POSTs it to /api/webhook/merchant. Example file:
-d and --data are mutually meaningful — they both contribute to the same body. If you pass both, --data wins and -d fields are ignored. Use one or the other per command.

Passing nested objects and arrays

Some API fields aren’t a single string or number — they’re objects (e.g. authentication, consumerDetails) or arrays (e.g. paymentMethod, storeIds). How you pass these depends on which kind of command you’re using.
-d and --data are flags on the generic verbs only (atoa get, atoa post, atoa delete). Typed commands like atoa payments create and atoa customers create accept only their named flags — they do not accept -d key=value or --data @file.json.

On typed commands (e.g. atoa payments create)

Use the command’s own named flags. Quote complex values so the shell passes them to the CLI intact:
PowerShell users: Windows re-parses arguments when handing them to native .exe / .cmd programs, so the bash-style '{"key":"value"}' doesn’t survive intact. Use backslash-escaped double quotes inside the single quotes instead:
If a value contains whitespace (e.g. "Jane Doe"), wrap the whole backslash-escaped JSON in an extra pair of outer double-quotes so Windows doesn’t split at the space:
bash / zsh / git-bash users — the single-quoted plain form (top of section) works directly, no escaping needed.
If a typed command doesn’t expose a flag for the field you need, fall through to the generic verbs below.

On generic verbs (e.g. atoa post /api/...)

The generic verbs accept any JSON body. Three ways to specify it:
Wrap JSON values in single quotes so {, ", and spaces pass through untouched.PowerShell: same rule, but escape any inner single quote by doubling it ('It''s urgent'It's urgent).
These use your active profile’s credentials and respect every common flag (--env, --output, --dryRun, --verbose). Useful for:
  • New endpoints that haven’t gained a typed wrapper yet
  • Debugging--verbose prints the redacted request line so you can see exactly what was sent
  • CI scripts where you want explicit control over the exact body sent

Shell completion

Enable TAB-completion of commands, flags, profile names, and IDs:
After installing, hit <TAB> mid-command:

Command reference

Most commands accept these common flags (per-command --help is authoritative):

Troubleshooting

First-run state, or your session expired / was revoked (e.g. a later login on the same device evicted it). Check who you are, then re-pair:
If an account command complains you only have an SDK key (or vice versa), obtain the missing credential — atoa login for a login session, atoa keys create for an SDK key. See the dual-credential model.
Another atoa process is mid-write. If none is running (e.g. one crashed), remove the stale lockfile:
The session file gained group/other read bits — fix with chmod 600 ~/.atoa/auth/session.json.
You need to register a sandbox webhook URL first:
The trigger uses the URL registered for the same event type under your active profile’s sandbox.
  1. Re-source your shell config after install (e.g. source ~/.bashrc, or open a new PowerShell window).
  2. Confirm completion is registered:
  3. For PowerShell specifically, make sure you ran | Out-String | Invoke-Expression after atoa completion pwsh — the script must be evaluated, not just printed.

Need Help?

Contact our team at [email protected] or use chat support on the Dashboard.