Creates a new customer account and returns a JWT token
POST
/
api
/
v3
/
store
/
customers
Spree SDK
import { createClient } from '@spree/sdk'
const client = createClient({
baseUrl: 'https://your-store.com',
publishableKey: '<api-key>',
})
const auth = await client.customers.create({
email: 'newuser@example.com',
password: 'password123',
password_confirmation: 'password123',
first_name: 'John',
last_name: 'Doe',
phone: '+1234567890',
accepts_email_marketing: true,
metadata: { source: 'storefront' },
})curl --request POST \
--url http://{defaultHost}/api/v3/store/customers \
--header 'Content-Type: application/json' \
--header 'x-spree-api-key: <api-key>' \
--data '
{
"email": "newuser@example.com",
"password": "password123",
"password_confirmation": "password123",
"first_name": "John",
"last_name": "Doe",
"phone": "+1234567890",
"accepts_email_marketing": true,
"metadata": {
"source": "storefront"
}
}
'{
"token": "eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJ1c2VyX3R5cGUiOiJjdXN0b21lciIsImp0aSI6IjBiNDk1ZTBmLTRhZmQtNDY1Zi1hMTA0LTU2NzdkZGRhN2U2ZiIsImlzcyI6InNwcmVlIiwiYXVkIjoic3RvcmVfYXBpIiwiZXhwIjoxNzg1MDEyMDgwfQ.XBJaPkz-mXn6KzhhDNOkzBRZDqEV6WGKR3sDC8vtbP0",
"refresh_token": "Rwa2AmXx3wLhcxiPjH4wxbjT",
"user": {
"id": "cus_UkLWZg9DAJ",
"email": "newuser@example.com",
"first_name": "John",
"last_name": "Doe",
"phone": "+1234567890",
"accepts_email_marketing": true,
"full_name": "John Doe",
"available_store_credit_total": "0",
"display_available_store_credit_total": "$0.00",
"addresses": [],
"default_billing_address": null,
"default_shipping_address": null,
"newsletter_subscriber": {
"id": "sub_UkLWZg9DAJ",
"email": "newuser@example.com",
"created_at": "2026-07-25T19:41:19.980Z",
"updated_at": "2026-07-25T19:41:19.981Z",
"verified": true,
"verified_at": "2026-07-25T19:41:19Z",
"customer_id": "cus_UkLWZg9DAJ"
},
"customer_groups": []
}
}{
"error": {
"code": "validation_error",
"message": "Email has already been taken",
"details": {
"email": [
"has already been taken"
]
}
}
}Authorizations
Publishable API key for store access
Headers
Body
application/json
Example:
"newuser@example.com"
Minimum string length:
6Example:
"password123"
Example:
"password123"
Example:
"John"
Example:
"Doe"
Example:
"+1234567890"
Example:
true
Example:
{ "source": "storefront" }
Was this page helpful?
Spree SDK
import { createClient } from '@spree/sdk'
const client = createClient({
baseUrl: 'https://your-store.com',
publishableKey: '<api-key>',
})
const auth = await client.customers.create({
email: 'newuser@example.com',
password: 'password123',
password_confirmation: 'password123',
first_name: 'John',
last_name: 'Doe',
phone: '+1234567890',
accepts_email_marketing: true,
metadata: { source: 'storefront' },
})curl --request POST \
--url http://{defaultHost}/api/v3/store/customers \
--header 'Content-Type: application/json' \
--header 'x-spree-api-key: <api-key>' \
--data '
{
"email": "newuser@example.com",
"password": "password123",
"password_confirmation": "password123",
"first_name": "John",
"last_name": "Doe",
"phone": "+1234567890",
"accepts_email_marketing": true,
"metadata": {
"source": "storefront"
}
}
'{
"token": "eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJ1c2VyX3R5cGUiOiJjdXN0b21lciIsImp0aSI6IjBiNDk1ZTBmLTRhZmQtNDY1Zi1hMTA0LTU2NzdkZGRhN2U2ZiIsImlzcyI6InNwcmVlIiwiYXVkIjoic3RvcmVfYXBpIiwiZXhwIjoxNzg1MDEyMDgwfQ.XBJaPkz-mXn6KzhhDNOkzBRZDqEV6WGKR3sDC8vtbP0",
"refresh_token": "Rwa2AmXx3wLhcxiPjH4wxbjT",
"user": {
"id": "cus_UkLWZg9DAJ",
"email": "newuser@example.com",
"first_name": "John",
"last_name": "Doe",
"phone": "+1234567890",
"accepts_email_marketing": true,
"full_name": "John Doe",
"available_store_credit_total": "0",
"display_available_store_credit_total": "$0.00",
"addresses": [],
"default_billing_address": null,
"default_shipping_address": null,
"newsletter_subscriber": {
"id": "sub_UkLWZg9DAJ",
"email": "newuser@example.com",
"created_at": "2026-07-25T19:41:19.980Z",
"updated_at": "2026-07-25T19:41:19.981Z",
"verified": true,
"verified_at": "2026-07-25T19:41:19Z",
"customer_id": "cus_UkLWZg9DAJ"
},
"customer_groups": []
}
}{
"error": {
"code": "validation_error",
"message": "Email has already been taken",
"details": {
"email": [
"has already been taken"
]
}
}
}
