Catalogus

Producten

Actieve producten ophalen en oplijsten, inclusief varianten, afbeeldingen, categorieën, voorraadstatus en klantcontextuele prijzen.

Bekijk als Markdown

De product-endpoints geven de actieve producten van de geauthenticeerde tenant terug. Beide endpoints vereisen een tenant-API-key met de scope catalog:read of commerce:read, meegestuurd als Authorization: Bearer {api_key}, en de catalog-module moet voor de winkel ingeschakeld zijn. Tenancy wordt afgeleid uit de key, dus een X-Tenant-Id-header is niet nodig. Requests tellen mee voor de gedeelde tenant-rate-limit van 120 requests per minuut; overschrijding geeft 429 {"message":"Too Many Attempts."} terug met Retry-After- en X-RateLimit-*-headers.

Alleen producten met status active worden ooit teruggegeven. Concept-, gearchiveerde en soft-deleted producten worden uit de lijst gefilterd en geven 404 terug op het detail-endpoint.

Productobject

Alle ID's zijn UUID's. Alle geldbedragen zijn integers in minor units (centen), gekoppeld aan de ISO-valutacode van het product (bijvoorbeeld "EUR", dus 18900 betekent 189.00 EUR). Timestamps zijn ISO 8601 UTC.

NaamTypeVerplichtBeschrijving
idstring (uuid)altijdProduct-ID.
capabilitystringaltijdHoe het product verkocht wordt: standard (een gewoon product of een product met varianten, in de cart gezet met product_id en, bij varianten, variant_id) of made_to_measure (geprijsd door de configurator, in de cart gezet met een configuration). Behandel de enum als open en toon een onbekende waarde neutraal.
capability_activebooleanaltijdOf de capability van het product nu verkocht kan worden: standard heeft de commerce-module nodig, made_to_measure de configurator-module. Bij false weigert een cart-add het product met CAPABILITY_INACTIVE; verberg de koopknop.
purchasabilitystringaltijdEén van direct, quote, both; direct wanneer de merchant niets heeft ingesteld. quote betekent dat het product niet direct afgerekend kan worden; leid de koper naar een offerteaanvraag. Het veld wordt ook gerapporteerd wanneer de winkel de sales-module uit heeft staan, maar alleen een winkel met sales ingeschakeld (en offerteaanvragen aan) weigert er de checkout voor.
unitstringaltijdEenheid waarin het product verkocht wordt: piece, kg, g, l, m, m2, m3 of hour. Een piece-product accepteert alleen hele cart-hoeveelheden; elke andere eenheid accepteert tot drie decimalen (bijvoorbeeld 0.75 kg).
skustring of nullaltijdSKU op productniveau.
slugstringaltijdURL-slug, uniek per tenant.
namestringaltijdProductnaam.
descriptionstring of nullaltijdProductbeschrijving.
statusstringaltijdAltijd active op deze API.
meta_titlestring of nullaltijdSEO-titel.
meta_descriptionstring of nullaltijdSEO-beschrijving.
compare_at_amountinteger of nullaltijdDoor de merchant ingestelde vergelijkingsprijs (van-prijs) in minor units, altijd hoger dan de productprijs. null wanneer niet ingesteld. Los van list_price_amount, dat de prijs vóór klantgroep- of staffelprijzen rapporteert.
barcodestring of nullaltijdBarcode (EAN, UPC of een eigen code van de merchant).
weight_gramsinteger of nullaltijdVerzendgewicht in grammen.
requires_shippingbooleanaltijdOf het product fysiek verzonden wordt. Een cart heeft bij de checkout alleen een verzendmethode nodig wanneer er minstens één regel in zit waarvan het product verzending vereist.
track_stockbooleanaltijdOf de winkel voorraad bijhoudt voor dit product. Bij false is stock_status untracked en raakt het product nooit uitverkocht.
returnablebooleanaltijdOf de merchant retouren accepteert. made_to_measure-producten worden op bestelling gemaakt en zijn na bestelling nooit retourneerbaar, wat deze vlag ook zegt (zie attributes.returnable op de orderregel).
lead_time_daysinteger of nullaltijdProductie- of levertijd in dagen, 0 tot 365. null wanneer niet ingesteld.
tagsarray van stringaltijdTags van de merchant. Lege array wanneer er geen zijn.
social_imageobject of nullaltijdAfbeelding voor social sharing (Open Graph), zie het afbeeldingsobject hieronder, plus de id. null wanneer niet ingesteld; val dan terug op image.
priceobjectaltijd{amount, currency}. amount is de opgeloste stuksprijs bij hoeveelheid 1 voor de klantcontext van de request (gast wanneer geen X-Customer-Token-header wordt meegestuurd). amount is null wanneer de tenant prijzen voor gasten verbergt en de request een gastrequest is.
list_price_amountintegerconditioneelOorspronkelijke (list)prijs in minor units. Alleen aanwezig wanneer hij afwijkt van de opgeloste prijs en de tenant oorspronkelijke prijzen toont.
quantity_tiersarrayconditioneel[{min_quantity, price_amount}]-rijen, alleen aanwezig wanneer de tenant staffeltabellen toont en er product-scope staffels met min_quantity > 1 bestaan. Klantgroeprijen overschaduwen publieke rijen bij dezelfde min_quantity.
price_displayobjectconditioneel{mode} waarbij mode inc of ex is (weergave inclusief of exclusief btw). Opgelost uit de vat_display-instelling van de tenant (inc, ex of auto; auto lost op naar ex voor B2B-klanten geïdentificeerd via X-Customer-Token, anders inc).
attributesobject of arrayaltijdVrije-vorm attributenmap ingesteld door de merchant. Geserialiseerd als [] wanneer leeg.
optionsarrayalleen detail[{name, values}], de optiedefinities van het product (bijvoorbeeld {"name":"Color","values":["Natural","Black"]}). Alleen opgenomen op GET /v1/api/commerce/products/{id}.
categoriesarrayaltijdActieve categorieën waar het product bij hoort: [{id, name, slug, is_active}].
variantsarrayaltijdActieve varianten, zie het variantobject hieronder. Lege array wanneer het product geen varianten heeft.
has_variantsbooleanaltijdOf variants niet-leeg is.
price_fromobjectaltijd{amount, currency}. De laagste opgeloste variantprijs, of de productprijs wanneer er geen varianten zijn. amount is null voor gasten wanneer de tenant gastprijzen verbergt.
imageobject of nullaltijdPrimaire afbeelding (het media-item dat als primair is gemarkeerd, of het eerste), zie het afbeeldingsobject hieronder. null wanneer het product geen media heeft.
imagesarrayalleen detailVolledige galerij, elk item is een afbeeldingsobject plus id, is_primary (boolean) en sort_order (integer). Alleen opgenomen op GET /v1/api/commerce/products/{id}.
stock_statusstringconditioneelEén van in_stock, low_stock, out_of_stock, backorder, untracked. untracked betekent dat de winkel dit product niet telt: track_stock is false, er bestaan geen voorraadrijen, of de winkel heeft de stock-module uitgeschakeld. Volledig weggelaten wanneer de stock-module niet op het platform is geregistreerd.
created_atstring (ISO 8601)altijdAanmaaktimestamp.
updated_atstring (ISO 8601)altijdTimestamp van laatste wijziging.

