Skip to main content
The spree api command group turns the CLI into a first-class Admin API client: generic HTTP verbs against any endpoint, schema introspection without leaving the terminal, and credentials that resolve automatically — from a local dev project to a production store profile. It works against any Spree 5.5+ instance and is designed to be driven by both humans and AI coding agents.

Credentials

Credentials resolve through four layers — first match wins: Host and key resolve together per source — a saved or minted key is never silently re-pointed at a host from a different layer. Only --base-url (or SPREE_BASE_URL paired with SPREE_API_KEY) re-points a key deliberately. So against local dev:
Zero configuration is needed for local development — the first spree api get inside your project just works:
Auto-minted keys carry read_all only. Writes always require an explicitly created key:
For remote stores, create a secret key in the admin under Settings → API Keys and save it as a profile — the key is read from a prompt, never from a flag:

Use with a sandbox

A free sandbox works like any remote store. Create a secret key in the sandbox admin under Settings → API Keys, then save it as a profile:
No local project or Docker needed — the CLI (npm install -g @spree/cli) plus a sandbox is a complete environment for exploring the Admin API.

Reading data

-q takes Ransack predicates as repeatable key=value pairs; sorting, pagination, and shaping flags pass through under the Admin API conventions:
--fields trims the response to the attributes you name (comma-separated). The resource id is always returned even if you don’t list it, so you only need to name the extra fields. --expand is the companion axis — --fields selects top-level attributes, --expand pulls in related resources:

Output format

Output is JSON on stdout, and it adapts to where it goes:
  • In a terminal — indented and syntax-colored, for reading.
  • Piped or redirected — compact, single-line, uncolored, so it stays fast and feeds cleanly into jq (color codes would corrupt it).
--format table renders collections as a table for humans (nested objects collapse to {…}, arrays to [N]).

Writing data

Request bodies are flat JSON (no root wrapping), inline, from a file, or from stdin:
Mutations automatically carry an Idempotency-Key, so retries are safe.

Creating products

A product is a catalog grouping; everything purchasable — SKU, price, stock, weight — lives on its variants. For a simple product with no options, ship a top-level prices array and Spree creates the single backing variant for you:
For a product with options, send the variants array, each with its own options and prices (and optionally stock_items):
Run spree api schema "POST /products" for the full request body.

Discovering endpoints and schemas

The CLI bundles a snapshot of the Admin API OpenAPI spec, so discovery works offline:
spree api endpoints shows the read_* / write_* scope each endpoint requires (see Authentication) — useful for deciding what to grant a new key.

Shell completion

Tab-completion suggests resource paths, Ransack predicate stems (name_cont=, status_eq=, …), and scope names — all offline from the bundled spec. Add the generated script to your shell:
Then spree api get /pro⇥ completes to /products, and spree api get /products -q name_⇥ offers the Ransack predicates.

Errors and exit codes

API errors print the error envelope to stderr and exit 1; usage and configuration problems exit 2. A scope denial includes the exact remediation:

Using it with AI agents

Agents with shell access (Claude Code, Cursor, and similar) can drive a Spree back office through spree api with no extra configuration: inside a project the credentials self-provision read-only, and for remote stores two environment variables (SPREE_BASE_URL, SPREE_API_KEY) are the whole contract. The endpoints/schema commands give agents request shapes on demand instead of loading the entire API surface up front, and error messages name the missing scope so agents can self-correct.