Dots CLI
Install, authenticate, and use the Dots CLI safely from a terminal or AI agent.
The Dots CLI (dots) provides friendly commands for common Dots resources and
access to every operation in the documented Dots API.
Install
On macOS or Linux, install the latest release:
curl -fsSL https://github.com/Send-Dots/dots-cli/releases/latest/download/install.sh | shThe installer places dots in $HOME/.local/bin by default and verifies the
download against the release checksums. You can also install the CLI through
npm on macOS, Linux, or Windows:
npm install --global @usedots/cliThe npm package requires Node.js 18 or later. Windows users can alternatively
download the Windows ZIP archive from the
latest GitHub release
and extract dots.exe.
Verify the installation:
dots --version
dots --helpChoose an environment
The environment flag is global. Place it before the command so the destination is clear:
| Environment | Command prefix | Use |
|---|---|---|
| Production | dots | Live Dots account and funds |
| Sandbox | dots --sandbox | Development and testing |
Sandbox and production have separate credentials. The CLI uses production when
you omit an environment flag; add --sandbox when you want to test against
Sandbox.
Authenticate
Interactive login
Sign in with your Dots dashboard account:
dots login
dots auth statusThe CLI opens the dashboard so you can choose the App it may access. Paste the five-minute, single-use authorization code into the terminal. The resulting session lasts 72 hours and is stored in your operating system’s credential store. Dots checks your current App membership and role on every request.
To revoke and remove the session:
dots logoutAdd --sandbox before these commands to manage a separate Sandbox session.
API keys for automation
Use API keys for unattended scripts and AI agents. Supply credentials through a secret manager or environment variables:
export DOTS_CLIENT_ID='your-client-id'
export DOTS_API_KEY='your-secret-api-key'
dots doctor --check-apiWhen using organization credentials to act for an App, also set:
export DOTS_APP_ID='your-app-id'In a headless environment, use explicit environment variables instead of a saved login. See API Authentication for information about App and organization keys.
Read-only API keys for agents
When an agent or automation only needs to inspect data, create a named read-only API key from API Management in the Dots dashboard. Configure the CLI with the read-only key’s client ID and API key just like any other API credentials:
export DOTS_CLIENT_ID='your-read-only-client-id'
export DOTS_API_KEY='your-read-only-api-key'
dots --json doctor --check-apiWhen verification succeeds, auth.api_key_mode is read_only. You can also
verify access with a read request:
dots --json transfers list --query limit=1Read-only keys are enforced by the Dots API. Requests that create, update, or
delete resources are rejected with 403 Forbidden, even if a caller bypasses
the CLI’s local safeguards. Use a full-access key only when the automation must
perform writes.
Security
- Never put credentials in prompts, source control, command arguments, or custom headers. Prefer environment variables supplied by your secrets manager.
- Preview writes with
--dry-runbefore sending them. Dry runs do not make an API request. - Reuse an idempotency key when retrying a write so the same operation is not performed twice.
- Do not manually supply an
Authorizationheader. The CLI rejects it and applies configured credentials without exposing them in output. - Use
--jsonfor automation. Structured output omits configured credentials, custom header values, and multipart values. Request bodies remain visible in dry-run previews, so do not include credentials or other secrets in them.
Add a local read-only safeguard
For defense in depth, set DOTS_READ_ONLY=1 in addition to using a server-enforced
read-only API key. The CLI then refuses every non-GET/HEAD API request locally
while still allowing dry-run previews:
export DOTS_READ_ONLY=1
dots --json transfers list
dots users create --body-file ./user.json --dry-runIf an agent needs ordinary writes but must not move money, use:
export DOTS_BLOCK_MONEY_MOVEMENT=1
dots users create --body-file ./user.json --dry-runThis guard blocks live requests involving transfers, payouts, payout links, payout batches and requests, payments, payable payments, wallet deposits and withdrawals, and organization transfers.
Configure these variables outside the agent’s control. A local guard cannot protect a full-access key if the agent can unset or override it. Use a server-enforced read-only API key when writes must never be allowed.
Use with AI agents
Install the CLI’s bundled agent skill interactively:
dots skill installFor non-interactive installation, choose the scope and agent harness explicitly:
dots skill install --project --harness all
dots skill install --global --harness .agentsProject scope installs into the current Git repository. Global scope makes the
skill available across projects. The .agents harness supports Codex,
OpenCode, and OpenClaw; claude and hermes are also available. Current
Hermes releases require global scope.
For reliable agent use:
- Give the agent only the environment it needs and keep the guard variable outside its control.
- Select the intended environment explicitly and use
--jsonwhen reading command output. - Require
--dry-runfor every write. - Review the preview before allowing a live write. All money-moving requests,
including payouts and payout batches, require
--confirmin JSON or non-interactive mode.
Common workflows
Check configuration
dots doctor --check-api
dots config showconfig show reports only non-secret settings.
Discover commands
Use the CLI’s current help and API catalog instead of relying on memorized syntax:
dots users --help
dots operations list --tag users
dots operations show get-userList and retrieve resources
Friendly commands cover users, transfers, transactions, vendors, flows, payout links, payouts, payout batches, and apps:
dots --json users list --query limit=10
dots --json users get USER_UUID
dots --json transfers get TRANSFER_UUID
dots --json transactions list --query limit=10
dots --json transactions get TRANSACTION_ID
dots --json flows get FLOW_UUID
dots --json apps listUse transfers to inspect a transfer and transactions to inspect the ledger
entries created by transfers and other money movement.
Manage payout batches
List a batch, inspect its processing state, and retrieve its item-level results:
dots --json payout-batches list --query limit=10
dots --json payout-batches get PAYOUT_BATCH_UUID
dots --json payout-batches results PAYOUT_BATCH_UUIDPreview batch creation from a JSON file before submitting it:
dots payout-batches create --body-file ./payout-batch.json --dry-runThe batch preview includes a generated body.idempotency_key. Reuse it with
--idempotency-key on the confirmed command. In JSON or non-interactive mode,
the create command requires --confirm; call and request enforce the same
gate for money-moving endpoints.
Manage vendors and payment methods
Use the accounts-payable vendor commands to list or retrieve vendors and to preview create or delete requests:
dots --json vendors list --query limit=10
dots --json vendors get VENDOR_UUID
dots vendors create --body-file ./vendor.json --dry-run
dots vendors delete VENDOR_UUID --dry-runPayment-method commands are nested under their vendor. Both the vendor ID and payment-method ID are positional arguments where required:
dots --json vendors payment-methods list VENDOR_UUID
dots --json vendors payment-methods get VENDOR_UUID PAYMENT_METHOD_UUID
dots vendors payment-methods create VENDOR_UUID \
--body-file ./payment-method.json \
--dry-run
dots vendors payment-methods delete VENDOR_UUID PAYMENT_METHOD_UUID --dry-runPayment-method previews replace account_number and routing_number values
with [REDACTED]. The CLI does not offer idempotency keys for vendor writes
because these API routes do not support idempotent retries.
Preview a write
Pass request JSON inline or read it from a file:
dots users create --body-file ./user.json --dry-run
dots transfers create --body-file ./transfer.json --dry-runAfter reviewing the preview, remove --dry-run to send the request. For a
money-moving request such as transfers create, also pass --confirm. Scripts
and --json mode cannot submit money-moving requests without it.
Call any documented API operation
When a friendly resource command is not available, discover and call the OpenAPI operation:
dots operations show get-user
dots --json call get-user --path user_id=USER_UUID
dots call create-transfer \
--body-file ./transfer.json \
--dry-runUse --path NAME=VALUE for path parameters, --query NAME=VALUE for query
parameters, and --body or --body-file for JSON request bodies.
Send a payout
Amounts are expressed in cents. First preview the payout:
dots --json payouts send \
--amount-cents 100 \
--user USER_UUID \
--memo "CLI payout" \
--dry-runThe preview includes an automatically generated idempotency key. Copy that key into the approved request:
dots --json payouts send \
--amount-cents 100 \
--user USER_UUID \
--memo "CLI payout" \
--idempotency-key IDEMPOTENCY_UUID \
--confirm--amount-cents 100 sends $1.00. Never add --confirm until the dry-run
preview has been reviewed.
Troubleshooting
dots auth status
dots doctor --check-api
dots payouts send --help- If authentication expired, run
dots loginagain. - If
doctorcannot reach the API, confirm the environment and network. - If an argument is rejected, inspect that exact command with
--help. - If an agent write is refused, check whether
DOTS_READ_ONLYorDOTS_BLOCK_MONEY_MOVEMENTwas intentionally enabled. Do not disable a guard to bypass the refusal.