Het client-panelveld stock_available wordt nooit opgenomen op deze API.

Variantobject

NaamTypeVerplichtBeschrijving
idstring (uuid)altijdVariant-ID.
option_valuesobjectaltijdMap van optienaam naar gekozen waarde, bijvoorbeeld {"Color":"Natural"}.
skustring of nullaltijdVariant-SKU.
barcodestring of nullaltijdBarcode van de variant.
weight_gramsinteger of nullaltijdVerzendgewicht van de variant in grammen; null betekent dat de weight_grams van het product geldt.
priceobjectaltijd{amount, currency}. Valt terug op de productprijs wanneer de variant geen eigen prijs heeft. amount is null voor gasten wanneer de tenant gastprijzen verbergt.
is_activebooleanaltijdAltijd true op deze API (inactieve varianten worden weggefilterd).
image_idstring (uuid) of nullaltijdDe eigen afbeelding van de variant: de id van een van de media-items van het product, dus die komt overeen met een item in images op het detail-endpoint. Toon hem als een klant deze variant kiest. null als de variant geen eigen afbeelding heeft; val dan terug op de image van het product.
imageobject of nullaltijdDe eigen afbeelding van de variant als afbeeldingsobject (zie hieronder), zonder id. null als de variant geen eigen afbeelding heeft.
stock_statusstringconditioneelZelfde enum als de stock_status op productniveau; elke variant van een product met track_stock false is untracked. Alleen aanwezig wanneer de stock-module is geregistreerd.

