borkoldocs

Configurator

Configuration schema

Fetch the complete configuration schema of a configurable product.

View as Markdown

The schema endpoint returns everything a storefront needs to render a configurator UI for one product: dimensions with their per-choice range constraints, the product's price matrices (for hinting which matrix applies), and the option groups with their choices, price deltas, cross-choice rules, images, and requires_quote flags. See the chapter introduction for how these concepts fit together.

GET /v1/api/commerce/configurator/products/{id}/schema

Returns the complete configuration schema for one active configurable product. Everything in the response is pruned to currently visible choices: only active, non-deleted choices appear, and dimension constraints, matrix conditions, and requires and excludes lists reference only those visible choice IDs. Returns 404 for any product that is not both status = active and type = configurable.

Path parameters

NameTypeRequiredDescription
idstring (uuid)YesProduct ID. Must be an active product of type configurable.

Response fields

The data object has three keys.

data.dimensions (array, in position order; the order defines the mapping to price matrix axes dim1 and dim2):

NameTypeRequiredDescription
keystringalwaysRequest key to use for this dimension in quote calls.
labelstringalwaysDisplay label.
unitstringalwaysDisplay unit string, for example "cm".
minintegeralwaysMinimum allowed value before constraint tightening.
maxintegeralwaysMaximum allowed value before constraint tightening.
constraintsarrayalwaysPer-choice range tightenings; empty array when none. Each item: choice_id (uuid), min (integer or null), max (integer or null). When that choice is selected, a non-null min raises the effective minimum and a non-null max lowers the effective maximum.

data.price_matrices (array, in creation order):

NameTypeRequiredDescription
idstring (uuid)alwaysMatrix ID. Echoed back by the quote endpoint as matrix.id when this matrix supplied the base price.
namestringalwaysMatrix name.
conditionsarray of string (uuid)alwaysChoice IDs that must all be selected for the matrix to be eligible. Empty array means always eligible. Among eligible matrices, the one with the most conditions wins.

data.option_groups (array, in position order):

NameTypeRequiredDescription
idstring (uuid)alwaysGroup ID.
namestringalwaysGroup name. Also used as the prefix of quote breakdown labels ("Group: Choice").
typestringalwayssingle (at most one choice selectable) or multi (any number).
requiredbooleanalwaysWhether at least one choice from this group must be selected.
choicesarrayalwaysChoices in position order, see below.

data.option_groups[].choices[]:

NameTypeRequiredDescription
idstring (uuid)alwaysChoice ID. Send this in the quote request's choices array.
namestringalwaysChoice name.
delta_typestringalwaysfixed, per_area, percent, or percent_of_total.
delta_valueintegeralwaysMinor units for fixed; minor units per square meter for per_area; percent times 100 for percent and percent_of_total (1050 = 10.50 percent).
is_defaultbooleanalwaysUI hint for the initial selection.
requiresarray of string (uuid)alwaysChoice IDs this choice requires. OR within one target group, AND across target groups.
excludesarray of string (uuid)alwaysChoice IDs this choice cannot be combined with.
imagesarrayalways[{url, alt}]; empty array when the choice has no media.
requires_quotebooleanalwaysWhen true, the storefront should route the buyer to a manual quote request instead of checkout. Informational: the quote endpoint still prices the configuration.
Request
curl "https://api.borkol.com/v1/api/commerce/configurator/products/9c2f1e6a-8b4d-4f2a-9e11-3d5a7b9c0e21/schema" \
  -H "Authorization: Bearer {api_key}" \
  -H "Accept: application/json"
Request (JS)
const res = await fetch(
  `https://api.borkol.com/v1/api/commerce/configurator/products/${productId}/schema`,
  {
    headers: {
      Authorization: `Bearer ${apiKey}`,
      Accept: "application/json",
    },
  }
);
const { data } = await res.json();
Response
{
  "data": {
    "dimensions": [
      {
        "key": "width",
        "label": "Width",
        "unit": "cm",
        "min": 200,
        "max": 700,
        "constraints": [
          {
            "choice_id": "c1a2b3c4-d5e6-4f7a-8b9c-0d1e2f3a4b5c",
            "min": null,
            "max": 600
          }
        ]
      },
      {
        "key": "depth",
        "label": "Depth",
        "unit": "cm",
        "min": 150,
        "max": 400,
        "constraints": []
      }
    ],
    "price_matrices": [
      {
        "id": "d4e5f6a7-b8c9-4d0e-9f1a-2b3c4d5e6f7a",
        "name": "Glass roof",
        "conditions": ["c1a2b3c4-d5e6-4f7a-8b9c-0d1e2f3a4b5c"]
      },
      {
        "id": "e5f6a7b8-c9d0-4e1f-a2b3-c4d5e6f7a8b9",
        "name": "Base",
        "conditions": []
      }
    ],
    "option_groups": [
      {
        "id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
        "name": "Roof type",
        "type": "single",
        "required": true,
        "choices": [
          {
            "id": "c1a2b3c4-d5e6-4f7a-8b9c-0d1e2f3a4b5c",
            "name": "Glass",
            "delta_type": "fixed",
            "delta_value": 0,
            "is_default": true,
            "requires": [],
            "excludes": ["f6a7b8c9-d0e1-4f2a-b3c4-d5e6f7a8b9c0"],
            "images": [
              {
                "url": "https://cdn.borkol.com/t/9c2f/glass-roof.jpg",
                "alt": "Glass roof"
              }
            ],
            "requires_quote": false
          }
        ]
      },
      {
        "id": "b2c3d4e5-f6a7-4b8c-9d0e-1f2a3b4c5d6e",
        "name": "LED lighting",
        "type": "multi",
        "required": false,
        "choices": [
          {
            "id": "f6a7b8c9-d0e1-4f2a-b3c4-d5e6f7a8b9c0",
            "name": "LED set (6)",
            "delta_type": "per_area",
            "delta_value": 2500,
            "is_default": false,
            "requires": ["c1a2b3c4-d5e6-4f7a-8b9c-0d1e2f3a4b5c"],
            "excludes": [],
            "images": [],
            "requires_quote": false
          }
        ]
      }
    ]
  }
}

Errors

StatusBodyCause
401{"message":"Unauthenticated."}Missing or invalid API key.
403{"message":"Invalid ability provided."}Key lacks the commerce:read scope.
403{"error":"Module not enabled: commerce"}Tenant does not have the commerce module enabled. Note the error key instead of message.
403{"message":"Tenant suspended.","code":"tenant_suspended"}Tenant account is suspended.
404{"message":"..."}Product does not exist, is not active, or its type is not configurable.
429{"message":"Too Many Attempts."}Rate limit of 120 requests per minute exceeded.