docs/plans/6.0-admin-api.md
Status: In Progress
Target: Spree 6.0
Depends on: 6.0-admin-spa.md, 6.0-platform-auth.md
Author: damian
Last updated: 2026-04-11
A new REST API namespace (/api/v3/admin/*) that exposes every admin resource and operation currently served by the spree/admin Rails engine. Provides the programmatic backbone for the new React admin SPA, the TypeScript SDK, the CLI, and any other admin-facing tooling. Follows the same conventions as the Store API (flat JSON, prefixed IDs, Ransack filters, Pagy pagination, CanCanCan authorization) with a separate JWT audience and admin-scoped authentication.
Spree::Api::V3::Admin::ResourceController — no bespoke controllers unless absolutely necessary.POST to create, PATCH to update, DELETE to destroy. No custom verbs except for state-machine actions (/cancel, /approve, etc.).admin_api) — admin tokens MUST NOT be valid on the Store API and vice versa. Uses Spree.admin_user_class.spree_sk_xxx) via Authorization: Bearer for server-to-serverAuthorization: Bearer for SPA sessionsdocs/api-reference/store-api/errors.mdx).record.update! would embed non-trivial business rules in the controller./orders/:id/line_items/:id is fine, /orders/:id/shipments/:id/rates/:id is not. Flatten with filter params when necessary.Spree::Asset (ActiveStorage + alt text + ordering + variant scoping).Spree::Api::V3::BaseController # shared concerns: pagination, Ransack, caching
└── Spree::Api::V3::Admin::BaseController
└── Spree::Api::V3::Admin::ResourceController # default CRUD
└── Spree::Api::V3::Admin::ProductsController
└── Spree::Api::V3::Admin::OrdersController
└── ...
ResourceController provides a default index/show/create/update/destroy implementation. Subclasses override model_class, serializer_class, and optionally scope, permitted_params, find_resource, scope_includes. Most admin controllers should fit in 30–80 lines.
Spree::Api::V3::AdminAuthentication concern added to Admin::BaseControllerSpree::RefreshToken — rotated on every refresh/auth/login, /auth/refresh live on Admin::AuthController which skips authenticate_admin!{ token, refresh_token, user } shape{ id: ..., name: ... } not { product: { id: ... } }){ data: [...], meta: { total_count, page, pages, limit } }prod_86Rf07xd4z, variant_k5nR8xLq)?expand=variants,variants.prices to include associations (max 4 levels)?q[name_cont]=shirt for Ransack filtering?sort=-created_at for sorting (JSON:API convention){
"name": "Test product",
"tax_category_id": "taxcat_abc1234",
"taxon_ids": ["taxon_abc123", "taxon_def456"],
"tags": ["eco", "best-seller"],
"variants": [
{
"option_type": "size",
"option_value": "small",
"total_on_hand": 10,
"track_inventory": true,
"width": 10.5,
"height": 5.2,
"depth": 2.1,
"weight": 0.5,
"dimensions_unit": "cm",
"weight_unit": "kg",
"prices": [
{ "currency": "USD", "amount": 10.99 },
{ "currency": "EUR", "amount": 9.99 }
]
}
]
}
Validation errors return 422 with:
{
"error": {
"code": "validation_error",
"message": "Name can't be blank",
"details": { "name": ["can't be blank"] }
}
}
{
"currency": "USD",
"locale": "en-US",
"line_items": [
{ "variant_id": "variant_123456789", "quantity": 1 },
{ "variant_id": "variant_987654321", "quantity": 2 }
]
}
GET /meGET /api/v3/admin/me returns the current admin user plus a serialized list of their permissions (CanCanCan rules flattened). The SPA consumes this to drive UI permission checks; the server still enforces authorize! on every action.
{
"user": { "id": "admin_xxx", "email": "...", ... },
"permissions": [
{ "allow": true, "actions": ["manage"], "subjects": ["all"], "has_conditions": false },
{ "allow": false, "actions": ["destroy"], "subjects": ["Spree::Order"], "has_conditions": true }
]
}
Per-record conditions (CanCanCan blocks/hashes) are not serialized — only has_conditions: true as a hint. The SPA shows actions optimistically and handles 403 from the API.
bundle exec rake typelizer:generate + pnpm generate:zod@spree/admin-sdk[x] in this planbundle exec rake rswag:specs:swaggerizeAdmin::ResourceController hierarchy without a written exception in this plan.record.update is almost always enough.This plan reflects the 6.0 model/naming landscape. Endpoints removed from 5.x or renamed are tracked in the Removed / Renamed endpoints table at the top so contributors don't accidentally re-implement them.
| 5.x endpoint | 6.0 endpoint | Reason |
|---|---|---|
/api/v3/admin/taxonomies/* | removed | Spree::Taxonomy dropped; Category belongs directly to store. See 6.0-replace-taxons-with-categories.md |
/api/v3/admin/taxons/* | /api/v3/admin/categories/* | Spree::Taxon → Spree::Category rename |
/api/v3/admin/shipping_methods/* | /api/v3/admin/delivery_methods/* | ShippingMethod → DeliveryMethod rename |
/api/v3/admin/orders/:id/shipments/* | /api/v3/admin/orders/:id/fulfillments/* | Shipment → Fulfillment rename |
/api/v3/admin/shipping_categories/* | removed | Replaced by ProductType.fulfillment_types. See 6.0-fulfillment-and-delivery.md |
/api/v3/admin/zones/* | removed | Tax zones → direct country/state FKs on TaxRate. Shipping zones → new DeliveryZone. See 6.0-tax-provider.md, 6.0-fulfillment-and-delivery.md |
/api/v3/admin/return_authorizations/* | /api/v3/admin/returns/* | ReturnAuthorization → Return. See 6.0-returns-exchanges-claims.md |
/api/v3/admin/customer_returns/* | removed | Merged into Return + ReturnItem |
/api/v3/admin/orders/:id/reimbursements/* | removed | Replaced by direct Refund on Returns/Exchanges/Claims |
/api/v3/admin/reimbursement_types/* | removed | Concept dropped |
/api/v3/admin/prototypes/* | /api/v3/admin/product_types/* | Prototype → ProductType rename. See 6.0-product-types.md |
/api/v3/admin/metafield_definitions/* | /api/v3/admin/custom_field_definitions/* | Metafield → CustomField rename. See 5.4-6.0-custom-fields-rename.md |
/api/v3/admin/orders/:id/adjustments/* | /api/v3/admin/orders/:id/tax_lines, discounts, fees (read-only) | Polymorphic Adjustment → typed TaxLine, Discount, Fee. See 6.0-split-adjustments.md |
?expand=master_variant | ?expand=default_variant | is_master dropped, default_variant_id FK. See 6.0-remove-master-variant.md |
?expand=images | ?expand=media | Image / Asset → Media. See 5.4-6.0-product-media-system.md |
The following field names change across all endpoints. See 5.4-store-api-naming-standardization.md for the full list.
| Model | 5.x | 6.0 |
|---|---|---|
Payment | state | status |
Fulfillment (was Shipment) | state | status |
Fulfillment | shipped_at | fulfilled_at |
FulfillmentItem (was InventoryUnit) | state | status |
Return (was ReturnAuthorization) | state | status |
GiftCard | state | status |
Order | shipment_state | fulfillment_status |
Order | payment_state | payment_status |
Order | shipment_total | delivery_total |
Order | promo_total | discount_total |
Order | item_count | total_quantity |
Order | special_instructions | customer_note |
Order | bill_address_id | billing_address_id |
Order | ship_address_id | shipping_address_id |
LineItem | promo_total | discount_total |
Address | firstname | first_name |
Address | lastname | last_name |
Address | zipcode | postal_code |
OptionType, OptionValue, CustomFieldDefinition | presentation | label |
CreditCard | cc_type | brand |
CreditCard | last_digits | last4 |
CustomFieldDefinition | display_on (string) | storefront_visible (boolean) |
CustomFieldDefinition | metafield_type | field_type |
Also tracked in the SDK type definitions. See each linked plan for rationale.
| Model | 5.x prefix | 6.0 prefix |
|---|---|---|
Fulfillment (was Shipment) | shipment_ | ful_ |
DeliveryMethod (was ShippingMethod) | — | dm_ |
DeliveryRate (was ShippingRate) | — | dr_ |
FulfillmentItem (was InventoryUnit) | — | fi_ |
DeliveryZone (new) | — | dz_ |
StockReservation (new) | — | res_ |
StockMovement | — | sm_ |
Return (was ReturnAuthorization) | — | ret_ |
Exchange (new) | — | exch_ |
Claim (new) | — | claim_ |
Channel (new) | — | ch_ |
Catalog (new) | — | cat_ |
Company (new) | — | comp_ |
CompanyLocation (new) | — | cloc_ |
CompanyContact (new) | — | cc_ |
ProductPublication (replaces StoreProduct) | — | pp_ |
Collection (new) | — | coll_ |
ProductType (was Prototype) | proto_ | pt_ |
Customer (was User) | user_ | cust_ |
AdminUser | admin_ | adm_ |
CustomField (was Metafield) | mf_ | cf_ |
CustomFieldDefinition (was MetafieldDefinition) | mfdef_ | cfdef_ |
Media (was Image/Asset) | image_/asset_ | media_ |
Each endpoint below is tracked as [ ] (pending) or [x] (shipped). When you implement one, flip the checkbox in the same PR. Endpoints are grouped by resource. Removed/renamed 5.x endpoints are NOT listed — see the table above.
POST /api/v3/admin/auth/login — admin user login (JWT + refresh token)POST /api/v3/admin/auth/refresh — rotate refresh token, return new JWTDELETE /api/v3/admin/auth/logout — invalidate JWT and refresh tokenGET /api/v3/admin/me — current admin user + serialized permissionsGET /api/v3/admin/products — list (Ransack, sort, paginate)GET /api/v3/admin/products/:idPOST /api/v3/admin/products — with nested variants, prices, category_idsPATCH /api/v3/admin/products/:idDELETE /api/v3/admin/products/:id — soft deletePOST /api/v3/admin/products/:id/clonePATCH /api/v3/admin/products/bulk_update — bulk status/category/tags6.0 field changes:
shipping_category_idis dropped (fulfillment types come fromProductType.fulfillment_types).prototype_id→product_type_id.taxon_ids→category_ids. Product hasdefault_variant_idFK (no moreis_master).
GET /api/v3/admin/products/:product_id/variantsGET /api/v3/admin/products/:product_id/variants/:idPOST /api/v3/admin/products/:product_id/variants — with nested pricesPATCH /api/v3/admin/products/:product_id/variants/:idDELETE /api/v3/admin/products/:product_id/variants/:idManaged via nested variant params — no standalone endpoints.
GET /api/v3/admin/products/:product_id/media — list (filterable by media_type)POST /api/v3/admin/products/:product_id/media — upload via multipart OR source_url param (async download). Params: media_type, alt, position, variant_idsPATCH /api/v3/admin/products/:product_id/media/:id — update alt, position, variant assignmentDELETE /api/v3/admin/products/:product_id/media/:idGET /api/v3/admin/products/:product_id/digital_assetsPOST /api/v3/admin/products/:product_id/digital_assetsPATCH /api/v3/admin/products/:product_id/digital_assets/:idDELETE /api/v3/admin/products/:product_id/digital_assets/:idGET /api/v3/admin/option_typesGET /api/v3/admin/option_types/:idPOST /api/v3/admin/option_typesPATCH /api/v3/admin/option_types/:idDELETE /api/v3/admin/option_types/:idGET /api/v3/admin/option_types/:option_type_id/option_valuesPOST /api/v3/admin/option_types/:option_type_id/option_valuesPATCH /api/v3/admin/option_types/:option_type_id/option_values/:idDELETE /api/v3/admin/option_types/:option_type_id/option_values/:idGET /api/v3/admin/product_typesGET /api/v3/admin/product_types/:idPOST /api/v3/admin/product_typesPATCH /api/v3/admin/product_types/:idDELETE /api/v3/admin/product_types/:id6.0:
fulfillment_typesJSON array column (['shipping']default). Product types can require specificCustomFieldDefinitions via nested definition records. See6.0-product-types.md.
GET /api/v3/admin/categories — list with tree metadataGET /api/v3/admin/categories/:idPOST /api/v3/admin/categoriesPATCH /api/v3/admin/categories/:idDELETE /api/v3/admin/categories/:idPATCH /api/v3/admin/categories/:id/reposition — reposition in tree6.0:
Spree::Categorybelongs directly toSpree::Store(no Taxonomy).Classification→ProductCategory. See6.0-replace-taxons-with-categories.md.
GET /api/v3/admin/categories/:category_id/productsPOST /api/v3/admin/categories/:category_id/products — assignPATCH /api/v3/admin/categories/:category_id/products/:product_id — update positionDELETE /api/v3/admin/categories/:category_id/products/:product_id — unassignGET /api/v3/admin/collectionsGET /api/v3/admin/collections/:idPOST /api/v3/admin/collections — with nested rules (automatic) or manual product listPATCH /api/v3/admin/collections/:idDELETE /api/v3/admin/collections/:id6.0: Collections replace the "smart taxon" (
automatic: true,rules_match_policy) feature.CollectionRulereplacesTaxonRule. See6.0-replace-taxons-with-categories.md.
GET /api/v3/admin/channelsGET /api/v3/admin/channels/:idPOST /api/v3/admin/channelsPATCH /api/v3/admin/channels/:idDELETE /api/v3/admin/channels/:id6.0: A Channel is a sales surface (POS, Storefront A, Marketplace, etc.). See
6.0-channels-catalogs-b2b.md.
GET /api/v3/admin/channels/:channel_id/product_publicationsPOST /api/v3/admin/channels/:channel_id/product_publicationsDELETE /api/v3/admin/channels/:channel_id/product_publications/:idPOST /api/v3/admin/channels/:channel_id/product_publications/bulk — bulk add/removeGET /api/v3/admin/catalogsGET /api/v3/admin/catalogs/:idPOST /api/v3/admin/catalogsPATCH /api/v3/admin/catalogs/:idDELETE /api/v3/admin/catalogs/:idGET /api/v3/admin/catalogs/:id/productsPOST /api/v3/admin/catalogs/:id/products — bulk assignDELETE /api/v3/admin/catalogs/:id/products/:product_idPOST /api/v3/admin/catalogs/:id/assign — assign catalog to companies/locationsGET /api/v3/admin/companiesGET /api/v3/admin/companies/:idPOST /api/v3/admin/companiesPATCH /api/v3/admin/companies/:idDELETE /api/v3/admin/companies/:idGET /api/v3/admin/companies/:company_id/locationsPOST /api/v3/admin/companies/:company_id/locationsGET /api/v3/admin/company_locations/:idPATCH /api/v3/admin/company_locations/:idDELETE /api/v3/admin/company_locations/:idGET /api/v3/admin/company_locations/:location_id/contactsPOST /api/v3/admin/company_locations/:location_id/contactsPATCH /api/v3/admin/company_contacts/:idDELETE /api/v3/admin/company_contacts/:idGET /api/v3/admin/ordersGET /api/v3/admin/orders/:idPOST /api/v3/admin/orders — create draftPATCH /api/v3/admin/orders/:idDELETE /api/v3/admin/orders/:idPATCH /api/v3/admin/orders/:id/completePATCH /api/v3/admin/orders/:id/cancelPATCH /api/v3/admin/orders/:id/approvePATCH /api/v3/admin/orders/:id/resumePOST /api/v3/admin/orders/:id/resend_confirmation6.0: Order state machine dropped (derived status from line items + fulfillments + payments — see
6.0-cart-order-split.md).PATCH /nextand/advanceno longer apply and have been removed from the 5.x admin API ahead of the 6.0 cart/order split. Cart and Order are separate models;LineItem.owneris polymorphic. Order gainschannel_id,company_location_id,withdrawal_eligible_untilFKs.
/carts/:id/items convention)GET /api/v3/admin/orders/:order_id/itemsGET /api/v3/admin/orders/:order_id/items/:idPOST /api/v3/admin/orders/:order_id/itemsPATCH /api/v3/admin/orders/:order_id/items/:idDELETE /api/v3/admin/orders/:order_id/items/:idGET /api/v3/admin/orders/:order_id/fulfillmentsGET /api/v3/admin/orders/:order_id/fulfillments/:idPOST /api/v3/admin/orders/:order_id/fulfillmentsPATCH /api/v3/admin/orders/:order_id/fulfillments/:idPATCH /api/v3/admin/orders/:order_id/fulfillments/:id/fulfill — mark as fulfilledPATCH /api/v3/admin/orders/:order_id/fulfillments/:id/cancelPATCH /api/v3/admin/orders/:order_id/fulfillments/:id/resumePATCH /api/v3/admin/orders/:order_id/fulfillments/:id/split6.0: Third-party fulfillment via
FulfillmentProviderinterface.pickup_point_dataJSON snapshot for pickup points. See6.0-fulfillment-and-delivery.md.
GET /api/v3/admin/orders/:order_id/paymentsGET /api/v3/admin/orders/:order_id/payments/:idPOST /api/v3/admin/orders/:order_id/payments — supports off-session admin charges via source_id (saved Spree::CreditCard belonging to the order's customer)PATCH /api/v3/admin/orders/:order_id/payments/:id/capturePATCH /api/v3/admin/orders/:order_id/payments/:id/voidOff-session charges: pass
{ payment_method_id, source_id, amount }to charge a saved card. There is no separate "PaymentSession" endpoint on the admin side — the cart/store API haspayment_sessionsfor SCA/3DS storefront flows; admin-initiated charges use saved sources directly.
GET /api/v3/admin/orders/:order_id/refundsPOST /api/v3/admin/orders/:order_id/refunds — with payment_id in bodyPATCH /api/v3/admin/orders/:order_id/refunds/:idGET /api/v3/admin/orders/:order_id/adjustmentsGET /api/v3/admin/orders/:order_id/adjustments/:id5.x → 6.0: The 5.x admin API exposes
/adjustmentsas read-only (no create/update/destroy) so client integrations don't depend on a write surface that is going away. Manual adjustment management has been removed. In 6.0, this endpoint is replaced by the three typed endpoints below.
GET /api/v3/admin/orders/:order_id/tax_linesGET /api/v3/admin/orders/:order_id/discountsGET /api/v3/admin/orders/:order_id/fees6.0: Polymorphic
Spree::Adjustmentis dropped. Tax, discount, and fee data is returned via typed, read-only endpoints. See6.0-split-adjustments.md.
Customer assignment is handled via the standard PATCH /api/v3/admin/orders/:id endpoint with customer_id in the body. No dedicated endpoint. Pass customer_id: null to unassign.
PATCH /api/v3/admin/orders/:id { customer_id } — assign / reassign / unassign customer (5.x bridge: also accepts user_id)POST /api/v3/admin/orders/:order_id/gift_cards { code } — apply a gift card by codeDELETE /api/v3/admin/orders/:order_id/gift_cards/:id — remove the applied gift cardPOST /api/v3/admin/orders/:order_id/store_credits { amount? } — apply customer's available store credit (auto up to balance, or a specific amount)DELETE /api/v3/admin/orders/:order_id/store_credits — remove store credit applicationPOST /api/v3/admin/orders/:order_id/discounts — apply promotion or couponDELETE /api/v3/admin/orders/:order_id/discounts/:id — removeGET /api/v3/admin/returnsGET /api/v3/admin/orders/:order_id/returnsGET /api/v3/admin/returns/:idPOST /api/v3/admin/orders/:order_id/returnsPATCH /api/v3/admin/returns/:idDELETE /api/v3/admin/returns/:idPOST /api/v3/admin/returns/:id/approvePOST /api/v3/admin/returns/:id/receivePOST /api/v3/admin/returns/:id/refundPATCH /api/v3/admin/returns/:return_id/items/:id — reception + acceptance statusGET /api/v3/admin/exchangesGET /api/v3/admin/orders/:order_id/exchangesGET /api/v3/admin/exchanges/:idPOST /api/v3/admin/orders/:order_id/exchangesPATCH /api/v3/admin/exchanges/:idPOST /api/v3/admin/exchanges/:id/approvePOST /api/v3/admin/exchanges/:id/receivePOST /api/v3/admin/exchanges/:id/fulfillGET /api/v3/admin/claimsGET /api/v3/admin/orders/:order_id/claimsGET /api/v3/admin/claims/:idPOST /api/v3/admin/orders/:order_id/claimsPATCH /api/v3/admin/claims/:idPOST /api/v3/admin/claims/:id/approvePOST /api/v3/admin/claims/:id/resolve6.0: Returns, Exchanges, and Claims are first-class models. Replaces the
ReturnAuthorization → CustomerReturn → Reimbursementchain. See6.0-returns-exchanges-claims.md.
GET /api/v3/admin/customersGET /api/v3/admin/customers/:idPOST /api/v3/admin/customersPATCH /api/v3/admin/customers/:idDELETE /api/v3/admin/customers/:idPOST /api/v3/admin/customers/:id/anonymize — GDPR right to erasureGET /api/v3/admin/customers/:id/export — GDPR data export (returns JSON download URL)6.0:
Spree.user_class→Spree.customer_class.Spree::LegacyUser→Spree::Customer. Anonymize + export endpoints from5.4-6.0-eu-legal-compliance.md.
GET /api/v3/admin/customers/:customer_id/addressesPOST /api/v3/admin/customers/:customer_id/addressesPATCH /api/v3/admin/customers/:customer_id/addresses/:idDELETE /api/v3/admin/customers/:customer_id/addresses/:idGET /api/v3/admin/customers/:customer_id/store_creditsGET /api/v3/admin/customers/:customer_id/store_credits/:idPOST /api/v3/admin/customers/:customer_id/store_creditsPATCH /api/v3/admin/customers/:customer_id/store_credits/:idDELETE /api/v3/admin/customers/:customer_id/store_credits/:idGET /api/v3/admin/gift_cardsGET /api/v3/admin/gift_cards/:idPOST /api/v3/admin/gift_cardsPATCH /api/v3/admin/gift_cards/:idDELETE /api/v3/admin/gift_cards/:idPOST /api/v3/admin/gift_card_batches — batch createGET /api/v3/admin/customer_groupsGET /api/v3/admin/customer_groups/:idPOST /api/v3/admin/customer_groupsPATCH /api/v3/admin/customer_groups/:idDELETE /api/v3/admin/customer_groups/:idGET /api/v3/admin/customer_groups/:customer_group_id/membersPOST /api/v3/admin/customer_groups/:customer_group_id/members — bulk addDELETE /api/v3/admin/customer_groups/:customer_group_id/members/:idDELETE /api/v3/admin/customer_groups/:customer_group_id/members — bulk removeGET /api/v3/admin/newsletter_subscribersDELETE /api/v3/admin/newsletter_subscribers/:idGET /api/v3/admin/companies/:company_id/tax_exemption_certificatesPOST /api/v3/admin/companies/:company_id/tax_exemption_certificatesPATCH /api/v3/admin/tax_exemption_certificates/:idDELETE /api/v3/admin/tax_exemption_certificates/:idGET /api/v3/admin/promotionsGET /api/v3/admin/promotions/:idPOST /api/v3/admin/promotionsPATCH /api/v3/admin/promotions/:idDELETE /api/v3/admin/promotions/:idPOST /api/v3/admin/promotions/:id/cloneGET /api/v3/admin/promotions/:promotion_id/actionsPOST /api/v3/admin/promotions/:promotion_id/actionsPATCH /api/v3/admin/promotions/:promotion_id/actions/:idDELETE /api/v3/admin/promotions/:promotion_id/actions/:idGET /api/v3/admin/promotions/:promotion_id/rulesPOST /api/v3/admin/promotions/:promotion_id/rulesPATCH /api/v3/admin/promotions/:promotion_id/rules/:idDELETE /api/v3/admin/promotions/:promotion_id/rules/:idGET /api/v3/admin/promotions/:promotion_id/coupon_codesGET /api/v3/admin/stock_locationsGET /api/v3/admin/stock_locations/:idPOST /api/v3/admin/stock_locationsPATCH /api/v3/admin/stock_locations/:idDELETE /api/v3/admin/stock_locations/:idGET /api/v3/admin/stock_items — filterable by stock_location, variantPATCH /api/v3/admin/stock_items/:idDELETE /api/v3/admin/stock_items/:idGET /api/v3/admin/stock_movements — filterable by kind, fulfillment_id, order_id, return_id, stock_transfer_id6.0:
StockMovementgainskindenum (received,allocated,shipped,released,adjusted) + concrete FKs to the originating event. See6.0-typed-stock-movements.md.
GET /api/v3/admin/stock_reservations — filterable by variant, order, cartDELETE /api/v3/admin/stock_reservations/:id — manual release6.0: Time-limited reservations during checkout. See
6.0-stock-reservations.md.
GET /api/v3/admin/stock_transfersGET /api/v3/admin/stock_transfers/:idPOST /api/v3/admin/stock_transfersDELETE /api/v3/admin/stock_transfers/:idGET /api/v3/admin/price_listsGET /api/v3/admin/price_lists/:idPOST /api/v3/admin/price_listsPATCH /api/v3/admin/price_lists/:idDELETE /api/v3/admin/price_lists/:idGET /api/v3/admin/price_lists/:price_list_id/price_rulesPOST /api/v3/admin/price_lists/:price_list_id/price_rulesPATCH /api/v3/admin/price_lists/:price_list_id/price_rules/:idDELETE /api/v3/admin/price_lists/:price_list_id/price_rules/:idGET /api/v3/admin/price_lists/:price_list_id/productsPOST /api/v3/admin/price_lists/:price_list_id/products — bulk addDELETE /api/v3/admin/price_lists/:price_list_id/products — bulk removeGET /api/v3/admin/products/:product_id/price_history — per-variant history for Omnibus "lowest price in 30 days"6.0: See
5.4-6.0-eu-legal-compliance.md.
GET /api/v3/admin/payment_methodsGET /api/v3/admin/payment_methods/:idPOST /api/v3/admin/payment_methodsPATCH /api/v3/admin/payment_methods/:idDELETE /api/v3/admin/payment_methods/:idGET /api/v3/admin/delivery_methodsGET /api/v3/admin/delivery_methods/:idPOST /api/v3/admin/delivery_methodsPATCH /api/v3/admin/delivery_methods/:idDELETE /api/v3/admin/delivery_methods/:id6.0: No more
calculator_id. New fields:rate_provider(class name),fulfillment_provider(class name),pickup_point_provider(for third-party pickup),fulfillment_type(enum:shipping,pickup,pickup_point,digital,local_delivery). See6.0-delivery-rate-provider.md,6.0-fulfillment-and-delivery.md.
GET /api/v3/admin/delivery_zonesGET /api/v3/admin/delivery_zones/:idPOST /api/v3/admin/delivery_zonesPATCH /api/v3/admin/delivery_zones/:idDELETE /api/v3/admin/delivery_zones/:idGET /api/v3/admin/delivery_zones/:zone_id/membersPOST /api/v3/admin/delivery_zones/:zone_id/membersDELETE /api/v3/admin/delivery_zones/:zone_id/members/:idGET /api/v3/admin/tax_categoriesGET /api/v3/admin/tax_categories/:idPOST /api/v3/admin/tax_categoriesPATCH /api/v3/admin/tax_categories/:idDELETE /api/v3/admin/tax_categories/:idGET /api/v3/admin/tax_ratesGET /api/v3/admin/tax_rates/:idPOST /api/v3/admin/tax_ratesPATCH /api/v3/admin/tax_rates/:idDELETE /api/v3/admin/tax_rates/:id6.0:
zone_idFK is dropped.TaxRategets directcountry_id+state_idFKs. Tax logic moves behind aTaxProviderinterface. See6.0-tax-provider.md.
GET /api/v3/admin/marketsGET /api/v3/admin/markets/:idPOST /api/v3/admin/marketsPATCH /api/v3/admin/markets/:idDELETE /api/v3/admin/markets/:idGET /api/v3/admin/countriesGET /api/v3/admin/countries/:idGET /api/v3/admin/storePATCH /api/v3/admin/storeGET /api/v3/admin/policiesGET /api/v3/admin/policies/:idPOST /api/v3/admin/policiesPATCH /api/v3/admin/policies/:idDELETE /api/v3/admin/policies/:idGET /api/v3/admin/admin_usersGET /api/v3/admin/admin_users/:idPOST /api/v3/admin/admin_usersPATCH /api/v3/admin/admin_users/:idDELETE /api/v3/admin/admin_users/:id6.0:
Spree::LegacyAdminUser→Spree::AdminUser. Owns auth stack (no Devise). See6.0-platform-auth.md.
GET /api/v3/admin/rolesGET /api/v3/admin/roles/:idPOST /api/v3/admin/rolesPATCH /api/v3/admin/roles/:idDELETE /api/v3/admin/roles/:idGET /api/v3/admin/invitationsPOST /api/v3/admin/invitationsDELETE /api/v3/admin/invitations/:idPATCH /api/v3/admin/invitations/:id/resendGET /api/v3/admin/custom_field_definitionsGET /api/v3/admin/custom_field_definitions/:idPOST /api/v3/admin/custom_field_definitionsPATCH /api/v3/admin/custom_field_definitions/:idDELETE /api/v3/admin/custom_field_definitions/:id6.0:
display_on→storefront_visible(boolean).metafield_type→field_type. See5.4-6.0-custom-fields-rename.md.
GET /api/v3/admin/:resource_type/:resource_id/custom_fieldsPOST /api/v3/admin/:resource_type/:resource_id/custom_fieldsPATCH /api/v3/admin/:resource_type/:resource_id/custom_fields/:idDELETE /api/v3/admin/:resource_type/:resource_id/custom_fields/:idGET /api/v3/admin/:resource_type/:resource_id/translationsPATCH /api/v3/admin/:resource_type/:resource_id/translationsGET /api/v3/admin/tagsPOST /api/v3/admin/tagsDELETE /api/v3/admin/tags/:idGET /api/v3/admin/refund_reasonsGET /api/v3/admin/refund_reasons/:idPOST /api/v3/admin/refund_reasonsPATCH /api/v3/admin/refund_reasons/:idDELETE /api/v3/admin/refund_reasons/:idGET /api/v3/admin/return_reasonsGET /api/v3/admin/return_reasons/:idPOST /api/v3/admin/return_reasonsPATCH /api/v3/admin/return_reasons/:idDELETE /api/v3/admin/return_reasons/:idGET /api/v3/admin/store_credit_categoriesGET /api/v3/admin/store_credit_categories/:idPOST /api/v3/admin/store_credit_categoriesPATCH /api/v3/admin/store_credit_categories/:idDELETE /api/v3/admin/store_credit_categories/:idGET /api/v3/admin/webhook_endpointsGET /api/v3/admin/webhook_endpoints/:idPOST /api/v3/admin/webhook_endpointsPATCH /api/v3/admin/webhook_endpoints/:idDELETE /api/v3/admin/webhook_endpoints/:idGET /api/v3/admin/webhook_endpoints/:webhook_endpoint_id/deliveriesGET /api/v3/admin/webhook_endpoints/:webhook_endpoint_id/deliveries/:idGET /api/v3/admin/api_keysPOST /api/v3/admin/api_keysPATCH /api/v3/admin/api_keys/:idDELETE /api/v3/admin/api_keys/:idPATCH /api/v3/admin/api_keys/:id/revokeGET /api/v3/admin/integrationsGET /api/v3/admin/integrations/:idPOST /api/v3/admin/integrationsPATCH /api/v3/admin/integrations/:idDELETE /api/v3/admin/integrations/:id6.0: Integration records back the TaxProvider, DeliveryRateProvider, FulfillmentProvider, and PickupPointProvider interfaces (along with external search, email, etc.).
GET /api/v3/admin/reportsGET /api/v3/admin/reports/:idPOST /api/v3/admin/reports — generateGET /api/v3/admin/exportsGET /api/v3/admin/exports/:id — includes download URLPOST /api/v3/admin/exportsGET /api/v3/admin/importsGET /api/v3/admin/imports/:id — status, row countsPOST /api/v3/admin/imports — multipart/form-dataPATCH /api/v3/admin/imports/:id/complete_mappingGET /api/v3/admin/dashboard/analyticsPOST /bulk endpoint per resource, or per-action bulk routes (bulk_update, bulk_destroy)? Currently leaning toward per-action for clarity, but it bloats the route table.PUT /orders/:id/user the right shape, or should this be PATCH /orders/:id { customer_id: ... }?/:resource_type/:resource_id/custom_fields is ugly. Consider a flat /custom_fields?resource_type=...&resource_id=... instead.docs/api-reference/store-api/errors.mdx — error response conventions (shared)docs/plans/6.0-admin-spa.md — consumer of this APIdocs/plans/6.0-platform-auth.md — auth stack and Spree.admin_user_class renamedocs/plans/5.4-6.0-custom-fields-rename.md — Metafields → Custom Fieldsdocs/plans/6.0-fulfillment-and-delivery.md — shipping category dropped