Afbeeldingsobject

NaamTypeVerplichtBeschrijving
urlstringaltijdURL van de originele afbeelding.
variantsobjectaltijdOn-the-fly webp-resize-URL's met de keys thumb (160px breed), card (480px breed), detail (1200px breed), geserveerd via wsrv.nl.
altstring of nullaltijdAlt-tekst.

GET /v1/api/commerce/products

Geeft een gepagineerde lijst terug van de actieve producten van de tenant, nieuwste eerst (created_at aflopend, niet instelbaar). Elk product bevat zijn primaire afbeelding, actieve varianten, actieve categorieën, voorraadstatus (wanneer de stock-module is geregistreerd) en klantcontextuele prijzen. De lijst bevat niet de options-array of de images-galerij; haal daarvoor het detail-endpoint op. De paginagrootte staat vast op 20; er is geen per_page-, sorteer- of zoekparameter.

Queryparameters

NaamTypeVerplichtBeschrijving
filter[category]stringNeeCategorieslug. Matcht producten in die actieve categorie of in elk van haar actieve afstammelingen. Een onbekende of inactieve slug levert een lege resultaatset op (200, geen 404).
pageintegerNeePaginanummer, standaard 1. Paginagrootte staat vast op 20.

Headers

NaamTypeVerplichtBeschrijving
X-Customer-TokenstringNeeStorefront-klantsessietoken. Schakelt de prijsberekening naar de context van die klant (groepsprijzen, B2B ex-btw-weergave, staffeltabellen). Zonder dit token wordt de prijs voor een gast berekend.
Request
curl "https://api.borkol.com/v1/api/commerce/products?filter%5Bcategory%5D=tables&page=1" \
  -H "Authorization: Bearer {api_key}" \
  -H "Accept: application/json"
Request (JS)
const res = await fetch(
  "https://api.borkol.com/v1/api/commerce/products?" +
    new URLSearchParams({ "filter[category]": "tables", page: "1" }),
  {
    headers: {
      Authorization: `Bearer ${apiKey}`,
      Accept: "application/json",
    },
  }
);
const { data, links, meta } = await res.json();
Response
{
  "data": [
    {
      "id": "9c2f1e6a-8b4d-4f2a-9e11-3d5a7b9c0e21",
      "capability": "standard",
      "capability_active": true,
      "purchasability": "direct",
      "unit": "piece",
      "sku": "TABLE-OAK",
      "slug": "oak-table",
      "name": "Oak Table",
      "description": "Solid oak table.",
      "status": "active",
      "meta_title": null,
      "meta_description": null,
      "compare_at_amount": null,
      "barcode": null,
      "weight_grams": 32000,
      "requires_shipping": true,
      "track_stock": true,
      "returnable": true,
      "lead_time_days": null,
      "tags": [],
      "social_image": null,
      "price": { "amount": 54900, "currency": "EUR" },
      "price_display": { "mode": "inc" },
      "attributes": [],
      "categories": [
        {
          "id": "7a1b3c5d-2e4f-4a6b-8c0d-1e2f3a4b5c6d",
          "name": "Tables",
          "slug": "tables",
          "is_active": true
        }
      ],
      "variants": [],
      "has_variants": false,
      "price_from": { "amount": 54900, "currency": "EUR" },
      "image": {
        "url": "https://cdn.borkol.com/t/9c2f/table.jpg",
        "variants": {
          "thumb": "https://wsrv.nl/?url=...&w=160&we=1&output=webp&q=80",
          "card": "https://wsrv.nl/?url=...&w=480&we=1&output=webp&q=80",
          "detail": "https://wsrv.nl/?url=...&w=1200&we=1&output=webp&q=80"
        },
        "alt": "Oak table"
      },
      "stock_status": "in_stock",
      "created_at": "2026-07-02T09:14:33.000000Z",
      "updated_at": "2026-08-01T15:20:11.000000Z"
    }
  ],
  "links": {
    "first": "https://api.borkol.com/v1/api/commerce/products?page=1",
    "last": "https://api.borkol.com/v1/api/commerce/products?page=3",
    "prev": null,
    "next": "https://api.borkol.com/v1/api/commerce/products?page=2"
  },
  "meta": {
    "current_page": 1,
    "from": 1,
    "last_page": 3,
    "links": [
      { "url": null, "label": "« Previous", "active": false },
      {
        "url": "https://api.borkol.com/v1/api/commerce/products?page=1",
        "label": "1",
        "active": true
      }
    ],
    "path": "https://api.borkol.com/v1/api/commerce/products",
    "per_page": 20,
    "to": 20,
    "total": 47
  }
}

