CLI
Check a key, read orders, contacts and usage, and diagnose a setup from the terminal.
Scoped operations · command inboxy · v0.2.0 on npm
npm i -g @inboxychat/cli@0.2.0On this page
Who it is for
Agencies managing several companies, support engineers and developers writing scripts.
What it can do
- This source version adds 80 audited operations across SDK, CLI and MCP. Installed npm versions and hosted enablement must be checked separately.
- Store the key in the OS keychain (macOS Keychain, Linux Secret Service), one profile per company.
- Read the company and key, plan usage, orders and contacts, with filters and cursor paging.
inboxy doctorchecks the URL, key, scopes, expiry, clock skew and config permissions in one go.--jsonprints one stable JSON document for scripts, with documented exit codes.
Install
Audited operations and actual coverage
This source version adds 80 audited operations across SDK, CLI and MCP. Installed npm versions and hosted enablement must be checked separately.
Coverage: contacts, tasks, tickets, inbox assignment/status/labels/internal notes and separate text sending; AI drafts/configuration/reviewed text knowledge/channels/tests/readiness/publish; manual orders/status/payment/fulfillment; products/categories; contact status/stage/assignment/tags/custom fields; automation inspection/inactive draft/dry simulation/pause/approved activation; campaign audience estimates/drafts/pause/cancel and approved send/resume/schedule. The 553-route inventory is discovery metadata, not executable full dashboard parity.
SDK: describeOperations(), prepareOperation(id, input, idempotencyKey), executeOperation(id, input, { idempotencyKey, confirmation }). CLI: operations list/inspect/preview/run with --input, --idempotency-key and --confirm. MCP: operations_list, operation_inspect, operation_preview, operation_execute; messages use message_send and activation uses lifecycle_activate; campaign delivery uses campaign_send or campaign_schedule. CLI sending uses messages send after previewing inbox.message.send.
Show the exact preview and obtain explicit user approval before a mutation. The confirmation hash binds normalized input and key; it does not prove human approval. Retain the same idempotency key for recovery. No automatic retries. Existing tenant, role, scope and plan gates apply. OAuth write scopes require new explicit consent and start unchecked; old grants do not gain permissions.
AI tests and knowledge processing may consume credits. Publishing and channel assignment can affect live replies. Sending requires approval of contactId, channelId/type and complete text; the server rechecks the target. Inbox media/template sends, entity deletion, arbitrary HTTP, billing and platform administration are not exposed. Campaign template delivery and scheduling require a separate approved frozen audience/content/sender/time snapshot. Order and contact tag changes may trigger configured automation; custom fields replace the entire map; payment updates do not charge a provider. Refunds/cancellation and full campaign/automation coverage remain excluded.
Needs Node.js >= 20.3.
npm i -g @inboxychat/cli
inboxy --versionnpx -y -p @inboxychat/cli inboxy --helpAuthentication
- Sign in to Inboxy as a company admin and open Developers → API keys in the dashboard (/developer-center/keys).
- Choose "Create an API key" and give the key a name you will recognise (for example "Claude on my laptop").
- Tick only the scopes you need. There is no default set: a key without scopes cannot be created. The read tools need the ":read" scopes (contacts:read, orders:read, ...).
- Pick an expiry: 30, 90 (default), 180 or 365 days, or never. The default is 90 days.
- Copy the key when it is shown. It starts with "inboxy_". Store it in a secret manager or the OS keychain, never in a repository.
Sign in
On a terminal, inboxy auth login opens the browser so you can approve a key for this company. The key is never an argument: inboxy auth login <key> and any --key / --token / --api-key flag are refused. When stdin is not a terminal, paste or pipe the key instead (a hidden prompt is not used for a pipe).
inboxy auth login # browser approval on a terminal
pbpaste | inboxy auth login # or pipe a key (macOS, not a TTY)
inboxy auth login --profile client-a # one profile per company
inboxy auth status # where the key comes from + is it accepted
inboxy auth logout --profile client-aWhere the key is kept
- In the OS keychain: macOS Keychain or Linux Secret Service (secret-tool).
- Without a keychain (or with --store file): in the config file with mode 0600 inside a 0700 directory. A config file other users can read is refused.
- Config file: $INBOXY_CONFIG_DIR, else $XDG_CONFIG_HOME/inboxy, else ~/.config/inboxy/config.json.
Quickstart
inboxy auth login
inboxy doctor
inboxy whoami
inboxy orders list --status pending --limit 5How-to guides
Find a customer and their orders
inboxy contacts search "9665" --stage customer
inboxy orders list --contact CONTACT_IDExport orders as JSON
--all follows the cursors up to --max-pages (default 10).
inboxy orders list --after 2026-10-20 --all --json > orders.jsonAgencies: one profile per company
inboxy auth login --profile client-a
inboxy --profile client-a usage
INBOXY_PROFILE=client-b inboxy orders listUse it in CI or a script
Set INBOXY_API_KEY from your secret store; it overrides the keychain. Branch on the exit code.
INBOXY_API_KEY="$INBOXY_API_KEY" inboxy doctor --json > doctor.json || echo "doctor exit $?"Reference
Commands
| Command | Scope | Does |
|---|---|---|
inboxy auth login | — | Sign in: browser approval on a terminal, or a key from stdin when it is not |
inboxy auth status | — | Where the key comes from, and whether Inboxy accepts it |
inboxy auth logout | — | Remove the stored key of a profile |
inboxy whoami | — | Company, key name, scopes, expiry and rate limits |
inboxy usage | analytics:read | Plan usage against limits |
inboxy stores list | analytics:read | Connected-store count against the plan limit (the public API has no stores route yet) |
inboxy orders list | orders:read | List orders with filters |
inboxy orders get | orders:read | One order |
inboxy contacts search | contacts:read | Search contacts |
inboxy doctor | — | Check URL, key, scopes, expiry, clock skew and config permissions |
inboxy operations list | — | List audited operations |
inboxy operations inspect | — | Inspect an operation schema |
inboxy operations preview | — | Preview locally before explicit approval |
inboxy operations run | — | Run the exact approved request |
inboxy messages send | messages:send | Send one explicitly approved customer text message |
inboxy lifecycle activate | — | Activate an approved lifecycle operation with --input, --idempotency-key and --confirm |
inboxy campaigns send | campaigns:write | Send or resume an explicitly approved campaign |
inboxy campaigns schedule | campaigns:write | Schedule an explicitly approved campaign snapshot |
inboxy auth login [--store keychain|file] [--no-verify] [--profile <name>]
inboxy auth status [--offline]
inboxy auth logout [--profile <name>]
inboxy whoami
inboxy usage
inboxy stores list
inboxy orders list [--status] [--payment-status] [--fulfillment-status] [--source] [--store <id>] [--contact <id>] [--search <text>] [--after <iso>] [--before <iso>]
inboxy orders get <id>
inboxy contacts search [text] [--status] [--stage] [--tags <ids>] [--created-after <iso>] [--created-before <iso>]
inboxy doctor
inboxy operations list
inboxy operations inspect <operation>
inboxy operations preview <operation> --input <json> --idempotency-key <key>
inboxy operations run <operation> --input <json> --idempotency-key <key> --confirm <preview-hash>
inboxy messages send --input <json> --idempotency-key <key> --confirm <preview-hash>
inboxy lifecycle activate <operation> --input <json> --idempotency-key <key> --confirm <hash>
inboxy campaigns send <operation> --input <json> --idempotency-key <key> --confirm <hash>
inboxy campaigns schedule --input <json> --idempotency-key <key> --confirm <hash>Paging and global options
--limit1-100,--cursor <nextCursor>, or--all(with--max-pages, default 10).--json,--profile <name>,--url <origin>,--timeout <ms>. Global options may come before or after the command.
--json output
One document on stdout, schemaVersion 1. Fields may be added, never renamed or removed. data items are the public API v1 objects unchanged.
{ "schemaVersion": 1, "ok": true, "command": "orders list",
"data": [ ... ], "meta": { "limit": 20, "hasMore": true, "nextCursor": "...", "pages": 1 } }
{ "schemaVersion": 1, "ok": false, "command": "orders list",
"error": { "kind": "forbidden", "code": "INSUFFICIENT_PERMISSIONS", "status": 403,
"message": "...", "details": { "requiredScope": "orders:read" }, "retryAfterSeconds": null } }Environment
| Variable | Meaning |
|---|---|
INBOXY_API_KEY | The API key. Overrides the keychain and config file. |
INBOXY_API_URL | API origin (default https://api.inboxy.chat). |
INBOXY_PROFILE | Which stored profile to use (one per company). |
INBOXY_CONFIG_DIR | Config directory (else $XDG_CONFIG_HOME/inboxy, else ~/.config/inboxy). |
INBOXY_KEYCHAIN | "off" disables the OS keychain. |
Limits and safety
- The operation run command can change data after exact preview confirmation.
- The key is never printed. Output and errors are redacted (any inboxy_… value, any Bearer value, and the key in use); status shows only the 8-character prefix.
- No shell: inputs reach the API only as validated, encoded values; ids must be 1-64 letters, digits, "_" or "-".
- HTTPS only (http for localhost); redirects are refused. The REST API rate limits apply.
Troubleshooting
Start with inboxy doctor. It exits 10 when a check fails and says what to fix.
| Check | What it looks at |
|---|---|
config-file | Config file exists and other users cannot read it |
api-url | API URL is valid and uses https (http only for localhost) |
api-key | A key was found, and where from |
key-format | The key looks like an Inboxy key (inboxy_…) |
keychain | OS keychain warnings |
api-reachable | Inboxy answered, with latency |
key-valid | Inboxy accepts the key |
clock-skew | Your clock against the server Date header |
scopes | Scopes the CLI commands need that the key lacks |
key-expiry | Days until the key expires |
rate-limits | Per-key and per-company limits |
Exit codes
| Code | Meaning |
|---|---|
0 | OK |
1 | Unexpected error |
2 | Usage error (bad flag, value or id); nothing was sent |
3 | Configuration: no key, bad URL, config file permissions, no keychain |
4 | Key refused (401) |
5 | Forbidden (403): missing scope, company paused, key owner no longer admin |
6 | Not found (404) |
7 | Rate limited (429); see retryAfterSeconds |
8 | Network error, timeout or cancelled |
9 | Server error, or a response that is not the API envelope |
10 | doctor found at least one failing check |
Common errors
- "No API key" (exit 3): run
inboxy auth login, or set INBOXY_API_KEY. - "Inboxy refused the API key" (exit 4): the key is unknown, revoked or expired. Create a new key.
- "does not have the … scope" (exit 5): create a key that includes the named scope.
- Linux without secret-tool: install libsecret tools, or use
inboxy auth login --store file.
Links
Create an API key
Keys are created by a company admin on the Developers page of the dashboard.
