Options

Manage product options like Size and Color

GET /admin/api/options

List options with pagination, search, type filtering, and sorting. Returns summary rows with value counts by default. Pass include_values=true for full detail with values and translations.

POST /admin/api/options

Create a new option. A URL slug is auto-derived from the name. Type defaults to "variant" if omitted.

GET /admin/api/options/{id}

Fetch a single option with its values and content translations.

PUT /admin/api/options/{id}

Update an option's name, root listing visibility, and translations. Re-derives the slug from the new name.

DELETE /admin/api/options/{id}

Delete an option and all its values.

POST /admin/api/options/{id}/values

Add a value to an option. A URL slug is auto-derived from the value and ensured unique within the option.

PUT /admin/api/options/{id}/values/reorder

Reorder the values of an option. Provide the complete list of value IDs in the desired order. All IDs must belong to the given option.

DELETE /admin/api/options/{id}/values/{vid}

Delete an option value.

POST /admin/api/options/{id}/values/{vid}/image

Upload or replace the swatch image for an option value (typically used for color or pattern swatches). Accepts multipart/form-data with a single field named "file".

DELETE /admin/api/options/{id}/values/{vid}/image

Remove the swatch image for an option value. Idempotent — succeeds even if no image is set.

PATCH /admin/api/options/{id}/values/{vid}/value

Update the displayed label of an option value (e.g. rename `M` to `Medium`). Whitespace is trimmed; the slug is not re-derived — use the slug endpoint for that.

PATCH /admin/api/options/{id}/values/{vid}/slug

Update the slug of an option value. The submitted text is run through `slugify`, so the caller may pass either a pre-slugified string or free text. Within the parent option, the slug is conflict-checked (excluding the current value), and a numeric suffix is appended if necessary to keep it unique. Existing variant slug redirects continue to honour the old slug.

PATCH /admin/api/options/{id}/values/{vid}/description

Set or clear the buyer-facing description for an option value (e.g. tooltip text on a swatch). Empty string clears; max 500 characters.

GET /admin/api/options

List options with pagination, search, type filtering, and sorting. Returns summary rows with value counts by default. Pass include_values=true for full detail with values and translations.

Parameters

Name Type Required Description
page integer optional Page number, 1-indexed (default: 1)
per_page integer optional Items per page, 1-100 (default: 20)
search string optional Case-insensitive text search on option name
option_type string optional Filter by type: "variant" or "attribute"
sort string optional Sort field with optional - prefix for descending. Valid: name, sort_order, option_type. Default: sort_order
include_values boolean optional When true, returns full option detail including values and translations instead of summary rows

Response 200

{
  "data": [
    {
      "id": 1,
      "name": "Size",
      "slug": "size",
      "sort_order": 0,
      "option_type": "variant",
      "show_in_root_listing": true,
      "values_count": 4
    },
    {
      "id": 2,
      "name": "Color",
      "slug": "color",
      "sort_order": 1,
      "option_type": "variant",
      "show_in_root_listing": true,
      "values_count": 6
    },
    {
      "id": 3,
      "name": "Material",
      "slug": "material",
      "sort_order": 2,
      "option_type": "attribute",
      "show_in_root_listing": false,
      "values_count": 3
    }
  ],
  "page": 1,
  "per_page": 20,
  "total": 3,
  "total_pages": 1
}

Example

curl "https://yourshop.zeroshop.io/admin/api/options?page=1&per_page=20&option_type=variant" \
  -H "Authorization: Bearer zspat_..."
POST /admin/api/options

Create a new option. A URL slug is auto-derived from the name. Type defaults to "variant" if omitted.

Request Body

{
  "name": "Size",
  "option_type": "variant",
  "show_in_root_listing": true,
  "translations": [
    {
      "locale": "de",
      "field": "name",
      "value": "Groesse"
    }
  ]
}

Response 201

{
  "id": 1,
  "name": "Size",
  "slug": "size"
}

Example

curl -X POST "https://yourshop.zeroshop.io/admin/api/options" \
  -H "Authorization: Bearer zspat_..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Size",
    "option_type": "variant",
    "show_in_root_listing": true,
    "translations": [
      { "locale": "de", "field": "name", "value": "Groesse" }
    ]
  }'
GET /admin/api/options/{id}

Fetch a single option with its values and content translations.

Response 200

{
  "id": 1,
  "name": "Size",
  "slug": "size",
  "sort_order": 0,
  "option_type": "variant",
  "show_in_root_listing": true,
  "values": [
    {
      "id": 10,
      "value": "S",
      "slug": "s",
      "sort_order": 0
    },
    {
      "id": 11,
      "value": "M",
      "slug": "m",
      "sort_order": 1
    },
    {
      "id": 12,
      "value": "L",
      "slug": "l",
      "sort_order": 2
    },
    {
      "id": 13,
      "value": "XL",
      "slug": "xl",
      "sort_order": 3
    }
  ],
  "translations": {
    "de": {
      "name": "Groesse"
    }
  }
}

Example

curl "https://yourshop.zeroshop.io/admin/api/options/1" \
  -H "Authorization: Bearer zspat_..."
PUT /admin/api/options/{id}