De envelope is de standaard Laravel resource-paginator: een top-level data-array plus links (first, last, prev, next, absolute URL's of null) en meta (current_page, from, last_page, links, path, per_page, to, total). per_page is altijd 20.

Errors

StatusBodyOorzaak
401{"message":"Unauthenticated."}Ontbrekende of ongeldige API-key.
403{"message":"Invalid ability provided."}Key heeft noch de scope catalog:read noch commerce:read.
403{"error":"Module not enabled: catalog"}Tenant heeft de catalog-module niet ingeschakeld. Let op de error-key in plaats van message.
403{"message":"Tenant suspended.","code":"tenant_suspended"}Tenant-account is geschorst.
429{"message":"Too Many Attempts."}Rate limit van 120 requests per minuut overschreden.

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

Haalt één actief product op via UUID. Vergeleken met het lijst-endpoint bevat de detailresponse daarnaast de options-array en de volledige images-galerij (met is_primary en sort_order). Voorraadstatus en prijzen worden op dezelfde manier verrijkt als op de lijst: gastprijzen tenzij een X-Customer-Token-header aanwezig is. Geeft 404 terug voor concept-, gearchiveerde, soft-deleted of onbekende producten.

Padparameters

NaamTypeVerplichtBeschrijving
idstring (uuid)JaProduct-ID.

Headers

NaamTypeVerplichtBeschrijving
X-Customer-TokenstringNeeStorefront-klantsessietoken. Schakelt de prijsberekening naar de groep en B2B-context van die klant.
Request
curl "https://api.borkol.com/v1/api/commerce/products/9c2f1e6a-8b4d-4f2a-9e11-3d5a7b9c0e21" \
  -H "Authorization: Bearer {api_key}" \
  -H "Accept: application/json"
Response
{
  "data": {
    "id": "9c2f1e6a-8b4d-4f2a-9e11-3d5a7b9c0e21",
    "capability": "standard",
    "capability_active": true,
    "purchasability": "direct",
    "unit": "piece",
    "sku": "CHAIR-OAK",
    "slug": "oak-dining-chair",
    "name": "Oak Dining Chair",
    "description": "Solid oak chair with linen seat.",
    "status": "active",
    "meta_title": "Oak Dining Chair",
    "meta_description": "Handmade solid oak dining chair.",
    "compare_at_amount": 22900,
    "barcode": "8712345678906",
    "weight_grams": 6500,
    "requires_shipping": true,
    "track_stock": true,
    "returnable": true,
    "lead_time_days": 5,
    "tags": ["oak", "dining"],
    "social_image": {
      "id": "3c4d5e6f-7a8b-4c9d-0e1f-2a3b4c5d6e7f",
      "url": "https://cdn.borkol.com/t/9c2f/chair-social.jpg",
      "variants": {
        "thumb": "https://wsrv.nl/?url=...&w=160&we=1&output=webp&q=80",
        "card": "https://wsrv.nl/?url=...&w=480&we=1&output=webp&q=80",
        "detail": "https://wsrv.nl/?url=...&w=1200&we=1&output=webp&q=80"
      },
      "alt": "Oak dining chair in a dining room"
    },
    "price": { "amount": 18900, "currency": "EUR" },
    "list_price_amount": 21900,
    "quantity_tiers": [
      { "min_quantity": 5, "price_amount": 17900 },
      { "min_quantity": 10, "price_amount": 16900 }
    ],
    "price_display": { "mode": "inc" },
    "attributes": { "material": "oak" },
    "options": [
      { "name": "Color", "values": ["Natural", "Black"] }
    ],
    "categories": [
      {
        "id": "7a1b3c5d-2e4f-4a6b-8c0d-1e2f3a4b5c6d",
        "name": "Chairs",
        "slug": "chairs",
        "is_active": true
      }
    ],
    "variants": [
      {
        "id": "5e6f7a8b-9c0d-4e1f-a2b3-c4d5e6f7a8b9",
        "option_values": { "Color": "Natural" },
        "sku": "CHAIR-OAK-NAT",
        "barcode": "8712345678913",
        "weight_grams": null,
        "price": { "amount": 18900, "currency": "EUR" },
        "is_active": true,
        "image_id": "2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e",
        "image": {
          "url": "https://cdn.borkol.com/t/9c2f/chair.jpg",
          "variants": {
            "thumb": "https://wsrv.nl/?url=...&w=160&we=1&output=webp&q=80",
            "card": "https://wsrv.nl/?url=...&w=480&we=1&output=webp&q=80",
            "detail": "https://wsrv.nl/?url=...&w=1200&we=1&output=webp&q=80"
          },
          "alt": "Oak dining chair front view"
        },
        "stock_status": "in_stock"
      }
    ],
    "has_variants": true,
    "price_from": { "amount": 18900, "currency": "EUR" },
    "image": {
      "url": "https://cdn.borkol.com/t/9c2f/chair.jpg",
      "variants": {
        "thumb": "https://wsrv.nl/?url=...&w=160&we=1&output=webp&q=80",
        "card": "https://wsrv.nl/?url=...&w=480&we=1&output=webp&q=80",
        "detail": "https://wsrv.nl/?url=...&w=1200&we=1&output=webp&q=80"
      },
      "alt": "Oak dining chair front view"
    },
    "images": [
      {
        "id": "2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e",
        "url": "https://cdn.borkol.com/t/9c2f/chair.jpg",
        "variants": {
          "thumb": "https://wsrv.nl/?url=...&w=160&we=1&output=webp&q=80",
          "card": "https://wsrv.nl/?url=...&w=480&we=1&output=webp&q=80",
          "detail": "https://wsrv.nl/?url=...&w=1200&we=1&output=webp&q=80"
        },
        "alt": "Oak dining chair front view",
        "is_primary": true,
        "sort_order": 0
      }
    ],
    "stock_status": "in_stock",
    "created_at": "2026-07-02T09:14:33.000000Z",
    "updated_at": "2026-08-01T15:20:11.000000Z"
  }
}

Errors

StatusBodyOorzaak
401{"message":"Unauthenticated."}Ontbrekende of ongeldige API-key.
403{"message":"Invalid ability provided."}Key heeft noch de scope catalog:read noch commerce:read.
403{"error":"Module not enabled: catalog"}Tenant heeft de catalog-module niet ingeschakeld.
403{"message":"Tenant suspended.","code":"tenant_suspended"}Tenant-account is geschorst.
404{"message":"..."}Product bestaat niet, is soft-deleted, of zijn status is niet active.
429{"message":"Too Many Attempts."}Rate limit van 120 requests per minuut overschreden.