--- openapi: 3.0.3 info: title: Admin 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. ## Authentication The Admin API requires a secret API key passed in the `x-spree-api-key` header. Secret API keys can be generated in the Spree admin dashboard. ## Response Format All responses are JSON. List endpoints return paginated responses with `data` and `meta` keys. Single resource endpoints return a flat JSON object. ## Resource IDs Every resource is identified by an opaque string ID (e.g. `prod_86Rf07xd4z`, `variant_k5nR8xLq`, `or_UkLWZg9DAJ`). Use these IDs everywhere — URL paths, request bodies, and Ransack filters all accept them directly. ## Error Handling Errors return a consistent format: ```json { "error": { "code": "validation_error", "message": "Validation failed", "details": { "name": ["can't be blank"] } } } ``` version: v3 paths: "/api/v3/admin/admin_users": get: summary: List staff tags: - Configuration security: - api_key: [] bearer_auth: [] description: |- Returns admin users with at least one role assignment on the current store. **Required scope:** `read_settings` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const { data: staff } = await client.adminUsers.list() parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string responses: '200': description: staff found content: application/json: example: data: - id: admin_UkLWZg9DAJ email: angelic@oconnell.us first_name: Jamal last_name: Doyle full_name: Jamal Doyle created_at: '2026-05-24T17:36:33.885Z' updated_at: '2026-05-24T17:36:33.885Z' roles: - id: role_UkLWZg9DAJ name: admin meta: page: 1 limit: 25 count: 1 pages: 1 from: 1 to: 1 in: 1 previous: next: "/api/v3/admin/admin_users/{id}": get: summary: Show a staff member tags: - Configuration security: - api_key: [] bearer_auth: [] description: "**Required scope:** `read_settings` (for API-key authentication)." x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const staff = await client.adminUsers.get('admin_xxx') parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string - name: id in: path required: true schema: type: string responses: '200': description: staff member found content: application/json: example: id: admin_UkLWZg9DAJ email: jess_king@rau.info first_name: Mercedez last_name: Bailey full_name: Mercedez Bailey created_at: '2026-05-24T17:36:34.235Z' updated_at: '2026-05-24T17:36:34.235Z' roles: - id: role_UkLWZg9DAJ name: admin patch: summary: Update a staff member tags: - Configuration security: - api_key: [] bearer_auth: [] description: |- Updates name fields and reassigns roles for the current store. `role_ids` is a complete replacement — roles not in the array are removed for this store. **Required scope:** `write_settings` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const staff = await client.adminUsers.update('admin_xxx', { first_name: 'Ada', role_ids: ['role_xxx'] }) parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string - name: id in: path required: true schema: type: string responses: '200': description: staff member updated content: application/json: example: id: admin_UkLWZg9DAJ email: joesph@grahammarks.ca first_name: Renamed last_name: Lindgren full_name: Renamed Lindgren created_at: '2026-05-24T17:36:34.526Z' updated_at: '2026-05-24T17:36:34.545Z' roles: - id: role_UkLWZg9DAJ name: admin requestBody: content: application/json: schema: type: object properties: first_name: type: string example: Ada last_name: type: string example: Lovelace role_ids: type: array items: type: string delete: summary: Remove a staff member from this store tags: - Configuration security: - api_key: [] bearer_auth: [] description: |- Removes the user's role assignments on the current store. The account is preserved — the user keeps access to any other stores. **Required scope:** `write_settings` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) await client.adminUsers.delete('admin_xxx') parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string - name: id in: path required: true schema: type: string responses: '204': description: staff removed from store "/api/v3/admin/api_keys": get: summary: List API keys tags: - Configuration security: - api_key: [] bearer_auth: [] description: |- Returns publishable and secret API keys for the current store. Secret keys are listed by `token_prefix` only — the plaintext token is delivered exactly once on create. **Required scope:** `read_settings` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const { data: keys } = await client.apiKeys.list() parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string responses: '200': description: API keys found content: application/json: example: data: - id: key_UkLWZg9DAJ name: Storefront key key_type: publishable token_prefix: scopes: [] created_at: '2026-05-24T17:36:34.854Z' updated_at: '2026-05-24T17:36:34.854Z' revoked_at: last_used_at: plaintext_token: pk_wqTPmhFDQiJbhbgokeP9tPzK created_by_email: - id: key_gbHJdmfrXB name: Backend integration key_type: secret token_prefix: sk_GAnG4mX7L scopes: - write_all created_at: '2026-05-24T17:36:34.855Z' updated_at: '2026-05-24T17:36:34.855Z' revoked_at: last_used_at: plaintext_token: created_by_email: - id: key_EfhxLZ9ck8 name: occaecati key_type: secret token_prefix: sk_Zf75n9zm3 scopes: - write_all created_at: '2026-05-24T17:36:34.857Z' updated_at: '2026-05-24T17:36:34.857Z' revoked_at: last_used_at: plaintext_token: created_by_email: meta: page: 1 limit: 25 count: 3 pages: 1 from: 1 to: 3 in: 3 previous: next: post: summary: Create an API key tags: - Configuration security: - api_key: [] bearer_auth: [] description: |- Creates a publishable or secret API key. The plaintext token is included in the response **once** for secret keys; publishable keys expose their token on every read since they are intended for client-side use. **Required scope:** `write_settings` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const key = await client.apiKeys.create({ name: 'Backend integration', key_type: 'secret', scopes: ['read_orders', 'write_orders'] }) // `key.plaintext_token` is available only on this response. 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: secret key created — plaintext token returned once content: application/json: example: id: key_VqXmZF31wY name: CI key key_type: secret token_prefix: sk_ryCceerpp scopes: - read_orders created_at: '2026-05-24T17:36:35.441Z' updated_at: '2026-05-24T17:36:35.441Z' revoked_at: last_used_at: plaintext_token: sk_ryCceerpp5vqodztxueeWXmc created_by_email: opal.herzog@cremin.info '422': description: validation error content: application/json: example: error: code: validation_error message: Name can't be blank and Scopes can't be blank details: name: - can't be blank scopes: - can't be blank requestBody: content: application/json: schema: type: object required: - name - key_type properties: name: type: string example: Backend integration key_type: type: string enum: - publishable - secret scopes: type: array items: type: string example: - read_orders - write_orders "/api/v3/admin/api_keys/{id}": get: summary: Show an API key tags: - Configuration security: - api_key: [] bearer_auth: [] description: "**Required scope:** `read_settings` (for API-key authentication)." x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const key = await client.apiKeys.get('key_xxx') parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string - name: id in: path required: true schema: type: string responses: '200': description: API key found content: application/json: example: id: key_UkLWZg9DAJ name: Storefront key key_type: publishable token_prefix: scopes: [] created_at: '2026-05-24T17:36:35.723Z' updated_at: '2026-05-24T17:36:35.723Z' revoked_at: last_used_at: plaintext_token: pk_yXJtU7SvnfLbkPvuuiUnKaEo created_by_email: delete: summary: Delete an API key tags: - Configuration security: - api_key: [] bearer_auth: [] description: "**Required scope:** `write_settings` (for API-key authentication)." x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) await client.apiKeys.delete('key_xxx') parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string - name: id in: path required: true schema: type: string responses: '204': description: API key deleted "/api/v3/admin/api_keys/{id}/revoke": patch: summary: Revoke an API key tags: - Configuration security: - api_key: [] bearer_auth: [] description: |- Marks the key revoked. Future requests using its token will fail; the row is preserved for audit. **Required scope:** `write_settings` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const key = await client.apiKeys.revoke('key_xxx') parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string - name: id in: path required: true schema: type: string responses: '200': description: API key revoked content: application/json: example: id: key_gbHJdmfrXB name: Backend integration key_type: secret token_prefix: sk_q6euaWxod scopes: - write_all created_at: '2026-05-24T17:36:36.279Z' updated_at: '2026-05-24T17:36:36.554Z' revoked_at: '2026-05-24T17:36:36.553Z' last_used_at: plaintext_token: created_by_email: "/api/v3/admin/promotions/{promotion_id}/coupon_codes": parameters: - name: promotion_id in: path required: true schema: type: string get: summary: List coupon codes for a promotion tags: - Promotions security: - api_key: [] bearer_auth: [] description: |- Returns the auto-generated coupon codes for a multi-code promotion. Single-code promotions store the code on the promotion itself; this endpoint returns an empty list for them. **Required scope:** `read_promotions` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const { data: coupons } = await client.promotions.couponCodes.list('promo_UkLWZg9DAJ') parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string responses: '200': description: coupon codes found content: application/json: example: data: - id: coupon_UkLWZg9DAJ code: AAA111 state: unused created_at: '2026-05-24T17:36:36.570Z' updated_at: '2026-05-24T17:36:36.570Z' promotion_id: promo_UkLWZg9DAJ order_id: - id: coupon_gbHJdmfrXB code: BBB222 state: unused created_at: '2026-05-24T17:36:36.571Z' updated_at: '2026-05-24T17:36:36.571Z' promotion_id: promo_UkLWZg9DAJ order_id: meta: page: 1 limit: 25 count: 2 pages: 1 from: 1 to: 2 in: 2 previous: next: "/api/v3/admin/custom_field_definitions": get: summary: List custom field definitions tags: - Custom Fields security: - api_key: [] bearer_auth: [] description: |- Returns all defined custom fields. Filter by `?q[resource_type_eq]=Spree::Product` to narrow to one parent type. **Required scope:** `read_custom_field_definitions` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const { data: definitions } = await client.customFieldDefinitions.list({ q: { resource_type_eq: 'Spree::Product' }, }) parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string - name: expand in: query required: false description: Comma-separated associations to expand. 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., key,label,field_type). id is always included. schema: type: string responses: '200': description: definitions returned content: application/json: example: data: - id: cfdef_UkLWZg9DAJ namespace: specs key: fabric label: Title field_type: short_text resource_type: Spree::Product storefront_visible: true created_at: '2026-05-24T17:36:36.857Z' updated_at: '2026-05-24T17:36:36.857Z' - id: cfdef_gbHJdmfrXB namespace: custom key: order_notes label: Order Notes field_type: short_text resource_type: Spree::Order storefront_visible: true created_at: '2026-05-24T17:36:36.857Z' updated_at: '2026-05-24T17:36:36.857Z' meta: page: 1 limit: 25 count: 2 pages: 1 from: 1 to: 2 in: 2 previous: next: post: summary: Create a custom field definition tags: - Custom Fields security: - api_key: [] bearer_auth: [] description: "**Required scope:** `write_custom_field_definitions` (for API-key authentication)." x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const definition = await client.customFieldDefinitions.create({ namespace: 'specs', key: 'origin', label: 'Country of Origin', field_type: 'short_text', resource_type: 'Spree::Product', storefront_visible: true, }) 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: definition created content: application/json: example: id: cfdef_EfhxLZ9ck8 namespace: specs key: origin label: Country of Origin field_type: short_text resource_type: Spree::Product storefront_visible: true created_at: '2026-05-24T17:36:37.407Z' updated_at: '2026-05-24T17:36:37.407Z' requestBody: content: application/json: schema: type: object required: - key - field_type - resource_type properties: namespace: type: string description: Defaults to `custom` key: type: string label: type: string description: Human-readable name; defaults to titleized `key` field_type: type: string description: Custom field type identifier (one of the registered field-type class names). resource_type: type: string description: Owner class, e.g. `Spree::Product` storefront_visible: type: boolean description: 'When false, definition is admin-only (was `display_on: back_end`)' "/api/v3/admin/custom_field_definitions/{id}": get: summary: Show a custom field definition tags: - Custom Fields security: - api_key: [] bearer_auth: [] description: "**Required scope:** `read_custom_field_definitions` (for API-key authentication)." parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header 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. 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., key,label,field_type). id is always included. schema: type: string responses: '200': description: definition found content: application/json: example: id: cfdef_UkLWZg9DAJ namespace: specs key: fabric label: Title field_type: short_text resource_type: Spree::Product storefront_visible: true created_at: '2026-05-24T17:36:37.410Z' updated_at: '2026-05-24T17:36:37.410Z' patch: summary: Update a custom field definition tags: - Custom Fields security: - api_key: [] bearer_auth: [] description: "**Required scope:** `write_custom_field_definitions` (for API-key authentication)." parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string - name: id in: path required: true schema: type: string responses: '200': description: definition updated content: application/json: example: id: cfdef_UkLWZg9DAJ namespace: specs key: fabric label: Fabric Composition field_type: short_text resource_type: Spree::Product storefront_visible: false created_at: '2026-05-24T17:36:37.685Z' updated_at: '2026-05-24T17:36:37.959Z' requestBody: content: application/json: schema: type: object properties: label: type: string storefront_visible: type: boolean delete: summary: Delete a custom field definition tags: - Custom Fields security: - api_key: [] bearer_auth: [] description: |- Deletes the definition and cascades to all custom field values referencing it. **Required scope:** `write_custom_field_definitions` (for API-key authentication). parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string - name: id in: path required: true schema: type: string responses: '204': description: definition deleted "/api/v3/admin/customer_groups": get: summary: List customer groups tags: - Customers security: - api_key: [] bearer_auth: [] description: |- Returns the customer groups configured for the current store. Groups segment customers for targeted promotions (see the `customer_group` promotion rule) and reporting. The list endpoint never embeds the member list — fetch a single group with `?expand=customers` if you need them inline, or query `/admin/customers?customer_group_id_in=…` for paginated membership. **Required scope:** `read_customers` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const { data: groups } = await client.customerGroups.list({ page: 1, limit: 25 }) 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 description: Page number schema: type: integer - name: limit in: query required: false description: Number of records per page schema: type: integer - name: q[name_cont] in: query required: false description: Filter by name (contains) schema: type: string - name: sort in: query required: false description: Sort by field. Prefix with `-` for descending (e.g., `-created_at`). schema: type: string - name: fields in: query required: false description: Comma-separated list of fields to include. id is always included. schema: type: string responses: '200': description: customer groups found content: application/json: example: data: - id: cg_UkLWZg9DAJ name: VIPs description: Top spenders customers_count: 0 created_at: '2026-05-24T17:36:38.239Z' updated_at: '2026-05-24T17:36:38.239Z' - id: cg_gbHJdmfrXB name: Wholesale description: customers_count: 0 created_at: '2026-05-24T17:36:38.240Z' updated_at: '2026-05-24T17:36:38.240Z' meta: page: 1 limit: 25 count: 2 pages: 1 from: 1 to: 2 in: 2 previous: next: schema: type: object properties: data: type: array items: "$ref": "#/components/schemas/CustomerGroup" meta: "$ref": "#/components/schemas/PaginationMeta" required: - data - meta '401': description: unauthorized content: application/json: example: error: code: authentication_required message: Authentication required schema: "$ref": "#/components/schemas/ErrorResponse" post: summary: Create a customer group tags: - Customers security: - api_key: [] bearer_auth: [] description: |- Creates a customer group in the current store. `customer_ids` is optional; when present, customers are attached at create time. Pass prefixed IDs (e.g. `cus_…`) — the server decodes them automatically. **Required scope:** `write_customers` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const group = await client.customerGroups.create({ name: 'VIP customers', description: 'Top spenders, eligible for early access', customer_ids: ['cus_UkLWZg9DAJ', 'cus_QrLWXg9CAJ'], }) 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 group created content: application/json: example: id: cg_EfhxLZ9ck8 name: Wholesale 2 description: B2B accounts customers_count: 1 created_at: '2026-05-24T17:36:39.101Z' updated_at: '2026-05-24T17:36:39.101Z' schema: "$ref": "#/components/schemas/CustomerGroup" '422': description: validation error content: application/json: example: error: code: validation_error message: Name can't be blank details: name: - can't be blank schema: "$ref": "#/components/schemas/ErrorResponse" requestBody: content: application/json: schema: type: object required: - name properties: name: type: string example: Wholesale description: type: string example: B2B accounts nullable: true customer_ids: type: array items: type: string example: - cus_UkLWZg9DAJ "/api/v3/admin/customer_groups/{id}": parameters: - name: id in: path required: true description: Customer group prefixed ID schema: type: string get: summary: Get a customer group tags: - Customers security: - api_key: [] bearer_auth: [] description: |- Returns a single customer group. Pass `?expand=customers` to embed the full member list inline (recommended only for single-record reads — embed cost scales with membership size). **Required scope:** `read_customers` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) // Pass `expand: ['customers']` to embed the group's customers in the response // — omit it for the much smaller index-payload shape. const group = await client.customerGroups.get('cg_UkLWZg9DAJ', { expand: ['customers'] }) parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string - name: expand in: query required: false description: 'Comma-separated associations to embed. Supported: `customers`.' schema: type: string - name: fields in: query required: false description: Comma-separated list of fields to include. id is always included. schema: type: string responses: '200': description: customer group with embedded customers content: application/json: example: id: cg_UkLWZg9DAJ name: VIPs description: Top spenders customers_count: 1 created_at: '2026-05-24T17:36:39.681Z' updated_at: '2026-05-24T17:36:39.681Z' customers: - id: cus_UkLWZg9DAJ email: paola_balistreri@dicki.com first_name: Janett last_name: Marvin phone: accepts_email_marketing: false full_name: Janett Marvin available_store_credit_total: '0' display_available_store_credit_total: "$0.00" login: paola_balistreri@dicki.com metadata: {} last_sign_in_at: current_sign_in_at: created_at: '2026-05-24T17:36:39.940Z' updated_at: '2026-05-24T17:36:39.940Z' sign_in_count: 0 failed_attempts: 0 last_sign_in_ip: current_sign_in_ip: tags: [] internal_note_html: default_billing_address_id: default_shipping_address_id: orders_count: 0 total_spent: '0.0' display_total_spent: "$0.00" last_order_completed_at: schema: "$ref": "#/components/schemas/CustomerGroup" '404': description: customer group not found content: application/json: example: error: code: record_not_found message: Customer group not found schema: "$ref": "#/components/schemas/ErrorResponse" patch: summary: Update a customer group tags: - Customers security: - api_key: [] bearer_auth: [] description: |- Updates name, description, or membership. `customer_ids` is a full-set replacement — the server reconciles the membership to match the array, adding new IDs and removing ones not present. Send `customer_ids: []` to clear all members. **Required scope:** `write_customers` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) // `customer_ids` is a full-set update — the model reconciles the membership // to match the array (adds new IDs, removes ones not present). const group = await client.customerGroups.update('cg_UkLWZg9DAJ', { name: 'VIP customers (Q1)', customer_ids: ['cus_UkLWZg9DAJ'], }) parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string responses: '200': description: customer group updated content: application/json: example: id: cg_UkLWZg9DAJ name: VIP customers (Q1) description: Top spenders customers_count: 0 created_at: '2026-05-24T17:36:40.533Z' updated_at: '2026-05-24T17:36:40.811Z' schema: "$ref": "#/components/schemas/CustomerGroup" '422': description: validation error content: application/json: example: error: code: validation_error message: Name can't be blank details: name: - can't be blank schema: "$ref": "#/components/schemas/ErrorResponse" requestBody: content: application/json: schema: type: object properties: name: type: string example: VIP customers (Q1) description: type: string example: Updated description nullable: true customer_ids: type: array items: type: string example: - cus_UkLWZg9DAJ delete: summary: Delete a customer group tags: - Customers security: - api_key: [] bearer_auth: [] description: |- Soft-deletes the group. Member users are not deleted; their `customer_group_users` rows are dropped. **Required scope:** `write_customers` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) await client.customerGroups.delete('cg_UkLWZg9DAJ') parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string responses: '204': description: customer group deleted "/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' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const { 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: metadata: {} created_at: '2026-05-24T17:36:41.658Z' updated_at: '2026-05-24T17:36:41.658Z' customer_id: cus_UkLWZg9DAJ meta: page: 1 limit: 25 count: 1 pages: 1 from: 1 to: 1 in: 1 previous: next: 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' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const address = await client.customers.addresses.create('cus_UkLWZg9DAJ', { first_name: 'Jane', last_name: 'Doe', address1: '350 Fifth Avenue', city: 'New York', postal_code: '10118', country_iso: 'US', state_abbr: 'NY', phone: '+1 212 555 1234', label: 'Office', is_default_shipping: true, }) 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: postal_code: '10118' city: New York phone: "+12125551234" 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: Office metadata: {} created_at: '2026-05-24T17:36:43.149Z' updated_at: '2026-05-24T17:36:43.149Z' 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' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const address = await client.customers.addresses.update( 'cus_UkLWZg9DAJ', 'addr_UkLWZg9DAJ', { city: 'Manhattan' }, ) 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: metadata: {} created_at: '2026-05-24T17:36:43.466Z' updated_at: '2026-05-24T17:36:44.249Z' 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' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) await 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' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const { 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: customer_id: cus_UkLWZg9DAJ payment_method_id: pm_UkLWZg9DAJ metadata: {} created_at: '2026-05-24T17:36:45.523Z' updated_at: '2026-05-24T17:36:45.523Z' meta: page: 1 limit: 25 count: 1 pages: 1 from: 1 to: 1 in: 1 previous: next: "/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' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const 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: customer_id: cus_UkLWZg9DAJ payment_method_id: pm_UkLWZg9DAJ metadata: {} created_at: '2026-05-24T17:36:46.077Z' updated_at: '2026-05-24T17:36:46.077Z' 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' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) await 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' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const { 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: metadata: {} created_at: '2026-05-24T17:36:47.452Z' updated_at: '2026-05-24T17:36:47.452Z' 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: next: 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' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const credit = await client.customers.storeCredits.create('cus_UkLWZg9DAJ', { amount: 25.00, currency: 'USD', category_id: 'cat_UkLWZg9DAJ', memo: 'Goodwill credit', }) 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-05-24T17:36:48.578Z' updated_at: '2026-05-24T17:36:48.578Z' 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' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const credit = await client.customers.storeCredits.update( 'cus_UkLWZg9DAJ', 'sc_UkLWZg9DAJ', { memo: 'Reissued for damaged shipment' }, ) 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-05-24T17:36:49.119Z' updated_at: '2026-05-24T17:36:49.399Z' 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' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) await 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' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const { data: customers } = await client.customers.list({ search: 'jane', sort: '-created_at', limit: 25, }) 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: 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: current_sign_in_at: created_at: '2026-05-24T17:36:50.510Z' updated_at: '2026-05-24T17:36:50.510Z' sign_in_count: 0 failed_attempts: 0 last_sign_in_ip: current_sign_in_ip: tags: [] internal_note_html: default_billing_address_id: default_shipping_address_id: orders_count: 0 total_spent: '0' display_total_spent: "$0.00" last_order_completed_at: meta: page: 1 limit: 25 count: 1 pages: 1 from: 1 to: 1 in: 1 previous: next: 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' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const customer = await client.customers.create({ email: 'jane@example.com', first_name: 'Jane', last_name: 'Doe', phone: '+1 212 555 1234', tags: ['wholesale'], accepts_email_marketing: true, }) 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: accepts_email_marketing: false full_name: New Customer available_store_credit_total: '0' display_available_store_credit_total: "$0.00" login: metadata: {} last_sign_in_at: current_sign_in_at: created_at: '2026-05-24T17:36:51.382Z' updated_at: '2026-05-24T17:36:51.382Z' sign_in_count: 0 failed_attempts: 0 last_sign_in_ip: current_sign_in_ip: tags: [] internal_note_html: default_billing_address_id: default_shipping_address_id: orders_count: 0 total_spent: '0.0' display_total_spent: "$0.00" last_order_completed_at: 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' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const customer = await client.customers.get('cus_UkLWZg9DAJ', { expand: ['addresses', 'store_credits'], }) parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string - name: id in: path required: true description: Customer ID schema: type: string - name: expand in: query required: false description: 'Comma-separated associations: addresses, orders, store_credits, default_billing_address, default_shipping_address' 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: customer found content: application/json: example: id: cus_UkLWZg9DAJ email: jane@example.com first_name: Jane last_name: Doe phone: 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: current_sign_in_at: created_at: '2026-05-24T17:36:51.654Z' updated_at: '2026-05-24T17:36:51.654Z' sign_in_count: 0 failed_attempts: 0 last_sign_in_ip: current_sign_in_ip: tags: [] internal_note_html: default_billing_address_id: default_shipping_address_id: orders_count: 0 total_spent: '0' display_total_spent: "$0.00" last_order_completed_at: patch: summary: Update a customer tags: - Customers security: - api_key: [] bearer_auth: [] description: |- Updates customer attributes. `tags` replaces the full set. **Required scope:** `write_customers` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const customer = await client.customers.update('cus_UkLWZg9DAJ', { first_name: 'Updated', tags: ['wholesale', 'vip'], }) parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string - name: id in: path required: true schema: type: string responses: '200': description: customer updated content: application/json: example: id: cus_UkLWZg9DAJ email: jane@example.com first_name: Updated last_name: Doe phone: accepts_email_marketing: false full_name: Updated Doe available_store_credit_total: '0' display_available_store_credit_total: "$0.00" login: jane@example.com metadata: {} last_sign_in_at: current_sign_in_at: created_at: '2026-05-24T17:36:52.193Z' updated_at: '2026-05-24T17:36:52.471Z' sign_in_count: 0 failed_attempts: 0 last_sign_in_ip: current_sign_in_ip: tags: [] internal_note_html: default_billing_address_id: default_shipping_address_id: orders_count: 0 total_spent: '0.0' display_total_spent: "$0.00" last_order_completed_at: requestBody: content: application/json: schema: type: object properties: email: type: string 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 delete: summary: Delete a customer tags: - Customers security: - api_key: [] bearer_auth: [] description: |- Deletes a customer. Returns 422 if the customer has any orders. **Required scope:** `write_customers` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) await client.customers.delete('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: id in: path required: true schema: type: string responses: '204': description: customer deleted "/api/v3/admin/customers/bulk_add_to_groups": post: summary: Bulk-add customers to groups tags: - Customers security: - api_key: [] bearer_auth: [] description: |- Attaches each customer in `ids` to every group in `customer_group_ids`. Idempotent — customers already in a group are skipped server-side. Groups from sibling stores are silently ignored. Returns counts of customers and groups that were processed (post store-scoping). **Required scope:** `write_customers` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const result = await client.customers.bulkAddToGroups({ ids: ['cus_UkLWZg9DAJ', 'cus_QrLWXg9CAJ'], customer_group_ids: ['cg_UkLWZg9DAJ'], }) parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string responses: '200': description: customers added to groups content: application/json: example: customer_count: 1 customer_group_count: 1 schema: type: object properties: customer_count: type: integer customer_group_count: type: integer requestBody: content: application/json: schema: type: object required: - ids - customer_group_ids properties: ids: type: array items: type: string example: - cus_UkLWZg9DAJ - cus_QrLWXg9CAJ customer_group_ids: type: array items: type: string example: - cg_UkLWZg9DAJ "/api/v3/admin/customers/bulk_remove_from_groups": post: summary: Bulk-remove customers from groups tags: - Customers security: - api_key: [] bearer_auth: [] description: |- Detaches each customer in `ids` from every group in `customer_group_ids`. No-op for non-members. Groups from sibling stores are silently ignored. **Required scope:** `write_customers` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const result = await client.customers.bulkRemoveFromGroups({ ids: ['cus_UkLWZg9DAJ'], customer_group_ids: ['cg_UkLWZg9DAJ'], }) parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string responses: '200': description: customers removed from groups content: application/json: example: customer_count: 1 customer_group_count: 1 schema: type: object properties: customer_count: type: integer customer_group_count: type: integer requestBody: content: application/json: schema: type: object required: - ids - customer_group_ids properties: ids: type: array items: type: string example: - cus_UkLWZg9DAJ customer_group_ids: type: array items: type: string example: - cg_UkLWZg9DAJ "/api/v3/admin/customers/bulk_add_tags": post: summary: Bulk-add tags to customers tags: - Customers security: - api_key: [] bearer_auth: [] description: |- Adds each tag name in `tags` to every customer in `ids`. Tags are upserted by name; re-adding an existing tag is a no-op. **Required scope:** `write_customers` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const result = await client.customers.bulkAddTags({ ids: ['cus_UkLWZg9DAJ', 'cus_QrLWXg9CAJ'], tags: ['vip', 'newsletter'], }) parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string responses: '200': description: tags added content: application/json: example: customer_count: 1 tag_count: 2 schema: type: object properties: customer_count: type: integer tag_count: type: integer requestBody: content: application/json: schema: type: object required: - ids - tags properties: ids: type: array items: type: string example: - cus_UkLWZg9DAJ tags: type: array items: type: string example: - vip - newsletter "/api/v3/admin/customers/bulk_remove_tags": post: summary: Bulk-remove tags from customers tags: - Customers security: - api_key: [] bearer_auth: [] description: |- Removes each tag name in `tags` from every customer in `ids`. No-op for customers that don't carry the tag. **Required scope:** `write_customers` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const result = await client.customers.bulkRemoveTags({ ids: ['cus_UkLWZg9DAJ'], tags: ['vip'], }) parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string responses: '200': description: tags removed content: application/json: example: customer_count: 1 tag_count: 1 schema: type: object properties: customer_count: type: integer tag_count: type: integer requestBody: content: application/json: schema: type: object required: - ids - tags properties: ids: type: array items: type: string example: - cus_UkLWZg9DAJ tags: type: array items: type: string example: - vip "/api/v3/admin/exports": get: summary: List exports tags: - Exports security: - api_key: [] bearer_auth: [] description: |- Returns CSV exports queued or completed for the current store. Polled by the admin SPA to detect when an export finishes (`done: true`). **Required scope:** `read_exports` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const { data: exports } = await client.exports.list() parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string responses: '200': description: exports found content: application/json: example: data: - id: exp_UkLWZg9DAJ number: EF797270070 type: Spree::Exports::Products format: csv created_at: '2026-05-24T17:36:56.574Z' updated_at: '2026-05-24T17:36:56.574Z' user_id: admin_UkLWZg9DAJ done: false filename: byte_size: download_url: meta: page: 1 limit: 25 count: 1 pages: 1 from: 1 to: 1 in: 1 previous: next: post: summary: Create an export tags: - Exports security: - api_key: [] bearer_auth: [] description: |- Queues a CSV export. The `type` selects the dataset; `search_params` is an optional Ransack query (same shape used by the `q[...]` params on list endpoints) that filters which records are exported. Pass `record_selection: "all"` to clear the filter server-side and export everything in scope. Generation is asynchronous. Poll `GET /admin/exports/{id}` until `done` is `true`, then redirect the browser to `download_url` to fetch the file. **Required scope:** `write_exports` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const exp = await client.exports.create({ type: 'Spree::Exports::Products', search_params: { name_cont: 'shirt' } }) 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: export queued content: application/json: example: id: exp_gbHJdmfrXB number: EF700540072 type: Spree::Exports::Products format: csv created_at: '2026-05-24T17:36:56.866Z' updated_at: '2026-05-24T17:36:56.866Z' user_id: admin_UkLWZg9DAJ done: false filename: byte_size: download_url: requestBody: content: application/json: schema: type: object required: - type properties: type: type: string enum: - Spree::Exports::Products - Spree::Exports::Orders - Spree::Exports::Customers - Spree::Exports::ProductTranslations - Spree::Exports::GiftCards - Spree::Exports::CouponCodes - Spree::Exports::NewsletterSubscribers example: Spree::Exports::Products record_selection: type: string enum: - filtered - all description: Set to "all" to ignore search_params and export everything in scope. example: filtered search_params: type: object description: Ransack query hash. Same predicates accepted by the list endpoint. example: name_cont: shirt additionalProperties: true "/api/v3/admin/exports/{id}": get: summary: Show an export tags: - Exports security: - api_key: [] bearer_auth: [] description: |- Returns export status. While `done` is `false`, the SPA continues polling. **Required scope:** `read_exports` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const exp = await client.exports.get('exp_xxx') parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string - name: id in: path required: true schema: type: string responses: '200': description: export found content: application/json: example: id: exp_UkLWZg9DAJ number: EF052905723 type: Spree::Exports::Products format: csv created_at: '2026-05-24T17:36:57.139Z' updated_at: '2026-05-24T17:36:57.139Z' user_id: admin_UkLWZg9DAJ done: false filename: byte_size: download_url: delete: summary: Delete an export tags: - Exports security: - api_key: [] bearer_auth: [] description: |- Removes the export and purges its attachment. **Required scope:** `write_exports` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) await client.exports.delete('exp_xxx') parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string - name: id in: path required: true schema: type: string responses: '204': description: export deleted "/api/v3/admin/exports/{id}/download": get: summary: Download an export tags: - Exports security: - api_key: [] bearer_auth: [] description: |- Streams the exported CSV with `Content-Disposition: attachment`. Returns 422 with `code: export_not_ready` while `done` is still `false`. The endpoint is JWT/API-key protected, so SPA clients must fetch it (with `Authorization` header) and trigger the browser download via a Blob URL — a top-level navigation cannot carry the JWT. **Required scope:** `read_exports` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) // Fetch with the Bearer token, then drive the browser download: const res = await fetch(exp.download_url, { headers: { Authorization: `Bearer ${token}` } }) const blob = await res.blob() const url = URL.createObjectURL(blob) const a = Object.assign(document.createElement('a'), { href: url, download: exp.filename }) a.click() URL.revokeObjectURL(url) parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string - name: id in: path required: true schema: type: string responses: '200': description: CSV file content: application/json: {} text/csv: schema: type: string format: binary "/api/v3/admin/gift_card_batches": get: summary: List gift card batches tags: - Gift Cards security: - api_key: [] bearer_auth: [] description: |- Returns the gift card batches issued by the current store. Each batch groups the cards generated together for a campaign or bulk-issuance — the cards themselves live under `/admin/gift_cards` and reference the batch via `gift_card_batch_id`. **Required scope:** `read_gift_cards` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const { data: batches } = await client.giftCardBatches.list({ page: 1, limit: 25 }) 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 description: Page number schema: type: integer - name: limit in: query required: false description: Records per page schema: type: integer - name: q[prefix_cont] in: query required: false description: Filter by prefix (contains) schema: type: string - name: sort in: query required: false description: Sort by field. Prefix with `-` for descending. schema: type: string responses: '200': description: gift card batches found content: application/json: example: data: - id: gcb_UkLWZg9DAJ codes_count: 2 currency: USD prefix: WELCOME created_at: '2026-05-24T17:36:57.736Z' updated_at: '2026-05-24T17:36:57.736Z' amount: '50.0' expires_at: created_by_id: meta: page: 1 limit: 25 count: 1 pages: 1 from: 1 to: 1 in: 1 previous: next: schema: type: object properties: data: type: array items: "$ref": "#/components/schemas/GiftCardBatch" meta: "$ref": "#/components/schemas/PaginationMeta" required: - data - meta post: summary: Create a gift card batch tags: - Gift Cards security: - api_key: [] bearer_auth: [] description: |- Issues a batch of gift cards in a single call. The server generates `codes_count` cards inline for small batches (configurable via `Spree.config.gift_card_batch_web_limit`, default 500) or enqueues a background job for larger ones. Each card's code is the batch `prefix` followed by random hex. **Required scope:** `write_gift_cards` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const batch = await client.giftCardBatches.create({ prefix: 'WELCOME', amount: '25.00', currency: 'USD', codes_count: 100, expires_at: '2030-12-31', }) 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: gift card batch created content: application/json: example: id: gcb_gbHJdmfrXB codes_count: 5 currency: USD prefix: NEWCAMP created_at: '2026-05-24T17:36:58.306Z' updated_at: '2026-05-24T17:36:58.306Z' amount: '25.0' expires_at: '2030-12-31' created_by_id: admin_UkLWZg9DAJ schema: "$ref": "#/components/schemas/GiftCardBatch" '422': description: validation error content: application/json: example: error: code: validation_error message: Prefix can't be blank details: prefix: - can't be blank schema: "$ref": "#/components/schemas/ErrorResponse" requestBody: content: application/json: schema: type: object required: - prefix - amount - codes_count properties: prefix: type: string example: WELCOME description: Lowercased and prepended to every generated code. amount: type: string example: '25.00' description: Decimal amount per card, greater than zero. currency: type: string example: USD description: ISO 4217 currency code. Defaults to the store currency. codes_count: type: integer example: 100 description: Number of cards to generate. Capped at `gift_card_batch_limit`. expires_at: type: string example: '2030-12-31' nullable: true "/api/v3/admin/gift_card_batches/{id}": parameters: - name: id in: path required: true description: Gift card batch prefixed ID schema: type: string get: summary: Get a gift card batch tags: - Gift Cards security: - api_key: [] bearer_auth: [] description: |- Returns a single batch. **Required scope:** `read_gift_cards` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const batch = await client.giftCardBatches.get('gcb_K3zr8x') parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string responses: '200': description: gift card batch found content: application/json: example: id: gcb_UkLWZg9DAJ codes_count: 2 currency: USD prefix: WELCOME created_at: '2026-05-24T17:36:58.593Z' updated_at: '2026-05-24T17:36:58.593Z' amount: '50.0' expires_at: created_by_id: schema: "$ref": "#/components/schemas/GiftCardBatch" '404': description: gift card batch not found content: application/json: example: error: code: record_not_found message: Gift card batch not found schema: "$ref": "#/components/schemas/ErrorResponse" "/api/v3/admin/gift_cards": get: summary: List gift cards tags: - Gift Cards security: - api_key: [] bearer_auth: [] description: |- Returns the gift cards issued by the current store. Filter by `q[code_cont]` for code search, `q[user_id_eq]` for cards issued to a specific customer, or `q[state_eq]` for status filtering. **Required scope:** `read_gift_cards` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const { data: giftCards } = await client.giftCards.list({ page: 1, limit: 25, expand: ['customer', 'created_by'], }) 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 description: Page number schema: type: integer - name: limit in: query required: false description: Number of records per page schema: type: integer - name: q[code_cont] in: query required: false description: Filter by gift card code (contains) schema: type: string - name: q[state_eq] in: query required: false description: Filter by status (active, redeemed, partially_redeemed, canceled) schema: type: string - name: sort in: query required: false description: Sort by field. Prefix with `-` for descending (e.g., `-created_at`). schema: type: string - name: fields in: query required: false description: Comma-separated list of fields to include. id is always included. schema: type: string responses: '200': description: gift cards found content: application/json: example: data: - id: gc_UkLWZg9DAJ code: CC7B2B4D3AB3008C status: active currency: USD amount: '50.0' amount_used: '0.0' amount_authorized: '0.0' amount_remaining: '50.0' display_amount: "$50.00" display_amount_used: "$0.00" display_amount_remaining: "$50.00" expires_at: redeemed_at: expired: false active: true created_at: '2026-05-24T17:36:59.157Z' updated_at: '2026-05-24T17:36:59.157Z' customer_id: created_by_id: - id: gc_gbHJdmfrXB code: DDB3EA9E5861FC28 status: active currency: USD amount: '25.0' amount_used: '0.0' amount_authorized: '0.0' amount_remaining: '25.0' display_amount: "$25.00" display_amount_used: "$0.00" display_amount_remaining: "$25.00" expires_at: redeemed_at: expired: false active: true created_at: '2026-05-24T17:36:59.158Z' updated_at: '2026-05-24T17:36:59.158Z' customer_id: created_by_id: meta: page: 1 limit: 25 count: 2 pages: 1 from: 1 to: 2 in: 2 previous: next: schema: type: object properties: data: type: array items: "$ref": "#/components/schemas/GiftCard" meta: "$ref": "#/components/schemas/PaginationMeta" required: - data - meta '401': description: unauthorized content: application/json: example: error: code: authentication_required message: Authentication required schema: "$ref": "#/components/schemas/ErrorResponse" post: summary: Create a gift card tags: - Gift Cards security: - api_key: [] bearer_auth: [] description: |- Issues a gift card scoped to the current store. The code is auto-generated when omitted. `currency` defaults to the store's configured currency. Pass `user_id` (prefixed ID) to attach the card to a specific customer. **Required scope:** `write_gift_cards` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const giftCard = await client.giftCards.create({ amount: '25.00', currency: 'USD', expires_at: '2030-12-31', user_id: 'cus_UkLWZg9DAJ', }) 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: gift card created content: application/json: example: id: gc_EfhxLZ9ck8 code: A45E3AF0F74D82E8 status: active currency: USD amount: '25.0' amount_used: '0.0' amount_authorized: '0.0' amount_remaining: '25.0' display_amount: "$25.00" display_amount_used: "$0.00" display_amount_remaining: "$25.00" expires_at: '2030-12-31' redeemed_at: expired: false active: true created_at: '2026-05-24T17:36:59.731Z' updated_at: '2026-05-24T17:36:59.731Z' customer_id: created_by_id: admin_UkLWZg9DAJ schema: "$ref": "#/components/schemas/GiftCard" '422': description: validation error content: application/json: example: error: code: validation_error message: Amount must be greater than 0 details: amount: - must be greater than 0 schema: "$ref": "#/components/schemas/ErrorResponse" requestBody: content: application/json: schema: type: object required: - amount properties: amount: type: string example: '25.00' description: Decimal amount, greater than zero. currency: type: string example: USD description: ISO 4217 currency code. Defaults to the store currency. code: type: string example: WELCOME50 description: Optional caller-supplied code. Auto-generated when omitted. expires_at: type: string example: '2030-12-31' description: ISO 8601 date. nullable: true user_id: type: string example: cus_UkLWZg9DAJ description: Optional customer prefixed ID. nullable: true "/api/v3/admin/gift_cards/{id}": parameters: - name: id in: path required: true description: Gift card prefixed ID schema: type: string get: summary: Get a gift card tags: - Gift Cards security: - api_key: [] bearer_auth: [] description: |- Returns a single gift card. **Required scope:** `read_gift_cards` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const giftCard = await client.giftCards.get('gc_K3zr8x', { expand: ['customer', 'created_by', 'orders'], }) parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string - name: fields in: query required: false description: Comma-separated list of fields to include. id is always included. schema: type: string responses: '200': description: gift card found content: application/json: example: id: gc_UkLWZg9DAJ code: 62E9760F39DB00B8 status: active currency: USD amount: '50.0' amount_used: '0.0' amount_authorized: '0.0' amount_remaining: '50.0' display_amount: "$50.00" display_amount_used: "$0.00" display_amount_remaining: "$50.00" expires_at: redeemed_at: expired: false active: true created_at: '2026-05-24T17:37:00.039Z' updated_at: '2026-05-24T17:37:00.039Z' customer_id: created_by_id: schema: "$ref": "#/components/schemas/GiftCard" '404': description: gift card not found content: application/json: example: error: code: record_not_found message: Gift card not found schema: "$ref": "#/components/schemas/ErrorResponse" patch: summary: Update a gift card tags: - Gift Cards security: - api_key: [] bearer_auth: [] description: |- Updates an active gift card's editable attributes. Redeemed or partially-redeemed cards cannot be edited. **Required scope:** `write_gift_cards` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const giftCard = await client.giftCards.update('gc_K3zr8x', { amount: '75.00', }) parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string responses: '200': description: gift card updated content: application/json: example: id: gc_UkLWZg9DAJ code: 80360376B43E9B35 status: active currency: USD amount: '75.0' amount_used: '0.0' amount_authorized: '0.0' amount_remaining: '75.0' display_amount: "$75.00" display_amount_used: "$0.00" display_amount_remaining: "$75.00" expires_at: redeemed_at: expired: false active: true created_at: '2026-05-24T17:37:00.647Z' updated_at: '2026-05-24T17:37:00.941Z' customer_id: created_by_id: schema: "$ref": "#/components/schemas/GiftCard" requestBody: content: application/json: schema: type: object properties: amount: type: string example: '75.00' expires_at: type: string example: '2031-12-31' nullable: true user_id: type: string example: cus_UkLWZg9DAJ nullable: true delete: summary: Delete a gift card tags: - Gift Cards security: - api_key: [] bearer_auth: [] description: |- Deletes an unused gift card. Cards that have been redeemed or partially redeemed cannot be deleted and return 422. **Required scope:** `write_gift_cards` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) await client.giftCards.delete('gc_K3zr8x') parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string responses: '204': description: gift card deleted '422': description: redeemed gift card cannot be deleted content: application/json: example: error: code: validation_error message: Gift card cannot be deleted "/api/v3/admin/invitations": get: summary: List invitations tags: - Configuration security: - api_key: [] bearer_auth: [] description: |- Returns invitations for the current store, including pending and accepted. **Required scope:** `read_settings` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const { data: invitations } = await client.invitations.list() parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string responses: '200': description: invitations found content: application/json: example: data: - id: inv_UkLWZg9DAJ email: eva@hauckwisozk.info status: pending created_at: '2026-05-24T17:37:01.802Z' updated_at: '2026-05-24T17:37:01.802Z' expires_at: '2026-06-07T17:37:01.798Z' role_id: role_UkLWZg9DAJ role_name: admin inviter_email: faith@moore.info acceptance_url: "/accept-invitation/inv_UkLWZg9DAJ?token=zySacMBFavnzmtA9ZV4NQdhg" invitee_exists: false store: id: store_UkLWZg9DAJ name: Spree Test Store meta: page: 1 limit: 25 count: 1 pages: 1 from: 1 to: 1 in: 1 previous: next: post: summary: Create an invitation tags: - Configuration security: - api_key: [] bearer_auth: [] description: |- Invites a teammate by email. The invitation is scoped to the current store and carries the chosen role; on accept, a `RoleUser` is created via the invitation's `after_accept` callback. **Required scope:** `write_settings` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const invitation = await client.invitations.create({ email: 'ada@example.com', role_id: 'role_xxx' }) 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: invitation created content: application/json: example: id: inv_gbHJdmfrXB email: new-staff@example.com status: pending created_at: '2026-05-24T17:37:02.111Z' updated_at: '2026-05-24T17:37:02.111Z' expires_at: '2026-06-07T17:37:02.108Z' role_id: role_UkLWZg9DAJ role_name: admin inviter_email: floy_cummerata@haleyvonrueden.com acceptance_url: "/accept-invitation/inv_gbHJdmfrXB?token=EzFbcPeHADJwGwapUkFjCjut" invitee_exists: false store: id: store_UkLWZg9DAJ name: Spree Test Store requestBody: content: application/json: schema: type: object required: - email - role_id properties: email: type: string example: ada@example.com role_id: type: string example: role_xxx "/api/v3/admin/invitations/{id}": delete: summary: Revoke an invitation tags: - Configuration security: - api_key: [] bearer_auth: [] description: "**Required scope:** `write_settings` (for API-key authentication)." x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) await client.invitations.delete('inv_xxx') parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string - name: id in: path required: true schema: type: string responses: '204': description: invitation revoked "/api/v3/admin/invitations/{id}/resend": patch: summary: Resend an invitation tags: - Configuration security: - api_key: [] bearer_auth: [] description: |- Issues a fresh token and dispatches the invitation email again. **Required scope:** `write_settings` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const invitation = await client.invitations.resend('inv_xxx') parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string - name: id in: path required: true schema: type: string responses: '200': description: invitation resent content: application/json: example: id: inv_UkLWZg9DAJ email: bao.grant@johnsonwitting.com status: pending created_at: '2026-05-24T17:37:02.736Z' updated_at: '2026-05-24T17:37:02.736Z' expires_at: '2026-06-07T17:37:02.733Z' role_id: role_UkLWZg9DAJ role_name: admin inviter_email: merlene_cormier@hanepredovic.info acceptance_url: "/accept-invitation/inv_UkLWZg9DAJ?token=KRTKCjz8LLoWUjxZrWFrAzKU" invitee_exists: false store: id: store_UkLWZg9DAJ name: Spree Test Store "/api/v3/admin/me": get: summary: Get current admin user and permissions tags: - Authentication security: - api_key: [] bearer_auth: [] description: Returns the current admin user profile and a serialized list of permissions (CanCanCan rules). The SPA uses these to drive UI permission checks. x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const me = await client.me.get() if (me.permissions.some((r) => r.allow && r.actions.includes('manage') && r.subjects.includes('Spree::Product'))) { // show "Create product" button } 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 responses: '200': description: current admin user and permissions content: application/json: example: user: id: admin_UkLWZg9DAJ email: nathanael@ritchie.name first_name: Venessa last_name: Bechtelar full_name: Venessa Bechtelar created_at: '2026-05-24T17:37:03.068Z' updated_at: '2026-05-24T17:37:03.068Z' roles: - id: role_UkLWZg9DAJ name: admin permissions: - allow: true actions: - manage subjects: - all has_conditions: false - allow: false actions: - cancel subjects: - Spree::Order has_conditions: false - allow: true actions: - cancel subjects: - Spree::Order has_conditions: true - allow: false actions: - destroy subjects: - Spree::Order has_conditions: false - allow: true actions: - destroy subjects: - Spree::Order has_conditions: true - allow: false actions: - edit - update subjects: - Spree::RefundReason has_conditions: true - allow: false actions: - edit - update subjects: - Spree::ReimbursementType has_conditions: true - allow: false actions: - update - destroy subjects: - Spree::Role has_conditions: true schema: "$ref": "#/components/schemas/MeResponse" '401': description: unauthorized content: application/json: example: error: code: authentication_required message: Authentication required schema: "$ref": "#/components/schemas/ErrorResponse" "/api/v3/admin/option_types": get: summary: List option types tags: - Product Catalog security: - api_key: [] bearer_auth: [] description: |- Returns a paginated list of option types. **Required scope:** `read_products` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const { data: optionTypes } = await client.optionTypes.list() 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 description: Page number schema: type: integer - name: limit in: query required: false description: Number of records per page schema: type: integer - name: q[name_cont] in: query required: false description: Filter by name (contains) schema: type: string - name: expand in: query required: false description: Comma-separated associations to expand (e.g., option_values). 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., name,label,position). id is always included. schema: type: string responses: '200': description: option types found content: application/json: example: data: - id: opt_UkLWZg9DAJ name: foo-size-1 label: Size position: 1 kind: dropdown metadata: {} filterable: true created_at: '2026-05-24T17:37:03.133Z' updated_at: '2026-05-24T17:37:03.133Z' meta: page: 1 limit: 25 count: 1 pages: 1 from: 1 to: 1 in: 1 previous: next: schema: type: object properties: data: type: array items: "$ref": "#/components/schemas/OptionType" meta: "$ref": "#/components/schemas/PaginationMeta" required: - data - meta '401': description: unauthorized content: application/json: example: error: code: authentication_required message: Authentication required schema: "$ref": "#/components/schemas/ErrorResponse" post: summary: Create an option type tags: - Product Catalog security: - api_key: [] bearer_auth: [] description: |- Creates a new option type. Supports nested option values. Option values can be provided inline and will be created or updated by name. **Required scope:** `write_products` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const optionType = await client.optionTypes.create({ name: 'color', presentation: 'Color', option_values: [ { name: 'red', presentation: 'Red' }, { name: 'navy', presentation: 'Navy' }, ], }) 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 responses: '201': description: option type created content: application/json: example: id: opt_gbHJdmfrXB name: material label: Material position: 2 kind: dropdown metadata: {} filterable: true created_at: '2026-05-24T17:37:03.722Z' updated_at: '2026-05-24T17:37:03.722Z' schema: "$ref": "#/components/schemas/OptionType" '422': description: validation error content: application/json: example: error: code: validation_error message: Name can't be blank and Presentation can't be blank details: name: - can't be blank presentation: - can't be blank schema: "$ref": "#/components/schemas/ErrorResponse" requestBody: content: application/json: schema: type: object properties: name: type: string example: color label: type: string example: Color position: type: integer example: 1 filterable: type: boolean example: true option_values: type: array items: type: object properties: name: type: string example: red label: type: string example: Red position: type: integer required: - name - label "/api/v3/admin/option_types/{id}": get: summary: Get an option type tags: - Product Catalog security: - api_key: [] bearer_auth: [] description: |- Returns a single option type by ID, including its option values. **Required scope:** `read_products` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const optionType = await client.optionTypes.get('ot_UkLWZg9DAJ') 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: id in: path required: true description: Option type ID schema: type: string - name: expand in: query required: false description: Comma-separated associations to expand (e.g., option_values). 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., name,label,position). id is always included. schema: type: string responses: '200': description: option type found content: application/json: example: id: opt_UkLWZg9DAJ name: foo-size-5 label: Size position: 1 kind: dropdown metadata: {} filterable: true created_at: '2026-05-24T17:37:04.014Z' updated_at: '2026-05-24T17:37:04.014Z' schema: "$ref": "#/components/schemas/OptionType" '404': description: option type not found content: application/json: example: error: code: record_not_found message: Option type not found schema: "$ref": "#/components/schemas/ErrorResponse" patch: summary: Update an option type tags: - Product Catalog security: - api_key: [] bearer_auth: [] description: |- Updates an option type. Supports updating nested option values. **Required scope:** `write_products` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const optionType = await client.optionTypes.update('ot_UkLWZg9DAJ', { presentation: 'Updated Presentation', option_values: [ { name: 'red', presentation: 'Crimson' }, ], }) 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: id in: path required: true description: Option type ID schema: type: string responses: '200': description: option type updated content: application/json: example: id: opt_UkLWZg9DAJ name: foo-size-7 label: Updated Label position: 1 kind: dropdown metadata: {} filterable: true created_at: '2026-05-24T17:37:04.617Z' updated_at: '2026-05-24T17:37:04.942Z' schema: "$ref": "#/components/schemas/OptionType" '422': description: validation error content: application/json: example: error: code: validation_error message: Presentation can't be blank details: presentation: - can't be blank schema: "$ref": "#/components/schemas/ErrorResponse" requestBody: content: application/json: schema: type: object properties: name: type: string example: color label: type: string example: Color position: type: integer example: 1 filterable: type: boolean example: true option_values: type: array items: type: object properties: id: type: string description: Existing option value ID to update name: type: string example: red label: type: string example: Red position: type: integer delete: summary: Delete an option type tags: - Product Catalog security: - api_key: [] bearer_auth: [] description: |- Deletes an option type. **Required scope:** `write_products` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) await client.optionTypes.delete('ot_UkLWZg9DAJ') 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: id in: path required: true description: Option type ID schema: type: string responses: '204': description: option type deleted "/api/v3/admin/orders/{order_id}/fulfillments": get: summary: List fulfillments tags: - Orders security: - api_key: [] bearer_auth: [] description: |- Returns all shipments for an order. **Required scope:** `read_fulfillments` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const { data: fulfillments } = await client.orders.fulfillments.list('or_UkLWZg9DAJ') 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: order_id in: path required: true description: Order ID schema: type: string - name: expand in: query required: false description: Comma-separated associations to expand (e.g., inventory_units, stock_location, shipping_rates). 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., number,status,tracking,cost). id is always included. schema: type: string responses: '200': description: fulfillments found content: application/json: example: data: - id: ful_UkLWZg9DAJ number: H88303288332 tracking: U10000 tracking_url: cost: '10.0' display_cost: "$10.00" total: '10.0' display_total: "$10.00" discount_total: '0.0' display_discount_total: "$0.00" additional_tax_total: '0.0' display_additional_tax_total: "$0.00" included_tax_total: '0.0' display_included_tax_total: "$0.00" tax_total: '0.0' display_tax_total: "$0.00" status: ready fulfillment_type: shipping fulfilled_at: items: - item_id: li_UkLWZg9DAJ variant_id: variant_UkLWZg9DAJ quantity: 1 metadata: {} adjustment_total: '0.0' pre_tax_amount: '0.0' created_at: '2026-05-24T17:37:06.032Z' updated_at: '2026-05-24T17:37:06.286Z' order_id: or_UkLWZg9DAJ stock_location_id: sloc_UkLWZg9DAJ meta: page: 1 limit: 25 count: 1 pages: 1 from: 1 to: 1 in: 1 previous: next: "/api/v3/admin/orders/{order_id}/fulfillments/{id}": get: summary: Show a shipment tags: - Orders security: - api_key: [] bearer_auth: [] description: |- Returns details of a specific shipment. **Required scope:** `read_fulfillments` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const fulfillment = await client.orders.fulfillments.get('or_UkLWZg9DAJ', 'ful_UkLWZg9DAJ') 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: order_id in: path required: true description: Order ID schema: type: string - name: id in: path required: true description: Fulfillment ID schema: type: string - name: expand in: query required: false description: Comma-separated associations to expand (e.g., inventory_units, stock_location, shipping_rates). 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., number,status,tracking,cost). id is always included. schema: type: string responses: '200': description: shipment found content: application/json: example: id: ful_UkLWZg9DAJ number: H51674325797 tracking: U10000 tracking_url: cost: '10.0' display_cost: "$10.00" total: '10.0' display_total: "$10.00" discount_total: '0.0' display_discount_total: "$0.00" additional_tax_total: '0.0' display_additional_tax_total: "$0.00" included_tax_total: '0.0' display_included_tax_total: "$0.00" tax_total: '0.0' display_tax_total: "$0.00" status: ready fulfillment_type: shipping fulfilled_at: items: - item_id: li_UkLWZg9DAJ variant_id: variant_UkLWZg9DAJ quantity: 1 metadata: {} adjustment_total: '0.0' pre_tax_amount: '0.0' created_at: '2026-05-24T17:37:07.105Z' updated_at: '2026-05-24T17:37:07.185Z' order_id: or_UkLWZg9DAJ stock_location_id: sloc_UkLWZg9DAJ patch: summary: Update a shipment tags: - Orders security: - api_key: [] bearer_auth: [] description: |- Updates a shipment (tracking, shipping rate). **Required scope:** `write_fulfillments` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const fulfillment = await client.orders.fulfillments.update('or_UkLWZg9DAJ', 'ful_UkLWZg9DAJ', { tracking: '1Z999AA10123456784', }) 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: order_id in: path required: true description: Order ID schema: type: string - name: id in: path required: true description: Fulfillment ID schema: type: string responses: '200': description: shipment updated content: application/json: example: id: ful_UkLWZg9DAJ number: H16091268662 tracking: 1Z999AA10123456784 tracking_url: https://wwwapps.ups.com/WebTracking/track?track=yes&trackNums=1Z999AA10123456784 cost: '10.0' display_cost: "$10.00" total: '10.0' display_total: "$10.00" discount_total: '0.0' display_discount_total: "$0.00" additional_tax_total: '0.0' display_additional_tax_total: "$0.00" included_tax_total: '0.0' display_included_tax_total: "$0.00" tax_total: '0.0' display_tax_total: "$0.00" status: ready fulfillment_type: shipping fulfilled_at: items: - item_id: li_UkLWZg9DAJ variant_id: variant_UkLWZg9DAJ quantity: 1 metadata: {} adjustment_total: '0.0' pre_tax_amount: '0.0' created_at: '2026-05-24T17:37:07.854Z' updated_at: '2026-05-24T17:37:08.221Z' order_id: or_UkLWZg9DAJ stock_location_id: sloc_UkLWZg9DAJ requestBody: content: application/json: schema: type: object properties: tracking: type: string example: 1Z999AA10123456784 selected_shipping_rate_id: type: string "/api/v3/admin/orders/{order_id}/fulfillments/{id}/fulfill": patch: summary: Fulfill a fulfillment tags: - Orders security: - api_key: [] bearer_auth: [] description: |- Marks a fulfillment as fulfilled. **Required scope:** `write_fulfillments` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const fulfillment = await client.orders.fulfillments.fulfill('or_UkLWZg9DAJ', 'ful_UkLWZg9DAJ') 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: order_id in: path required: true description: Order ID schema: type: string - name: id in: path required: true description: Fulfillment ID schema: type: string responses: '200': description: fulfillment fulfilled content: application/json: example: id: ful_UkLWZg9DAJ number: H47615606663 tracking: U10000 tracking_url: cost: '10.0' display_cost: "$10.00" total: '10.0' display_total: "$10.00" discount_total: '0.0' display_discount_total: "$0.00" additional_tax_total: '0.0' display_additional_tax_total: "$0.00" included_tax_total: '0.0' display_included_tax_total: "$0.00" tax_total: '0.0' display_tax_total: "$0.00" status: shipped fulfillment_type: shipping fulfilled_at: '2026-05-24T17:37:08Z' items: - item_id: li_UkLWZg9DAJ variant_id: variant_UkLWZg9DAJ quantity: 1 metadata: {} adjustment_total: '0.0' pre_tax_amount: '0.0' created_at: '2026-05-24T17:37:08.572Z' updated_at: '2026-05-24T17:37:08.932Z' order_id: or_UkLWZg9DAJ stock_location_id: sloc_UkLWZg9DAJ "/api/v3/admin/orders/{order_id}/fulfillments/{id}/cancel": patch: summary: Cancel a fulfillment tags: - Orders security: - api_key: [] bearer_auth: [] description: |- Cancels a fulfillment. **Required scope:** `write_fulfillments` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const fulfillment = await client.orders.fulfillments.cancel('or_UkLWZg9DAJ', 'ful_UkLWZg9DAJ') 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: order_id in: path required: true description: Order ID schema: type: string - name: id in: path required: true description: Fulfillment ID schema: type: string responses: '200': description: fulfillment canceled content: application/json: example: id: ful_UkLWZg9DAJ number: H68010739823 tracking: U10000 tracking_url: cost: '10.0' display_cost: "$10.00" total: '10.0' display_total: "$10.00" discount_total: '0.0' display_discount_total: "$0.00" additional_tax_total: '0.0' display_additional_tax_total: "$0.00" included_tax_total: '0.0' display_included_tax_total: "$0.00" tax_total: '0.0' display_tax_total: "$0.00" status: canceled fulfillment_type: shipping fulfilled_at: items: - item_id: li_UkLWZg9DAJ variant_id: variant_UkLWZg9DAJ quantity: 1 metadata: {} adjustment_total: '0.0' pre_tax_amount: '0.0' created_at: '2026-05-24T17:37:09.263Z' updated_at: '2026-05-24T17:37:09.602Z' order_id: or_UkLWZg9DAJ stock_location_id: sloc_UkLWZg9DAJ "/api/v3/admin/orders/{order_id}/fulfillments/{id}/resume": patch: summary: Resume a fulfillment tags: - Orders security: - api_key: [] bearer_auth: [] description: |- Resumes a canceled fulfillment. **Required scope:** `write_fulfillments` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const fulfillment = await client.orders.fulfillments.resume('or_UkLWZg9DAJ', 'ful_UkLWZg9DAJ') 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: order_id in: path required: true description: Order ID schema: type: string - name: id in: path required: true description: Fulfillment ID schema: type: string responses: '200': description: fulfillment resumed content: application/json: example: id: ful_UkLWZg9DAJ number: H15965565794 tracking: U10000 tracking_url: cost: '10.0' display_cost: "$10.00" total: '10.0' display_total: "$10.00" discount_total: '0.0' display_discount_total: "$0.00" additional_tax_total: '0.0' display_additional_tax_total: "$0.00" included_tax_total: '0.0' display_included_tax_total: "$0.00" tax_total: '0.0' display_tax_total: "$0.00" status: pending fulfillment_type: shipping fulfilled_at: items: - item_id: li_UkLWZg9DAJ variant_id: variant_UkLWZg9DAJ quantity: 1 metadata: {} adjustment_total: '0.0' pre_tax_amount: '0.0' created_at: '2026-05-24T17:37:09.918Z' updated_at: '2026-05-24T17:37:10.280Z' order_id: or_UkLWZg9DAJ stock_location_id: sloc_UkLWZg9DAJ "/api/v3/admin/orders/{order_id}/fulfillments/{id}/split": patch: summary: Split a fulfillment tags: - Orders security: - api_key: [] bearer_auth: [] description: |- Transfers items from this shipment to a new shipment at a different stock location. **Required scope:** `write_fulfillments` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const fulfillment = await client.orders.fulfillments.split('or_UkLWZg9DAJ', 'ful_UkLWZg9DAJ', { quantity: 1, }) 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: order_id in: path required: true description: Order ID schema: type: string - name: id in: path required: true description: Fulfillment ID schema: type: string responses: '200': description: fulfillment split content: application/json: example: data: - id: ful_gbHJdmfrXB number: H74934116654 tracking: tracking_url: cost: '10.0' display_cost: "$10.00" total: '10.0' display_total: "$10.00" discount_total: '0.0' display_discount_total: "$0.00" additional_tax_total: '0.0' display_additional_tax_total: "$0.00" included_tax_total: '0.0' display_included_tax_total: "$0.00" tax_total: '0.0' display_tax_total: "$0.00" status: ready fulfillment_type: shipping fulfilled_at: items: - item_id: li_UkLWZg9DAJ variant_id: variant_UkLWZg9DAJ quantity: 1 metadata: {} adjustment_total: '0.0' pre_tax_amount: '0.0' created_at: '2026-05-24T17:37:10.976Z' updated_at: '2026-05-24T17:37:11.028Z' order_id: or_UkLWZg9DAJ stock_location_id: sloc_gbHJdmfrXB requestBody: content: application/json: schema: type: object required: - variant_id - quantity properties: variant_id: type: string description: Variant ID quantity: type: integer example: 1 stock_location_id: type: string description: Target stock location ID "/api/v3/admin/orders/{order_id}/gift_cards": post: summary: Apply a gift card to an order tags: - Orders security: - api_key: [] bearer_auth: [] description: |- Applies a gift card by code to the order. Returns the gift card. **Required scope:** `write_gift_cards` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) await client.orders.giftCards.apply('or_UkLWZg9DAJ', { code: 'GIFT-XXXX-YYYY', }) 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: order_id in: path required: true description: Order ID schema: type: string responses: '201': description: gift card applied content: application/json: example: id: gc_UkLWZg9DAJ code: 0F0327B1613F79BD status: active currency: USD amount: '10.0' amount_used: '10.0' amount_authorized: '0.0' amount_remaining: '0.0' display_amount: "$10.00" display_amount_used: "$10.00" display_amount_remaining: "$0.00" expires_at: redeemed_at: expired: false active: true created_at: '2026-05-24T17:37:11.389Z' updated_at: '2026-05-24T17:37:11.722Z' customer_id: created_by_id: requestBody: content: application/json: schema: type: object required: - code properties: code: type: string description: Gift card code example: GIFT-XXXX-YYYY "/api/v3/admin/orders/{order_id}/gift_cards/{id}": delete: summary: Remove a gift card from an order tags: - Orders security: - api_key: [] bearer_auth: [] description: |- Removes the gift card from the order. **Required scope:** `write_gift_cards` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) await client.orders.giftCards.remove('or_UkLWZg9DAJ', 'gc_UkLWZg9DAJ') 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: order_id in: path required: true description: Order ID schema: type: string - name: id in: path required: true description: Gift card ID schema: type: string responses: '204': description: gift card removed "/api/v3/admin/orders/{order_id}/items": get: summary: List order items tags: - Orders security: - api_key: [] bearer_auth: [] description: |- Returns all line items for an order. **Required scope:** `read_orders` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const { data: items } = await client.orders.items.list('or_UkLWZg9DAJ') 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: order_id in: path required: true description: Order ID schema: type: string - name: expand in: query required: false description: Comma-separated associations to expand (e.g., variant, variant.product). 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., quantity,price,total). id is always included. schema: type: string responses: '200': description: items found content: application/json: example: data: - id: li_UkLWZg9DAJ variant_id: variant_gbHJdmfrXB quantity: 2 currency: USD name: Product 106366 slug: product-106366 options_text: 'Size: S' price: '10.0' display_price: "$10.00" total: '20.0' display_total: "$20.00" adjustment_total: '0.0' display_adjustment_total: "$0.00" additional_tax_total: '0.0' display_additional_tax_total: "$0.00" included_tax_total: '0.0' display_included_tax_total: "$0.00" discount_total: '0.0' display_discount_total: "$0.00" pre_tax_amount: '20.0' display_pre_tax_amount: "$20.00" discounted_amount: '20.0' display_discounted_amount: "$20.00" display_compare_at_amount: "$0.00" compare_at_amount: thumbnail_url: option_values: - id: optval_UkLWZg9DAJ option_type_id: opt_UkLWZg9DAJ name: size-1 label: S position: 1 color_code: option_type_name: foo-size-10 option_type_label: Size image_url: metadata: {} created_at: '2026-05-24T17:37:12.441Z' updated_at: '2026-05-24T17:37:12.441Z' digital_links: [] metadata: {} created_at: '2026-05-24T17:37:12.736Z' updated_at: '2026-05-24T17:37:12.736Z' cost_price: '17.0' tax_category_id: taxcat_UkLWZg9DAJ meta: page: 1 limit: 25 count: 1 pages: 1 from: 1 to: 1 in: 1 previous: next: post: summary: Add an item tags: - Orders security: - api_key: [] bearer_auth: [] description: |- Adds a new line item to the order. **Required scope:** `write_orders` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const item = await client.orders.items.create('or_UkLWZg9DAJ', { variant_id: 'variant_k5nR8xLq', quantity: 2, }) 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: order_id in: path required: true description: Order ID schema: type: string responses: '201': description: item added content: application/json: example: id: li_gbHJdmfrXB variant_id: variant_VqXmZF31wY quantity: 3 currency: USD name: Product 12521 slug: product-12521 options_text: 'Size: S' price: '19.99' display_price: "$19.99" total: '59.97' display_total: "$59.97" adjustment_total: '0.0' display_adjustment_total: "$0.00" additional_tax_total: '0.0' display_additional_tax_total: "$0.00" included_tax_total: '0.0' display_included_tax_total: "$0.00" discount_total: '0.0' display_discount_total: "$0.00" pre_tax_amount: '59.97' display_pre_tax_amount: "$59.97" discounted_amount: '59.97' display_discounted_amount: "$59.97" display_compare_at_amount: "$0.00" compare_at_amount: thumbnail_url: option_values: - id: optval_gbHJdmfrXB option_type_id: opt_gbHJdmfrXB name: size-3 label: S position: 1 color_code: option_type_name: foo-size-12 option_type_label: Size image_url: metadata: {} created_at: '2026-05-24T17:37:13.688Z' updated_at: '2026-05-24T17:37:13.688Z' digital_links: [] metadata: {} created_at: '2026-05-24T17:37:13.721Z' updated_at: '2026-05-24T17:37:13.721Z' cost_price: '17.0' tax_category_id: taxcat_UkLWZg9DAJ requestBody: content: application/json: schema: type: object required: - variant_id properties: variant_id: type: string description: Prefixed variant ID quantity: type: integer default: 1 "/api/v3/admin/orders/{order_id}/items/{id}": get: summary: Show an item tags: - Orders security: - api_key: [] bearer_auth: [] description: |- Returns details of a specific line item. **Required scope:** `read_orders` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const item = await client.orders.items.get('or_UkLWZg9DAJ', 'li_UkLWZg9DAJ') 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: order_id in: path required: true description: Order ID schema: type: string - name: id in: path required: true description: Item ID schema: type: string - name: expand in: query required: false description: Comma-separated associations to expand (e.g., variant, variant.product). 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., quantity,price,total). id is always included. schema: type: string responses: '200': description: item found content: application/json: example: id: li_UkLWZg9DAJ variant_id: variant_gbHJdmfrXB quantity: 2 currency: USD name: Product 131812 slug: product-131812 options_text: 'Size: S' price: '10.0' display_price: "$10.00" total: '20.0' display_total: "$20.00" adjustment_total: '0.0' display_adjustment_total: "$0.00" additional_tax_total: '0.0' display_additional_tax_total: "$0.00" included_tax_total: '0.0' display_included_tax_total: "$0.00" discount_total: '0.0' display_discount_total: "$0.00" pre_tax_amount: '20.0' display_pre_tax_amount: "$20.00" discounted_amount: '20.0' display_discounted_amount: "$20.00" display_compare_at_amount: "$0.00" compare_at_amount: thumbnail_url: option_values: - id: optval_UkLWZg9DAJ option_type_id: opt_UkLWZg9DAJ name: size-4 label: S position: 1 color_code: option_type_name: foo-size-13 option_type_label: Size image_url: metadata: {} created_at: '2026-05-24T17:37:13.789Z' updated_at: '2026-05-24T17:37:13.789Z' digital_links: [] metadata: {} created_at: '2026-05-24T17:37:14.071Z' updated_at: '2026-05-24T17:37:14.071Z' cost_price: '17.0' tax_category_id: taxcat_UkLWZg9DAJ patch: summary: Update an item tags: - Orders security: - api_key: [] bearer_auth: [] description: |- Updates an order item quantity or metadata. **Required scope:** `write_orders` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const item = await client.orders.items.update('or_UkLWZg9DAJ', 'li_UkLWZg9DAJ', { quantity: 5, }) 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: order_id in: path required: true description: Order ID schema: type: string - name: id in: path required: true description: Item ID schema: type: string responses: '200': description: item updated content: application/json: example: id: li_UkLWZg9DAJ variant_id: variant_gbHJdmfrXB quantity: 5 currency: USD name: Product 143486 slug: product-143486 options_text: 'Size: S' price: '19.99' display_price: "$19.99" total: '99.95' display_total: "$99.95" adjustment_total: '0.0' display_adjustment_total: "$0.00" additional_tax_total: '0.0' display_additional_tax_total: "$0.00" included_tax_total: '0.0' display_included_tax_total: "$0.00" discount_total: '0.0' display_discount_total: "$0.00" pre_tax_amount: '99.95' display_pre_tax_amount: "$99.95" discounted_amount: '99.95' display_discounted_amount: "$99.95" display_compare_at_amount: "$0.00" compare_at_amount: thumbnail_url: option_values: - id: optval_UkLWZg9DAJ option_type_id: opt_UkLWZg9DAJ name: size-5 label: S position: 1 color_code: option_type_name: foo-size-14 option_type_label: Size image_url: metadata: {} created_at: '2026-05-24T17:37:14.389Z' updated_at: '2026-05-24T17:37:14.389Z' digital_links: [] metadata: {} created_at: '2026-05-24T17:37:14.684Z' updated_at: '2026-05-24T17:37:15.018Z' cost_price: '17.0' tax_category_id: taxcat_UkLWZg9DAJ requestBody: content: application/json: schema: type: object properties: quantity: type: integer delete: summary: Remove an item tags: - Orders security: - api_key: [] bearer_auth: [] description: |- Removes an item from the order. **Required scope:** `write_orders` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) await client.orders.items.delete('or_UkLWZg9DAJ', 'li_UkLWZg9DAJ') 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: order_id in: path required: true description: Order ID schema: type: string - name: id in: path required: true description: Item ID schema: type: string responses: '204': description: line item removed "/api/v3/admin/orders/{order_id}/payments": get: summary: List payments tags: - Orders security: - api_key: [] bearer_auth: [] description: |- Returns all payments for an order. **Required scope:** `read_payments` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const { data: payments } = await client.orders.payments.list('or_UkLWZg9DAJ') 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: order_id in: path required: true description: Order ID schema: type: string - name: expand in: query required: false description: Comma-separated associations to expand (e.g., payment_method, source). 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,status,number,response_code). id is always included. schema: type: string responses: '200': description: payments found content: application/json: example: data: - id: py_UkLWZg9DAJ payment_method_id: pm_UkLWZg9DAJ response_code: BGS-ab886544a797 number: PFOT94SE amount: '110.0' display_amount: "$110.00" status: completed source_type: credit_card source_id: card_UkLWZg9DAJ source: id: card_UkLWZg9DAJ brand: visa last4: '1111' month: 12 year: 2027 name: Spree Commerce default: false gateway_payment_profile_id: customer_id: payment_method_id: pm_gbHJdmfrXB metadata: {} created_at: '2026-05-24T17:37:16.011Z' updated_at: '2026-05-24T17:37:16.014Z' metadata: {} avs_response: cvv_response_code: cvv_response_message: created_at: '2026-05-24T17:37:16.013Z' updated_at: '2026-05-24T17:37:16.013Z' captured_amount: '0.0' order_id: or_UkLWZg9DAJ meta: page: 1 limit: 25 count: 1 pages: 1 from: 1 to: 1 in: 1 previous: next: post: summary: Create a payment tags: - Orders security: - api_key: [] bearer_auth: [] description: |- Creates a new payment for the order. **Required scope:** `write_payments` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const payment = await client.orders.payments.create('or_UkLWZg9DAJ', { payment_method_id: 'pm_UkLWZg9DAJ', amount: 99.99, source_id: 'cc_UkLWZg9DAJ', }) 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: order_id in: path required: true description: Order ID schema: type: string responses: '201': description: payment created content: application/json: example: id: py_gbHJdmfrXB payment_method_id: pm_EfhxLZ9ck8 response_code: number: PY1TKFJ5 amount: '110.0' display_amount: "$110.00" status: checkout source_type: source_id: source: metadata: {} avs_response: cvv_response_code: cvv_response_message: created_at: '2026-05-24T17:37:17.285Z' updated_at: '2026-05-24T17:37:17.285Z' captured_amount: '0.0' order_id: or_gbHJdmfrXB requestBody: content: application/json: schema: type: object required: - payment_method_id properties: payment_method_id: type: string description: Payment method ID amount: type: number example: 99.99 source_id: type: string description: Payment source ID "/api/v3/admin/orders/{order_id}/payments/{id}": get: summary: Show a payment tags: - Orders security: - api_key: [] bearer_auth: [] description: |- Returns details of a specific payment. **Required scope:** `read_payments` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const payment = await client.orders.payments.get('or_UkLWZg9DAJ', 'pay_UkLWZg9DAJ') 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: order_id in: path required: true description: Order ID schema: type: string - name: id in: path required: true description: Payment ID schema: type: string - name: expand in: query required: false description: Comma-separated associations to expand (e.g., payment_method, source). 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,status,number,response_code). id is always included. schema: type: string responses: '200': description: payment found content: application/json: example: id: py_UkLWZg9DAJ payment_method_id: pm_UkLWZg9DAJ response_code: BGS-ecd6e3a829e6 number: P6DLMTIN amount: '110.0' display_amount: "$110.00" status: completed source_type: credit_card source_id: card_UkLWZg9DAJ source: id: card_UkLWZg9DAJ brand: visa last4: '1111' month: 12 year: 2027 name: Spree Commerce default: false gateway_payment_profile_id: customer_id: payment_method_id: pm_gbHJdmfrXB metadata: {} created_at: '2026-05-24T17:37:17.639Z' updated_at: '2026-05-24T17:37:17.642Z' metadata: {} avs_response: cvv_response_code: cvv_response_message: created_at: '2026-05-24T17:37:17.641Z' updated_at: '2026-05-24T17:37:17.641Z' captured_amount: '0.0' order_id: or_UkLWZg9DAJ "/api/v3/admin/orders/{order_id}/payments/{id}/capture": patch: summary: Capture a payment tags: - Orders security: - api_key: [] bearer_auth: [] description: |- Captures a pending payment. **Required scope:** `write_payments` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const payment = await client.orders.payments.capture('or_UkLWZg9DAJ', 'pay_UkLWZg9DAJ') 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: order_id in: path required: true description: Order ID schema: type: string - name: id in: path required: true description: Payment ID schema: type: string responses: '200': description: payment captured content: application/json: example: id: py_UkLWZg9DAJ payment_method_id: pm_UkLWZg9DAJ response_code: BGS-6e39b35672d4 number: PJJ3CQHY amount: '110.0' display_amount: "$110.00" status: completed source_type: credit_card source_id: card_UkLWZg9DAJ source: id: card_UkLWZg9DAJ brand: visa last4: '1111' month: 12 year: 2027 name: Spree Commerce default: false gateway_payment_profile_id: customer_id: payment_method_id: pm_gbHJdmfrXB metadata: {} created_at: '2026-05-24T17:37:18.265Z' updated_at: '2026-05-24T17:37:18.268Z' metadata: {} avs_response: cvv_response_code: cvv_response_message: created_at: '2026-05-24T17:37:18.267Z' updated_at: '2026-05-24T17:37:18.596Z' captured_amount: '110.0' order_id: or_UkLWZg9DAJ '422': description: capture failed content: application/json: example: error: code: processing_error message: 'Bogus Gateway: Forced failure' schema: "$ref": "#/components/schemas/ErrorResponse" "/api/v3/admin/orders/{order_id}/payments/{id}/void": patch: summary: Void a payment tags: - Orders security: - api_key: [] bearer_auth: [] description: |- Voids a payment. **Required scope:** `write_payments` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const payment = await client.orders.payments.void('or_UkLWZg9DAJ', 'pay_UkLWZg9DAJ') 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: order_id in: path required: true description: Order ID schema: type: string - name: id in: path required: true description: Payment ID schema: type: string responses: '200': description: payment voided content: application/json: example: id: py_UkLWZg9DAJ payment_method_id: pm_UkLWZg9DAJ response_code: void-BGS-f655707373af number: PYU6OBOS amount: '110.0' display_amount: "$110.00" status: void source_type: credit_card source_id: card_UkLWZg9DAJ source: id: card_UkLWZg9DAJ brand: visa last4: '1111' month: 12 year: 2027 name: Spree Commerce default: false gateway_payment_profile_id: customer_id: payment_method_id: pm_gbHJdmfrXB metadata: {} created_at: '2026-05-24T17:37:19.623Z' updated_at: '2026-05-24T17:37:19.625Z' metadata: {} avs_response: cvv_response_code: cvv_response_message: created_at: '2026-05-24T17:37:19.624Z' updated_at: '2026-05-24T17:37:19.923Z' captured_amount: '0.0' order_id: or_UkLWZg9DAJ "/api/v3/admin/orders/{order_id}/refunds": get: summary: List refunds tags: - Orders security: - api_key: [] bearer_auth: [] description: |- Returns all refunds for an order. **Required scope:** `read_refunds` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const { data: refunds } = await client.orders.refunds.list('or_UkLWZg9DAJ') 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: order_id in: path required: true description: Order ID schema: type: string - name: expand in: query required: false description: Comma-separated associations to expand (e.g., payment, refund_reason). 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,reason,transaction_id). id is always included. schema: type: string responses: '200': description: refunds found content: application/json: example: data: [] meta: page: 1 limit: 25 count: 0 pages: 1 from: 0 to: 0 in: 0 previous: next: post: summary: Create a refund tags: - Orders security: - api_key: [] bearer_auth: [] description: |- Creates a refund for a payment on the order. The refund is automatically processed via the payment gateway. **Required scope:** `write_refunds` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const refund = await client.orders.refunds.create('or_UkLWZg9DAJ', { payment_id: 'pay_UkLWZg9DAJ', amount: 5.00, refund_reason_id: 'refrsn_UkLWZg9DAJ', }) 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: order_id in: path required: true description: Order ID schema: type: string responses: '201': description: refund created content: application/json: example: id: re_UkLWZg9DAJ transaction_id: BGS-71407c2949ff amount: '5.0' payment_id: py_UkLWZg9DAJ refund_reason_id: rr_UkLWZg9DAJ reimbursement_id: metadata: {} created_at: '2026-05-24T17:37:21.214Z' updated_at: '2026-05-24T17:37:21.214Z' requestBody: content: application/json: schema: type: object required: - payment_id - amount properties: payment_id: type: string description: Payment ID amount: type: number example: 10.0 refund_reason_id: type: string description: Refund reason ID "/api/v3/admin/orders/{order_id}/store_credits": post: summary: Apply customer's store credit to an order tags: - Orders security: - api_key: [] bearer_auth: [] description: |- Applies the order customer's available store credit. When `amount` is omitted, applies up to the order outstanding balance. **Required scope:** `write_store_credits` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const order = await client.orders.storeCredits.apply('or_UkLWZg9DAJ', { amount: 25.00, }) 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: order_id in: path required: true description: Order ID schema: type: string responses: '201': description: store credit applied content: application/json: example: id: or_UkLWZg9DAJ market_id: channel_id: ch_UkLWZg9DAJ number: R479485011 email: kenyetta_schumm@welchfay.name customer_note: currency: USD locale: en total_quantity: 1 item_total: '10.0' display_item_total: "$10.00" adjustment_total: '0.0' display_adjustment_total: "$0.00" discount_total: '0.0' display_discount_total: "$0.00" tax_total: '0.0' display_tax_total: "$0.00" included_tax_total: '0.0' display_included_tax_total: "$0.00" additional_tax_total: '0.0' display_additional_tax_total: "$0.00" total: '110.0' display_total: "$110.00" gift_card_total: '0.0' display_gift_card_total: "$0.00" amount_due: '60.0' display_amount_due: "$60.00" delivery_total: '100.0' display_delivery_total: "$100.00" fulfillment_status: payment_status: completed_at: store_credit_total: '50.0' display_store_credit_total: "-$50.00" covered_by_store_credit: false gift_card: market: status: draft last_ip_address: considered_risky: false confirmation_delivered: false store_owner_notification_delivered: payment_total: '0.0' display_payment_total: "$0.00" metadata: {} canceled_at: approved_at: created_at: '2026-05-24T17:37:21.511Z' updated_at: '2026-05-24T17:37:21.557Z' preferred_stock_location_id: tags: [] internal_note: approver_id: canceler_id: created_by_id: customer_id: cus_UkLWZg9DAJ requestBody: content: application/json: schema: type: object properties: amount: type: number description: Optional explicit amount; defaults to order outstanding balance delete: summary: Remove store credit from an order tags: - Orders security: - api_key: [] bearer_auth: [] description: |- Removes any applied store credit from the order. **Required scope:** `write_store_credits` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) await client.orders.storeCredits.remove('or_UkLWZg9DAJ') 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: order_id in: path required: true description: Order ID schema: type: string responses: '204': description: store credit removed "/api/v3/admin/orders": get: summary: List orders tags: - Orders security: - api_key: [] bearer_auth: [] description: |- Returns a paginated list of orders for the current store. **Required scope:** `read_orders` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const { data: orders, meta } = await client.orders.list({ status_eq: 'complete', completed_at_gt: '2026-01-01', sort: '-completed_at', limit: 25, }) 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 description: Page number schema: type: integer - name: limit in: query required: false description: Number of records per page schema: type: integer - name: sort in: query required: false description: Sort field (e.g., created_at, -created_at, completed_at) schema: type: string - name: q[state_eq] in: query required: false description: Filter by state (cart, address, delivery, payment, confirm, complete, canceled) schema: type: string - name: q[email_cont] in: query required: false description: Filter by email (contains) schema: type: string - name: q[number_eq] in: query required: false description: Filter by order number schema: type: string - name: q[completed_at_gt] in: query required: false description: Filter by completed after date schema: type: string - name: expand in: query required: false description: Comma-separated associations to expand (e.g., items, fulfillments, payments, customer, discounts, billing_address, shipping_address). 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., number,total,status,completed_at). id is always included. schema: type: string responses: '200': description: orders found content: application/json: example: data: - id: or_UkLWZg9DAJ market_id: channel_id: ch_UkLWZg9DAJ number: R977527427 email: onie.roob@breitenberg.ca customer_note: currency: USD locale: en total_quantity: 0 item_total: '0.0' display_item_total: "$0.00" adjustment_total: '0.0' display_adjustment_total: "$0.00" discount_total: '0.0' display_discount_total: "$0.00" tax_total: '0.0' display_tax_total: "$0.00" included_tax_total: '0.0' display_included_tax_total: "$0.00" additional_tax_total: '0.0' display_additional_tax_total: "$0.00" total: '0.0' display_total: "$0.00" gift_card_total: '0.0' display_gift_card_total: "$0.00" amount_due: '0.0' display_amount_due: "$0.00" delivery_total: '0.0' display_delivery_total: "$0.00" fulfillment_status: payment_status: completed_at: store_credit_total: '0.0' display_store_credit_total: "$0.00" covered_by_store_credit: false gift_card: market: status: draft last_ip_address: considered_risky: false confirmation_delivered: false store_owner_notification_delivered: payment_total: '0.0' display_payment_total: "$0.00" metadata: {} canceled_at: approved_at: created_at: '2026-05-24T17:37:23.272Z' updated_at: '2026-05-24T17:37:23.272Z' preferred_stock_location_id: tags: [] internal_note: approver_id: canceler_id: created_by_id: customer_id: cus_UkLWZg9DAJ meta: page: 1 limit: 25 count: 1 pages: 1 from: 1 to: 1 in: 1 previous: next: '401': description: unauthorized content: application/json: example: error: code: authentication_required message: Authentication required schema: "$ref": "#/components/schemas/ErrorResponse" post: summary: Create a draft order tags: - Orders security: - api_key: [] bearer_auth: [] x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) // One-shot order create: customer, items, addresses, market, channel, // notes, metadata, and a coupon code in a single call. Everything // except `email` is optional. const order = await client.orders.create({ email: 'jane@example.com', customer_id: 'cus_UkLWZg9DAJ', // Existing customer; omit for guest orders use_customer_default_address: false, // true to copy the customer's saved addresses currency: 'USD', market_id: 'mkt_UkLWZg9DAJ', channel_id: 'ch_UkLWZg9DAJ', // Optional — defaults to the store's primary channel locale: 'en-US', // Pin the order's preferred fulfillment location. Order Routing's // built-in PreferredLocation rule ranks this location first when // it stocks the cart's items; if it doesn't, routing falls back // to the next rule (Minimize Splits → Default Location). preferred_stock_location_id: 'sloc_UkLWZg9DAJ', customer_note: 'Please leave at the front desk.', internal_note: 'VIP customer — handle with care.', metadata: { external_reference: 'subscription_invoice_2026_04', source: 'recurring-engine', }, // Items: each variant_id + quantity. Optional metadata per line. items: [ { variant_id: 'variant_k5nR8xLq', quantity: 2 }, { variant_id: 'variant_QXyZ12abCD', quantity: 1, metadata: { gift: true } }, ], // Provide addresses inline OR by ID (existing customer addresses). shipping_address: { first_name: 'Jane', last_name: 'Doe', address1: '350 Fifth Avenue', address2: 'Floor 42', city: 'New York', postal_code: '10118', country_iso: 'US', state_abbr: 'NY', phone: '+1 212 555 1234', company: 'Acme Inc.', }, // shipping_address_id: 'addr_UkLWZg9DAJ', // alternative to inline billing_address: { first_name: 'Jane', last_name: 'Doe', address1: '350 Fifth Avenue', city: 'New York', postal_code: '10118', country_iso: 'US', state_abbr: 'NY', phone: '+1 212 555 1234', }, // billing_address_id: 'addr_UkLWZg9DAJ', // Optional. Invalid codes are non-fatal — the order is created either way. coupon_code: 'WELCOME10', }) description: |- Creates a new draft order in one shot. Customer, items, addresses, currency, market, channel, locale, notes, metadata, and a coupon code can all be provided inline. Setting `preferred_stock_location_id` pins the order's preferred fulfillment location — Order Routing's built-in `PreferredLocation` rule consumes it when picking which stock location ships each shipment. Invalid coupon codes are non-fatal — the order is created and the failure is reported on the service result (not in the API response body for now). **Required scope:** `write_orders` (for API-key authentication). 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 responses: '201': description: order created with preferred_stock_location_id content: application/json: example: id: or_gbHJdmfrXB market_id: channel_id: ch_UkLWZg9DAJ number: R518772568 email: pinned@example.com customer_note: currency: USD locale: en total_quantity: 0 item_total: '0.0' display_item_total: "$0.00" adjustment_total: '0.0' display_adjustment_total: "$0.00" discount_total: '0.0' display_discount_total: "$0.00" tax_total: '0.0' display_tax_total: "$0.00" included_tax_total: '0.0' display_included_tax_total: "$0.00" additional_tax_total: '0.0' display_additional_tax_total: "$0.00" total: '0.0' display_total: "$0.00" gift_card_total: '0.0' display_gift_card_total: "$0.00" amount_due: '0.0' display_amount_due: "$0.00" delivery_total: '0.0' display_delivery_total: "$0.00" fulfillment_status: payment_status: completed_at: store_credit_total: '0.0' display_store_credit_total: "$0.00" covered_by_store_credit: false gift_card: market: status: draft last_ip_address: considered_risky: false confirmation_delivered: false store_owner_notification_delivered: payment_total: '0.0' display_payment_total: "$0.00" metadata: {} canceled_at: approved_at: created_at: '2026-05-24T17:37:24.939Z' updated_at: '2026-05-24T17:37:24.942Z' preferred_stock_location_id: sloc_UkLWZg9DAJ tags: [] internal_note: approver_id: canceler_id: created_by_id: customer_id: requestBody: content: application/json: schema: type: object properties: email: type: string example: customer@example.com customer_id: type: string description: 'Customer ID. Alias: user_id (legacy).' use_customer_default_address: type: boolean description: When true with customer_id, copies the customer's saved billing/shipping addresses onto the order. currency: type: string example: USD market_id: type: string description: Market ID channel_id: type: string description: Channel ID. Defaults to the store primary channel when omitted. preferred_stock_location_id: type: string description: Stock Location ID to prefer for fulfillment. Order Routing's built-in PreferredLocation rule reads this and ranks the location first; routing falls back to the next rule when the preferred location can't cover the cart. locale: type: string example: en-US customer_note: type: string description: Public, customer-visible note internal_note: type: string description: Staff-only note metadata: type: object description: Arbitrary key/value metadata shipping_address: type: object properties: first_name: type: string last_name: type: string address1: type: string city: type: string postal_code: type: string country_iso: type: string state_abbr: type: string phone: type: string shipping_address_id: type: string description: Existing customer address ID billing_address: type: object properties: first_name: type: string last_name: type: string address1: type: string city: type: string postal_code: type: string country_iso: type: string state_abbr: type: string phone: type: string billing_address_id: type: string description: Existing customer address ID items: type: array items: type: object required: - variant_id - quantity properties: variant_id: type: string description: Variant ID quantity: type: integer example: 1 metadata: type: object coupon_code: type: string description: Optional. Applied non-fatally; invalid codes do not block creation. "/api/v3/admin/orders/{id}": get: summary: Show an order tags: - Orders security: - api_key: [] bearer_auth: [] description: |- Returns full order details including admin-only fields. **Required scope:** `read_orders` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const order = await client.orders.get('or_UkLWZg9DAJ', { expand: ['items', 'fulfillments', 'payments', 'customer'], }) 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: id in: path required: true description: Order ID (e.g., or_xxx) schema: type: string - name: expand in: query required: false description: Comma-separated associations to expand (e.g., items, fulfillments, payments, customer, discounts, billing_address, shipping_address). 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., number,total,status,completed_at). id is always included. schema: type: string responses: '200': description: order found content: application/json: example: id: or_UkLWZg9DAJ market_id: channel_id: ch_UkLWZg9DAJ number: R351185598 email: daysi.mccullough@stiedemann.us customer_note: currency: USD locale: en total_quantity: 0 item_total: '0.0' display_item_total: "$0.00" adjustment_total: '0.0' display_adjustment_total: "$0.00" discount_total: '0.0' display_discount_total: "$0.00" tax_total: '0.0' display_tax_total: "$0.00" included_tax_total: '0.0' display_included_tax_total: "$0.00" additional_tax_total: '0.0' display_additional_tax_total: "$0.00" total: '0.0' display_total: "$0.00" gift_card_total: '0.0' display_gift_card_total: "$0.00" amount_due: '0.0' display_amount_due: "$0.00" delivery_total: '0.0' display_delivery_total: "$0.00" fulfillment_status: payment_status: completed_at: store_credit_total: '0.0' display_store_credit_total: "$0.00" covered_by_store_credit: false gift_card: market: status: draft last_ip_address: considered_risky: false confirmation_delivered: false store_owner_notification_delivered: payment_total: '0.0' display_payment_total: "$0.00" metadata: {} canceled_at: approved_at: created_at: '2026-05-24T17:37:25.214Z' updated_at: '2026-05-24T17:37:25.214Z' preferred_stock_location_id: tags: [] internal_note: approver_id: canceler_id: created_by_id: customer_id: cus_UkLWZg9DAJ '404': description: order not found content: application/json: example: error: code: order_not_found message: Order not found schema: "$ref": "#/components/schemas/ErrorResponse" patch: summary: Update an order tags: - Orders security: - api_key: [] bearer_auth: [] description: |- Updates an order. Supports updating email, addresses, special instructions, and line items. **Required scope:** `write_orders` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const order = await client.orders.update('or_UkLWZg9DAJ', { email: 'updated@example.com', internal_note: 'VIP — gift wrap on next order', }) 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: id in: path required: true description: Order ID schema: type: string responses: '200': description: order updated content: application/json: example: id: or_UkLWZg9DAJ market_id: channel_id: ch_UkLWZg9DAJ number: R963129287 email: updated@example.com customer_note: currency: USD locale: en total_quantity: 0 item_total: '0.0' display_item_total: "$0.00" adjustment_total: '0.0' display_adjustment_total: "$0.00" discount_total: '0.0' display_discount_total: "$0.00" tax_total: '0.0' display_tax_total: "$0.00" included_tax_total: '0.0' display_included_tax_total: "$0.00" additional_tax_total: '0.0' display_additional_tax_total: "$0.00" total: '0.0' display_total: "$0.00" gift_card_total: '0.0' display_gift_card_total: "$0.00" amount_due: '0.0' display_amount_due: "$0.00" delivery_total: '0.0' display_delivery_total: "$0.00" fulfillment_status: payment_status: completed_at: store_credit_total: '0.0' display_store_credit_total: "$0.00" covered_by_store_credit: false gift_card: market: status: draft last_ip_address: considered_risky: false confirmation_delivered: false store_owner_notification_delivered: payment_total: '0.0' display_payment_total: "$0.00" metadata: {} canceled_at: approved_at: created_at: '2026-05-24T17:37:26.302Z' updated_at: '2026-05-24T17:37:26.584Z' preferred_stock_location_id: tags: [] internal_note: approver_id: canceler_id: created_by_id: customer_id: cus_UkLWZg9DAJ requestBody: content: application/json: schema: type: object properties: email: type: string special_instructions: type: string internal_note: type: string channel_id: type: string description: Channel ID preferred_stock_location_id: type: string description: Stock Location ID to prefer for fulfillment. Re-runs Order Routing's PreferredLocation rule on subsequent shipment rebuilds. ship_address: type: object properties: firstname: type: string lastname: type: string address1: type: string city: type: string zipcode: type: string country_iso: type: string state_abbr: type: string phone: type: string bill_address: type: object properties: firstname: type: string lastname: type: string address1: type: string city: type: string zipcode: type: string country_iso: type: string state_abbr: type: string phone: type: string items: type: array items: type: object required: - variant_id properties: variant_id: type: string description: Variant ID quantity: type: integer example: 1 metadata: type: object delete: summary: Delete a draft order tags: - Orders security: - api_key: [] bearer_auth: [] description: |- Deletes a draft order. Completed orders cannot be deleted. **Required scope:** `write_orders` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) await client.orders.delete('or_UkLWZg9DAJ') 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: id in: path required: true description: Order ID schema: type: string responses: '204': description: order deleted "/api/v3/admin/orders/{id}/complete": patch: summary: Complete an order tags: - Orders security: - api_key: [] bearer_auth: [] description: |- Completes an order in the `confirm` state, marking it as placed. Set `notify_customer: true` to send the order confirmation email. **Required scope:** `write_orders` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const order = await client.orders.complete('or_UkLWZg9DAJ', { notify_customer: true, }) 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: id in: path required: true description: Order ID schema: type: string responses: '200': description: order completed content: application/json: example: id: or_UkLWZg9DAJ market_id: channel_id: ch_UkLWZg9DAJ number: R325816233 email: ellsworth@haag.co.uk customer_note: currency: USD locale: en total_quantity: 1 item_total: '10.0' display_item_total: "$10.00" adjustment_total: '0.0' display_adjustment_total: "$0.00" discount_total: '0.0' display_discount_total: "$0.00" tax_total: '0.0' display_tax_total: "$0.00" included_tax_total: '0.0' display_included_tax_total: "$0.00" additional_tax_total: '0.0' display_additional_tax_total: "$0.00" total: '110.0' display_total: "$110.00" gift_card_total: '0.0' display_gift_card_total: "$0.00" amount_due: '0.0' display_amount_due: "$0.00" delivery_total: '100.0' display_delivery_total: "$100.00" fulfillment_status: ready payment_status: paid completed_at: '2026-05-24T17:37:27.485Z' store_credit_total: '0.0' display_store_credit_total: "$0.00" covered_by_store_credit: false gift_card: market: status: draft last_ip_address: considered_risky: false confirmation_delivered: false store_owner_notification_delivered: payment_total: '110.0' display_payment_total: "$110.00" metadata: {} canceled_at: approved_at: created_at: '2026-05-24T17:37:27.437Z' updated_at: '2026-05-24T17:37:27.507Z' preferred_stock_location_id: tags: [] internal_note: approver_id: canceler_id: created_by_id: customer_id: cus_UkLWZg9DAJ '422': description: order cannot be completed content: application/json: example: error: code: order_cannot_complete message: No payment found details: base: - No payment found schema: "$ref": "#/components/schemas/ErrorResponse" requestBody: content: application/json: schema: type: object properties: notify_customer: type: boolean description: Send the order confirmation email after completion. "/api/v3/admin/orders/{id}/cancel": patch: summary: Cancel an order tags: - Orders security: - api_key: [] bearer_auth: [] description: |- Cancels a completed order. **Required scope:** `write_orders` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const order = await client.orders.cancel('or_UkLWZg9DAJ') 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: id in: path required: true description: Order ID schema: type: string responses: '200': description: order canceled content: application/json: example: id: or_UkLWZg9DAJ market_id: channel_id: ch_UkLWZg9DAJ number: R715045671 email: alverta.nader@murazikhuels.biz customer_note: currency: USD locale: en total_quantity: 1 item_total: '10.0' display_item_total: "$10.00" adjustment_total: '0.0' display_adjustment_total: "$0.00" discount_total: '0.0' display_discount_total: "$0.00" tax_total: '0.0' display_tax_total: "$0.00" included_tax_total: '0.0' display_included_tax_total: "$0.00" additional_tax_total: '0.0' display_additional_tax_total: "$0.00" total: '20.0' display_total: "$20.00" gift_card_total: '0.0' display_gift_card_total: "$0.00" amount_due: "-0.0" display_amount_due: "$0.00" delivery_total: '10.0' display_delivery_total: "$10.00" fulfillment_status: canceled payment_status: void completed_at: '2026-05-24T17:37:28.733Z' store_credit_total: '0.0' display_store_credit_total: "$0.00" covered_by_store_credit: false gift_card: market: status: canceled last_ip_address: considered_risky: false confirmation_delivered: false store_owner_notification_delivered: payment_total: '0.0' display_payment_total: "$0.00" metadata: {} canceled_at: '2026-05-24T17:37:29.026Z' approved_at: created_at: '2026-05-24T17:37:28.686Z' updated_at: '2026-05-24T17:37:29.069Z' preferred_stock_location_id: tags: [] internal_note: approver_id: canceler_id: admin_UkLWZg9DAJ created_by_id: customer_id: cus_UkLWZg9DAJ "/api/v3/admin/orders/{id}/approve": patch: summary: Approve an order tags: - Orders security: - api_key: [] bearer_auth: [] description: |- Approves an order (e.g., for fraud review). **Required scope:** `write_orders` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const order = await client.orders.approve('or_UkLWZg9DAJ') 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: id in: path required: true description: Order ID schema: type: string responses: '200': description: order approved content: application/json: example: id: or_UkLWZg9DAJ market_id: channel_id: ch_UkLWZg9DAJ number: R801788034 email: karmen_lubowitz@kertzmann.ca customer_note: currency: USD locale: en total_quantity: 1 item_total: '10.0' display_item_total: "$10.00" adjustment_total: '0.0' display_adjustment_total: "$0.00" discount_total: '0.0' display_discount_total: "$0.00" tax_total: '0.0' display_tax_total: "$0.00" included_tax_total: '0.0' display_included_tax_total: "$0.00" additional_tax_total: '0.0' display_additional_tax_total: "$0.00" total: '110.0' display_total: "$110.00" gift_card_total: '0.0' display_gift_card_total: "$0.00" amount_due: '110.0' display_amount_due: "$110.00" delivery_total: '100.0' display_delivery_total: "$100.00" fulfillment_status: payment_status: completed_at: '2026-05-24T17:37:29.425Z' store_credit_total: '0.0' display_store_credit_total: "$0.00" covered_by_store_credit: false gift_card: market: status: draft last_ip_address: considered_risky: false confirmation_delivered: false store_owner_notification_delivered: payment_total: '0.0' display_payment_total: "$0.00" metadata: {} canceled_at: approved_at: '2026-05-24T17:37:29.716Z' created_at: '2026-05-24T17:37:29.365Z' updated_at: '2026-05-24T17:37:29.425Z' preferred_stock_location_id: tags: [] internal_note: approver_id: admin_UkLWZg9DAJ canceler_id: created_by_id: customer_id: cus_UkLWZg9DAJ "/api/v3/admin/orders/{id}/resume": patch: summary: Resume a canceled order tags: - Orders security: - api_key: [] bearer_auth: [] description: |- Resumes a previously canceled order. **Required scope:** `write_orders` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const order = await client.orders.resume('or_UkLWZg9DAJ') 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: id in: path required: true description: Order ID schema: type: string responses: '200': description: order resumed content: application/json: example: id: or_UkLWZg9DAJ market_id: channel_id: ch_UkLWZg9DAJ number: R074770237 email: ingrid_jacobson@schneider.name customer_note: currency: USD locale: en total_quantity: 1 item_total: '10.0' display_item_total: "$10.00" adjustment_total: '0.0' display_adjustment_total: "$0.00" discount_total: '0.0' display_discount_total: "$0.00" tax_total: '0.0' display_tax_total: "$0.00" included_tax_total: '0.0' display_included_tax_total: "$0.00" additional_tax_total: '0.0' display_additional_tax_total: "$0.00" total: '20.0' display_total: "$20.00" gift_card_total: '0.0' display_gift_card_total: "$0.00" amount_due: '20.0' display_amount_due: "$20.00" delivery_total: '10.0' display_delivery_total: "$10.00" fulfillment_status: canceled payment_status: void completed_at: '2026-05-24T17:37:30.041Z' store_credit_total: '0.0' display_store_credit_total: "$0.00" covered_by_store_credit: false gift_card: market: status: placed last_ip_address: considered_risky: false confirmation_delivered: false store_owner_notification_delivered: payment_total: '0.0' display_payment_total: "$0.00" metadata: {} canceled_at: '2026-05-24T17:37:30.319Z' approved_at: created_at: '2026-05-24T17:37:29.994Z' updated_at: '2026-05-24T17:37:30.411Z' preferred_stock_location_id: tags: [] internal_note: approver_id: canceler_id: admin_UkLWZg9DAJ created_by_id: customer_id: cus_UkLWZg9DAJ "/api/v3/admin/orders/{id}/resend_confirmation": post: summary: Resend confirmation email tags: - Orders security: - api_key: [] bearer_auth: [] description: |- Publishes the order.completed event to trigger confirmation email delivery. **Required scope:** `write_orders` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) await client.orders.resendConfirmation('or_UkLWZg9DAJ') 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: id in: path required: true description: Order ID schema: type: string responses: '200': description: confirmation resent content: application/json: example: id: or_UkLWZg9DAJ market_id: channel_id: ch_UkLWZg9DAJ number: R726922313 email: mallory_ziemann@hoegerzboncak.co.uk customer_note: currency: USD locale: en total_quantity: 1 item_total: '10.0' display_item_total: "$10.00" adjustment_total: '0.0' display_adjustment_total: "$0.00" discount_total: '0.0' display_discount_total: "$0.00" tax_total: '0.0' display_tax_total: "$0.00" included_tax_total: '0.0' display_included_tax_total: "$0.00" additional_tax_total: '0.0' display_additional_tax_total: "$0.00" total: '110.0' display_total: "$110.00" gift_card_total: '0.0' display_gift_card_total: "$0.00" amount_due: '110.0' display_amount_due: "$110.00" delivery_total: '100.0' display_delivery_total: "$100.00" fulfillment_status: payment_status: completed_at: '2026-05-24T17:37:30.745Z' store_credit_total: '0.0' display_store_credit_total: "$0.00" covered_by_store_credit: false gift_card: market: status: draft last_ip_address: considered_risky: false confirmation_delivered: false store_owner_notification_delivered: payment_total: '0.0' display_payment_total: "$0.00" metadata: {} canceled_at: approved_at: created_at: '2026-05-24T17:37:30.693Z' updated_at: '2026-05-24T17:37:30.745Z' preferred_stock_location_id: tags: [] internal_note: approver_id: canceler_id: created_by_id: customer_id: cus_UkLWZg9DAJ "/api/v3/admin/payment_methods": get: summary: List payment methods tags: - Configuration security: - api_key: [] bearer_auth: [] description: |- Returns the store's configured payment methods. Use `source_required: true` to know which methods need a saved source. **Required scope:** `read_settings` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const { data: paymentMethods } = await client.paymentMethods.list() parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string - name: expand in: query required: false description: Comma-separated associations to expand. 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., name,type,active). id is always included. schema: type: string responses: '200': description: payment methods found content: application/json: example: data: - id: pm_UkLWZg9DAJ name: Check description: type: check session_required: false source_required: false metadata: {} active: true auto_capture: storefront_visible: true position: 1 created_at: '2026-05-24T17:37:31.151Z' updated_at: '2026-05-24T17:37:31.153Z' preferences: {} preference_schema: [] meta: page: 1 limit: 25 count: 1 pages: 1 from: 1 to: 1 in: 1 previous: next: "/api/v3/admin/payment_methods/types": get: summary: List available payment provider types tags: - Configuration security: - api_key: [] bearer_auth: [] description: |- Returns the registered Spree::PaymentMethod subclasses that can be used to create new payment methods. Useful for populating a "Provider" dropdown in admin UIs. **Required scope:** `read_settings` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const { data: types } = await client.paymentMethods.types() parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string responses: '200': description: provider types found content: application/json: example: data: - type: bogus label: Bogus description: preference_schema: - key: dummy_key type: string default: PUBLICKEY123 - key: dummy_secret_key type: password default: - type: custom_payment_source_method label: Custom Payment Source Method description: preference_schema: [] "/api/v3/admin/payment_methods/{id}": get: summary: Show a payment method tags: - Configuration security: - api_key: [] bearer_auth: [] description: |- Returns a payment method by ID. **Required scope:** `read_settings` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const paymentMethod = await client.paymentMethods.get('pm_UkLWZg9DAJ') parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header 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. 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., name,type,active). id is always included. schema: type: string responses: '200': description: payment method found content: application/json: example: id: pm_UkLWZg9DAJ name: Check description: type: check session_required: false source_required: false metadata: {} active: true auto_capture: storefront_visible: true position: 1 created_at: '2026-05-24T17:37:31.752Z' updated_at: '2026-05-24T17:37:31.754Z' preferences: {} preference_schema: [] "/api/v3/admin/products/{product_id}/custom_fields": get: summary: List product custom fields tags: - Products security: - api_key: [] bearer_auth: [] description: |- Returns the product's custom field values. **Required scope:** `read_products` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const { data: customFields } = await client.products.customFields.list('prod_UkLWZg9DAJ') parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string - name: product_id in: path required: true schema: type: string - name: expand in: query required: false description: Comma-separated associations to expand (e.g., custom_field_definition). 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., key,value,namespace). id is always included. schema: type: string responses: '200': description: custom fields found content: application/json: example: data: - id: cf_UkLWZg9DAJ label: Title type: Spree::Metafields::ShortText field_type: short_text key: custom.title value: wool created_at: '2026-05-24T17:37:32.172Z' updated_at: '2026-05-24T17:37:32.172Z' storefront_visible: true custom_field_definition_id: cfdef_UkLWZg9DAJ meta: page: 1 limit: 25 count: 1 pages: 1 from: 1 to: 1 in: 1 previous: next: post: summary: Create a product custom field tags: - Products security: - api_key: [] bearer_auth: [] description: |- Sets a custom field value on the product. Requires an existing CustomFieldDefinition; pass its prefixed `cfdef_…` id. **Required scope:** `write_products` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const customField = await client.products.customFields.create('prod_UkLWZg9DAJ', { custom_field_definition_id: 'cfdef_AbC123XyZ', value: 'wool', }) parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string - name: product_id in: path required: true schema: type: string responses: '201': description: custom field created content: application/json: example: id: cf_gbHJdmfrXB label: Description type: Spree::Metafields::LongText field_type: long_text key: custom.description value: A longer description created_at: '2026-05-24T17:37:32.769Z' updated_at: '2026-05-24T17:37:32.769Z' storefront_visible: true custom_field_definition_id: cfdef_gbHJdmfrXB '422': description: duplicate definition for the same product content: application/json: example: error: code: validation_error message: Metafield definition has already been taken details: metafield_definition_id: - has already been taken requestBody: content: application/json: schema: type: object required: - custom_field_definition_id - value properties: custom_field_definition_id: type: string description: Prefixed `cfdef_…` id value: description: Value matching the definition's `field_type` "/api/v3/admin/products/{product_id}/custom_fields/{id}": get: summary: Show a product custom field tags: - Products security: - api_key: [] bearer_auth: [] description: "**Required scope:** `read_products` (for API-key authentication)." parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string - name: product_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., custom_field_definition). 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., key,value,namespace). id is always included. schema: type: string responses: '200': description: custom field found content: application/json: example: id: cf_UkLWZg9DAJ label: Title type: Spree::Metafields::ShortText field_type: short_text key: custom.title value: wool created_at: '2026-05-24T17:37:33.120Z' updated_at: '2026-05-24T17:37:33.120Z' storefront_visible: true custom_field_definition_id: cfdef_UkLWZg9DAJ patch: summary: Update a product custom field tags: - Products security: - api_key: [] bearer_auth: [] description: |- Updates the custom field's `value`. The linked definition cannot be changed — delete and recreate to switch. **Required scope:** `write_products` (for API-key authentication). parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string - name: product_id in: path required: true schema: type: string - name: id in: path required: true schema: type: string responses: '200': description: custom field updated content: application/json: example: id: cf_UkLWZg9DAJ label: Title type: Spree::Metafields::ShortText field_type: short_text key: custom.title value: cotton created_at: '2026-05-24T17:37:33.439Z' updated_at: '2026-05-24T17:37:33.726Z' storefront_visible: true custom_field_definition_id: cfdef_UkLWZg9DAJ requestBody: content: application/json: schema: type: object required: - value properties: value: description: New value delete: summary: Delete a product custom field tags: - Products security: - api_key: [] bearer_auth: [] description: "**Required scope:** `write_products` (for API-key authentication)." parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string - name: product_id in: path required: true schema: type: string - name: id in: path required: true schema: type: string responses: '204': description: custom field deleted "/api/v3/admin/products": get: summary: List products tags: - Product Catalog security: - api_key: [] bearer_auth: [] description: |- Returns a paginated list of products for the current store. **Required scope:** `read_products` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const { data: products } = await client.products.list({ name_cont: 'shirt', status_eq: 'active', sort: '-created_at', limit: 25, }) 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 description: Page number schema: type: integer - name: limit in: query required: false description: Number of records per page schema: type: integer - name: sort in: query required: false description: Sort field (e.g., name, -name, price, -price, best_selling) schema: type: string - name: expand in: query required: false description: Comma-separated associations to expand (e.g., variants, media, option_types, categories). 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., name,slug,price,status). id is always included. schema: type: string - name: q[name_cont] in: query required: false description: Filter by name (contains) schema: type: string - name: q[status_eq] in: query required: false description: Filter by status schema: type: string responses: '200': description: products found content: application/json: example: data: - id: prod_UkLWZg9DAJ name: Product 396394 slug: product-396394 meta_title: meta_description: meta_keywords: variant_count: 0 available_on: '2025-05-24T17:37:34.067Z' purchasable: true in_stock: false backorderable: true available: true description: Eaque soluta sit officiis sequi. Deleniti perspiciatis repudiandae ratione quod illum enim. Tenetur tempora similique soluta corporis magni ea itaque dolore. Harum aliquid tempore facilis amet deleniti facere. Nisi ducimus nihil a optio veniam totam. Libero aut deleniti laudantium aliquam reprehenderit. Nam neque assumenda a nisi iusto aliquid perferendis. Quas tenetur non consequatur assumenda. Quos explicabo error culpa aspernatur quod earum cupiditate omnis. Eaque id iste saepe ratione repellendus. Porro cum ducimus eaque occaecati natus cupiditate itaque. Quisquam esse dolore distinctio labore. Minima excepturi fugiat quibusdam voluptatem. description_html: |- Eaque soluta sit officiis sequi. Deleniti perspiciatis repudiandae ratione quod illum enim. Tenetur tempora similique soluta corporis magni ea itaque dolore. Harum aliquid tempore facilis amet deleniti facere. Nisi ducimus nihil a optio veniam totam. Libero aut deleniti laudantium aliquam reprehenderit. Nam neque assumenda a nisi iusto aliquid perferendis. Quas tenetur non consequatur assumenda. Quos explicabo error culpa aspernatur quod earum cupiditate omnis. Eaque id iste saepe ratione repellendus. Porro cum ducimus eaque occaecati natus cupiditate itaque. Quisquam esse dolore distinctio labore. Minima excepturi fugiat quibusdam voluptatem. default_variant_id: variant_UkLWZg9DAJ thumbnail_url: tags: [] price: id: price_UkLWZg9DAJ amount: '19.99' amount_in_cents: 1999 compare_at_amount: compare_at_amount_in_cents: currency: USD display_amount: "$19.99" display_compare_at_amount: price_list_id: variant_id: variant_UkLWZg9DAJ created_at: '2026-05-24T17:37:34.092Z' updated_at: '2026-05-24T17:37:34.092Z' original_price: status: active make_active_at: '2025-05-24T17:37:34.067Z' discontinue_on: metadata: {} deleted_at: created_at: '2026-05-24T17:37:34.079Z' updated_at: '2026-05-24T17:37:34.093Z' tax_category_id: taxcat_UkLWZg9DAJ meta: page: 1 limit: 25 count: 1 pages: 1 from: 1 to: 1 in: 1 previous: next: schema: type: object properties: data: type: array items: "$ref": "#/components/schemas/Product" meta: "$ref": "#/components/schemas/PaginationMeta" required: - data - meta '401': description: unauthorized content: application/json: example: error: code: authentication_required message: Authentication required schema: "$ref": "#/components/schemas/ErrorResponse" post: summary: Create a product tags: - Product Catalog security: - api_key: [] bearer_auth: [] description: |- Creates a new product. Supports nested variants with prices and option types. Option types and values are auto-created if they don't exist. Prices are upserted by currency. Stock items are upserted by stock location. **Required scope:** `write_products` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const product = await client.products.create({ name: 'Premium T-Shirt', description: 'Soft, organic cotton.', status: 'active', variants: [ { sku: 'TSHIRT-S-NAVY', options: [ { name: 'size', value: 'Small' }, { name: 'color', value: 'navy' }, ], prices: [ { currency: 'USD', amount: 29.99 }, { currency: 'EUR', amount: 27.99 }, ], stock_items: [ { stock_location_id: 'sloc_UkLWZg9DAJ', count_on_hand: 50 }, ], }, { sku: 'TSHIRT-M-NAVY', options: [ { name: 'size', value: 'Medium' }, { name: 'color', value: 'navy' }, ], prices: [{ currency: 'USD', amount: 29.99 }], stock_items: [ { stock_location_id: 'sloc_UkLWZg9DAJ', count_on_hand: 30 }, ], }, ], }) 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 responses: '201': description: product created content: application/json: example: id: prod_gbHJdmfrXB name: New Product slug: new-product meta_title: meta_description: meta_keywords: variant_count: 0 available_on: purchasable: false in_stock: false backorderable: false available: false description: description_html: default_variant_id: variant_gbHJdmfrXB thumbnail_url: tags: [] price: original_price: status: draft make_active_at: discontinue_on: metadata: {} deleted_at: created_at: '2026-05-24T17:37:34.756Z' updated_at: '2026-05-24T17:37:34.758Z' tax_category_id: schema: "$ref": "#/components/schemas/Product" '422': description: validation error content: application/json: example: error: code: validation_error message: Name can't be blank details: name: - can't be blank schema: "$ref": "#/components/schemas/ErrorResponse" requestBody: content: application/json: schema: type: object properties: name: type: string example: Premium T-Shirt description: type: string slug: type: string status: type: string enum: - draft - active - archived tax_category_id: type: string description: Tax category ID category_ids: type: array items: type: string description: Array of category IDs tags: type: array items: type: string example: - eco - sale variants: type: array description: Array of variant payloads. Variants can declare multiple option pairs via `options:` and per-currency prices via `prices:`. Stock counts go in `stock_items:` (per stock location). items: type: object properties: sku: type: string options: type: array description: One pair per option type the variant participates in (e.g. size + color). Option types and values are auto-created if missing. items: type: object required: - name - value properties: name: type: string example: size value: type: string example: Small prices: type: array description: Per-currency prices. Upserted by currency. items: type: object required: - currency - amount properties: currency: type: string example: USD amount: type: number example: 29.99 compare_at_amount: type: number example: 39.99 stock_items: type: array description: Per-stock-location inventory. Upserted by stock_location_id. items: type: object required: - stock_location_id - count_on_hand properties: stock_location_id: type: string description: Stock location ID (e.g. sloc_xxx) count_on_hand: type: integer example: 50 backorderable: type: boolean required: - name "/api/v3/admin/products/{id}": get: summary: Get a product tags: - Product Catalog security: - api_key: [] bearer_auth: [] description: |- Returns a single product by ID. **Required scope:** `read_products` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const product = await client.products.get('prod_86Rf07xd4z', { expand: ['variants', 'option_types'], }) 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: id in: path required: true description: Product ID (e.g., prod_xxx) schema: type: string - name: expand in: query required: false description: Comma-separated associations to expand (e.g., variants, media, option_types, categories). 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., name,slug,price,status). id is always included. schema: type: string responses: '200': description: product found content: application/json: example: id: prod_UkLWZg9DAJ name: Product 431256 slug: product-431256 meta_title: meta_description: meta_keywords: variant_count: 0 available_on: '2025-05-24T17:37:35.110Z' purchasable: true in_stock: false backorderable: true available: true description: Nemo quam et hic libero natus qui. Saepe repudiandae eaque autem provident omnis at quia. Porro fugiat voluptatibus vero dolore beatae minus id. Molestias est illo unde quis. Velit quis at voluptatem ut quam mollitia saepe nam. Eligendi laudantium quis aspernatur ea incidunt culpa. Cupiditate sequi reiciendis aspernatur maiores. Tempore blanditiis sint libero odit veniam. description_html: |- Nemo quam et hic libero natus qui. Saepe repudiandae eaque autem provident omnis at quia. Porro fugiat voluptatibus vero dolore beatae minus id. Molestias est illo unde quis. Velit quis at voluptatem ut quam mollitia saepe nam. Eligendi laudantium quis aspernatur ea incidunt culpa. Cupiditate sequi reiciendis aspernatur maiores. Tempore blanditiis sint libero odit veniam. default_variant_id: variant_UkLWZg9DAJ thumbnail_url: tags: [] price: id: price_UkLWZg9DAJ amount: '19.99' amount_in_cents: 1999 compare_at_amount: compare_at_amount_in_cents: currency: USD display_amount: "$19.99" display_compare_at_amount: price_list_id: variant_id: variant_UkLWZg9DAJ created_at: '2026-05-24T17:37:35.137Z' updated_at: '2026-05-24T17:37:35.137Z' original_price: status: active make_active_at: '2025-05-24T17:37:35.110Z' discontinue_on: metadata: {} deleted_at: created_at: '2026-05-24T17:37:35.121Z' updated_at: '2026-05-24T17:37:35.138Z' tax_category_id: taxcat_UkLWZg9DAJ schema: "$ref": "#/components/schemas/Product" '404': description: product not found content: application/json: example: error: code: record_not_found message: Product not found schema: "$ref": "#/components/schemas/ErrorResponse" patch: summary: Update a product tags: - Product Catalog security: - api_key: [] bearer_auth: [] description: |- Updates a product. Only provided fields are updated. **Required scope:** `write_products` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const product = await client.products.update('prod_86Rf07xd4z', { name: 'Updated Name', status: 'active', tags: ['eco', 'sale'], }) 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: id in: path required: true description: Product ID schema: type: string responses: '200': description: product updated content: application/json: example: id: prod_UkLWZg9DAJ name: Updated Name slug: product-458011 meta_title: meta_description: meta_keywords: variant_count: 0 available_on: '2025-05-24T17:37:35.789Z' purchasable: true in_stock: false backorderable: true available: true description: Non occaecati aut quidem tempore aliquid nisi reprehenderit. Amet culpa hic ullam molestiae cupiditate provident. Nostrum magni soluta velit eius. Itaque sequi iste repudiandae qui esse. Sapiente tenetur doloremque ipsum nesciunt delectus rerum voluptas. Odit voluptatem deleniti sunt veniam. Quidem molestiae possimus illo debitis alias earum quas accusantium. Possimus ea est unde culpa. Alias atque autem ullam voluptatibus iste. Consectetur exercitationem autem natus odit eveniet. Quibusdam similique delectus culpa cumque iure. description_html: |- Non occaecati aut quidem tempore aliquid nisi reprehenderit. Amet culpa hic ullam molestiae cupiditate provident. Nostrum magni soluta velit eius. Itaque sequi iste repudiandae qui esse. Sapiente tenetur doloremque ipsum nesciunt delectus rerum voluptas. Odit voluptatem deleniti sunt veniam. Quidem molestiae possimus illo debitis alias earum quas accusantium. Possimus ea est unde culpa. Alias atque autem ullam voluptatibus iste. Consectetur exercitationem autem natus odit eveniet. Quibusdam similique delectus culpa cumque iure. default_variant_id: variant_UkLWZg9DAJ thumbnail_url: tags: [] price: id: price_UkLWZg9DAJ amount: '19.99' amount_in_cents: 1999 compare_at_amount: compare_at_amount_in_cents: currency: USD display_amount: "$19.99" display_compare_at_amount: price_list_id: variant_id: variant_UkLWZg9DAJ created_at: '2026-05-24T17:37:35.810Z' updated_at: '2026-05-24T17:37:35.810Z' original_price: status: active make_active_at: '2025-05-24T17:37:35.789Z' discontinue_on: metadata: {} deleted_at: created_at: '2026-05-24T17:37:35.799Z' updated_at: '2026-05-24T17:37:36.106Z' tax_category_id: taxcat_UkLWZg9DAJ schema: "$ref": "#/components/schemas/Product" '422': description: validation error content: application/json: example: error: code: validation_error message: Name can't be blank details: name: - can't be blank schema: "$ref": "#/components/schemas/ErrorResponse" requestBody: content: application/json: schema: type: object properties: name: type: string example: Premium T-Shirt description: type: string slug: type: string status: type: string enum: - draft - active - archived tax_category_id: type: string description: Tax category ID category_ids: type: array items: type: string description: Array of category IDs tags: type: array items: type: string example: - eco - sale variants: type: array description: Array of variant payloads. Variants can declare multiple option pairs via `options:` and per-currency prices via `prices:`. Stock counts go in `stock_items:` (per stock location). items: type: object properties: sku: type: string options: type: array description: One pair per option type the variant participates in (e.g. size + color). Option types and values are auto-created if missing. items: type: object required: - name - value properties: name: type: string example: size value: type: string example: Small prices: type: array description: Per-currency prices. Upserted by currency. items: type: object required: - currency - amount properties: currency: type: string example: USD amount: type: number example: 29.99 compare_at_amount: type: number example: 39.99 stock_items: type: array description: Per-stock-location inventory. Upserted by stock_location_id. items: type: object required: - stock_location_id - count_on_hand properties: stock_location_id: type: string description: Stock location ID (e.g. sloc_xxx) count_on_hand: type: integer example: 50 backorderable: type: boolean delete: summary: Delete a product tags: - Product Catalog security: - api_key: [] bearer_auth: [] description: |- Soft-deletes a product. **Required scope:** `write_products` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) await client.products.delete('prod_86Rf07xd4z') 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: id in: path required: true description: Product ID schema: type: string responses: '204': description: product deleted "/api/v3/admin/products/bulk_status_update": post: summary: Bulk-update product status tags: - Product Catalog security: - api_key: [] bearer_auth: [] description: |- Sets `status` on each product in `ids`. Reindexes the affected products for search. Cross-store IDs are silently dropped. Returns counts. **Required scope:** `write_products` (for API-key authentication). parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string responses: '200': description: cross-store products silently dropped content: application/json: example: product_count: 0 status: archived schema: type: object properties: product_count: type: integer status: type: string '422': description: invalid status content: application/json: example: error: code: invalid_status message: Invalid status schema: "$ref": "#/components/schemas/ErrorResponse" requestBody: content: application/json: schema: type: object required: - ids - status properties: ids: type: array items: type: string example: - prod_UkLWZg9DAJ status: type: string enum: - draft - active - archived example: archived "/api/v3/admin/products/bulk_add_to_categories": post: summary: Bulk-add products to categories tags: - Product Catalog security: - api_key: [] bearer_auth: [] description: |- Attaches each product in `ids` to every category (taxon) in `category_ids`. Categories from sibling stores are silently ignored. **Required scope:** `write_products` (for API-key authentication). parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string responses: '200': description: products added to categories content: application/json: example: product_count: 1 category_count: 1 schema: type: object properties: product_count: type: integer category_count: type: integer requestBody: content: application/json: schema: type: object required: - ids - category_ids properties: ids: type: array items: type: string category_ids: type: array items: type: string "/api/v3/admin/products/bulk_remove_from_categories": post: summary: Bulk-remove products from categories tags: - Product Catalog security: - api_key: [] bearer_auth: [] description: |- Detaches each product in `ids` from every category in `category_ids`. **Required scope:** `write_products` (for API-key authentication). parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string responses: '200': description: products removed from categories content: application/json: example: product_count: 1 category_count: 1 requestBody: content: application/json: schema: type: object required: - ids - category_ids properties: ids: type: array items: type: string category_ids: type: array items: type: string "/api/v3/admin/products/bulk_add_tags": post: summary: Bulk-add tags to products tags: - Product Catalog security: - api_key: [] bearer_auth: [] description: |- Adds each tag name in `tags` to every product in `ids`. Tags are upserted by name. **Required scope:** `write_products` (for API-key authentication). parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string responses: '200': description: tags added content: application/json: example: product_count: 1 tag_count: 2 schema: type: object properties: product_count: type: integer tag_count: type: integer requestBody: content: application/json: schema: type: object required: - ids - tags properties: ids: type: array items: type: string tags: type: array items: type: string example: - summer - sale "/api/v3/admin/products/bulk_remove_tags": post: summary: Bulk-remove tags from products tags: - Product Catalog security: - api_key: [] bearer_auth: [] description: |- Removes each tag in `tags` from every product in `ids`. **Required scope:** `write_products` (for API-key authentication). parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string responses: '200': description: tags removed content: application/json: example: product_count: 1 tag_count: 1 requestBody: content: application/json: schema: type: object required: - ids - tags properties: ids: type: array items: type: string tags: type: array items: type: string "/api/v3/admin/products/bulk_destroy": delete: summary: Bulk-delete products tags: - Product Catalog security: - api_key: [] bearer_auth: [] description: |- Soft-deletes each product in `ids`. Returns the count actually destroyed. **Required scope:** `write_products` (for API-key authentication). parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string responses: '200': description: products deleted content: application/json: example: product_count: 1 schema: type: object properties: product_count: type: integer requestBody: content: application/json: schema: type: object required: - ids properties: ids: type: array items: type: string "/api/v3/admin/promotions/{promotion_id}/promotion_actions": parameters: - name: promotion_id in: path required: true schema: type: string get: summary: List actions for a promotion tags: - Promotions security: - api_key: [] bearer_auth: [] description: "**Required scope:** `read_promotions` (for API-key authentication)." x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const { data: actions } = await client.promotions.actions.list('promo_UkLWZg9DAJ') parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string responses: '200': description: actions found content: application/json: example: data: - id: pact_UkLWZg9DAJ created_at: '2026-05-24T17:37:39.416Z' updated_at: '2026-05-24T17:37:39.416Z' type: free_shipping promotion_id: promo_UkLWZg9DAJ preferences: {} preference_schema: [] label: Free shipping calculator: line_items: meta: page: 1 limit: 25 count: 1 pages: 1 from: 1 to: 1 in: 1 previous: next: post: summary: Create an action on a promotion tags: - Promotions security: - api_key: [] bearer_auth: [] description: |- Adds a new action to a promotion. The `type` is the wire shorthand from `GET /promotion_actions/types` (e.g. `free_shipping`, `create_item_adjustments`). Fully-qualified Ruby class names are also accepted for backward compatibility. **Required scope:** `write_promotions` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const action = await client.promotions.actions.create('promo_UkLWZg9DAJ', { type: 'free_shipping', }) 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: action created content: application/json: example: id: pact_UkLWZg9DAJ created_at: '2026-05-24T17:37:39.979Z' updated_at: '2026-05-24T17:37:39.979Z' type: free_shipping promotion_id: promo_UkLWZg9DAJ preferences: {} preference_schema: [] label: Free shipping calculator: line_items: '422': description: unknown action type content: application/json: example: error: code: unknown_promotion_action_type message: Unknown type requestBody: content: application/json: schema: type: object properties: type: type: string example: free_shipping preferences: type: object additionalProperties: true required: - type "/api/v3/admin/promotions/{promotion_id}/promotion_actions/{id}": parameters: - name: promotion_id in: path required: true schema: type: string - name: id in: path required: true schema: type: string delete: summary: Delete an action from a promotion tags: - Promotions security: - api_key: [] bearer_auth: [] description: "**Required scope:** `write_promotions` (for API-key authentication)." parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string responses: '204': description: action deleted "/api/v3/admin/promotions/{promotion_id}/promotion_rules": parameters: - name: promotion_id in: path required: true schema: type: string get: summary: List rules for a promotion tags: - Promotions security: - api_key: [] bearer_auth: [] description: "**Required scope:** `read_promotions` (for API-key authentication)." x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const { data: rules } = await client.promotions.rules.list('promo_UkLWZg9DAJ') parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string responses: '200': description: rules found content: application/json: example: data: - id: prorule_UkLWZg9DAJ created_at: '2026-05-24T17:37:40.551Z' updated_at: '2026-05-24T17:37:40.551Z' type: currency promotion_id: promo_UkLWZg9DAJ preferences: currency: USD preference_schema: - key: currency type: string default: label: Currency product_ids: category_ids: customer_ids: meta: page: 1 limit: 25 count: 1 pages: 1 from: 1 to: 1 in: 1 previous: next: post: summary: Create a rule on a promotion tags: - Promotions security: - api_key: [] bearer_auth: [] description: |- Adds a new rule to a promotion. The `type` is the wire shorthand from `GET /promotion_rules/types` (e.g. `currency`, `item_total`, `product`). Fully-qualified Ruby class names are also accepted for backward compatibility. **Required scope:** `write_promotions` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const rule = await client.promotions.rules.create('promo_UkLWZg9DAJ', { type: 'currency', preferences: { currency: 'EUR' }, }) 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: rule created with preferences content: application/json: example: id: prorule_UkLWZg9DAJ created_at: '2026-05-24T17:37:41.133Z' updated_at: '2026-05-24T17:37:41.133Z' type: currency promotion_id: promo_UkLWZg9DAJ preferences: currency: EUR preference_schema: - key: currency type: string default: label: Currency product_ids: category_ids: customer_ids: '422': description: unknown rule type content: application/json: example: error: code: unknown_promotion_rule_type message: Unknown type requestBody: content: application/json: schema: type: object properties: type: type: string example: currency preferences: type: object additionalProperties: true required: - type "/api/v3/admin/promotions/{promotion_id}/promotion_rules/{id}": parameters: - name: promotion_id in: path required: true schema: type: string - name: id in: path required: true schema: type: string patch: summary: Update a rule's preferences tags: - Promotions security: - api_key: [] bearer_auth: [] description: "**Required scope:** `write_promotions` (for API-key authentication)." parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string responses: '200': description: rule updated content: application/json: example: id: prorule_UkLWZg9DAJ created_at: '2026-05-24T17:37:41.423Z' updated_at: '2026-05-24T17:37:41.701Z' type: currency promotion_id: promo_UkLWZg9DAJ preferences: currency: GBP preference_schema: - key: currency type: string default: label: Currency product_ids: category_ids: customer_ids: requestBody: content: application/json: schema: type: object properties: preferences: type: object additionalProperties: true delete: summary: Delete a rule from a promotion tags: - Promotions security: - api_key: [] bearer_auth: [] description: "**Required scope:** `write_promotions` (for API-key authentication)." parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string responses: '204': description: rule deleted "/api/v3/admin/promotions": get: summary: List promotions tags: - Promotions security: - api_key: [] bearer_auth: [] description: |- Returns the store's promotions, including manual coupon and automatic promotions. **Required scope:** `read_promotions` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const { data: promotions } = await client.promotions.list() parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string responses: '200': description: promotions found content: application/json: example: data: - id: promo_UkLWZg9DAJ name: Summer Sale description: code: summer starts_at: '2026-05-24T17:37:41.992Z' expires_at: usage_limit: match_policy: all path: kind: coupon_code multi_codes: false number_of_codes: code_prefix: promotion_category_id: metadata: {} created_at: '2026-05-24T17:37:41.993Z' updated_at: '2026-05-24T17:37:41.994Z' store_ids: - store_UkLWZg9DAJ action_ids: [] rule_ids: [] meta: page: 1 limit: 25 count: 1 pages: 1 from: 1 to: 1 in: 1 previous: next: post: summary: Create a promotion tags: - Promotions security: - api_key: [] bearer_auth: [] description: |- Creates a new promotion. `code` is required for single-code coupon promotions; pass `multi_codes: true` with `number_of_codes` to auto-generate a batch. Rules and actions can be created in the same request by passing arrays of `{ type, preferences, ... }` rows. The server reconciles to the desired set: new rows are built, existing rows (by `id`) are updated, omitted rows are removed. **Required scope:** `write_promotions` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) // Single coupon code, no rules/actions const promotion = await client.promotions.create({ name: 'Black Friday', code: 'BLACKFRIDAY', starts_at: '2026-11-29T00:00:00Z', expires_at: '2026-12-01T00:00:00Z', }) // One-shot: promotion + rules + actions in a single request const blackFriday = await client.promotions.create({ name: 'Black Friday', code: 'BLACKFRIDAY', kind: 'coupon_code', starts_at: '2026-11-29T00:00:00Z', expires_at: '2026-12-01T00:00:00Z', match_policy: 'all', rules: [ { type: 'currency', preferences: { currency: 'USD' }, }, { type: 'item_total', preferences: { amount_min: 100, operator_min: 'gte' }, }, { type: 'product', preferences: { match_policy: 'any' }, product_ids: ['prod_abc123', 'prod_def456'], }, ], actions: [ { type: 'create_item_adjustments', calculator: { type: 'percent_on_line_item', preferences: { percent: 25 }, }, }, { type: 'free_shipping' }, ], }) 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: promotion created with rules and actions content: application/json: example: id: promo_gbHJdmfrXB name: Black Friday description: code: blackfriday-os starts_at: '2026-05-24T17:37:42.886Z' expires_at: usage_limit: match_policy: all path: kind: coupon_code multi_codes: false number_of_codes: code_prefix: promotion_category_id: metadata: {} created_at: '2026-05-24T17:37:42.887Z' updated_at: '2026-05-24T17:37:42.905Z' store_ids: - store_UkLWZg9DAJ action_ids: - pact_UkLWZg9DAJ - pact_gbHJdmfrXB rule_ids: - prorule_UkLWZg9DAJ - prorule_gbHJdmfrXB - prorule_EfhxLZ9ck8 '422': description: invalid params content: application/json: example: error: code: validation_error message: Name can't be blank and Code can't be blank details: name: - can't be blank code: - can't be blank requestBody: content: application/json: schema: type: object properties: name: type: string code: type: string nullable: true description: type: string nullable: true starts_at: type: string format: date-time nullable: true expires_at: type: string format: date-time nullable: true usage_limit: type: integer nullable: true match_policy: type: string enum: - all - any kind: type: string enum: - coupon_code - automatic multi_codes: type: boolean number_of_codes: type: integer nullable: true code_prefix: type: string nullable: true promotion_category_id: type: string nullable: true rules: type: array items: type: object properties: type: type: string example: currency preferences: type: object additionalProperties: true product_ids: type: array items: type: string category_ids: type: array items: type: string customer_ids: type: array items: type: string required: - type actions: type: array items: type: object properties: type: type: string example: free_shipping preferences: type: object additionalProperties: true calculator: type: object properties: type: type: string example: flat_percent_item_total preferences: type: object additionalProperties: true required: - type required: - name "/api/v3/admin/promotions/{id}": get: summary: Show a promotion tags: - Promotions security: - api_key: [] bearer_auth: [] description: "**Required scope:** `read_promotions` (for API-key authentication)." parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string - name: id in: path required: true schema: type: string responses: '200': description: promotion found content: application/json: example: id: promo_UkLWZg9DAJ name: Summer Sale description: code: summer starts_at: '2026-05-24T17:37:43.209Z' expires_at: usage_limit: match_policy: all path: kind: coupon_code multi_codes: false number_of_codes: code_prefix: promotion_category_id: metadata: {} created_at: '2026-05-24T17:37:43.209Z' updated_at: '2026-05-24T17:37:43.211Z' store_ids: - store_UkLWZg9DAJ action_ids: [] rule_ids: [] patch: summary: Update a promotion tags: - Promotions security: - api_key: [] bearer_auth: [] description: |- Updates a promotion. The `rules` and `actions` arrays are treated as a *desired set* — rows with `id` update in place, rows without `id` are built fresh, and any existing row not present in the array is destroyed. Pass `rules: []` or `actions: []` to clear them. **Required scope:** `write_promotions` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) // Basic field update await client.promotions.update(promotionId, { description: 'Updated description', }) // One-shot: rewrite rules + actions in a single request await client.promotions.update(promotionId, { name: 'Holiday Sale', rules: [ // Update an existing rule by id — `preferences` overwrite the prior set { id: 'prorule_existing', type: 'currency', preferences: { currency: 'EUR' }, }, // Add a new rule { type: 'item_total', preferences: { amount_min: 50, operator_min: 'gte' }, }, ], actions: [ // Swap calculator type on an existing action { id: 'proaction_existing', type: 'create_item_adjustments', calculator: { type: 'percent_on_line_item', preferences: { percent: 15 }, }, }, ], }) // Remove all rules/actions await client.promotions.update(promotionId, { rules: [], actions: [], }) parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string - name: id in: path required: true schema: type: string responses: '200': description: rules and actions cleared with empty arrays content: application/json: example: id: promo_UkLWZg9DAJ name: Summer Sale description: code: summer starts_at: '2026-05-24T17:37:44.083Z' expires_at: usage_limit: match_policy: all path: kind: coupon_code multi_codes: false number_of_codes: code_prefix: promotion_category_id: metadata: {} created_at: '2026-05-24T17:37:44.084Z' updated_at: '2026-05-24T17:37:44.366Z' store_ids: - store_UkLWZg9DAJ action_ids: [] rule_ids: [] requestBody: content: application/json: schema: type: object properties: name: type: string description: type: string nullable: true code: type: string nullable: true starts_at: type: string format: date-time nullable: true expires_at: type: string format: date-time nullable: true usage_limit: type: integer nullable: true match_policy: type: string enum: - all - any kind: type: string enum: - coupon_code - automatic promotion_category_id: type: string nullable: true rules: type: array items: type: object properties: id: type: string nullable: true description: Pass to update an existing rule; omit to build a new one type: type: string example: currency preferences: type: object additionalProperties: true product_ids: type: array items: type: string category_ids: type: array items: type: string customer_ids: type: array items: type: string required: - type actions: type: array items: type: object properties: id: type: string nullable: true type: type: string example: free_shipping preferences: type: object additionalProperties: true calculator: type: object properties: type: type: string example: flat_percent_item_total preferences: type: object additionalProperties: true required: - type delete: summary: Delete a promotion tags: - Promotions security: - api_key: [] bearer_auth: [] description: "**Required scope:** `write_promotions` (for API-key authentication)." parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string - name: id in: path required: true schema: type: string responses: '204': description: promotion deleted "/api/v3/admin/promotion_actions/types": get: summary: List available promotion action types tags: - Promotions security: - api_key: [] bearer_auth: [] description: |- Returns the registered Spree::PromotionAction subclasses with their preference schemas. Used by admin UIs to populate the "Add action" picker and render generic preference forms. **Required scope:** `read_promotions` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const { data: actionTypes } = await client.promotionActions.types() parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string responses: '200': description: action types found content: application/json: example: data: - type: create_line_items label: Create line items description: preference_schema: [] - type: create_item_adjustments label: Create per-line-item adjustment description: preference_schema: [] - type: create_adjustment label: Create whole-order adjustment description: preference_schema: [] - type: free_shipping label: Free shipping description: preference_schema: [] "/api/v3/admin/promotion_rules/types": get: summary: List available promotion rule types tags: - Promotions security: - api_key: [] bearer_auth: [] description: |- Returns the registered Spree::PromotionRule subclasses with their preference schemas. **Required scope:** `read_promotions` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const { data: ruleTypes } = await client.promotionRules.types() parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string responses: '200': description: rule types found content: application/json: example: data: - type: category label: Categories description: preference_schema: - key: match_policy type: string default: any - type: country label: Country description: preference_schema: - key: country_isos type: array default: [] - key: country_id type: integer default: - key: country_iso type: string default: - type: currency label: Currency description: preference_schema: - key: currency type: string default: - type: customer_group label: Customer Group(s) description: preference_schema: - key: customer_group_ids type: array default: [] - type: customer label: Customers description: preference_schema: [] - type: first_order label: First order description: preference_schema: [] - type: item_total label: Item total description: preference_schema: - key: amount_min type: decimal default: 100.0 - key: operator_min type: string default: ">" - key: amount_max type: decimal default: - key: operator_max type: string default: "<" - type: one_use_per_user label: One Use Per User description: preference_schema: [] - type: customer_logged_in label: Only logged in customers description: preference_schema: [] - type: option_value label: Option Value(s) description: preference_schema: - key: match_policy type: string default: any - key: eligible_values type: array default: [] - type: product label: Product(s) description: preference_schema: - key: match_policy type: string default: any "/api/v3/admin/roles": get: summary: List roles tags: - Configuration security: - api_key: [] bearer_auth: [] description: |- Returns the roles available for staff role pickers. Roles are global, not per-store. **Required scope:** `read_settings` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const { data: roles } = await client.roles.list() parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string responses: '200': description: roles found content: application/json: example: data: - id: role_UkLWZg9DAJ name: admin created_at: '2026-05-24T17:37:45.227Z' updated_at: '2026-05-24T17:37:45.227Z' meta: page: 1 limit: 25 count: 1 pages: 1 from: 1 to: 1 in: 1 previous: next: "/api/v3/admin/stock_locations": get: summary: List stock locations tags: - Configuration security: - api_key: [] bearer_auth: [] description: |- Returns the configured stock locations. Stock locations are global (shared across stores). Filter with Ransack predicates such as `q[active_eq]`, `q[kind_eq]`, `q[pickup_enabled_eq]`, or `q[name_cont]`. Pickup-related attributes (`kind`, `pickup_enabled`, `pickup_stock_policy`, `pickup_ready_in_minutes`, `pickup_instructions`) drive merchant pickup support at checkout — customers can collect orders from any active location with `pickup_enabled: true`. **Required scope:** `read_settings` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const { data: stockLocations } = await client.stockLocations.list() 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 description: Page number schema: type: integer - name: limit in: query required: false description: Number of records per page schema: type: integer - name: q[name_cont] in: query required: false description: Filter by name (contains) schema: type: string - name: q[active_eq] in: query required: false description: Filter by active status schema: type: boolean - name: q[kind_eq] in: query required: false description: 'Filter by kind (built-in: ''warehouse'', ''store'', ''fulfillment_center'')' schema: type: string - name: q[pickup_enabled_eq] in: query required: false description: Filter by pickup-enabled flag schema: type: boolean - name: sort in: query required: false description: Sort by field. Prefix with `-` for descending (e.g., `-created_at`). schema: type: string - name: fields in: query required: false description: Comma-separated list of fields to include. id is always included. schema: type: string responses: '200': description: stock locations found content: application/json: example: data: - id: sloc_UkLWZg9DAJ state_abbr: STATE_ABBR_30 name: Brooklyn warehouse address1: 1600 Pennsylvania Ave NW city: Washington zipcode: '20500' country_iso: US country_name: United States of America state_text: STATE_ABBR_30 admin_name: address2: state_name: phone: "(202) 456-1111" company: active: true default: false backorderable_default: true propagate_all_variants: false kind: warehouse pickup_enabled: false pickup_stock_policy: local pickup_ready_in_minutes: pickup_instructions: created_at: '2026-05-24T17:37:45.507Z' updated_at: '2026-05-24T17:37:45.507Z' meta: page: 1 limit: 25 count: 1 pages: 1 from: 1 to: 1 in: 1 previous: next: schema: type: object properties: data: type: array items: "$ref": "#/components/schemas/StockLocation" meta: "$ref": "#/components/schemas/PaginationMeta" required: - data - meta '401': description: unauthorized content: application/json: example: error: code: authentication_required message: Authentication required schema: "$ref": "#/components/schemas/ErrorResponse" post: summary: Create a stock location tags: - Configuration security: - api_key: [] bearer_auth: [] description: |- Creates a new stock location. Setting `default: true` automatically demotes the previous default location. **Required scope:** `write_settings` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const stockLocation = await client.stockLocations.create({ name: 'Brooklyn warehouse', kind: 'warehouse', country_iso: 'US', state_abbr: 'NY', city: 'Brooklyn', zipcode: '11201', pickup_enabled: true, pickup_stock_policy: 'local', pickup_ready_in_minutes: 60, }) 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 responses: '201': description: stock location created content: application/json: example: id: sloc_gbHJdmfrXB state_abbr: name: Manhattan store address1: city: zipcode: country_iso: country_name: state_text: admin_name: address2: state_name: phone: company: active: true default: false backorderable_default: false propagate_all_variants: false kind: store pickup_enabled: true pickup_stock_policy: local pickup_ready_in_minutes: 30 pickup_instructions: created_at: '2026-05-24T17:37:46.092Z' updated_at: '2026-05-24T17:37:46.092Z' schema: "$ref": "#/components/schemas/StockLocation" '422': description: validation error content: application/json: example: error: code: validation_error message: Name can't be blank details: name: - can't be blank schema: "$ref": "#/components/schemas/ErrorResponse" requestBody: content: application/json: schema: type: object properties: name: type: string example: Brooklyn warehouse admin_name: type: string nullable: true description: Internal name shown only in the admin active: type: boolean example: true default: type: boolean description: Setting to true demotes the previous default. kind: type: string enum: - warehouse - store - fulfillment_center description: Categorizes the location. example: warehouse propagate_all_variants: type: boolean backorderable_default: type: boolean address1: type: string nullable: true address2: type: string nullable: true city: type: string nullable: true zipcode: type: string nullable: true phone: type: string nullable: true company: type: string nullable: true country_iso: type: string nullable: true description: ISO-3166 alpha-2 country code (e.g. "US"). state_abbr: type: string nullable: true description: State / province abbreviation (e.g. "NY"). Resolved against the selected country. state_name: type: string nullable: true description: Free-text state for countries without a states list. pickup_enabled: type: boolean pickup_stock_policy: type: string enum: - local - any description: "'local' = items at this location only; 'any' = transfer-eligible (ship-to-store)." pickup_ready_in_minutes: type: number nullable: true minimum: 0 pickup_instructions: type: string nullable: true required: - name "/api/v3/admin/stock_locations/{id}": parameters: - name: id in: path required: true description: Stock location ID schema: type: string get: summary: Get a stock location tags: - Configuration security: - api_key: [] bearer_auth: [] description: |- Returns a single stock location by prefixed ID. **Required scope:** `read_settings` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const stockLocation = await client.stockLocations.get('sloc_UkLWZg9DAJ') 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: fields in: query required: false description: Comma-separated list of fields to include. id is always included. schema: type: string responses: '200': description: stock location found content: application/json: example: id: sloc_UkLWZg9DAJ state_abbr: STATE_ABBR_34 name: Brooklyn warehouse address1: 1600 Pennsylvania Ave NW city: Washington zipcode: '20500' country_iso: US country_name: United States of America state_text: STATE_ABBR_34 admin_name: address2: state_name: phone: "(202) 456-1111" company: active: true default: false backorderable_default: true propagate_all_variants: false kind: warehouse pickup_enabled: false pickup_stock_policy: local pickup_ready_in_minutes: pickup_instructions: created_at: '2026-05-24T17:37:46.381Z' updated_at: '2026-05-24T17:37:46.381Z' schema: "$ref": "#/components/schemas/StockLocation" '404': description: stock location not found content: application/json: example: error: code: record_not_found message: Stock location not found schema: "$ref": "#/components/schemas/ErrorResponse" patch: summary: Update a stock location tags: - Configuration security: - api_key: [] bearer_auth: [] description: |- Updates an existing stock location. Same address-field conventions as the create endpoint. Setting `default: true` automatically demotes the previous default. **Required scope:** `write_settings` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const stockLocation = await client.stockLocations.update('sloc_UkLWZg9DAJ', { pickup_enabled: true, pickup_ready_in_minutes: 45, pickup_instructions: 'Enter through the back door, ring the bell.', }) 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 responses: '200': description: stock location updated content: application/json: example: id: sloc_UkLWZg9DAJ state_abbr: STATE_ABBR_36 name: Renamed warehouse address1: 1600 Pennsylvania Ave NW city: Washington zipcode: '20500' country_iso: US country_name: United States of America state_text: STATE_ABBR_36 admin_name: address2: state_name: phone: "(202) 456-1111" company: active: true default: false backorderable_default: true propagate_all_variants: false kind: warehouse pickup_enabled: true pickup_stock_policy: local pickup_ready_in_minutes: 45 pickup_instructions: created_at: '2026-05-24T17:37:46.959Z' updated_at: '2026-05-24T17:37:47.265Z' schema: "$ref": "#/components/schemas/StockLocation" '422': description: validation error content: application/json: example: error: code: validation_error message: Pickup stock policy is not included in the list details: pickup_stock_policy: - is not included in the list schema: "$ref": "#/components/schemas/ErrorResponse" requestBody: content: application/json: schema: type: object properties: name: type: string admin_name: type: string nullable: true active: type: boolean default: type: boolean kind: type: string enum: - warehouse - store - fulfillment_center propagate_all_variants: type: boolean backorderable_default: type: boolean address1: type: string nullable: true address2: type: string nullable: true city: type: string nullable: true zipcode: type: string nullable: true phone: type: string nullable: true company: type: string nullable: true country_iso: type: string nullable: true state_abbr: type: string nullable: true state_name: type: string nullable: true pickup_enabled: type: boolean pickup_stock_policy: type: string enum: - local - any pickup_ready_in_minutes: type: number nullable: true minimum: 0 pickup_instructions: type: string nullable: true delete: summary: Delete a stock location tags: - Configuration security: - api_key: [] bearer_auth: [] description: |- Soft-deletes the stock location (sets `deleted_at`). Existing fulfillments that referenced it keep the historical record via `Spree::StockLocation.with_deleted`. **Required scope:** `write_settings` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) await client.stockLocations.delete('sloc_UkLWZg9DAJ') 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 responses: '204': description: stock location deleted "/api/v3/admin/store_credit_categories": get: summary: List store credit categories tags: - Configuration security: - api_key: [] bearer_auth: [] description: |- Returns the configured store credit categories. Categories classify store credits (e.g., "Goodwill", "Gift Card", "Refund") and surface in the admin UI as a dropdown when issuing or editing a store credit. Category names matching `Spree::Config[:non_expiring_credit_types]` are flagged via `non_expiring: true`. **Required scope:** `read_settings` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const { data: categories } = await client.storeCreditCategories.list() 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 description: Page number schema: type: integer - name: limit in: query required: false description: Number of records per page schema: type: integer - name: q[name_cont] in: query required: false description: Filter by name (contains) schema: type: string - name: sort in: query required: false description: Sort by field. Prefix with `-` for descending (e.g., `-created_at`). schema: type: string - name: fields in: query required: false description: Comma-separated list of fields to include. id is always included. schema: type: string responses: '200': description: store credit categories found content: application/json: example: data: - id: sccat_UkLWZg9DAJ name: Goodwill created_at: '2026-05-24T17:37:47.897Z' updated_at: '2026-05-24T17:37:47.897Z' non_expiring: false meta: page: 1 limit: 25 count: 1 pages: 1 from: 1 to: 1 in: 1 previous: next: schema: type: object properties: data: type: array items: "$ref": "#/components/schemas/StoreCreditCategory" meta: "$ref": "#/components/schemas/PaginationMeta" required: - data - meta '401': description: unauthorized content: application/json: example: error: code: authentication_required message: Authentication required schema: "$ref": "#/components/schemas/ErrorResponse" "/api/v3/admin/store_credit_categories/{id}": parameters: - name: id in: path required: true description: Store credit category ID schema: type: string get: summary: Get a store credit category tags: - Configuration security: - api_key: [] bearer_auth: [] description: |- Returns a single store credit category by prefixed ID. **Required scope:** `read_settings` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const category = await client.storeCreditCategories.get('sccat_UkLWZg9DAJ') 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: fields in: query required: false description: Comma-separated list of fields to include. id is always included. schema: type: string responses: '200': description: store credit category found content: application/json: example: id: sccat_UkLWZg9DAJ name: Goodwill created_at: '2026-05-24T17:37:48.191Z' updated_at: '2026-05-24T17:37:48.191Z' non_expiring: false schema: "$ref": "#/components/schemas/StoreCreditCategory" '404': description: store credit category not found content: application/json: example: error: code: record_not_found message: Store credit category not found schema: "$ref": "#/components/schemas/ErrorResponse" "/api/v3/admin/store": get: summary: Get the current store tags: - Configuration security: - api_key: [] bearer_auth: [] description: |- Returns the current store configuration. The store is resolved from the request context (host or admin selection); there is no `id` parameter. **Required scope:** `read_settings` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const store = await client.store.get() 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 responses: '200': description: current store content: application/json: example: id: store_UkLWZg9DAJ metadata: {} name: Spree Test Store default_currency: USD default_locale: en preferred_admin_locale: preferred_timezone: UTC preferred_weight_unit: lb preferred_unit_system: imperial created_at: '2026-05-24T17:36:33.540Z' updated_at: '2026-05-24T17:37:48.768Z' url: http://www.example.com:3000 supported_currencies: - USD supported_locales: - en logo_url: schema: "$ref": "#/components/schemas/Store" '401': description: unauthorized content: application/json: example: error: code: authentication_required message: Authentication required schema: "$ref": "#/components/schemas/ErrorResponse" patch: summary: Update the current store tags: - Configuration security: - api_key: [] bearer_auth: [] description: |- Updates the current store configuration. **Required scope:** `write_settings` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const store = await client.store.update({ name: 'My Store' }) 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 responses: '200': description: store updated content: application/json: example: id: store_UkLWZg9DAJ metadata: {} name: Renamed Store default_currency: USD default_locale: en preferred_admin_locale: preferred_timezone: UTC preferred_weight_unit: lb preferred_unit_system: imperial created_at: '2026-05-24T17:36:33.540Z' updated_at: '2026-05-24T17:37:49.372Z' url: http://www.example.com:3000 supported_currencies: - USD supported_locales: - en logo_url: schema: "$ref": "#/components/schemas/Store" '422': description: validation error content: application/json: example: error: code: validation_error message: Site Name can't be blank details: name: - can't be blank schema: "$ref": "#/components/schemas/ErrorResponse" requestBody: content: application/json: schema: type: object properties: name: type: string example: My Store preferred_admin_locale: type: string example: en preferred_timezone: type: string example: UTC preferred_weight_unit: type: string example: kg preferred_unit_system: type: string example: metric "/api/v3/admin/tags": get: summary: List tags tags: - Configuration security: - api_key: [] bearer_auth: [] description: Returns tag names for a given taggable type. Used for autocomplete in tag inputs on products, orders, and customers. x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const { data: tags } = await client.tags.list({ taggable_type: 'Spree::User', q: 'vip', }) parameters: - name: x-spree-api-key in: header required: true schema: type: string - name: Authorization in: header required: true schema: type: string - name: taggable_type in: query required: true description: Taggable type (`Spree::Product`, `Spree::Order`, or `Spree::User`) schema: type: string - name: q in: query required: false description: Optional case-insensitive substring filter schema: type: string responses: '200': description: tags found content: application/json: example: data: - name: vip - name: wholesale '422': description: invalid taggable type content: application/json: example: error: code: invalid_taggable_type message: taggable_type must be one of Spree::Product, Spree::Order, Spree::LegacyUser "/api/v3/admin/products/{product_id}/variants": get: summary: List product variants tags: - Product Catalog security: - api_key: [] bearer_auth: [] description: |- Returns a paginated list of variants for a product, including the master variant. **Required scope:** `read_products` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const { data: variants } = await client.products.variants.list('prod_86Rf07xd4z', { expand: ['prices', 'stock_items'], }) 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: product_id in: path required: true description: Product ID schema: type: string - name: page in: query required: false description: Page number schema: type: integer - name: limit in: query required: false description: Number of records per page schema: type: integer - name: expand in: query required: false description: Comma-separated associations to expand (e.g., images, prices, stock_items, option_values). 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., sku,price,stock). id is always included. schema: type: string responses: '200': description: variants found content: application/json: example: data: - id: variant_UkLWZg9DAJ product_id: prod_UkLWZg9DAJ sku: SKU-65 options_text: '' track_inventory: true media_count: 0 thumbnail_url: purchasable: false in_stock: false backorderable: false weight: 0.0 height: width: depth: price: id: amount: amount_in_cents: 0 compare_at_amount: compare_at_amount_in_cents: currency: USD display_amount: "$0.00" display_compare_at_amount: price_list_id: original_price: option_values: [] metadata: {} position: 1 cost_price: '17.0' cost_currency: USD barcode: weight_unit: lb dimensions_unit: deleted_at: created_at: '2026-05-24T17:37:50.786Z' updated_at: '2026-05-24T17:37:50.796Z' tax_category_id: taxcat_UkLWZg9DAJ available_stock: 0 reserved_quantity: 0 total_on_hand: 0 product_name: Product 596609 - id: variant_gbHJdmfrXB product_id: prod_UkLWZg9DAJ sku: SKU-66 options_text: 'Size: S' track_inventory: true media_count: 0 thumbnail_url: purchasable: true in_stock: false backorderable: true weight: 79.4 height: 180.38 width: 28.4 depth: 47.4 price: id: price_gbHJdmfrXB amount: '19.99' amount_in_cents: 1999 compare_at_amount: compare_at_amount_in_cents: currency: USD display_amount: "$19.99" display_compare_at_amount: price_list_id: original_price: option_values: - id: optval_UkLWZg9DAJ option_type_id: opt_UkLWZg9DAJ name: size-7 label: S position: 1 color_code: option_type_name: foo-size-16 option_type_label: Size image_url: metadata: {} created_at: '2026-05-24T17:37:50.805Z' updated_at: '2026-05-24T17:37:50.805Z' metadata: {} position: 2 cost_price: '17.0' cost_currency: USD barcode: weight_unit: lb dimensions_unit: deleted_at: created_at: '2026-05-24T17:37:50.803Z' updated_at: '2026-05-24T17:37:50.816Z' tax_category_id: taxcat_UkLWZg9DAJ available_stock: 0 reserved_quantity: 0 total_on_hand: 0 product_name: Product 596609 meta: page: 1 limit: 25 count: 2 pages: 1 from: 1 to: 2 in: 2 previous: next: post: summary: Create a variant tags: - Product Catalog security: - api_key: [] bearer_auth: [] description: |- Creates a new variant for a product. Supports nested prices and stock items. Option types and values are auto-created if they don't exist. Prices are upserted by currency. Stock items are upserted by stock location. **Required scope:** `write_products` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const variant = await client.products.variants.create('prod_86Rf07xd4z', { sku: 'TSHIRT-L-NAVY', options: [ { name: 'size', value: 'Large' }, { name: 'color', value: 'navy' }, ], prices: [ { currency: 'USD', amount: 29.99, compare_at_amount: 34.99 }, { currency: 'EUR', amount: 27.99 }, ], stock_items: [ { stock_location_id: 'sloc_UkLWZg9DAJ', count_on_hand: 25 }, ], }) 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: product_id in: path required: true description: Product ID schema: type: string responses: '201': description: variant created content: application/json: example: id: variant_EfhxLZ9ck8 product_id: prod_UkLWZg9DAJ sku: NEW-SKU-001 options_text: 'Size: XL' track_inventory: true media_count: 0 thumbnail_url: purchasable: false in_stock: false backorderable: false weight: 0.0 height: width: depth: price: id: price_EfhxLZ9ck8 amount: '24.99' amount_in_cents: 2499 compare_at_amount: compare_at_amount_in_cents: currency: USD display_amount: "$24.99" display_compare_at_amount: price_list_id: original_price: option_values: - id: optval_gbHJdmfrXB option_type_id: opt_gbHJdmfrXB name: xl label: XL position: 1 color_code: option_type_name: size option_type_label: Size image_url: metadata: {} created_at: '2026-05-24T17:37:51.471Z' updated_at: '2026-05-24T17:37:51.471Z' metadata: {} position: 3 cost_price: cost_currency: USD barcode: weight_unit: lb dimensions_unit: deleted_at: created_at: '2026-05-24T17:37:51.475Z' updated_at: '2026-05-24T17:37:51.477Z' tax_category_id: taxcat_UkLWZg9DAJ available_stock: 0 reserved_quantity: 0 total_on_hand: 0 product_name: Product 606004 '422': description: validation error content: application/json: example: error: code: validation_error message: Option value variants can't be blank details: option_value_variants: - can't be blank schema: "$ref": "#/components/schemas/ErrorResponse" requestBody: content: application/json: schema: type: object properties: sku: type: string example: SKU-001 price: type: number example: 29.99 compare_at_price: type: number example: 39.99 cost_price: type: number example: 10.0 cost_currency: type: string example: USD weight: type: number height: type: number width: type: number depth: type: number weight_unit: type: string dimensions_unit: type: string track_inventory: type: boolean tax_category_id: type: string options: type: array description: One pair per option type the variant participates in (e.g. size + color). Option types and values are auto-created if missing. items: type: object required: - name - value properties: name: type: string example: size value: type: string example: Small position: type: integer barcode: type: string prices: type: array description: Per-currency prices. Upserted by currency. items: type: object required: - currency - amount properties: currency: type: string example: USD amount: type: number example: 29.99 compare_at_amount: type: number example: 39.99 stock_items: type: array description: Per-stock-location inventory. Upserted by stock_location_id. items: type: object required: - stock_location_id - count_on_hand properties: stock_location_id: type: string description: Stock location ID (e.g. sloc_xxx) count_on_hand: type: integer example: 50 backorderable: type: boolean "/api/v3/admin/products/{product_id}/variants/{id}": get: summary: Get a variant tags: - Product Catalog security: - api_key: [] bearer_auth: [] description: |- Returns a single variant by ID. **Required scope:** `read_products` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const variant = await client.products.variants.get('prod_86Rf07xd4z', 'variant_k5nR8xLq', { expand: ['prices', 'stock_items'], }) 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: product_id in: path required: true description: Product ID schema: type: string - name: id in: path required: true description: Variant ID schema: type: string - name: expand in: query required: false description: Comma-separated associations to expand (e.g., images, prices, stock_items, option_values). 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., sku,price,stock). id is always included. schema: type: string responses: '200': description: variant found content: application/json: example: id: variant_gbHJdmfrXB product_id: prod_UkLWZg9DAJ sku: SKU-72 options_text: 'Size: S' track_inventory: true media_count: 0 thumbnail_url: purchasable: true in_stock: false backorderable: true weight: 181.11 height: 171.7 width: 181.35 depth: 135.86 price: id: price_gbHJdmfrXB amount: '19.99' amount_in_cents: 1999 compare_at_amount: compare_at_amount_in_cents: currency: USD display_amount: "$19.99" display_compare_at_amount: price_list_id: original_price: option_values: - id: optval_UkLWZg9DAJ option_type_id: opt_UkLWZg9DAJ name: size-10 label: S position: 1 color_code: option_type_name: foo-size-19 option_type_label: Size image_url: metadata: {} created_at: '2026-05-24T17:37:51.868Z' updated_at: '2026-05-24T17:37:51.868Z' metadata: {} position: 2 cost_price: '17.0' cost_currency: USD barcode: weight_unit: lb dimensions_unit: deleted_at: created_at: '2026-05-24T17:37:51.866Z' updated_at: '2026-05-24T17:37:51.881Z' tax_category_id: taxcat_UkLWZg9DAJ available_stock: 0 reserved_quantity: 0 total_on_hand: 0 product_name: Product 624851 '404': description: variant not found content: application/json: example: error: code: variant_not_found message: Variant not found schema: "$ref": "#/components/schemas/ErrorResponse" patch: summary: Update a variant tags: - Product Catalog security: - api_key: [] bearer_auth: [] description: |- Updates a variant. Only provided fields are updated. **Required scope:** `write_products` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) const variant = await client.products.variants.update('prod_86Rf07xd4z', 'variant_k5nR8xLq', { sku: 'UPDATED-SKU', stock_items: [ { stock_location_id: 'sloc_UkLWZg9DAJ', count_on_hand: 75 }, ], }) 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: product_id in: path required: true description: Product ID schema: type: string - name: id in: path required: true description: Variant ID schema: type: string responses: '200': description: variant updated content: application/json: example: id: variant_gbHJdmfrXB product_id: prod_UkLWZg9DAJ sku: UPDATED-SKU options_text: 'Size: S' track_inventory: true media_count: 0 thumbnail_url: purchasable: true in_stock: false backorderable: true weight: 58.48 height: 8.7 width: 169.3 depth: 28.62 price: id: price_gbHJdmfrXB amount: '19.99' amount_in_cents: 1999 compare_at_amount: compare_at_amount_in_cents: currency: USD display_amount: "$19.99" display_compare_at_amount: price_list_id: original_price: option_values: - id: optval_UkLWZg9DAJ option_type_id: opt_UkLWZg9DAJ name: size-12 label: S position: 1 color_code: option_type_name: foo-size-21 option_type_label: Size image_url: metadata: {} created_at: '2026-05-24T17:37:52.555Z' updated_at: '2026-05-24T17:37:52.555Z' metadata: {} position: 2 cost_price: '17.0' cost_currency: USD barcode: weight_unit: lb dimensions_unit: deleted_at: created_at: '2026-05-24T17:37:52.553Z' updated_at: '2026-05-24T17:37:52.843Z' tax_category_id: taxcat_UkLWZg9DAJ available_stock: 0 reserved_quantity: 0 total_on_hand: 0 product_name: Product 641234 requestBody: content: application/json: schema: type: object properties: sku: type: string example: SKU-001 price: type: number example: 29.99 compare_at_price: type: number example: 39.99 cost_price: type: number example: 10.0 cost_currency: type: string example: USD weight: type: number height: type: number width: type: number depth: type: number weight_unit: type: string dimensions_unit: type: string track_inventory: type: boolean tax_category_id: type: string options: type: array items: type: object properties: name: type: string example: Size value: type: string example: Large total_on_hand: type: integer example: 100 position: type: integer barcode: type: string prices: type: array items: type: object properties: currency: type: string example: USD amount: type: number example: 29.99 compare_at_amount: type: number example: 39.99 required: - currency - amount stock_items: type: array items: type: object properties: stock_location_id: type: string count_on_hand: type: integer backorderable: type: boolean delete: summary: Delete a variant tags: - Product Catalog security: - api_key: [] bearer_auth: [] description: |- Soft-deletes a variant. **Required scope:** `write_products` (for API-key authentication). x-codeSamples: - lang: javascript label: Spree Admin SDK source: |- import { createAdminClient } from '@spree/admin-sdk' const client = createAdminClient({ baseUrl: 'https://your-store.com', secretKey: 'sk_xxx', }) await client.products.variants.delete('prod_86Rf07xd4z', 'variant_k5nR8xLq') 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: product_id in: path required: true description: Product ID schema: type: string - name: id in: path required: true description: Variant ID schema: type: string responses: '204': description: variant deleted servers: - url: http://{defaultHost} variables: defaultHost: default: localhost:3000 tags: - name: Authentication description: Admin user authentication - name: Product Catalog description: Products, variants, and option types - name: Orders description: Order management — orders, items, payments, fulfillments, refunds, gift cards, store credits - name: Customers description: Customer management — profiles, addresses, store credits, credit cards - name: Configuration description: Store configuration — payment methods, tag autocomplete x-tagGroups: - name: Authentication tags: - Authentication - name: Product Catalog tags: - Product Catalog - name: Orders tags: - Orders - name: Customers tags: - Customers - name: Configuration tags: - Configuration components: securitySchemes: api_key: type: apiKey name: x-spree-api-key in: header description: Secret API key for admin access bearer_auth: type: http scheme: bearer bearerFormat: JWT description: JWT token for admin user authentication schemas: PaginationMeta: type: object properties: page: type: integer example: 1 limit: type: integer example: 25 count: type: integer example: 100 description: Total number of records pages: type: integer example: 4 description: Total number of pages from: type: integer example: 1 description: Index of first record on this page to: type: integer example: 25 description: Index of last record on this page in: type: integer example: 25 description: Number of records on this page previous: type: integer nullable: true example: description: Previous page number next: type: integer nullable: true example: 2 description: Next page number required: - page - limit - count - pages - from - to - in ErrorResponse: type: object properties: error: type: object properties: code: type: string example: record_not_found message: type: string example: Record not found details: type: object description: Field-specific validation errors nullable: true example: name: - is too short - is required email: - is invalid required: - code - message required: - error example: error: code: validation_error message: Validation failed details: name: - is too short email: - is invalid AuthResponse: type: object properties: token: type: string description: JWT access token refresh_token: type: string description: Refresh token for obtaining new access tokens user: "$ref": "#/components/schemas/AdminUser" required: - token - refresh_token - user PermissionRule: type: object description: A single permission rule (CanCanCan rule). Rules are applied in order, last-matching-wins. properties: allow: type: boolean description: true for `can`, false for `cannot` actions: type: array items: type: string description: Action names, e.g. ["read", "update"] or ["manage"] subjects: type: array items: type: string description: Subject class names, e.g. ["Spree::Product"] or ["all"] has_conditions: type: boolean description: True if the server-side rule has per-record conditions. The SPA shows the action optimistically and handles 403 from the API. required: - allow - actions - subjects - has_conditions MeResponse: type: object description: Current admin user profile and serialized permissions properties: user: "$ref": "#/components/schemas/AdminUser" permissions: type: array items: "$ref": "#/components/schemas/PermissionRule" required: - user - permissions CheckoutRequirement: type: object properties: step: type: string description: Checkout step this requirement belongs to example: payment field: type: string description: Field that needs to be satisfied example: payment message: type: string description: Human-readable requirement message example: Add a payment method required: - step - field - message CartWarning: type: object description: A warning about a cart issue (e.g., item removed due to stock change) properties: code: type: string description: Machine-readable warning code example: line_item_removed message: type: string description: Human-readable warning message example: Blue T-Shirt was removed because it was sold out line_item_id: type: string nullable: true description: Prefixed line item ID (when applicable) example: li_abc123 variant_id: type: string nullable: true description: Prefixed variant ID (when applicable) example: variant_abc123 required: - code - message FulfillmentManifestItem: type: object description: An item within a fulfillment — which line item and how many units are in this fulfillment properties: item_id: type: string description: Line item ID example: li_abc123 variant_id: type: string description: Variant ID example: variant_abc123 quantity: type: integer description: Quantity in this fulfillment example: 2 required: - item_id - variant_id - quantity AdminUserRoleAssignment: type: object description: A role assignment for the current store on a staff member properties: id: type: string description: Prefixed role ID example: role_abc123 name: type: string description: Role name example: admin required: - id - name PreferenceField: type: object description: A single configurable preference on a payment method, promotion rule/action, or calculator. The frontend uses `type` + `default` to render a sensible input. properties: key: type: string example: amount_min type: type: string example: decimal description: string | text | password | integer | decimal | boolean | array | hash default: description: Default value (any JSON type), null when there is no default nullable: true required: - key - type PromotionActionCalculator: type: object description: The action's nested calculator (when the action carries one — null for actions like `free_shipping`) properties: type: type: string example: flat_rate description: Wire shorthand for the calculator subclass label: type: string example: Flat Rate preferences: type: object additionalProperties: true preference_schema: type: array items: "$ref": "#/components/schemas/PreferenceField" required: - type - label - preferences - preference_schema PromotionActionLineItem: type: object description: One row in a `create_line_items` action — the variant added to the order and how many properties: variant_id: type: string example: variant_abc123 quantity: type: integer example: 1 required: - variant_id - quantity Address: type: object properties: id: type: string first_name: type: string nullable: true last_name: type: string nullable: true full_name: type: string address1: type: string nullable: true address2: type: string nullable: true postal_code: type: string nullable: true city: type: string nullable: true phone: type: string nullable: true company: type: string nullable: true country_name: type: string country_iso: type: string state_text: type: string nullable: true state_abbr: type: string nullable: true quick_checkout: type: boolean is_default_billing: type: boolean is_default_shipping: type: boolean state_name: type: string nullable: true label: type: string nullable: true metadata: type: object created_at: type: string updated_at: type: string customer_id: type: string nullable: true required: - id - first_name - last_name - full_name - address1 - address2 - postal_code - city - phone - company - country_name - country_iso - state_text - state_abbr - quick_checkout - is_default_billing - is_default_shipping - state_name - label - metadata - created_at - updated_at - customer_id x-typelizer: true Adjustment: type: object properties: id: type: string label: type: string display_amount: type: string included: type: boolean created_at: type: string updated_at: type: string amount: type: string order_id: type: string nullable: true required: - id - label - display_amount - included - created_at - updated_at - amount - order_id x-typelizer: true AdminUser: type: object properties: id: type: string email: type: string first_name: type: string nullable: true last_name: type: string nullable: true full_name: type: string nullable: true created_at: type: string updated_at: type: string roles: type: array items: "$ref": "#/components/schemas/AdminUserRoleAssignment" required: - id - email - first_name - last_name - full_name - created_at - updated_at - roles x-typelizer: true AllowedOrigin: type: object properties: id: type: string origin: type: object created_at: type: string updated_at: type: string store_id: type: string required: - id - origin - created_at - updated_at - store_id x-typelizer: true ApiKey: type: object properties: id: type: string name: type: string key_type: type: string token_prefix: type: string nullable: true scopes: type: array items: type: string created_at: type: string updated_at: type: string revoked_at: type: string nullable: true last_used_at: type: string nullable: true plaintext_token: type: string nullable: true created_by_email: type: string nullable: true required: - id - name - key_type - token_prefix - scopes - created_at - updated_at - revoked_at - last_used_at - plaintext_token - created_by_email x-typelizer: true Category: type: object properties: id: type: string name: type: string permalink: type: string position: type: number depth: type: number meta_title: type: string nullable: true meta_description: type: string nullable: true meta_keywords: type: string nullable: true children_count: type: number parent_id: type: string nullable: true description: type: string description_html: type: string image_url: type: string nullable: true square_image_url: type: string nullable: true is_root: type: boolean is_child: type: boolean is_leaf: type: boolean parent: "$ref": "#/components/schemas/Category" children: type: array items: "$ref": "#/components/schemas/Category" ancestors: type: array items: "$ref": "#/components/schemas/Category" custom_fields: type: array items: "$ref": "#/components/schemas/CustomField" metadata: type: object pretty_name: type: string lft: type: number rgt: type: number created_at: type: string updated_at: type: string required: - id - name - permalink - position - depth - meta_title - meta_description - meta_keywords - children_count - parent_id - description - description_html - image_url - square_image_url - is_root - is_child - is_leaf - metadata - pretty_name - lft - rgt - created_at - updated_at x-typelizer: true Channel: type: object properties: id: type: string name: type: string code: type: string active: type: boolean preferred_order_routing_strategy: type: string nullable: true created_at: type: string updated_at: type: string store_id: type: string required: - id - name - code - active - preferred_order_routing_strategy - created_at - updated_at - store_id x-typelizer: true Country: type: object properties: iso: type: string iso3: type: string name: type: string states_required: type: boolean zipcode_required: type: boolean states: type: array items: "$ref": "#/components/schemas/State" market: allOf: - "$ref": "#/components/schemas/Market" nullable: true created_at: type: object updated_at: type: object required: - iso - iso3 - name - states_required - zipcode_required - created_at - updated_at x-typelizer: true CouponCode: type: object properties: id: type: string code: type: string state: type: string nullable: true created_at: type: string updated_at: type: string promotion_id: type: string order_id: type: string nullable: true required: - id - code - state - created_at - updated_at - promotion_id - order_id x-typelizer: true CreditCard: type: object properties: id: type: string brand: type: string last4: type: string month: type: number year: type: number name: type: string nullable: true default: type: boolean gateway_payment_profile_id: type: string nullable: true customer_id: type: string nullable: true payment_method_id: type: string nullable: true metadata: type: object created_at: type: string updated_at: type: string required: - id - brand - last4 - month - year - name - default - gateway_payment_profile_id - customer_id - payment_method_id - metadata - created_at - updated_at x-typelizer: true CustomFieldDefinition: type: object properties: id: type: string namespace: type: string key: type: string label: type: string field_type: type: string enum: - short_text - long_text - rich_text - number - boolean - json resource_type: type: string storefront_visible: type: boolean created_at: type: string updated_at: type: string required: - id - namespace - key - label - field_type - resource_type - storefront_visible - created_at - updated_at x-typelizer: true CustomField: type: object properties: id: type: string label: type: string type: type: string deprecated: true field_type: type: string enum: - short_text - long_text - rich_text - number - boolean - json key: type: string value: type: object created_at: type: string updated_at: type: string storefront_visible: type: boolean custom_field_definition_id: type: string required: - id - label - type - field_type - key - value - created_at - updated_at - storefront_visible - custom_field_definition_id x-typelizer: true CustomerGroup: type: object properties: id: type: string name: type: string description: type: string nullable: true customers_count: type: number created_at: type: string updated_at: type: string customers: type: array items: "$ref": "#/components/schemas/Customer" required: - id - name - description - customers_count - created_at - updated_at x-typelizer: true Customer: type: object properties: id: type: string email: type: string first_name: type: string nullable: true last_name: type: string nullable: true phone: type: string nullable: true accepts_email_marketing: type: boolean full_name: type: string available_store_credit_total: type: string display_available_store_credit_total: type: string addresses: type: array items: "$ref": "#/components/schemas/Address" default_billing_address: allOf: - "$ref": "#/components/schemas/Address" nullable: true default_shipping_address: allOf: - "$ref": "#/components/schemas/Address" nullable: true login: type: string nullable: true metadata: type: object last_sign_in_at: type: string nullable: true current_sign_in_at: type: string nullable: true created_at: type: string updated_at: type: string sign_in_count: type: number failed_attempts: type: number last_sign_in_ip: type: string nullable: true current_sign_in_ip: type: string nullable: true tags: type: array items: type: string internal_note_html: type: string nullable: true default_billing_address_id: type: string nullable: true default_shipping_address_id: type: string nullable: true orders_count: type: number total_spent: type: string display_total_spent: type: string last_order_completed_at: type: string nullable: true orders: type: array items: "$ref": "#/components/schemas/Order" store_credits: type: array items: "$ref": "#/components/schemas/StoreCredit" customer_groups: type: array items: "$ref": "#/components/schemas/CustomerGroup" required: - id - email - first_name - last_name - phone - accepts_email_marketing - full_name - available_store_credit_total - display_available_store_credit_total - login - metadata - last_sign_in_at - current_sign_in_at - created_at - updated_at - sign_in_count - failed_attempts - last_sign_in_ip - current_sign_in_ip - tags - internal_note_html - default_billing_address_id - default_shipping_address_id - orders_count - total_spent - display_total_spent - last_order_completed_at x-typelizer: true DeliveryMethod: type: object properties: id: type: string name: type: string code: type: string nullable: true created_at: type: string updated_at: type: string required: - id - name - code - created_at - updated_at x-typelizer: true DeliveryRate: type: object properties: id: type: string delivery_method_id: type: string name: type: string selected: type: boolean cost: type: string total: type: string additional_tax_total: type: string included_tax_total: type: string tax_total: type: string display_cost: type: string display_total: type: string display_additional_tax_total: type: string display_included_tax_total: type: string display_tax_total: type: string delivery_method: "$ref": "#/components/schemas/DeliveryMethod" created_at: type: string updated_at: type: string required: - id - delivery_method_id - name - selected - cost - total - additional_tax_total - included_tax_total - tax_total - display_cost - display_total - display_additional_tax_total - display_included_tax_total - display_tax_total - created_at - updated_at x-typelizer: true DigitalLink: type: object properties: id: type: string access_counter: type: number filename: type: string content_type: type: string download_url: type: string authorizable: type: boolean expired: type: boolean access_limit_exceeded: type: boolean created_at: type: string updated_at: type: string required: - id - access_counter - filename - content_type - download_url - authorizable - expired - access_limit_exceeded - created_at - updated_at x-typelizer: true Discount: type: object properties: id: type: string promotion_id: type: string name: type: string description: type: string nullable: true code: type: string nullable: true amount: type: string display_amount: type: string created_at: type: string updated_at: type: string required: - id - promotion_id - name - description - code - amount - display_amount - created_at - updated_at x-typelizer: true Export: type: object properties: id: type: string number: type: string type: type: string nullable: true format: type: string nullable: true created_at: type: string updated_at: type: string user_id: type: string nullable: true done: type: boolean filename: type: string nullable: true byte_size: type: number nullable: true download_url: type: string nullable: true required: - id - number - type - format - created_at - updated_at - user_id - done - filename - byte_size - download_url x-typelizer: true Fulfillment: type: object properties: id: type: string number: type: string tracking: type: string nullable: true tracking_url: type: string nullable: true cost: type: string display_cost: type: string total: type: string display_total: type: string discount_total: type: string display_discount_total: type: string additional_tax_total: type: string display_additional_tax_total: type: string included_tax_total: type: string display_included_tax_total: type: string tax_total: type: string display_tax_total: type: string status: type: string fulfillment_type: type: string fulfilled_at: type: string nullable: true items: type: array items: "$ref": "#/components/schemas/FulfillmentManifestItem" delivery_method: "$ref": "#/components/schemas/DeliveryMethod" stock_location: "$ref": "#/components/schemas/StockLocation" delivery_rates: type: array items: "$ref": "#/components/schemas/DeliveryRate" metadata: type: object adjustment_total: type: string pre_tax_amount: type: string created_at: type: string updated_at: type: string order_id: type: string nullable: true stock_location_id: type: string nullable: true order: "$ref": "#/components/schemas/Order" adjustments: type: array items: "$ref": "#/components/schemas/Adjustment" required: - id - number - tracking - tracking_url - cost - display_cost - total - display_total - discount_total - display_discount_total - additional_tax_total - display_additional_tax_total - included_tax_total - display_included_tax_total - tax_total - display_tax_total - status - fulfillment_type - fulfilled_at - items - metadata - adjustment_total - pre_tax_amount - created_at - updated_at - order_id - stock_location_id x-typelizer: true GiftCardBatch: type: object properties: id: type: string codes_count: type: number currency: type: string nullable: true prefix: type: string nullable: true created_at: type: string updated_at: type: string amount: type: string nullable: true expires_at: type: string nullable: true created_by_id: type: string nullable: true required: - id - codes_count - currency - prefix - created_at - updated_at - amount - expires_at - created_by_id x-typelizer: true GiftCard: type: object properties: id: type: string code: type: string status: type: string currency: type: string amount: type: string amount_used: type: string amount_authorized: type: string amount_remaining: type: string display_amount: type: string display_amount_used: type: string display_amount_remaining: type: string expires_at: type: string nullable: true redeemed_at: type: string nullable: true expired: type: boolean active: type: boolean created_at: type: string updated_at: type: string customer_id: type: string nullable: true created_by_id: type: string nullable: true customer: "$ref": "#/components/schemas/Customer" created_by: "$ref": "#/components/schemas/AdminUser" gift_card_batch: "$ref": "#/components/schemas/GiftCardBatch" orders: type: array items: "$ref": "#/components/schemas/Order" required: - id - code - status - currency - amount - amount_used - amount_authorized - amount_remaining - display_amount - display_amount_used - display_amount_remaining - expires_at - redeemed_at - expired - active - created_at - updated_at - customer_id - created_by_id x-typelizer: true Invitation: type: object properties: id: type: string email: type: string status: type: string created_at: type: string updated_at: type: string expires_at: type: string role_id: type: string role_name: type: string inviter_email: type: string acceptance_url: type: string invitee_exists: type: boolean store: type: object required: - id - email - status - created_at - updated_at - expires_at - role_id - role_name - inviter_email - acceptance_url - invitee_exists - store x-typelizer: true LineItem: type: object properties: id: type: string variant_id: type: string quantity: type: number currency: type: string name: type: string slug: type: string options_text: type: string price: type: string display_price: type: string total: type: string display_total: type: string adjustment_total: type: string display_adjustment_total: type: string additional_tax_total: type: string display_additional_tax_total: type: string included_tax_total: type: string display_included_tax_total: type: string discount_total: type: string display_discount_total: type: string pre_tax_amount: type: string display_pre_tax_amount: type: string discounted_amount: type: string display_discounted_amount: type: string display_compare_at_amount: type: string nullable: true compare_at_amount: type: string nullable: true thumbnail_url: type: string nullable: true option_values: type: array items: "$ref": "#/components/schemas/OptionValue" digital_links: type: array items: "$ref": "#/components/schemas/DigitalLink" metadata: type: object created_at: type: string updated_at: type: string cost_price: type: string nullable: true tax_category_id: type: string nullable: true variant: "$ref": "#/components/schemas/Variant" tax_category: "$ref": "#/components/schemas/TaxCategory" adjustments: type: array items: "$ref": "#/components/schemas/Adjustment" required: - id - variant_id - quantity - currency - name - slug - options_text - price - display_price - total - display_total - adjustment_total - display_adjustment_total - additional_tax_total - display_additional_tax_total - included_tax_total - display_included_tax_total - discount_total - display_discount_total - pre_tax_amount - display_pre_tax_amount - discounted_amount - display_discounted_amount - display_compare_at_amount - compare_at_amount - thumbnail_url - option_values - digital_links - metadata - created_at - updated_at - cost_price - tax_category_id x-typelizer: true Market: type: object properties: id: type: string name: type: string currency: type: string default_locale: type: string tax_inclusive: type: boolean default: type: boolean supported_locales: type: array items: type: string countries: type: array items: "$ref": "#/components/schemas/Country" created_at: type: string updated_at: type: string required: - id - name - currency - default_locale - tax_inclusive - default - supported_locales - created_at - updated_at x-typelizer: true Media: type: object properties: id: type: string product_id: type: string nullable: true variant_ids: type: array items: type: string position: type: number alt: type: string nullable: true media_type: type: string focal_point_x: type: number nullable: true focal_point_y: type: number nullable: true external_video_url: type: string nullable: true original_url: type: string nullable: true mini_url: type: string nullable: true small_url: type: string nullable: true medium_url: type: string nullable: true large_url: type: string nullable: true xlarge_url: type: string nullable: true og_image_url: type: string nullable: true created_at: type: string updated_at: type: string viewable_id: type: string download_url: type: string nullable: true metadata: type: object viewable_type: type: string required: - id - product_id - variant_ids - position - alt - media_type - focal_point_x - focal_point_y - external_video_url - original_url - mini_url - small_url - medium_url - large_url - xlarge_url - og_image_url - created_at - updated_at - viewable_id - download_url - metadata - viewable_type x-typelizer: true OptionType: type: object properties: id: type: string name: type: string label: type: string position: type: number kind: type: string metadata: type: object filterable: type: boolean created_at: type: string updated_at: type: string option_values: type: array items: "$ref": "#/components/schemas/OptionValue" required: - id - name - label - position - kind - metadata - filterable - created_at - updated_at x-typelizer: true OptionValue: type: object properties: id: type: string option_type_id: type: string name: type: string label: type: string position: type: number color_code: type: string nullable: true option_type_name: type: string option_type_label: type: string image_url: type: string nullable: true metadata: type: object created_at: type: string updated_at: type: string option_type: "$ref": "#/components/schemas/OptionType" required: - id - option_type_id - name - label - position - color_code - option_type_name - option_type_label - image_url - metadata - created_at - updated_at x-typelizer: true Order: type: object properties: id: type: string market_id: type: string nullable: true channel_id: type: string nullable: true number: type: string email: type: string customer_note: type: string nullable: true currency: type: string locale: type: string nullable: true total_quantity: type: number item_total: type: string display_item_total: type: string adjustment_total: type: string display_adjustment_total: type: string discount_total: type: string display_discount_total: type: string tax_total: type: string display_tax_total: type: string included_tax_total: type: string display_included_tax_total: type: string additional_tax_total: type: string display_additional_tax_total: type: string total: type: string display_total: type: string gift_card_total: type: string display_gift_card_total: type: string amount_due: type: string display_amount_due: type: string delivery_total: type: string display_delivery_total: type: string fulfillment_status: type: string nullable: true payment_status: type: string nullable: true completed_at: type: string nullable: true store_credit_total: type: string display_store_credit_total: type: string covered_by_store_credit: type: boolean discounts: type: array items: "$ref": "#/components/schemas/Discount" items: type: array items: "$ref": "#/components/schemas/LineItem" fulfillments: type: array items: "$ref": "#/components/schemas/Fulfillment" payments: type: array items: "$ref": "#/components/schemas/Payment" billing_address: allOf: - "$ref": "#/components/schemas/Address" nullable: true shipping_address: allOf: - "$ref": "#/components/schemas/Address" nullable: true gift_card: allOf: - "$ref": "#/components/schemas/GiftCard" nullable: true market: allOf: - "$ref": "#/components/schemas/Market" nullable: true status: type: string last_ip_address: type: string nullable: true considered_risky: type: boolean confirmation_delivered: type: boolean store_owner_notification_delivered: type: boolean payment_total: type: string display_payment_total: type: string metadata: type: object canceled_at: type: string nullable: true approved_at: type: string nullable: true created_at: type: string updated_at: type: string preferred_stock_location_id: type: string nullable: true tags: type: array items: type: string internal_note: type: string nullable: true approver_id: type: string nullable: true canceler_id: type: string nullable: true created_by_id: type: string nullable: true customer_id: type: string nullable: true channel: "$ref": "#/components/schemas/Channel" preferred_stock_location: "$ref": "#/components/schemas/StockLocation" payment_methods: type: array items: "$ref": "#/components/schemas/PaymentMethod" customer: "$ref": "#/components/schemas/Customer" approver: "$ref": "#/components/schemas/Customer" canceler: "$ref": "#/components/schemas/Customer" created_by: "$ref": "#/components/schemas/Customer" adjustments: type: array items: "$ref": "#/components/schemas/Adjustment" return_authorizations: type: array items: "$ref": "#/components/schemas/ReturnAuthorization" reimbursements: type: array items: "$ref": "#/components/schemas/Reimbursement" required: - id - market_id - channel_id - number - email - customer_note - currency - locale - total_quantity - item_total - display_item_total - adjustment_total - display_adjustment_total - discount_total - display_discount_total - tax_total - display_tax_total - included_tax_total - display_included_tax_total - additional_tax_total - display_additional_tax_total - total - display_total - gift_card_total - display_gift_card_total - amount_due - display_amount_due - delivery_total - display_delivery_total - fulfillment_status - payment_status - completed_at - store_credit_total - display_store_credit_total - covered_by_store_credit - gift_card - market - status - last_ip_address - considered_risky - confirmation_delivered - store_owner_notification_delivered - payment_total - display_payment_total - metadata - canceled_at - approved_at - created_at - updated_at - preferred_stock_location_id - tags - internal_note - approver_id - canceler_id - created_by_id - customer_id x-typelizer: true PaymentMethod: type: object properties: id: type: string name: type: string description: type: string nullable: true type: type: string session_required: type: boolean source_required: type: boolean metadata: type: object active: type: boolean auto_capture: type: boolean nullable: true storefront_visible: type: boolean position: type: number created_at: type: string updated_at: type: string preferences: type: object preference_schema: type: object required: - id - name - description - type - session_required - source_required - metadata - active - auto_capture - storefront_visible - position - created_at - updated_at - preferences - preference_schema x-typelizer: true Payment: type: object properties: id: type: string payment_method_id: type: string response_code: type: string nullable: true number: type: string amount: type: string display_amount: type: string status: type: string source_type: type: string nullable: true enum: - credit_card - store_credit - payment_source source_id: type: string nullable: true source: anyOf: - "$ref": "#/components/schemas/CreditCard" - "$ref": "#/components/schemas/StoreCredit" - "$ref": "#/components/schemas/PaymentSource" nullable: true payment_method: "$ref": "#/components/schemas/PaymentMethod" metadata: type: object avs_response: type: string nullable: true cvv_response_code: type: string nullable: true cvv_response_message: type: string nullable: true created_at: type: string updated_at: type: string captured_amount: type: string order_id: type: string nullable: true order: "$ref": "#/components/schemas/Order" refunds: type: array items: "$ref": "#/components/schemas/Refund" required: - id - payment_method_id - response_code - number - amount - display_amount - status - source_type - source_id - source - metadata - avs_response - cvv_response_code - cvv_response_message - created_at - updated_at - captured_amount - order_id x-typelizer: true PaymentSource: type: object properties: id: type: string gateway_payment_profile_id: type: string nullable: true metadata: type: object created_at: type: string updated_at: type: string required: - id - gateway_payment_profile_id - metadata - created_at - updated_at x-typelizer: true PriceHistory: type: object properties: id: type: string amount: type: string amount_in_cents: type: number currency: type: string display_amount: type: string recorded_at: type: string variant_id: type: string price_id: type: string compare_at_amount: type: string nullable: true created_at: type: string required: - id - amount - amount_in_cents - currency - display_amount - recorded_at - variant_id - price_id - compare_at_amount - created_at x-typelizer: true Price: type: object properties: id: type: string amount: type: string nullable: true amount_in_cents: type: number nullable: true compare_at_amount: type: string nullable: true compare_at_amount_in_cents: type: number nullable: true currency: type: string nullable: true display_amount: type: string nullable: true display_compare_at_amount: type: string nullable: true price_list_id: type: string nullable: true variant_id: type: string nullable: true created_at: type: string updated_at: type: string variant: "$ref": "#/components/schemas/Variant" required: - id - amount - amount_in_cents - compare_at_amount - compare_at_amount_in_cents - currency - display_amount - display_compare_at_amount - price_list_id - variant_id - created_at - updated_at x-typelizer: true Product: type: object properties: id: type: string name: type: string slug: type: string meta_title: type: string nullable: true meta_description: type: string nullable: true meta_keywords: type: string nullable: true variant_count: type: number available_on: type: string nullable: true purchasable: type: boolean in_stock: type: boolean backorderable: type: boolean available: type: boolean description: type: string nullable: true description_html: type: string nullable: true default_variant_id: type: string thumbnail_url: type: string nullable: true tags: type: array items: type: string price: allOf: - "$ref": "#/components/schemas/Price" nullable: true original_price: allOf: - "$ref": "#/components/schemas/Price" nullable: true primary_media: "$ref": "#/components/schemas/Media" media: type: array items: "$ref": "#/components/schemas/Media" variants: type: array items: "$ref": "#/components/schemas/Variant" default_variant: "$ref": "#/components/schemas/Variant" option_types: type: array items: "$ref": "#/components/schemas/OptionType" categories: type: array items: "$ref": "#/components/schemas/Category" custom_fields: type: array items: "$ref": "#/components/schemas/CustomField" prior_price: allOf: - "$ref": "#/components/schemas/PriceHistory" nullable: true status: type: string make_active_at: type: string nullable: true discontinue_on: type: string nullable: true metadata: type: object deleted_at: type: string nullable: true created_at: type: string updated_at: type: string tax_category_id: type: string nullable: true required: - id - name - slug - meta_title - meta_description - meta_keywords - variant_count - available_on - purchasable - in_stock - backorderable - available - description - description_html - default_variant_id - thumbnail_url - tags - price - original_price - status - make_active_at - discontinue_on - metadata - deleted_at - created_at - updated_at - tax_category_id x-typelizer: true PromotionAction: type: object properties: id: type: string created_at: type: string updated_at: type: string type: type: string promotion_id: type: string preferences: type: object preference_schema: type: array items: "$ref": "#/components/schemas/PreferenceField" label: type: string calculator: allOf: - "$ref": "#/components/schemas/PromotionActionCalculator" nullable: true line_items: type: array items: "$ref": "#/components/schemas/PromotionActionLineItem" nullable: true required: - id - created_at - updated_at - type - promotion_id - preferences - preference_schema - label - calculator - line_items x-typelizer: true PromotionRule: type: object properties: id: type: string created_at: type: string updated_at: type: string type: type: string promotion_id: type: string preferences: type: object preference_schema: type: array items: "$ref": "#/components/schemas/PreferenceField" label: type: string product_ids: type: array items: type: string nullable: true category_ids: type: array items: type: string nullable: true customer_ids: type: array items: type: string nullable: true products: type: array items: "$ref": "#/components/schemas/Product" categories: type: array items: "$ref": "#/components/schemas/Category" customers: type: array items: "$ref": "#/components/schemas/Customer" customer_groups: type: array items: "$ref": "#/components/schemas/CustomerGroup" countries: type: array items: "$ref": "#/components/schemas/Country" required: - id - created_at - updated_at - type - promotion_id - preferences - preference_schema - label - product_ids - category_ids - customer_ids x-typelizer: true Promotion: type: object properties: id: type: string name: type: string description: type: string nullable: true code: type: string nullable: true starts_at: type: string nullable: true expires_at: type: string nullable: true usage_limit: type: number nullable: true match_policy: type: string enum: - all - any path: type: string nullable: true kind: type: string enum: - coupon_code - automatic multi_codes: type: boolean number_of_codes: type: number nullable: true code_prefix: type: string nullable: true promotion_category_id: type: string nullable: true metadata: type: object created_at: type: string updated_at: type: string store_ids: type: array items: type: string action_ids: type: array items: type: string rule_ids: type: array items: type: string required: - id - name - description - code - starts_at - expires_at - usage_limit - match_policy - path - kind - multi_codes - number_of_codes - code_prefix - promotion_category_id - metadata - created_at - updated_at - store_ids - action_ids - rule_ids x-typelizer: true Refund: type: object properties: id: type: string transaction_id: type: string nullable: true amount: type: string nullable: true payment_id: type: string nullable: true refund_reason_id: type: string nullable: true reimbursement_id: type: string nullable: true metadata: type: object created_at: type: string updated_at: type: string payment: "$ref": "#/components/schemas/Payment" reimbursement: "$ref": "#/components/schemas/Reimbursement" required: - id - transaction_id - amount - payment_id - refund_reason_id - reimbursement_id - metadata - created_at - updated_at x-typelizer: true Reimbursement: type: object properties: id: type: string number: type: string reimbursement_status: type: string nullable: true total: type: string nullable: true order_id: type: string nullable: true customer_return_id: type: string nullable: true created_at: type: string updated_at: type: string order: "$ref": "#/components/schemas/Order" required: - id - number - reimbursement_status - total - order_id - customer_return_id - created_at - updated_at x-typelizer: true ReturnAuthorization: type: object properties: id: type: string number: type: string status: type: string order_id: type: string nullable: true stock_location_id: type: string nullable: true return_authorization_reason_id: type: string nullable: true created_at: type: string updated_at: type: string order: "$ref": "#/components/schemas/Order" stock_location: "$ref": "#/components/schemas/StockLocation" required: - id - number - status - order_id - stock_location_id - return_authorization_reason_id - created_at - updated_at x-typelizer: true Role: type: object properties: id: type: string name: type: string created_at: type: string updated_at: type: string required: - id - name - created_at - updated_at x-typelizer: true State: type: object properties: abbr: type: string name: type: string created_at: type: object updated_at: type: object required: - abbr - name - created_at - updated_at x-typelizer: true StockItem: type: object properties: id: type: string count_on_hand: type: number backorderable: type: boolean stock_location_id: type: string nullable: true variant_id: type: string nullable: true metadata: type: object created_at: type: string updated_at: type: string allocated_count: type: number available_count: type: number stock_location: "$ref": "#/components/schemas/StockLocation" variant: "$ref": "#/components/schemas/Variant" required: - id - count_on_hand - backorderable - stock_location_id - variant_id - metadata - created_at - updated_at - allocated_count - available_count x-typelizer: true StockLocation: type: object properties: id: type: string state_abbr: type: string nullable: true name: type: string address1: type: string nullable: true city: type: string nullable: true zipcode: type: string nullable: true country_iso: type: string nullable: true country_name: type: string nullable: true state_text: type: string nullable: true admin_name: type: string nullable: true address2: type: string nullable: true state_name: type: string nullable: true phone: type: string nullable: true company: type: string nullable: true active: type: boolean default: type: boolean backorderable_default: type: boolean propagate_all_variants: type: boolean kind: type: string pickup_enabled: type: boolean pickup_stock_policy: type: string pickup_ready_in_minutes: type: number nullable: true pickup_instructions: type: string nullable: true created_at: type: string updated_at: type: string required: - id - state_abbr - name - address1 - city - zipcode - country_iso - country_name - state_text - admin_name - address2 - state_name - phone - company - active - default - backorderable_default - propagate_all_variants - kind - pickup_enabled - pickup_stock_policy - pickup_ready_in_minutes - pickup_instructions - created_at - updated_at x-typelizer: true StockReservation: type: object properties: id: type: string stock_item_id: type: string line_item_id: type: string order_id: type: string variant_id: type: string nullable: true stock_location_id: type: string nullable: true quantity: type: number expires_at: type: string active: type: boolean created_at: type: string updated_at: type: string required: - id - stock_item_id - line_item_id - order_id - variant_id - stock_location_id - quantity - expires_at - active - created_at - updated_at x-typelizer: true StockTransfer: type: object properties: id: type: string number: type: string reference: type: string nullable: true metadata: type: object created_at: type: string updated_at: type: string source_location_id: type: string nullable: true destination_location_id: type: string nullable: true source_location: "$ref": "#/components/schemas/StockLocation" destination_location: "$ref": "#/components/schemas/StockLocation" required: - id - number - reference - metadata - created_at - updated_at - source_location_id - destination_location_id x-typelizer: true StoreCreditCategory: type: object properties: id: type: string name: type: string created_at: type: string updated_at: type: string non_expiring: type: boolean required: - id - name - created_at - updated_at - non_expiring x-typelizer: true StoreCredit: type: object properties: id: type: string amount: type: string amount_used: type: string amount_remaining: type: string display_amount: type: string display_amount_used: type: string display_amount_remaining: type: string currency: type: string memo: type: string nullable: true metadata: type: object created_at: type: string updated_at: type: string customer_id: type: string nullable: true created_by_id: type: string nullable: true category_id: type: string nullable: true category_name: type: string nullable: true required: - id - amount - amount_used - amount_remaining - display_amount - display_amount_used - display_amount_remaining - currency - memo - metadata - created_at - updated_at - customer_id - created_by_id - category_id - category_name x-typelizer: true Store: type: object properties: id: type: string metadata: type: object name: type: string default_currency: type: string default_locale: type: string preferred_admin_locale: type: string nullable: true preferred_timezone: type: string preferred_weight_unit: type: string preferred_unit_system: type: string created_at: type: string updated_at: type: string url: type: string supported_currencies: type: array items: type: string supported_locales: type: array items: type: string logo_url: type: string nullable: true required: - id - metadata - name - default_currency - default_locale - preferred_admin_locale - preferred_timezone - preferred_weight_unit - preferred_unit_system - created_at - updated_at - url - supported_currencies - supported_locales - logo_url x-typelizer: true TaxCategory: type: object properties: id: type: string name: type: string tax_code: type: string nullable: true description: type: string nullable: true is_default: type: boolean created_at: type: string updated_at: type: string required: - id - name - tax_code - description - is_default - created_at - updated_at x-typelizer: true Variant: type: object properties: id: type: string product_id: type: string sku: type: string nullable: true options_text: type: string track_inventory: type: boolean media_count: type: number thumbnail_url: type: string nullable: true purchasable: type: boolean in_stock: type: boolean backorderable: type: boolean weight: type: number nullable: true height: type: number nullable: true width: type: number nullable: true depth: type: number nullable: true price: "$ref": "#/components/schemas/Price" original_price: allOf: - "$ref": "#/components/schemas/Price" nullable: true primary_media: "$ref": "#/components/schemas/Media" media: type: array items: "$ref": "#/components/schemas/Media" option_values: type: array items: "$ref": "#/components/schemas/OptionValue" custom_fields: type: array items: "$ref": "#/components/schemas/CustomField" prior_price: allOf: - "$ref": "#/components/schemas/PriceHistory" nullable: true metadata: type: object position: type: number cost_price: type: string nullable: true cost_currency: type: string nullable: true barcode: type: string nullable: true weight_unit: type: string nullable: true dimensions_unit: type: string nullable: true deleted_at: type: string nullable: true created_at: type: string updated_at: type: string tax_category_id: type: string nullable: true available_stock: type: number nullable: true reserved_quantity: type: number total_on_hand: type: number nullable: true product_name: type: string prices: type: array items: "$ref": "#/components/schemas/Price" stock_items: type: array items: "$ref": "#/components/schemas/StockItem" required: - id - product_id - sku - options_text - track_inventory - media_count - thumbnail_url - purchasable - in_stock - backorderable - weight - height - width - depth - price - original_price - option_values - metadata - position - cost_price - cost_currency - barcode - weight_unit - dimensions_unit - deleted_at - created_at - updated_at - tax_category_id - available_stock - reserved_quantity - total_on_hand - product_name x-typelizer: true