Aan de slag
Changelog
Gedateerd overzicht (nieuwste bovenaan) van elke wijziging aan de publieke storefront API. Lees dit voordat je een integratie bijwerkt.
Bekijk als MarkdownDe storefront API is geversioneerd via het URL-prefix (/v1). Binnen v1 is elke wijziging additief: velden, endpoints, optionele parameters en enum-waarden worden alleen toegevoegd. Elke vermelding hieronder noemt de datum, wat er veranderde en welke pagina's van deze referentie zijn bijgewerkt. Dezelfde vermeldingen staan in de changelog van de repository.
2026-10-29
Toegevoegd
variants[].image_id(uuid of null) envariants[].image(afbeeldingsobject of null) opGET /v1/api/commerce/productsenGET /v1/api/commerce/products/{id}: de eigen afbeelding van een variant, een van de media-items van het product, dusimage_idkomt overeen met een item inimagesop het detail-endpoint. Producten die uit Shopify zijn geïmporteerd krijgen hem uit de kolomVariant Image. Zie Variantobject.
2026-10-24
Opmerkingen
- Documentatiefix, niets veranderd in de API. De eventcatalogus van webhooks documenteert nu de acht abonneerbare sales-events die
WebhookDispatchersinds de sales-module toestaat:quote.offered,quote.accepted,quote.declined,quote.expired({id, number, status, origin, total_amount, currency, email, valid_until, signed_at}) eninvoice.sent,invoice.paid,invoice.overdue,credit_note.sent({id, number, kind, status, total_amount, paid_amount, open_amount, currency, email, issue_date, due_date}), met wanneer elk wordt verstuurd. Zie Webhooks. - De scopetabel noemt elke toekenbare scope en de routes die hem controleren:
catalog:read(en het paarcatalog:write,configurator:*),contacts:read/contacts:writemetcustomers:*als hun vroegere namen,sales:read/sales:write, en welke scopes toekenbaar zijn maar nog door geen/v1/api-route worden gebruikt. Zie Authenticatie.
2026-10-18
Toegevoegd
GET /v1/api/forms/address-lookup(scopeforms:read):country=NL,postal_code,house_numberen een optioneleadditiongeven200 {street, city, postal_code, lat, lon}(niet verpakt indata). Fouten:404(No address found.),422opcountry,postal_codeofhouse_number,503(Address lookup is temporarily unavailable.). 60 requests per minuut per winkel, daarna429. Zie Adres opzoeken.- Veldtype
addressbij formulieren.configis{country, lookup?, service_area?}; het antwoord is{postal_code, house_number, addition?, street, city, lat?, lon?}en een ongeldige waarde geeftMust be a valid address.opanswers.{key}.service_areais{origin: {lat, lon, label?}, radius_km, mode: notice | block, message}. Zie Veldtypes. meta.addressbij een opgeslagen inzending: peraddress-veld met een werkgebied{distance_km, in_area}. Bijmode: "block"geeft een adres dat aantoonbaar buiten het gebied ligt422opanswers.{key}met demessagevan het veld. Zie Adresvelden en het werkgebied.options_sourcebijchoice-velden:{object_type, label, description?, sort?, limit?}.GET /v1/api/forms/{key}vultconfig.optionsbij elk request uit de publiek zichtbare records van de collectie en een inzending wordt daartegen gecontroleerd. Zie Veldtypes.- Lengtegrenzen voor de onderdelen van een
address-antwoord, na het verwijderen van de spaties:postal_code12 tekens,house_number20,addition10,streetencityelk 255. Een langer onderdeel geeftMust be a valid address.opanswers.{key}, ook incheck()van@borkol/forms. Zie Veldtypes. @borkol/forms0.2.0: de optiepersistKeybijBorkolFormenuseBorkolFormbewaart het concept van een bezoeker tot 30 dagen inlocalStorage, enformatAddress,normaliseAddressendistanceKmworden geëxporteerd. Zie Het pakket @borkol/forms.
Gewijzigd
- Een formulier mag nu 150 invoervelden hebben (was 60).
headingenparagraphtellen niet mee. Stappen blijven op 20. Zie Definitie: stappen en velden.
Opmerkingen
addressis een nieuw veldtype: een renderer die een component kiest opkindheeft er een nodig. Behandel een onbekend type als additief, zoals altijd binnen/v1.- Bij
GET /v1/api/forms/{key}isconfig.service_area.messagevan eenaddress-veld een tekst in de gevraagde taal (met de gebruikelijke terugval), zoals elke andere tekst van de definitie. Zie Veldtypes.
2026-10-16
Toegevoegd
code: "module_disabled"enmodule(de module-key) op de body van de module-disabled-error, zowel bij de403- als de404-variant.errorblijft ongewijzigd, dus bestaande checks blijven werken. Zie Module niet ingeschakeld.
2026-10-13
Toegevoegd
- Formulieren. Een nieuwe module
formsen een nieuw hoofdstuk.GET /v1/api/forms/{key}?locale=(scopeforms:read) geeft de gepubliceerde versie van een actief formulier terug, verpakt indata:{key, version, name, steps, settings: {thank_you: {message, redirect_url}}}, met elke tekst in één taal en de standaardtaal van de winkel als terugval. Stappen en velden hebbenshow_if-regels (equals,not_equals,contains,filled,empty, één niveauallofany); de veldtypes zijntext,textarea,number,email,phone,date,select,link,choice,consent,hidden,file,headingenparagraph. Zie Formulieren en Een formulier laden. POST /v1/api/forms/{key}/submissions(scopeforms:write) controleert de antwoorden met dezelfde regels tegen de gepubliceerde versie, laat antwoorden op verborgen velden weg, slaat de inzending op en antwoordt201 {"data": {"number", "thank_you": {message, redirect_url}}}. Fouten volgen de422-envelope met keysanswers.{key}enfiles.{key}; eenhoneypotmet een andere waarde dan een lege string ofnullgeeft201metnumber: nullen slaat niets op. Zie Inzendingen.- Header
X-Borkol-Visitor-Ipop de formulierroutes: de limiet per uur per formulier (1 tot 100 per bezoeker, standaard 5) telt per bezoekersadres, ook pogingen die met422stranden, en antwoordt429 {"message": "Too many submissions. Try again later."}. Zonder geldige header wordt het adres van de verbinding gebruikt. Zie Bezoekers-IP en de limiet per uur. - Scopes
forms:readenforms:write, enformsals module-key in403 {"error": "Module not enabled: forms"}. Houdforms:write-sleutels op je server. Zie Authenticatie. - Webhook-events
form.published({key, version}) enform_submission.created({id, number, form_key, status, locale, name, email, created_at}, nooit de antwoorden). Zie Webhooks. POST /v1/api/forms/{key}/uploads(scopeforms:write, multipartfieldenfile) slaat één bestand voor eenfile-veld privé op en antwoordt201 {"data": {"token", "name", "size"}}. Het type wordt bepaald aan de hand van de inhoud (image: JPEG, PNG, WebP, HEIC/HEIF;pdf: PDF), de grootte tegenmax_mbvan het veld (maximaal 20 MB); fouten zijn422opfieldoffile. 30 uploads per formulier per bezoeker per uur, daarna429 {"message": "Too many uploads. Try again later."}. Tokens werken één keer, horen bij het formulier en het veld, en verlopen na 24 uur. Zie Uploads.filesopPOST /v1/api/forms/{key}/submissions: veld-key naar een lijst uploadtokens, geclaimd met de inzending; een token dat onbekend is, bij een ander formulier of veld hoort, gebruikt of verlopen is, geeft422opfiles.{key}(This upload is invalid or has expired. Upload the file again.). Zie Inzendingen.- Cloudflare Turnstile op formulieren:
settings.turnstile_site_keyopGET /v1/api/forms/{key}als het formulier Turnstile aan heeft en de winkel beide keys heeft ingesteld, enturnstile_tokenop de inzending, gecontroleerd na de limiet per uur en vóór de antwoorden. Een mislukte controle geeft422opturnstile; tokens werken één keer, dus reset de widget na elke422. Zie Turnstile en Een formulier laden. - Het pakket
@borkol/forms: types, de zichtbaarheids- en antwoordregels (visible,check,prefill) en een headless React-renderer (@borkol/forms/react) metupload,turnstileToken,onServerErrorsen eenformError-component. Zie Het pakket @borkol/forms.
Opmerkingen
- Een formulier met Turnstile aan wordt niet gecontroleerd zolang de winkel niet beide Turnstile-keys heeft ingesteld:
turnstile_site_keyontbreekt dan en inzendingen worden zonder controle geaccepteerd.
2026-10-12
Toegevoegd
- Filteren op een
tags-,record_ref_list- ofrecord_ref-property metfilter[{propertyKey}]: een tag of record-id die de opgeslagen lijst bevat (een verwijzing matcht op gelijkheid). Zie Records. settingsop elk objecttype vanGET /v1/api/objects/types:{publishable, slug?}, waarbijslug{source, prefixes}is en alleen aanwezig als het type zijn records adressen geeft.localized(boolean) enconfig(object of null) op elke propertydefinitie. Zie Types.- De propertytypes
richtext,datetime,media,media_list,link,icon,token_variant,color,email,phone,tags,record_ref,record_ref_listen eenrepeatermet één niveau nesting voor objectproperties, naast de bestaande types. Properties kunnen worden gelokaliseerd (niet number, money, boolean, date, datetime, customer, color, media_list, recordverwijzingen, repeater, sections; eenmedia_listdraagt in plaats daarvanaltencaptionals locale-maps). Zie Objecten. published_atop elk record, enslugs(taaltag naar adres) op de records van een type met adressen, beperkt tot de voor de winkel ingeschakelde talen. Zie Records.GET /v1/api/objects/types/{key}/records/by-slug/{slug}?locale=haalt één gepubliceerd record op via zijn adres in één taal (localeis standaard de standaardtaal van de winkel;422oplocaleals die niet is ingeschakeld,404als niets zichtbaars matcht). Zie Records.- Webhook-events
object_record.published,object_record.updated,object_record.unpublishedenobject_record.deleted, met de payload{id, type_key, slugs, published_at}. Ze gaan alleen af bij echte overgangen; een ingepland record dat zijn tijd bereikt, verstuurt niets. Zie Webhooks. GET /v1/api/redirectsaccepteert ooktenant:readenobjects:read, en stuurt door naar recordadressen op dezelfde manier als naar producten en categorieën (een gewijzigd recordadres legt alleen een redirect vast als het type voor die taal een niet-leeg adresvoorvoegsel heeft). Zie Redirects en sitemap.include=refs(ofinclude[]=refs) opGET /v1/api/objects/types/{key}/records,GET /v1/api/objects/records/{id}en het by-slug-endpoint klaptrecord_ref- enrecord_ref_list-waarden uit tot{id, type_key, values, slugs?, published_at}, één niveau diep. Doelen die niet publiek zichtbaar zijn vallen weg (nullvoor een verwijzing, uit een lijst verwijderd); onbekendeinclude-tokens worden genegeerd. Zie Records.- Query-parameter
localeopGET /v1/api/objects/types/{key}/records: gelokaliseerdefilter[...],sortenqgebruiken die taal. Een tag van een ingeschakelde taal is nodig om te werken; elke andere waarde valt terug op de standaardtaal van de winkel. Zie Records. - Objectrecords in
GET /v1/api/sitemap: items{type: "object_record", object_type, locale, path, lastmod, alternates}, één per publiek zichtbaar record, taal en adres, voor types met een niet-leeg adresvoorvoegsel. Zie Redirects en sitemap. GET /v1/api/business(scopetenant:read) geeft het openbare bedrijfsprofiel: handels- en juridische naam, contactgegevens, adres, registratie- en BTW-nummers,social_links({platform, url, label}, 23 platforms), de standaardlocaleencontent_locales. Bank-, ondertekenaar-, afzender- en voorwaardenvelden worden nooit getoond, en een winkel zonder profiel antwoordt200met nulls. Zie Bedrijfsprofiel.
Gewijzigd
- Mediawaarden zijn objecten. Een
media-waarde (een property, of een veld binnen een sectie of repeaterrij) is nu{id, url, alt, width, height, mime_type}, ofnullals het item ontbreekt of privé is. Het was het media-id als string. Eenmedia_list-waarde is een lijst van dezelfde objecten, elk met eencaption; items die ontbreken of privé zijn, vallen uit de lijst. Het media-id zelf ophalen is niet meer nodig. Zie Objecten. - Concepten en ingeplande records zijn verborgen. Op een type met
settings.publishable: trueontbreken concepten en records met eenpublished_atin de toekomst in de recordlijst en geven ze404opGET /v1/api/objects/records/{id}en via slug.filter[status]wordt publiek niet geaccepteerd (422opfilter). Typen zonder publicatiestap blijven ongewijzigd. Zie Records en Publiceren en zichtbaarheid. - Gelokaliseerde waarden worden teruggesneden tot de ingeschakelde talen. Een gelokaliseerde property of veld geeft een map van taaltag naar waarde met alleen de voor de winkel ingeschakelde talen. Een opgeslagen lege
sections-waarde komt terug als[]; secties van een type dat niet meer bestaat, vallen weg. Zie Gelokaliseerde waarden. GET /v1/api/redirectsenGET /v1/api/sitemapworden door het platform geleverd. Zelfde paden, zelfde responses. Ze vereisen de catalog-module niet meer (geen403 Module not enabled: catalogmeer), accepteren één van de scopescatalog:read,commerce:read,tenant:readofobjects:read, en de sitemap lijst alleen de items van ingeschakelde modules (een winkel zonder catalog-module krijgt een lege lijst). De referentiepagina is verplaatst van Catalogus naar Aan de slag. Zie Redirects en sitemap.- Gelokaliseerde filters, sortering en zoeken volgen
locale. Filteren of sorteren op een gelokaliseerde property, enqop een gelokaliseerde tekstproperty, lezen nu de waarde in de gevraagde taal (de standaardtaal van de winkel alslocaleontbreekt) in plaats van de ruwe opgeslagen map. Zie Records. - Vertalingen zonder standaardtaal blijven bewaard. Een vertaalbare property of veld dat niet verplicht is en geen waarde voor de standaardtaal van de winkel heeft, bijvoorbeeld
{"en": "Dusk"}met standaardnl, wordt zoals ingevuld opgeslagen in plaats van weggelaten; alleen een map waarvan alle waarden leeg zijn telt nog als leeg. Een verplicht veld geeft nog steeds422. Derichtext-allowlist bevat nu ookimgmet alleensrcenalt(https://of root-relatieve/bronnen; elke andereimgwordt verwijderd). Zie Objects.
Opmerkingen
- De recordvorm kreeg
published_at(altijd) enslugs(typen met adressen) erbij. Behandel onbekende velden als additief, zoals altijd binnen/v1.
2026-10-11
Toegevoegd
capability(standardofmade_to_measure) encapability_active(boolean) op het productobject vanGET /v1/api/commerce/productsenGET /v1/api/commerce/products/{id}.capabilityzegt hoe het product in een cart komt;capability_activeisfalsezolang de module die het verkoopt (commerce voorstandard, configurator voormade_to_measure) uitgeschakeld is. Zie Producten.unitop het productobject (piece,kg,g,l,m,m2,m3,hour) en op elke orderregel (lines[].unit, de eenheid van het product op het moment van de order). Zie Producten en Bestellingen.- Productvelden
compare_at_amount,barcode,weight_grams,requires_shipping,track_stock,returnable,lead_time_days,tagsensocial_image, en variantveldenbarcodeenweight_grams. Zie Producten. GET /v1/api/redirects?path=geeft{data: {from_path, to_path, status}}terug voor een product- of categoriepad waarvan de slug is gewijzigd (404 als er geen is), enGET /v1/api/sitemaplijst elk actief product- en categoriepad op als{data: [{type, path, lastmod}]}. Beide nemencatalog:readofcommerce:readen de catalog-module. Zie Redirects en sitemap.- Een
codeop het hoogste niveau op de 422 waarmee een cart-add een regel weigert (POST /v1/api/commerce/carts/{id}/lines):CAPABILITY_INACTIVE,INVALID_CONFIGURATIONofNOT_PURCHASABLE, naast de ongewijzigdemessageenerrors. Zie Cartregels en Errors en rate limits. attributes.returnableenattributes.lead_time_daysop elke orderregel die via de checkout of een geaccepteerde offerte is geplaatst; een made-to-measure-regel is nooit retourneerbaar. Zie Bestellingen.
Gewijzigd
- Breaking:
typeis verwijderd uit het productobject. Gebruik in plaats daarvancapability, plusrequires_shippingentrack_stock: voormaligesimple- envariable-producten zijnstandard;configurable-producten zijnmade_to_measure(en niet retourneerbaar);digital-,license- ensubscription-producten zijnstandardmetrequires_shipping: falseentrack_stock: false. Zie Producten. - Breaking: hoeveelheden zijn decimaal.
quantityop cart-, order- en offerteregels,availablebij beschikbaarheid,out_of_stock[].requesteden.availablebij checkout en offerte-acceptatie, enquantityin destock.adjusted-webhook zijn JSON-getallen die decimalen kunnen hebben (0.75,12).quantityopPOST /v1/api/commerce/carts/{id}/linesenPATCH .../lines/{lineId}accepteert tot drie decimalen; een product metunitpieceneemt nog steeds alleen gehele getallen (422 opquantity). Zie Cartregels, Carts, Bestellingen, Beschikbaarheid en Webhooks. - Breaking: de configurator-endpoints (
GET /v1/api/commerce/configurator/products/{id}/schema,POST .../quote) hangen af van de configurator-module: zonder die module antwoorden ze403 {"error":"Module not enabled: configurator"}(wascatalog). Ze antwoorden 404 voor een product waarvan decapabilitynietmade_to_measureis. Zie Configuratieschema, Prijsofferte en Hoe de configurator werkt. - Configurator-dimensies moeten gehele getallen zijn; een waarde met decimalen werd vroeger afgekapt en wordt nu geweigerd. Het quote-endpoint antwoordt 422 op
dimensions.{key}({Label} must be a whole number.) in zijn gewone validatie-envelope, zondercodeop het hoogste niveau; een cart-add geeft dezelfde fout metcodeINVALID_CONFIGURATION. Zie Prijsofferte en Cartregels. - Breaking:
components[].qtyin de configuratiesnapshot op cart- en orderregels is een exacte decimale string ("2.16"), was een integer. Zie Carts en Bestellingen. - Breaking:
POST /v1/api/commerce/carts/{id}/quote-requesthoort bij de sales-module en antwoordt404 {"error":"Module not enabled: sales"}wanneer de winkel sales heeft uitgeschakeld. Quote-triggers gaan alleen af wanneer sales is ingeschakeld en offerteaanvragen aan staan; anders isrequires_quotealtijd false en weigert de checkout nooit metQUOTE_REQUIRED. Zie Offerteaanvragen, Checkout en Errors en rate limits. purchasabilitywordt ingesteld door de sales-module en isdirectwanneer de merchant niets heeft ingesteld; het wordt ook gerapporteerd wanneer sales uitgeschakeld is. Eenquote-product kan aan een cart worden toegevoegd: de cart meldtrequires_quote: truemet redenproduct_purchasability, de checkout weigert met409 {"code": "QUOTE_REQUIRED", "reasons": [...]}, en de cart gaat via de offerteaanvraag. De instelling altijd offreren van een contactgroep is nu een sales-instelling; de redencustomer_groupis ongewijzigd. Zie Producten en Offerteaanvragen.stock_statusisuntrackedvoor een product mettrack_stock: falseen al zijn varianten, ook wanneer er voorraadrijen bestaan, op het productobject en opGET /v1/api/stock/availabilityenGET /v1/api/stock/products/{productId}(tracked: false). Zie Producten en Beschikbaarheid.- De checkout vereist
shipping_method_idwanneer de cart een regel bevat waarvan het productrequires_shipping: trueheeft (was: een product van typesimple,variableofconfigurable). Zie Checkout en Verzendmethoden. - Offerteregels die uit een cart zijn gemaakt hebben
unitpcsvoor een product dat per stuk verkocht wordt en anders de eenheid van het product (wasnull). Zie Offerteaanvragen en Offertetokens. - Een offerte accepteren in bestelmodus reserveert voorraad via de line handler van elk product tegen de geoffreerde prijs, zodat een made-to-measure-regel zijn componenten afboekt. Alleen een echt tekort weigert met
OUT_OF_STOCK; een regel waarvan het product niet meer verkocht kan worden, wordt zonder voorraadmutatie omgezet. Zie Offertetokens.
Verouderd
QUOTE_NOT_ORDERABLE(422) opPOST /v1/api/sales/quotes/by-token/{token}/acceptenPOST /v1/api/commerce/quotes/by-token/{token}/acceptwordt niet meer teruggegeven: een offerte met fractionele regelhoeveelheden wordt omgezet in een bestelling met die hoeveelheden. Blijf de code tolereren, maar verwacht hem niet meer te zien. Zie Offertetokens.
Opmerkingen
- Het
/v1-oppervlak is geherstructureerd voordat een productieconsument ervan afhankelijk was, dus de breaking changes hierboven zitten binnen/v1in plaats van onder een nieuwe URL-versie. Vanaf deze release zijn wijzigingen binnen/v1weer additief. - Documentatiecorrecties, er is niets aan de API veranderd: de product- en categorie-endpoints accepteren
catalog:readofcommerce:readen hangen af van de catalog-module (de referentie noemdecommerce:readencommerce);invoice_idop het orderobject en de volledige offerteaanvraag-respons (origin,intro,terms,acceptance_mode,pdf_url,signed_at,signed_pdf_url, en de regelveldenkind,unit,description,tax_rate,unit_price) zijn nu gedocumenteerd. Zie Producten, Categorieën, Bestellingen en Offerteaanvragen.
2026-09-17
Toegevoegd
discount_total(money) endiscount_breakdown(array of null) op het orderobject datPOST /v1/api/commerce/carts/{id}/checkout,GET /v1/api/commerce/orders/{id}enGET /v1/api/commerce/my/ordersteruggeven.discount_total.amountis de productkorting die bij het afrekenen is toegepast (0als er geen was);discount_breakdownbevat per toegepaste korting één{discount_id, name, code, kind, amount}-item en isnullals er geen korting gold. Beide zijn additief; er is geen bestaand veld gewijzigd. Zie Orders en Checkout.messageop deOUT_OF_STOCK-weigering vanPOST /v1/api/commerce/quotes/by-token/{token}/accept(alleen bestelmodus). De 409-body luidt nu{"code": "OUT_OF_STOCK", "message": "Insufficient stock.", "out_of_stock": [...]}; deout_of_stock-regels zijn ongewijzigd. Additief, en de envelope komt nu overeen met elke andere weigering op het endpoint (code+message). Zie Offertetokens.
Gewijzigd
POST /v1/api/commerce/carts/{id}/claimvoegt nu elke andereactivecart van de klant samen in de geclaimde cart, niet alleen de eerste die gevonden wordt. Elke samengevoegde cart krijgt statusmergeden geeft zijn voorraadreserveringen vrij, precies zoals voorheen; er blijft alleen geen verweesde actieve cart meer achter. Zie Een cart claimen en Storefront-gids.- De claim-merge neemt identiteit mee: de geclaimde cart behoudt zijn eigen
emailenmetadataals die gezet zijn en neemt anders de waarde van de samengevoegde cart over, zodat een guest-e-mailadres dat vóór het inloggen is vastgelegd niet meer verloren gaat. Er is geen veld toegevoegd of van type veranderd op de cart-envelope. Zie Een cart claimen.
Opmerkingen
POST /v1/api/commerce/carts/{id}/lines: twee gelijktijdige identieke adds (zelfde product, variant en configuratie) lieten de verliezer voorheen falen met een 500. De verliezer telt zijn aantal nu op bij de winnende regel en geeft dezelfde 201-envelope terug als voorheen, nog steeds begrensd opmax_quantity_per_line. Zie Cart-regels.- De verwerking van
X-Customer-Tokenvolgt nu consequent de gedocumenteerde regel "moet naar een klant herleiden, anders 401": een token dat voorbij zijnexpires_atis, of ouder is dan het sessievenster van het platform, herleidt niet meer en kan dus geen klantgebonden cart claimen of afrekenen. Log opnieuw in voor een vers token. Zie Een cart claimen en Checkout. POST /v1/api/customers/forgot-passwordantwoordt nog steeds 202 met dezelfde body voor bekende en onbekende adressen; het doet nu op beide paden ook evenveel queue-werk, zodat de responstijd niet langer verraadt of een account bestaat. Zie Wachtwoorden.- Een
bogo-korting geeft zijn ontvangaantal nu één keer per kwalificatie in plaats van één keer per cart: het aantal afgeprijsde eenheden isget_quantity × floor(kwalificerend koopaantal ÷ minimaal koopaantal), begrensd door het aantal op de goedkoopste ontvangregel.discounts[].amountop de cart endiscount_totalop de order groeien mee; er is geen veld of enum-waarde gewijzigd. Zie Cart-kortingen. - Producten van het type
configurableworden uitsluitend door de configurator-engine geprijsd; klantgroep- en staffelprijsrijen die na een typewijziging zijn achtergebleven verschijnen niet meer inprice,quantity_tiersof de cart-regelprijs van zo'n product. Simpele producten zijn niet geraakt. Zie Producten. POST /v1/api/commerce/quotes/by-token/{token}/accept: deQUOTE_NOT_OFFERED-weigering die tijdens het opbouwen van de bestelling ontstaat (een race met een andere accept van dezelfde offerte) draagt nu het gedocumenteerde berichtQuote is not awaiting a response (status: ...)in plaats vanQuote cannot be accepted in its current status (...). Code en status zijn ongewijzigd. Zie Offertetokens.
2026-09-04
Gewijzigd
- Een configurator-keuze waarvan de
requires-regel niet vervuld kan worden door de andere gepubliceerde keuzes wordt nu weggelaten uitGET /v1/api/commerce/configurator/products/{id}/schema, in plaats van gepubliceerd te worden en daarna bij het opvragen van een quote afgewezen te worden. Het filteren werkt door, dus elke keuze die het schema toont kan geselecteerd en geprijsd worden. Zie Configuratieschema en Hoe de configurator werkt. POST /v1/api/commerce/configurator/products/{id}/quotepast dezelfde beschikbaarheidsregel toe: een keuze selecteren die het schema niet meer publiceert faalt met het bestaande generiekechoices-bericht, en dechoices.{choiceId}-berichten noemen nu alleen nog keuzes die beschikbaar zijn, zodat een gedeactiveerde keuze nooit in een foutmelding wordt prijsgegeven. Zie Prijsofferte.- Een prijsmatrix met een condition op een niet-beschikbare keuze wordt nu weggelaten uit
price_matricesin plaats van vermeld te worden met een ingekorteconditions-array. Zo'n matrix kan nooit in aanmerking komen, dus de engine beschouwt de configuratie alsnot_priceablein plaats van erop terug te vallen. Zie Configuratieschema.
Opmerkingen
- Documentatiecorrectie op beide configurator-endpoints: ze accepteren een API key met ofwel de scope
catalog:readofwelcommerce:read(ongewijzigd sinds 2026-08-25), en hun module-gate is de catalog-module, dus de 403-body luidt{"error":"Module not enabled: catalog"}. De referentie noemde voor beidecommerce:readencommerce. Er is niets aan de API veranderd. Zie Prijsofferte, Configuratieschema en Hoe de configurator werkt.
2026-08-26
Toegevoegd
- Customer-endpoints worden nu ook aangeboden op
/v1/api/contacts/*; de eerdere/v1/api/customers/*paden blijven bestaan als permanente alias met identieke request- en responsevormen. Nieuwe API-key scopescontacts:readencontacts:writezijn beschikbaar; bestaandecustomers:read/customers:writekeys blijven ongewijzigd werken. Zie Contactaccounts. - Het contactprofiel (
GET/PATCH /v1/api/contacts/me, ook.../customers/me) bevat nukind(personofcompany),company_name,registration_number,vat_id,external_id, endisplay_name. Deze velden zijn alleen-lezen via de storefront API.emailkan nunullzijn voor elk door de handelaar aangemaakt contact; registratie via de storefront vereist het nog steeds. Zie Profiel. - Het veld
typevan een adres accepteert een nieuwe waarde,work, naastshippingenbilling. Zie Adressen. contact_idop bestelling- en merchant-offerteobjecten: dezelfde waarde alscustomer_id, onder de canonieke naam vanaf nu.customer_idverandert niet en blijft bestaan. Het token-geadresseerde offerteobject bevat geen van beide. Zie Bestellingen en Checkout.- De offertetoken-endpoints worden nu ook aangeboden op
/v1/api/sales/quotes/by-token/{token}(GET,/accept,/decline)./v1/api/commerce/quotes/by-token/*blijft identiek en permanent werken; beide paden accepteren een key metsales:read/sales:writeofcommerce:read/commerce:write. Zie Offertetokens. GET /v1/api/{sales,commerce}/quotes/by-token/{token}retourneertorigin,intro,terms,scope_items[],acceptance_mode,pdf_url,signed_atensigned_pdf_url; elk item vanlines[]krijgt erkind,unit,descriptionentax_ratebij. Zie Offertetokens.POST /v1/api/{sales,commerce}/quotes/by-token/{token}/acceptaccepteert een optionele body-parametersignature— een PNG-data-URL van hoogstens 2 MB, verplicht wanneer deacceptance_modevan de winkelsignatureis — en retourneertsigned_pdf_url. Nieuwe foutcodesSIGNATURE_REQUIRED(422),SIGNATURE_INVALID(422),QUOTE_NOT_ORDERABLE(422),ALREADY_CONVERTED(409) enQUOTE_EXPIRED(410). Zie Offertetokens.- Nieuwe scopes
sales:readensales:write, overal geaccepteerd waarcommerce:read/commerce:writewordt geaccepteerd op de offertetoken-endpoints. Zie Authenticatie. - De
statusvan een offerte kan nudraftzijn: door de merchant geschreven offertes bestaan voordat ze worden verstuurd. Een draft heeft geen nummer en is nooit bereikbaar via token.
Gewijzigd
- Customer-endpoints vereisen niet langer dat een module is ingeschakeld; het 403-antwoord
Module not enabled: customerskan niet meer voorkomen. Zie Klantaccounts en Errors en rate limits. - Offerteregel
quantity(merchant-offertes en het token-geadresseerde offerteobject) wordt nu gedocumenteerd alsnumberin plaats vaninteger: productregels melden nog steeds altijd een heel getal, maar dienst- en materiaalregels kunnen nu een fractionele hoeveelheid bevatten (uren, meters). Elke voorheen geheeltallige waarde blijft exact hetzelfde serialiseren. Zie Offerteaanvragen en Offerte-tokens. - Accept en decline op de offertetoken-endpoints zijn beperkt tot 30 requests per minuut, gesleuteld op het IP-adres van de aanroeper. Zie Errors en rate limits.
Opmerkingen
lines[].quantityop de offertetoken-endpoints was altijd al een JSON-getal en is dat nog steeds; het mag nu fractioneel zijn (twee decimalen). Er is geen veld verwijderd, hernoemd of van type veranderd.
2026-08-25
Gewijzigd
- Publieke catalogusroutes (
/v1/api/commerce/products,/v1/api/commerce/categories,/v1/api/commerce/configurator/*) accepteren nu een API key met ofwel de scopecatalog:readofwelcommerce:read. Bestaande keys blijven ongewijzigd werken. Zie Authenticatie. - Nieuwe API-key scopes
catalog:readencatalog:writezijn beschikbaar voor winkels met de Catalog-module ingeschakeld. Scope-namen van alle andere modules zijn ongewijzigd.
Opmerkingen
- In deze release is geen requestparameter, responseveld, statuswaarde of error envelope gewijzigd.