- Environment variables configure the application: database, hosts, email, file storage, search, background jobs, error tracking and more.
- Webhooks tell your services when something happens.
- The Admin API, called with a scoped secret key, lets them read and change the store.
- The TypeScript SDKs give typed clients for both.
- The MCP server lets an AI agent read and change the store on a person’s behalf.
- Dashboard plugins add your own screens to the admin, written in React.
Quick reference
Configure with environment variables
The whole application is configured through environment variables, so the prebuilt image runs in any environment without a code change. Set them in the project’s.env for local development, or in your hosting provider’s settings in production.
Environment Variables lists every variable. Store settings, such as markets, currencies, payment methods, delivery methods, taxes, staff and roles, are data rather than configuration: change them in the dashboard or through the Admin API.
Webhooks
A webhook sends an HTTP POST to your service when an event happens in the store — an order is placed, a payment is completed, a product sells out. Your service can be written in any language. Create an endpoint in the dashboard under Settings → Webhooks, or through the Admin API:- Admin SDK
- cURL
@spree/sdk/webhooks checks it and returns a typed event:
X-Spree-Webhook-Timestamp header is a Unix time within 300 seconds of now, then compute the HMAC-SHA256 of {timestamp}.{body} with the endpoint’s secret key over the raw request body, encode the digest as lowercase hexadecimal, and compare that string with the X-Spree-Webhook-Signature header in constant time. Reject the request if either check fails. The SDK does both.
Things to know:
- A failed delivery is retried, so your service can receive the same event more than once. Every attempt carries the same event
id. Pass it as an idempotency key to whatever the event triggers, so a second delivery does no extra work. Don’t use the record’s ID instead:order.placedandorder.canceledshare an order ID, and keying on it would drop the cancellation. Use the record’s ID only for work that must happen once per record. See Delivery guarantees. - Payloads carry what a customer could see. For back-office fields, fetch the record from the Admin API with the
idin the payload. - A webhook tells you something happened. It can’t stop it or change it.
The Admin API
The Admin API is the back office as a REST API: products, orders, customers, stock, fulfillments, settings and more. It is described by an OpenAPI specification, so you can generate a client for any language from it. Integrations authenticate with a secret API key. Each key carries scopes —read_orders, write_fulfillments, read_all and so on — and can only reach what its scopes allow. Give each integration its own key with the fewest scopes it needs.
Create a key in the dashboard under Settings → API Keys, or with the Spree CLI:
- Admin SDK
- cURL
spree api to call the API from scripts and the terminal.
The TypeScript SDKs
Spree publishes typed clients for its APIs:
The types are generated from the API itself, so your editor knows the fields of every record and the filters every list accepts.
The MCP server
Your store serves an MCP server at/api/v3/admin/mcp, with nothing extra to deploy. Connect Claude, Cursor or your own agent to it, and the agent can work in the back office in plain language.
The server reads and writes:
- Reads: search products, orders and customers, read a record in full, run reports.
- Writes: cancel an order, capture a payment, update stock, curate a collection, start an import, and more.
Dashboard plugins
The admin dashboard is a React application. You extend it in TypeScript: add pages and navigation entries, place components in slots on existing screens, add table columns, translations and themes. For your own project, register them insrc/plugins.ts in your dashboard app — no package needed. To share an extension between projects or publish it, package it as a dashboard plugin.
Your screens talk to the Admin API through the same typed client the dashboard uses, so they follow the signed-in person’s permissions.
See Dashboard customization and Backend integration.
When to use Ruby instead
The options above work from outside Spree’s process. Write Ruby when the change has to happen inside it:
You can mix both. A common setup keeps validation in a small Ruby hook and does everything else — syncing, notifications, reporting — from a TypeScript service over webhooks and the Admin API.
Ruby code runs only once the project builds the backend from its own source instead of the prebuilt image. Switch with
spree eject.Related
- Environment Variables — every configuration variable
- Customization quickstart — every way to customize Spree, in order of recommendation
- Events — what Spree announces, and delivery guarantees
- Webhooks — endpoints, payloads, signatures and retries
- Admin SDK — the typed Admin API client
- MCP Server — connecting AI agents to a store

