Back to Spree

Authentication

docs/api-reference/store-api/authentication.mdx

5.4.24.8 KB
Original Source

The Store API uses three authentication mechanisms depending on the use case: API keys for all requests, JWT tokens for authenticated customers, and order tokens for guest checkout.

API Key (Required)

Every request to the Store API requires a publishable API key. This key identifies your storefront and is safe to use in client-side code.

Pass the key via the X-Spree-Api-Key header:

<CodeGroup>
typescript
import { createClient } from '@spree/sdk'

const client = createClient({
  baseUrl: 'http://localhost:3000',
  publishableKey: 'pk_xxx',
})

// The SDK automatically sends the publishable key with every request
const products = await client.products.list()
bash
curl -X GET 'http://localhost:3000/api/v3/store/products' \
  -H 'X-Spree-Api-Key: pk_xxx'
</CodeGroup>

Publishable API keys are prefixed with pk_. You can create them in the Spree Admin under Settings > API Keys or via the Spree CLI:

bash
spree api-key create       # Create a new API key
spree api-key list         # List existing API keys
<Warning> If you omit the API key, the API returns a `401 Unauthorized` error:
json
{
  "error": {
    "code": "invalid_token",
    "message": "Valid API key required"
  }
}
</Warning>

JWT Token (Authenticated Customer)

For actions that require a logged-in customer (viewing orders, managing addresses, saved payment methods), use a JWT bearer token in addition to the API key.

Login

<CodeGroup>
typescript
// Login to get a JWT token
const { token, user } = await client.auth.login({
  email: '[email protected]',
  password: 'password123',
})

// Use the token for authenticated requests
const orders = await client.customer.orders.list({}, { token })
bash
# Login
curl -X POST 'http://localhost:3000/api/v3/store/auth/login' \
  -H 'X-Spree-Api-Key: pk_xxx' \
  -H 'Content-Type: application/json' \
  -d '{"email": "[email protected]", "password": "password123"}'

# Use the returned token for authenticated requests
curl -X GET 'http://localhost:3000/api/v3/store/orders' \
  -H 'X-Spree-Api-Key: pk_xxx' \
  -H 'Authorization: Bearer <jwt_token>'
</CodeGroup>

Register

<CodeGroup>
typescript
const { token, user } = await client.customers.create({
  email: '[email protected]',
  password: 'password123',
  password_confirmation: 'password123',
  first_name: 'John',
  last_name: 'Doe',
})
bash
curl -X POST 'http://localhost:3000/api/v3/store/customers' \
  -H 'X-Spree-Api-Key: pk_xxx' \
  -H 'Content-Type: application/json' \
  -d '{
    "email": "[email protected]",
    "password": "password123",
    "password_confirmation": "password123",
    "first_name": "John",
    "last_name": "Doe"
  }'
</CodeGroup>

Token Refresh

JWT tokens expire after 1 hour by default. Use the refresh endpoint to get a new token:

<CodeGroup>
typescript
const { token } = await client.auth.refresh({ token: currentToken })
bash
curl -X POST 'http://localhost:3000/api/v3/store/auth/refresh' \
  -H 'X-Spree-Api-Key: pk_xxx' \
  -H 'Authorization: Bearer <current_jwt_token>'
</CodeGroup>

Order Token (Guest Checkout)

For guest checkout flows, use the order token returned when creating a cart. This allows unauthenticated users to manage their cart and complete checkout.

Pass the token via the x-spree-token header:

<CodeGroup>
typescript
// Create a cart (guest)
const cart = await client.carts.create()

// Use spreeToken for all guest cart operations
const options = { spreeToken: cart.token }

// Add items
await client.carts.items.create(cart.id, {
  variant_id: 'variant_abc123',
  quantity: 1,
}, options)
bash
# Create a cart
curl -X POST 'http://localhost:3000/api/v3/store/carts' \
  -H 'X-Spree-Api-Key: pk_xxx'

# Use the returned token for cart operations
curl -X POST 'http://localhost:3000/api/v3/store/carts/cart_xxx/items' \
  -H 'X-Spree-Api-Key: pk_xxx' \
  -H 'X-Spree-Token: <order_token>' \
  -H 'Content-Type: application/json' \
  -d '{"variant_id": "variant_abc123", "quantity": 1}'
</CodeGroup>

Associating a Guest Cart

After a guest user logs in, you can associate their guest cart with their account:

<CodeGroup>
typescript
await client.carts.associate(cart.id, {
  token: jwtToken,
  spreeToken: cart.token,
})
bash
curl -X PATCH 'http://localhost:3000/api/v3/store/carts/cart_xxx/associate' \
  -H 'X-Spree-Api-Key: pk_xxx' \
  -H 'Authorization: Bearer <jwt_token>' \
  -H 'X-Spree-Token: <order_token>'
</CodeGroup>

Authentication Summary

MethodHeaderUse Case
API KeyX-Spree-Api-Key: pk_xxxAll requests (required)
JWT TokenAuthorization: Bearer <token>Authenticated customer actions
Order TokenX-Spree-Token: <token>Guest cart and checkout