Spree Commerce Customers API
Customer profiles, addresses, credit cards, and store credits
Customer profiles, addresses, credit cards, and store credits
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
find_apisBrowse and filter every API in the catalog.get_api_artifactsOne API's artifacts, grouped by type.get_openapiThe primary OpenAPI for this API.find_similar_apisAPIs that look like this one.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.curl "https://apis.io/api/v1/apis/spree-customers-api"
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
openapi: 3.0.3
info:
title: Admin Account / Address Customers API
contact:
name: Spree Commerce
url: https://spreecommerce.org
email: hello@spreecommerce.org
description: "Spree Admin API v3 - Administrative API for managing products, orders, and store settings.\n\n## Authentication\n\nThe Admin API requires a secret API key passed in the `x-spree-api-key` header.\nSecret API keys can be generated in the Spree admin dashboard.\n\n## Response Format\n\nAll responses are JSON. List endpoints return paginated responses with `data` and `meta` keys.\nSingle resource endpoints return a flat JSON object.\n\n## Resource IDs\n\nEvery resource is identified by an opaque string ID (e.g. `prod_86Rf07xd4z`,\n`variant_k5nR8xLq`, `or_UkLWZg9DAJ`). Use these IDs everywhere — URL paths,\nrequest bodies, and Ransack filters all accept them directly.\n\n## Error Handling\n\nErrors return a consistent format:\n```json\n{\n \"error\": {\n \"code\": \"validation_error\",\n \"message\": \"Validation failed\",\n \"details\": { \"name\": [\"can't be blank\"] }\n }\n}\n```\n"
version: v3
servers:
- url: http://{defaultHost}
variables:
defaultHost:
default: localhost:3000
tags:
- name: Customers
description: Customer profiles, addresses, credit cards, and store credits
paths:
/api/v3/admin/customers/{customer_id}/addresses:
get:
summary: List customer addresses
tags:
- Customers
security:
- api_key: []
bearer_auth: []
description: 'Returns the customer''s saved addresses.
**Required scope:** `read_customers` (for API-key authentication).'
x-codeSamples:
- lang: javascript
label: Spree Admin SDK
source: "import { createAdminClient } from '@spree/admin-sdk'\n\nconst client = createAdminClient({\n baseUrl: 'https://your-store.com',\n secretKey: 'sk_xxx',\n})\n\nconst { data: addresses } = await client.customers.addresses.list('cus_UkLWZg9DAJ')"
parameters:
- name: x-spree-api-key
in: header
required: true
schema:
type: string
- name: Authorization
in: header
required: true
schema:
type: string
- name: customer_id
in: path
required: true
schema:
type: string
- name: expand
in: query
required: false
description: Comma-separated associations to expand (e.g., country, state). Use dot notation for nested expand (max 4 levels).
schema:
type: string
- name: fields
in: query
required: false
description: Comma-separated list of fields to include (e.g., first_name,last_name,address1,city). id is always included.
schema:
type: string
responses:
'200':
description: addresses found
content:
application/json:
example:
data:
- id: addr_UkLWZg9DAJ
first_name: John
last_name: Doe
full_name: John Doe
address1: 1 Lovely Street
address2: Northwest
postal_code: '10118'
city: New York
phone: 555-555-0199
company: Company
country_name: United States of America
country_iso: US
state_text: NY
state_abbr: NY
quick_checkout: false
is_default_billing: false
is_default_shipping: false
state_name: New York
label: null
metadata: {}
created_at: '2026-06-12T17:23:58.540Z'
updated_at: '2026-06-12T17:23:58.540Z'
customer_id: cus_UkLWZg9DAJ
meta:
page: 1
limit: 25
count: 1
pages: 1
from: 1
to: 1
in: 1
previous: null
next: null
post:
summary: Create a customer address
tags:
- Customers
security:
- api_key: []
bearer_auth: []
description: 'Adds a new address to the customer''s address book. Pass `is_default_billing: true` or `is_default_shipping: true` to set as the default — the previous default loses its flag in the same transaction.
**Required scope:** `write_customers` (for API-key authentication).'
x-codeSamples:
- lang: javascript
label: Spree Admin SDK
source: "import { createAdminClient } from '@spree/admin-sdk'\n\nconst client = createAdminClient({\n baseUrl: 'https://your-store.com',\n secretKey: 'sk_xxx',\n})\n\nconst address = await client.customers.addresses.create('cus_UkLWZg9DAJ', {\n first_name: 'Jane',\n last_name: 'Doe',\n address1: '350 Fifth Avenue',\n city: 'New York',\n postal_code: '10118',\n country_iso: 'US',\n state_abbr: 'NY',\n phone: '+1 212 555 1234',\n label: 'Office',\n is_default_shipping: true,\n})"
parameters:
- name: x-spree-api-key
in: header
required: true
schema:
type: string
- name: Authorization
in: header
required: true
schema:
type: string
- name: customer_id
in: path
required: true
schema:
type: string
responses:
'201':
description: address created
content:
application/json:
example:
id: addr_gbHJdmfrXB
first_name: Jane
last_name: Doe
full_name: Jane Doe
address1: 350 Fifth Avenue
address2: null
postal_code: '10118'
city: New York
phone: '+12125551234'
company: null
country_name: United States of America
country_iso: US
state_text: NY
state_abbr: NY
quick_checkout: false
is_default_billing: false
is_default_shipping: false
state_name: New York
label: Office
metadata: {}
created_at: '2026-06-12T17:23:59.952Z'
updated_at: '2026-06-12T17:23:59.952Z'
customer_id: cus_UkLWZg9DAJ
requestBody:
content:
application/json:
schema:
type: object
properties:
first_name:
type: string
last_name:
type: string
address1:
type: string
address2:
type: string
city:
type: string
postal_code:
type: string
country_iso:
type: string
description: ISO-2 country code (e.g. US)
state_abbr:
type: string
description: State/province abbreviation (e.g. NY)
phone:
type: string
company:
type: string
label:
type: string
is_default_billing:
type: boolean
is_default_shipping:
type: boolean
/api/v3/admin/customers/{customer_id}/addresses/{id}:
patch:
summary: Update a customer address
tags:
- Customers
security:
- api_key: []
bearer_auth: []
description: 'Updates a customer address.
**Required scope:** `write_customers` (for API-key authentication).'
x-codeSamples:
- lang: javascript
label: Spree Admin SDK
source: "import { createAdminClient } from '@spree/admin-sdk'\n\nconst client = createAdminClient({\n baseUrl: 'https://your-store.com',\n secretKey: 'sk_xxx',\n})\n\nconst address = await client.customers.addresses.update(\n 'cus_UkLWZg9DAJ',\n 'addr_UkLWZg9DAJ',\n { city: 'Manhattan' },\n)"
parameters:
- name: x-spree-api-key
in: header
required: true
schema:
type: string
- name: Authorization
in: header
required: true
schema:
type: string
- name: customer_id
in: path
required: true
schema:
type: string
- name: id
in: path
required: true
schema:
type: string
responses:
'200':
description: address updated
content:
application/json:
example:
id: addr_UkLWZg9DAJ
first_name: John
last_name: Doe
full_name: John Doe
address1: 3 Lovely Street
address2: Northwest
postal_code: '10118'
city: Manhattan
phone: 555-555-0199
company: Company
country_name: United States of America
country_iso: US
state_text: NY
state_abbr: NY
quick_checkout: false
is_default_billing: false
is_default_shipping: false
state_name: New York
label: null
metadata: {}
created_at: '2026-06-12T17:24:00.227Z'
updated_at: '2026-06-12T17:24:00.777Z'
customer_id: cus_UkLWZg9DAJ
requestBody:
content:
application/json:
schema:
type: object
properties:
city:
type: string
is_default_billing:
type: boolean
is_default_shipping:
type: boolean
delete:
summary: Delete a customer address
tags:
- Customers
security:
- api_key: []
bearer_auth: []
description: 'Deletes the address. If it was a default, the customer loses that default (no auto-promotion).
**Required scope:** `write_customers` (for API-key authentication).'
x-codeSamples:
- lang: javascript
label: Spree Admin SDK
source: "import { createAdminClient } from '@spree/admin-sdk'\n\nconst client = createAdminClient({\n baseUrl: 'https://your-store.com',\n secretKey: 'sk_xxx',\n})\n\nawait client.customers.addresses.delete('cus_UkLWZg9DAJ', 'addr_UkLWZg9DAJ')"
parameters:
- name: x-spree-api-key
in: header
required: true
schema:
type: string
- name: Authorization
in: header
required: true
schema:
type: string
- name: customer_id
in: path
required: true
schema:
type: string
- name: id
in: path
required: true
schema:
type: string
responses:
'204':
description: address deleted
/api/v3/admin/customers/{customer_id}/credit_cards:
get:
summary: List customer credit cards
tags:
- Customers
security:
- api_key: []
bearer_auth: []
description: 'Returns the customer''s saved credit cards. Useful for off-session admin charges via `POST /admin/orders/:id/payments { source_id }`.
**Required scope:** `read_customers` (for API-key authentication).'
x-codeSamples:
- lang: javascript
label: Spree Admin SDK
source: "import { createAdminClient } from '@spree/admin-sdk'\n\nconst client = createAdminClient({\n baseUrl: 'https://your-store.com',\n secretKey: 'sk_xxx',\n})\n\nconst { data: cards } = await client.customers.creditCards.list('cus_UkLWZg9DAJ')"
parameters:
- name: x-spree-api-key
in: header
required: true
schema:
type: string
- name: Authorization
in: header
required: true
schema:
type: string
- name: customer_id
in: path
required: true
schema:
type: string
- name: expand
in: query
required: false
description: Comma-separated associations to expand (e.g., payment_method). Use dot notation for nested expand (max 4 levels).
schema:
type: string
- name: fields
in: query
required: false
description: Comma-separated list of fields to include (e.g., brand,last4,month,year). id is always included.
schema:
type: string
responses:
'200':
description: credit cards found
content:
application/json:
example:
data:
- id: card_UkLWZg9DAJ
brand: visa
last4: '1111'
month: 12
year: 2027
name: Spree Commerce
default: false
gateway_payment_profile_id: null
customer_id: cus_UkLWZg9DAJ
payment_method_id: pm_UkLWZg9DAJ
metadata: {}
created_at: '2026-06-12T17:24:01.924Z'
updated_at: '2026-06-12T17:24:01.924Z'
meta:
page: 1
limit: 25
count: 1
pages: 1
from: 1
to: 1
in: 1
previous: null
next: null
/api/v3/admin/customers/{customer_id}/credit_cards/{id}:
get:
summary: Show a customer credit card
tags:
- Customers
security:
- api_key: []
bearer_auth: []
description: 'Returns a saved credit card by ID.
**Required scope:** `read_customers` (for API-key authentication).'
x-codeSamples:
- lang: javascript
label: Spree Admin SDK
source: "import { createAdminClient } from '@spree/admin-sdk'\n\nconst client = createAdminClient({\n baseUrl: 'https://your-store.com',\n secretKey: 'sk_xxx',\n})\n\nconst card = await client.customers.creditCards.get('cus_UkLWZg9DAJ', 'cc_UkLWZg9DAJ')"
parameters:
- name: x-spree-api-key
in: header
required: true
schema:
type: string
- name: Authorization
in: header
required: true
schema:
type: string
- name: customer_id
in: path
required: true
schema:
type: string
- name: id
in: path
required: true
schema:
type: string
- name: expand
in: query
required: false
description: Comma-separated associations to expand (e.g., payment_method). Use dot notation for nested expand (max 4 levels).
schema:
type: string
- name: fields
in: query
required: false
description: Comma-separated list of fields to include (e.g., brand,last4,month,year). id is always included.
schema:
type: string
responses:
'200':
description: credit card found
content:
application/json:
example:
id: card_UkLWZg9DAJ
brand: visa
last4: '1111'
month: 12
year: 2027
name: Spree Commerce
default: false
gateway_payment_profile_id: null
customer_id: cus_UkLWZg9DAJ
payment_method_id: pm_UkLWZg9DAJ
metadata: {}
created_at: '2026-06-12T17:24:02.498Z'
updated_at: '2026-06-12T17:24:02.498Z'
delete:
summary: Delete a customer credit card
tags:
- Customers
security:
- api_key: []
bearer_auth: []
description: 'Deletes a saved credit card.
**Required scope:** `write_customers` (for API-key authentication).'
x-codeSamples:
- lang: javascript
label: Spree Admin SDK
source: "import { createAdminClient } from '@spree/admin-sdk'\n\nconst client = createAdminClient({\n baseUrl: 'https://your-store.com',\n secretKey: 'sk_xxx',\n})\n\nawait client.customers.creditCards.delete('cus_UkLWZg9DAJ', 'cc_UkLWZg9DAJ')"
parameters:
- name: x-spree-api-key
in: header
required: true
schema:
type: string
- name: Authorization
in: header
required: true
schema:
type: string
- name: customer_id
in: path
required: true
schema:
type: string
- name: id
in: path
required: true
schema:
type: string
responses:
'204':
description: credit card deleted
/api/v3/admin/customers/{customer_id}/store_credits:
get:
summary: List customer store credits
tags:
- Customers
security:
- api_key: []
bearer_auth: []
description: 'Returns store credits issued to the customer.
**Required scope:** `read_store_credits` (for API-key authentication).'
x-codeSamples:
- lang: javascript
label: Spree Admin SDK
source: "import { createAdminClient } from '@spree/admin-sdk'\n\nconst client = createAdminClient({\n baseUrl: 'https://your-store.com',\n secretKey: 'sk_xxx',\n})\n\nconst { data: storeCredits } = await client.customers.storeCredits.list('cus_UkLWZg9DAJ')"
parameters:
- name: x-spree-api-key
in: header
required: true
schema:
type: string
- name: Authorization
in: header
required: true
schema:
type: string
- name: customer_id
in: path
required: true
schema:
type: string
- name: expand
in: query
required: false
description: Comma-separated associations to expand (e.g., category, store, created_by). Use dot notation for nested expand (max 4 levels).
schema:
type: string
- name: fields
in: query
required: false
description: Comma-separated list of fields to include (e.g., amount,amount_used,memo,currency). id is always included.
schema:
type: string
responses:
'200':
description: store credits found
content:
application/json:
example:
data:
- id: credit_UkLWZg9DAJ
amount: '50.0'
amount_used: '0.0'
amount_remaining: '50.0'
display_amount: $50.00
display_amount_used: $0.00
display_amount_remaining: $50.00
currency: USD
memo: null
metadata: {}
created_at: '2026-06-12T17:24:03.896Z'
updated_at: '2026-06-12T17:24:03.896Z'
customer_id: cus_UkLWZg9DAJ
created_by_id: admin_UkLWZg9DAJ
category_id: sccat_UkLWZg9DAJ
category_name: Exchange
meta:
page: 1
limit: 25
count: 1
pages: 1
from: 1
to: 1
in: 1
previous: null
next: null
post:
summary: Issue a store credit to a customer
tags:
- Customers
security:
- api_key: []
bearer_auth: []
description: '`created_by` is set automatically from the authenticated admin.
**Required scope:** `write_store_credits` (for API-key authentication).'
x-codeSamples:
- lang: javascript
label: Spree Admin SDK
source: "import { createAdminClient } from '@spree/admin-sdk'\n\nconst client = createAdminClient({\n baseUrl: 'https://your-store.com',\n secretKey: 'sk_xxx',\n})\n\nconst credit = await client.customers.storeCredits.create('cus_UkLWZg9DAJ', {\n amount: 25.00,\n currency: 'USD',\n category_id: 'cat_UkLWZg9DAJ',\n memo: 'Goodwill credit',\n})"
parameters:
- name: x-spree-api-key
in: header
required: true
schema:
type: string
- name: Authorization
in: header
required: true
schema:
type: string
- name: customer_id
in: path
required: true
schema:
type: string
responses:
'201':
description: store credit created
content:
application/json:
example:
id: credit_gbHJdmfrXB
amount: '25.0'
amount_used: '0.0'
amount_remaining: '25.0'
display_amount: $25.00
display_amount_used: $0.00
display_amount_remaining: $25.00
currency: USD
memo: Goodwill
metadata: {}
created_at: '2026-06-12T17:24:05.013Z'
updated_at: '2026-06-12T17:24:05.013Z'
customer_id: cus_UkLWZg9DAJ
created_by_id: admin_gbHJdmfrXB
category_id: sccat_UkLWZg9DAJ
category_name: Exchange
requestBody:
content:
application/json:
schema:
type: object
required:
- amount
- currency
- category_id
properties:
amount:
type: number
example: 50.0
currency:
type: string
example: USD
category_id:
type: string
description: StoreCreditCategory ID
memo:
type: string
/api/v3/admin/customers/{customer_id}/store_credits/{id}:
patch:
summary: Update a store credit
tags:
- Customers
security:
- api_key: []
bearer_auth: []
description: 'Update memo / category / amount. The amount can only be changed if `amount_used == 0`.
**Required scope:** `write_store_credits` (for API-key authentication).'
x-codeSamples:
- lang: javascript
label: Spree Admin SDK
source: "import { createAdminClient } from '@spree/admin-sdk'\n\nconst client = createAdminClient({\n baseUrl: 'https://your-store.com',\n secretKey: 'sk_xxx',\n})\n\nconst credit = await client.customers.storeCredits.update(\n 'cus_UkLWZg9DAJ',\n 'sc_UkLWZg9DAJ',\n { memo: 'Reissued for damaged shipment' },\n)"
parameters:
- name: x-spree-api-key
in: header
required: true
schema:
type: string
- name: Authorization
in: header
required: true
schema:
type: string
- name: customer_id
in: path
required: true
schema:
type: string
- name: id
in: path
required: true
schema:
type: string
responses:
'200':
description: store credit updated
content:
application/json:
example:
id: credit_UkLWZg9DAJ
amount: '50.0'
amount_used: '0.0'
amount_remaining: '50.0'
display_amount: $50.00
display_amount_used: $0.00
display_amount_remaining: $50.00
currency: USD
memo: Updated
metadata: {}
created_at: '2026-06-12T17:24:05.556Z'
updated_at: '2026-06-12T17:24:05.841Z'
customer_id: cus_UkLWZg9DAJ
created_by_id: admin_UkLWZg9DAJ
category_id: sccat_UkLWZg9DAJ
category_name: Exchange
requestBody:
content:
application/json:
schema:
type: object
properties:
amount:
type: number
category_id:
type: string
memo:
type: string
delete:
summary: Delete a store credit
tags:
- Customers
security:
- api_key: []
bearer_auth: []
description: 'Deletes an unused store credit (amount_used == 0). Returns 422 otherwise.
**Required scope:** `write_store_credits` (for API-key authentication).'
x-codeSamples:
- lang: javascript
label: Spree Admin SDK
source: "import { createAdminClient } from '@spree/admin-sdk'\n\nconst client = createAdminClient({\n baseUrl: 'https://your-store.com',\n secretKey: 'sk_xxx',\n})\n\nawait client.customers.storeCredits.delete('cus_UkLWZg9DAJ', 'sc_UkLWZg9DAJ')"
parameters:
- name: x-spree-api-key
in: header
required: true
schema:
type: string
- name: Authorization
in: header
required: true
schema:
type: string
- name: customer_id
in: path
required: true
schema:
type: string
- name: id
in: path
required: true
schema:
type: string
responses:
'204':
description: store credit deleted
/api/v3/admin/customers:
get:
summary: List customers
tags:
- Customers
security:
- api_key: []
bearer_auth: []
description: 'Returns a paginated list of customers. Supports Ransack search/filters.
**Required scope:** `read_customers` (for API-key authentication).'
x-codeSamples:
- lang: javascript
label: Spree Admin SDK
source: "import { createAdminClient } from '@spree/admin-sdk'\n\nconst client = createAdminClient({\n baseUrl: 'https://your-store.com',\n secretKey: 'sk_xxx',\n})\n\nconst { data: customers } = await client.customers.list({\n search: 'jane',\n sort: '-created_at',\n limit: 25,\n})"
parameters:
- name: x-spree-api-key
in: header
required: true
schema:
type: string
- name: Authorization
in: header
required: true
description: Bearer token for admin authentication
schema:
type: string
- name: page
in: query
required: false
schema:
type: integer
- name: limit
in: query
required: false
schema:
type: integer
- name: q[search]
in: query
required: false
description: Email + name full-text-ish search
schema:
type: string
- name: expand
in: query
required: false
description: Comma-separated associations to expand (e.g., addresses, store_credits). Use dot notation for nested expand (max 4 levels).
schema:
type: string
- name: fields
in: query
required: false
description: Comma-separated list of fields to include (e.g., email,first_name,last_name). id is always included.
schema:
type: string
responses:
'200':
description: customers found
content:
application/json:
example:
data:
- id: cus_UkLWZg9DAJ
email: jane@example.com
first_name: Jane
last_name: Doe
phone: null
accepts_email_marketing: false
full_name: Jane Doe
available_store_credit_total: '0'
display_available_store_credit_total: $0.00
login: jane@example.com
metadata: {}
last_sign_in_at: null
current_sign_in_at: null
created_at: '2026-06-12T17:24:06.985Z'
updated_at: '2026-06-12T17:24:06.985Z'
sign_in_count: 0
failed_attempts: 0
last_sign_in_ip: null
current_sign_in_ip: null
tags: []
internal_note_html: null
default_billing_address_id: null
default_shipping_address_id: null
orders_count: 0
total_spent: '0'
display_total_spent: $0.00
last_order_completed_at: null
meta:
page: 1
limit: 25
count: 1
pages: 1
from: 1
to: 1
in: 1
previous: null
next: null
post:
summary: Create a customer
tags:
- Customers
security:
- api_key: []
bearer_auth: []
description: 'Creates a customer. No welcome email is sent automatically.
**Required scope:** `write_customers` (for API-key authentication).'
x-codeSamples:
- lang: javascript
label: Spree Admin SDK
source: "import { createAdminClient } from '@spree/admin-sdk'\n\nconst client = createAdminClient({\n baseUrl: 'https://your-store.com',\n secretKey: 'sk_xxx',\n})\n\nconst customer = await client.customers.create({\n email: 'jane@example.com',\n first_name: 'Jane',\n last_name: 'Doe',\n phone: '+1 212 555 1234',\n tags: ['wholesale'],\n accepts_email_marketing: true,\n})"
parameters:
- name: x-spree-api-key
in: header
required: true
schema:
type: string
- name: Authorization
in: header
required: true
schema:
type: string
responses:
'201':
description: customer created
content:
application/json:
example:
id: cus_gbHJdmfrXB
email: newcustomer@example.com
first_name: New
last_name: Customer
phone: null
accepts_email_marketing: false
full_name: New Customer
available_store_credit_total: '0'
display_available_store_credit_total: $0.00
login: null
metadata: {}
last_sign_in_at: null
current_sign_in_at: null
created_at: '2026-06-12T17:24:07.836Z'
updated_at: '2026-06-12T17:24:07.836Z'
sign_in_count: 0
failed_attempts: 0
last_sign_in_ip: null
current_sign_in_ip: null
tags: []
internal_note_html: null
default_billing_address_id: null
default_shipping_address_id: null
orders_count: 0
total_spent: '0.0'
display_total_spent: $0.00
last_order_completed_at: null
requestBody:
content:
application/json:
schema:
type: object
required:
- email
properties:
email:
type: string
example: new@example.com
first_name:
type: string
last_name:
type: string
phone:
type: string
accepts_email_marketing:
type: boolean
internal_note:
type: string
tags:
type: array
items:
type: string
metadata:
type: object
/api/v3/admin/customers/{id}:
get:
summary: Show a customer
tags:
- Customers
security:
- api_key: []
bearer_auth: []
description: 'Returns full customer details including computed order stats (orders_count, total_spent, last_order_completed_at).
**Required scope:** `read_customers` (for API-key authentication).'
x-codeSamples:
- lang: javascript
label: Spree Admin SDK
source: "import { createAdminClient } from '@spree/admin-sdk'\n\nconst client = createAdminClient({\n baseUrl: 'https://your-store.com',\n secretKey: 'sk_xxx',\n})\n\nconst customer = await client.customers.get('cus_UkLWZg9DAJ', {\n expan
# --- truncated at 32 KB (141 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/spree/refs/heads/main/openapi/spree-customers-api-openapi.yml