DotsDocs

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 | sh

The 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/cli

The 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 --help

Choose an environment

The environment flag is global. Place it before the command so the destination is clear:

EnvironmentCommand prefixUse
ProductiondotsLive Dots account and funds
Sandboxdots --sandboxDevelopment 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 status

The 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 logout

Add --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-api

When 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-api

When verification succeeds, auth.api_key_mode is read_only. You can also verify access with a read request:

dots --json transfers list --query limit=1

Read-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-run before 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 Authorization header. The CLI rejects it and applies configured credentials without exposing them in output.
  • Use --json for 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-run

If 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-run

This 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 install

For non-interactive installation, choose the scope and agent harness explicitly:

dots skill install --project --harness all
dots skill install --global --harness .agents

Project 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:

  1. Give the agent only the environment it needs and keep the guard variable outside its control.
  2. Select the intended environment explicitly and use --json when reading command output.
  3. Require --dry-run for every write.
  4. Review the preview before allowing a live write. All money-moving requests, including payouts and payout batches, require --confirm in JSON or non-interactive mode.

Common workflows

Check configuration

dots doctor --check-api
dots config show

config 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-user

List 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 list

Use 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_UUID

Preview batch creation from a JSON file before submitting it:

dots payout-batches create --body-file ./payout-batch.json --dry-run

The 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-run

Payment-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-run

Payment-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-run

After 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-run

Use --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-run

The 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 login again.
  • If doctor cannot 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_ONLY or DOTS_BLOCK_MONEY_MOVEMENT was intentionally enabled. Do not disable a guard to bypass the refusal.