CLI
The primitive CLI is the recommended interface for agents and humans operating from a terminal. It handles auth, file inputs, command discovery, and common workflows that are awkward with raw HTTP.
Install
# Homebrew brew install primitivedotdev/tap/primitive # npm npm install -g primitive
Homebrew installs the required Node.js runtime automatically. npm installs require Node.js 22 or newer. Both install the primitive binary.
No-install form:
npx primitive@latest <command>The CLI ships through the primitivedotdev/tap Homebrew tap and as primitive on npm (also published under the scoped name @primitivedotdev/cli). It is separate from the runtime SDK: primitive provides the primitive binary, and @primitivedotdev/sdk is imported from application code.
Authenticate
primitive login primitive whoami
primitive login opens a browser and stores an OAuth token set locally. whoami verifies the current token and prints the account context visible to the CLI. To revoke the current CLI session, run:
primitive logoutYou can also revoke CLI and third-party OAuth grants from Settings -> Connected Apps. For non-interactive automation, API keys still work by setting PRIMITIVE_API_KEY.
Send Mail
primitive send \ --to alice@example.com \ --subject "Hello" \ --body "Hi from Primitive" \ --wait
The CLI can infer a valid sender on the managed domain when possible.
Read Inbound Mail
primitive emails:latest --limit 5 primitive emails:get-email --id <email-id>
Piped table output keeps ids complete so agents can chain commands safely.
Reply
primitive sending:reply-to-email \ --id <inbound-email-id> \ --body-text "Got it."
Primitive derives recipient and threading headers from the inbound email.
Discover Send Permissions
primitive sending:get-send-permissionsRun this before a first outbound send if you are unsure whether a recipient is allowed.
Functions
Create and deploy a hosted Function:
primitive functions:init my-fn cd my-fn npm install npm run build primitive functions:deploy --name my-fn --file ./dist/handler.js
primitive functions:init is local filesystem scaffolding, so the API equivalent starts when you deploy the built bundle.
Test and inspect it:
primitive functions:test-function --id <function-id> primitive functions:list-function-logs --id <function-id>
Domains
Claim a domain, publish its DNS, and verify it for sending and receiving. The topic separator is a space; the colon forms (primitive domains:add) still resolve for back-compat.
primitive domains add --domain example.com primitive domains verify --id <domain-id> primitive domains list primitive domains zone-file --id <domain-id> --output example.com.zone
domains add returns the exact DNS records to publish. domains zone-file downloads those same records as a BIND-format zone file for bulk import (pass --domain example.com instead of --id if you only have the name). domains verify re-checks DNS and reports which records are still missing. See Receiving for the full inbound setup walkthrough.
More Commands
The CLI mirrors the full REST surface. Beyond the workflows above, these command groups are available:
primitive endpoints ...— webhook endpoint CRUD andtest. See Endpoints.primitive filters ...— allow/block filter CRUD.primitive routes ...— inbound routing rules, includingsimulate. See Routing.primitive payments ...— collect and pay USDC over x402 (see below).primitive chat <email> <message>— send a message to another agent or person and wait for the threaded reply.primitive agent start-agent-signup/verify-agent-signup— provision a managed inbox with no API key (one email-verification code). See Skills & Agent Signup.primitive inbox status— consolidated inbound readiness view.
Run primitive list-operations for the full machine-readable manifest of generated operations, and primitive describe <operation> for one operation's parameters and behavior.
Operation Discovery
Agents should use CLI help and operation descriptions before guessing command shapes.
primitive --help primitive list-operations primitive describe emails:get-email primitive describe sending:reply-to-email
list-operations is the broad machine-readable manifest. describe gives focused parameter and behavior details for one operation.
Proxy Environments
On Node 22+ behind a proxy, set:
export NODE_USE_ENV_PROXY=1Then HTTP_PROXY and HTTPS_PROXY are respected by Node networking. primitive doctor checks the environment.
primitive doctor is a local environment diagnostic. There is no REST endpoint for inspecting local proxy variables; use primitive whoami or the /v1/account request above to verify API reachability after setting them.
Payments
The primitive payments command group collects and pays USDC with x402. Signing commands read the wallet key from PRIMITIVE_X402_PRIVATE_KEY and sign locally. x402 is in an invite-only soft launch; see Collecting Payments for how to request access.
| Command | What it does |
|---|---|
primitive payments register-payout-address | Register (or update) your org's default payout wallet for a network. Signs an ownership proof locally. |
primitive payments list-payout-addresses | List your org's registered payout addresses. |
primitive payments charge | Request a synthetic payment (payee). Accepts human USDC via --amount-usdc. Prints the challenge JSON to stdout. |
primitive payments create-challenge | Low-level synthetic challenge create (payee), base-unit --amount. |
primitive payments create-email-challenge | Issue an email-native challenge (payee): sends the challenge email from --from to --to and binds the payment to that thread. |
primitive payments pay | Pay a synthetic challenge (payer). Reads the challenge from --challenge-file, --challenge, or stdin; signs and submits. |
primitive payments pay-email-step | Sign an email-native challenge (payer) and print the interaction.json payment step to stdout. It does NOT send; you reply on the thread with the printed part. |
primitive payments get-challenge | Read a challenge by id (status, settle tx). |
primitive payments get-spend-policy | Read your org's payer spend policy. |
primitive payments update-spend-policy | Update the payer spend policy (kill-switch, caps, allowlist). |
primitive payments list-declined-payments | List recent payments your spend policy refused. |
For the synthetic flow see Collecting Payments; for the agent-to-agent email flow see x402 over Email.
Good Agent Defaults
- Run
primitive whoamibefore state-changing operations. - Prefer CLI commands for terminal workflows instead of hand-written curl.
- Use
--waitwhen an immediate send result is needed. - Use
describebefore composing unfamiliar operations. - Never print API keys or webhook secrets in logs.