Skip to main content
Before you start customizing Spree API endpoints, make sure you reviewed all existing API endpoints in the Spree API docs. For a step-by-step walkthrough of adding a complete new resource (model, serializer, controller, routes), see the API tutorial.

Customizing JSON Responses

Spree uses Alba serializers to build API v3 responses. You can replace any serializer via Spree Dependencies.

Adding Custom Attributes

Let’s say you want to add a my_custom_attribute column to the Product API response. Create a custom serializer that inherits from the core one:
app/serializers/my_app/product_serializer.rb
Register it in config/initializers/spree.rb:
Restart the server and the Product API will include your new attribute.

Adding an Association

Let’s say you’ve created a Spree::Brand model that belongs to Product (see the tutorial for the full example). Create a serializer for the new model:
app/serializers/spree/api/v3/brand_serializer.rb
Then subclass the Product serializer to include the brand association:
app/serializers/my_app/product_serializer.rb
Register it in config/initializers/spree.rb:
The brand data is available via ?expand=brand:

Serializer Dependency Keys

Here are the most commonly customized v3 serializers: See Spree::Api::ApiDependencies for the full list.

Adding New Endpoints

Controller

Inherit from Spree::Api::V3::Store::ResourceController for Store API endpoints:
app/controllers/spree/api/v3/store/brands_controller.rb
The base ResourceController provides: Override these methods to customize:

Routes

Add routes in your app’s config/routes.rb:

Permitted Attributes

For endpoints that accept writes (create/update), declare the attributes in your controller:
Entries are params.permit fragments, so collections and nested structures use the shapes you would pass there directly — [:name, { region_ids: [] }].
Declare resource_permitted_attributes, not permitted_attributes. The latter is what appends extension-contributed attributes to your list, so overriding it replaces them.

Adding an Attribute to a Core Resource

To make a new column writable on a Spree model without decorating the controllers that write it, append to the model’s permitted attributes:
config/initializers/spree.rb
Standard resource endpoints append these to their own allowlist, so one declaration covers the model’s create and update endpoints. Use +=, never = — assigning replaces what another extension added — and declare only attributes of your own, since redeclaring a key the controller already permits replaces its filter rather than widening it.
For merchant-managed data, prefer Custom Fields, which need no code and are filterable and sortable. This is for extensions that add real database columns.
Two endpoints deliberately ignore this hook because their parameters are authorization data rather than resource data: API keys and invitations.

Consuming Custom Endpoints with the SDK

See the SDK tutorial for how to call custom endpoints from TypeScript and extend the generated types.