Update an option's name, root listing visibility, and translations. Re-derives the slug from the new name.

Request Body

{
  "name": "Shoe Size",
  "show_in_root_listing": false,
  "translations": [
    {
      "locale": "de",
      "field": "name",
      "value": "Schuhgroesse"
    }
  ]
}

Response 204

Example

curl -X PUT "https://yourshop.zeroshop.io/admin/api/options/1" \
  -H "Authorization: Bearer zspat_..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Shoe Size",
    "show_in_root_listing": false,
    "translations": [
      { "locale": "de", "field": "name", "value": "Schuhgroesse" }
    ]
  }'
DELETE /admin/api/options/{id}

Delete an option and all its values.

Response 204

Example

curl -X DELETE "https://yourshop.zeroshop.io/admin/api/options/1" \
  -H "Authorization: Bearer zspat_..."
POST /admin/api/options/{id}/values

Add a value to an option. A URL slug is auto-derived from the value and ensured unique within the option.

Request Body

{
  "value": "XXL",
  "translations": [
    {
      "locale": "de",
      "field": "value",
      "value": "XXL"
    }
  ]
}

Response 201

{
  "id": 14,
  "value": "XXL",
  "slug": "xxl"
}

Example

curl -X POST "https://yourshop.zeroshop.io/admin/api/options/1/values" \
  -H "Authorization: Bearer zspat_..." \
  -H "Content-Type: application/json" \
  -d '{
    "value": "XXL",
    "translations": [
      { "locale": "de", "field": "value", "value": "XXL" }
    ]
  }'
PUT /admin/api/options/{id}/values/reorder

Reorder the values of an option. Provide the complete list of value IDs in the desired order. All IDs must belong to the given option.

Request Body

{
  "ordered_ids": [
    12,
    11,
    10,
    13
  ]
}

Response 204

Example

curl -X PUT "https://yourshop.zeroshop.io/admin/api/options/1/values/reorder" \
  -H "Authorization: Bearer zspat_..." \
  -H "Content-Type: application/json" \
  -d '{ "ordered_ids": [12, 11, 10, 13] }'
DELETE /admin/api/options/{id}/values/{vid}

Delete an option value.

Response 204

Example

curl -X DELETE "https://yourshop.zeroshop.io/admin/api/options/1/values/13" \
  -H "Authorization: Bearer zspat_..."
POST /admin/api/options/{id}/values/{vid}/image

Upload or replace the swatch image for an option value (typically used for color or pattern swatches). Accepts multipart/form-data with a single field named "file".

Parameters

Name Type Required Description
file file required The image file (JPEG, PNG, GIF, or WebP).

Response 200

{
  "image_url": "https://cdn.zeroshop.io/tenants/abc/option-values/12/4c9a21.webp"
}

Example

curl -X POST "https://yourshop.zeroshop.io/admin/api/options/1/values/12/image" \
  -H "Authorization: Bearer zspat_..." \
  -F "file=@red-swatch.png"
DELETE /admin/api/options/{id}/values/{vid}/image

Remove the swatch image for an option value. Idempotent — succeeds even if no image is set.

Response 204

Example

curl -X DELETE "https://yourshop.zeroshop.io/admin/api/options/1/values/12/image" \
  -H "Authorization: Bearer zspat_..."
PATCH /admin/api/options/{id}/values/{vid}/value

Update the displayed label of an option value (e.g. rename `M` to `Medium`). Whitespace is trimmed; the slug is not re-derived — use the slug endpoint for that.

Request Body

{
  "value": "Medium"
}

Response 200

{
  "value": "Medium"
}

Example

curl -X PATCH "https://yourshop.zeroshop.io/admin/api/options/1/values/11/value" \
  -H "Authorization: Bearer zspat_..." \
  -H "Content-Type: application/json" \
  -d '{"value": "Medium"}'
PATCH /admin/api/options/{id}/values/{vid}/slug

Update the slug of an option value. The submitted text is run through `slugify`, so the caller may pass either a pre-slugified string or free text. Within the parent option, the slug is conflict-checked (excluding the current value), and a numeric suffix is appended if necessary to keep it unique. Existing variant slug redirects continue to honour the old slug.

Request Body

{
  "slug": "medium"
}

Response 200

{
  "slug": "medium"
}

Example

curl -X PATCH "https://yourshop.zeroshop.io/admin/api/options/1/values/11/slug" \
  -H "Authorization: Bearer zspat_..." \
  -H "Content-Type: application/json" \
  -d '{"slug": "medium"}'
PATCH /admin/api/options/{id}/values/{vid}/description

Set or clear the buyer-facing description for an option value (e.g. tooltip text on a swatch). Empty string clears; max 500 characters.

Request Body

{
  "description": "100% combed cotton with a slight stretch."
}

Response 204

Example

curl -X PATCH "https://yourshop.zeroshop.io/admin/api/options/1/values/3/description" \
  -H "Authorization: Bearer zspat_..." \
  -H "Content-Type: application/json" \
  -d '{"description":"100% combed cotton with a slight stretch."}'

We value your privacy

We use cookies for essential site functionality and, with your consent, analytics to understand how our platform is used. No personal data is shared with third parties. See our Privacy Policy for details.