Bol Retailer API: hoe de koppeling werkt, en waar het misgaat
Authenticatie, versieheaders, de rate limits per endpoint en het asynchrone model van v10, plus waar zelfgebouwde koppelingen stuklopen.
12 min lezen · voor bouwers en technisch e-commerce managers
- De Retailer API draait op
https://api.bol.com/retailer/, authenticeert via OAuth 2.0 oplogin.bol.com/tokenmet de client credentials-flow, en verwacht de versie in deAccept-header:application/vnd.retailer.v10+json. - Bijna alle schrijfacties zijn asynchroon. Je krijgt geen resultaat terug maar een
processStatusIddie je zelf moet nabellen. Wie dat overslaat, denkt dat voorraad is bijgewerkt terwijl dat niet zo is. - De rate limits verschillen sterk per endpoint:
/retailer/offers/*/stockmag 50 keer per seconde, maar/retailer/offers/exportmaar 9 keer per uur. Eén limiet voor je hele koppeling aannemen gaat mis.
Wie op bol verkoopt en meer dan een handvol artikelen heeft, komt vroeg of laat bij de Retailer API uit. Het verkoopdashboard is prima voor tien producten en onwerkbaar voor vijfhonderd. Deze pagina is de technische samenvatting die we zelf hadden willen hebben toen we de eerste koppeling bouwden: wat er precies staat, wat er niet staat, en waar het in productie stukgaat.
De officiële documentatie staat op developers.bol.com en is goed. Dit stuk vervangt hem niet, maar vult aan wat je pas merkt als je koppeling een paar maanden draait.
Wat wij doen, in één zin: maatwerkkoppelingen rechtstreeks op de bol Retailer API, tussen je webshop, je voorraad en je ERP of WMS, zonder tussenpartij.
De basis in zes regels
| onderdeel | waarde |
|---|---|
| Basis-URL | https://api.bol.com/retailer/ |
| Demo-omgeving | https://api.bol.com/retailer-demo/ |
| Authenticatie | OAuth 2.0, client credentials, via login.bol.com |
| Autorisatie | Authorization: Bearer <token> |
| Versie | in de header: Accept: application/vnd.retailer.v10+json |
| Datumformaat | ISO 8601, yyyy-MM-dd'T'HH:mm:ssXXX |
Twee dingen vallen mensen die van andere API's komen op.
Het eerste is dat de versie in de header staat en niet in de URL. Er is dus geen /v10/orders, maar /retailer/orders met een mediatype dat de versie draagt. Vergeet je die header, dan krijg je geen duidelijke foutmelding over een ontbrekende versie maar een 406 Not Acceptable, en dat is een uur zoeken waard als je het niet weet.
Het tweede is dat het mediatype ook het formaat bepaalt. Naast +json bestaan +csv en +pdf. Facturen haal je zo als pdf op zonder een apart endpoint: je verandert alleen de Accept-header.
Authenticatie
In je verkoopaccount maak je onder de API-instellingen een client aan. Je krijgt een client ID en een client secret. Die wissel je om voor een token:
POST https://login.bol.com/token?grant_type=client_credentials
Authorization: Basic base64(client_id:client_secret)
Het token dat je terugkrijgt is een paar minuten geldig. Bouw dus geen koppeling die per aanroep een nieuw token haalt, want dat is een extra netwerkronde bij elke API-call. Houd het token in het geheugen bij en ververs het pas als het bijna verloopt. Neem daarbij een marge van een minuut: als je precies op de vervaltijd ververst, loop je tegen requests aan die onderweg verlopen.
Werk je namens andere verkopers, dan bestaat er een aparte intermediair-autorisatie. Dat is een ander traject dan gewoon een client aanmaken en het is goed om dat te weten vóórdat je een dienst bouwt waar meerdere verkopers op zitten.
Het asynchrone model, en waarom het de meeste bugs veroorzaakt
Dit is het onderdeel waar zelfgebouwde koppelingen het vaakst op vastlopen, en het staat gewoon in de documentatie, het wordt alleen makkelijk overgeslagen.
Vrijwel elke POST, PUT en DELETE op de Retailer API doet zijn werk niet meteen. Je krijgt een ProcessStatus terug:
{
"processStatusId": "1234567",
"status": "PENDING",
"entityId": null
}
De status doorloopt PENDING en komt uit op SUCCESS, FAILURE of TIMEOUT. Meestal binnen een halve minuut. Het entityId wordt pas gevuld als de actie klaar is. Bij het aanmaken van een aanbieding is dat het offer-id dat je daarna nodig hebt.
Waar het misgaat: je zet een voorraadupdate weg, krijgt een 200 OK terug op je verzoek, en concludeert dat de voorraad is bijgewerkt. Dat is niet zo. Je hebt een opdracht ingediend die ook kan mislukken. Draait die koppeling elke tien minuten, dan lijkt alles goed te gaan tot de dag dat er een FAILURE tussen zit en niemand het merkt, want er wordt niet naar gekeken.
Wat je minimaal moet doen:
- de
processStatusIdopslaan bij de actie die hem veroorzaakte; - de status nabellen tot hij niet meer
PENDINGis, met oplopende wachttijden en niet in een strakke lus; - bij
FAILUREeen melding sturen die een mens leest, niet alleen een regel in een logbestand; TIMEOUTbehandelen als "onbekend" en niet als "mislukt", want de actie kan alsnog zijn doorgevoerd; opnieuw blind versturen levert dan dubbel werk op.
Statusrecords blijven ongeveer 24 uur bewaard. Verwerk je ze in een dagelijkse batch die 's nachts draait, dan zit je te dicht op die grens.
Rate limits: één getal bestaat niet
De rate limits verschillen per endpoint, en het verschil is groot. bol publiceert ze actueel op api.bol.com/retailer/public/ratelimits. De belangrijkste, zoals ze op 26 augustus 2026 stonden:
| endpoint | limiet |
|---|---|
/retailer/offers/*/stock | 50 per seconde |
/retailer/offers/*/price | 50 per seconde |
/retailer/offers (POST) | 50 per seconde |
/retailer/offers/* (GET) | 25 per seconde |
/retailer/orders/* | 25 per seconde |
/retailer/orders (lijst) | 25 per minuut |
/retailer/shipments (lijst) | 25 per minuut |
/retailer/returns | 20 per minuut |
/retailer/inventory | 20 per minuut |
/retailer/invoices | 24 per minuut |
/retailer/commission | 28 per seconde |
/retailer/shipping-labels | 240 per minuut |
/retailer/offers/export | 9 per uur |
/retailer/offers/unpublished | 5 per uur |
Let op het verschil tussen de eerste en de laatste rij. Losse voorraadupdates mogen vijftig keer per seconde; een volledige export van je aanbod mag negen keer per uur. Dat is geen willekeur: bol duwt je richting kleine, gerichte wijzigingen en weg van het steeds opnieuw ophalen van je hele catalogus.
Twee praktische gevolgen. Ten eerste: bouw je synchronisatie op wijzigingen en niet op volledige vergelijkingen. Wie elke tien minuten de hele exportlijst ophaalt om te kijken wat er veranderd is, zit na een uur zonder budget en heeft de rest van de dag geen enkele export meer.
Ten tweede: het onderscheid tussen limieten per seconde en per minuut is belangrijker dan het lijkt. /retailer/orders mag 25 keer per minuut, dus gemiddeld eens per 2,4 seconden. Een koppeling die orders per pagina doorloopt en dat zo snel mogelijk doet, is er in één seconde doorheen en zit dan 59 seconden op slot. Bouw een wachtrij met een vaste snelheid in plaats van het maximum te willen halen.
En bewaar de X-Request-ID uit je responses. Bij een storingsmelding aan bol is dat het eerste wat ze vragen, en zonder dat nummer wordt het een gesprek over gevoelens in plaats van over een verzoek.
Versiebeheer: wat er over rondgaat klopt niet meer
Dit staat verkeerd in veel Nederlandse bronnen, en het wordt sindsdien overal overgenomen: dat er twee keer per jaar, op 1 april en 1 oktober, een nieuwe API-versie uitkomt.
Zo werkte het, maar zo werkt het niet meer. v10 was de laatste keer dat de hele API in één keer op een nieuw versienummer ging. Daarna is bol overgestapt op versiebeheer per resource: endpoints krijgen los van elkaar een nieuwe versie.
Dat verandert hoe je onderhoud plant. Een jaarlijkse migratiesprint is niet meer genoeg. Je moet per resource de releasenotes volgen, en je koppeling zo bouwen dat het versiemediatype per endpoint instelbaar is en niet één constante voor de hele client. Dat laatste is vijf minuten werk als je het vooraf doet, en een vervelende refactor als je het achteraf moet.
De oude deadlines geven een idee van het tempo: v7 en v8 moesten voor 1 mei 2024 gemigreerd zijn, v9 voor 1 november 2024. Ongeveer een half jaar tussen aankondiging en afsluiting.
Vier plekken waar het in productie stukgaat
Wat we bij overnames van bestaande koppelingen het vaakst tegenkomen.
1. Voorraad die te laat op nul staat. De koppeling draait elke vijftien minuten. In die vijftien minuten verkoopt bol door. Bij een snelloper met twee stuks op voorraad levert dat een order op die je niet kunt leveren, en op bol drukt een annulering je kwaliteitsscore, en die wordt over 22 weken gemeten. De oplossing is niet vaker draaien maar een veiligheidsdrempel: onder een bepaald aantal stuks meld je minder voorraad dan je hebt, of je gebruikt de abonnementen (/retailer/subscriptions) zodat bol jou een seintje geeft in plaats van dat jij blijft vragen.
2. Retouren die nergens landen. Het retouren-endpoint wordt bij het bouwen vaak overgeslagen omdat het niet nodig is om te kunnen verkopen. Zes maanden later is er geen enkel zicht op welk product hoe vaak terugkomt en waarom, terwijl dat één van de weinige getallen is waar je marge echt aan hangt.
3. Fees die geschat worden. /retailer/commission geeft de daadwerkelijke commissie, en /retailer/invoices geeft de specificatie van wat er echt is ingehouden. We zien regelmatig koppelingen die in plaats daarvan met een vast percentage rekenen. Dat verschilt per categorie en per prijspunt, en het verschil tussen de schatting en de werkelijkheid is precies de marge waar je op stuurt.
4. Geen enkele melding als het stilvalt. De meest voorkomende. Een token dat niet ververst, een resource die van versie wisselt, een FAILURE die niemand leest. Een koppeling zonder alarm is geen koppeling maar een aanname. Bouw als laatste stap altijd een controle die schreeuwt als er een uur lang niets is gesynchroniseerd. Dat is minder werk dan alle bovenstaande fouten los oplossen.
Zelf bouwen of niet
Eerlijke afweging, want die vraag zit onder alle bovenstaande.
Zelf bouwen is verstandig als je koppeling iets moet doen wat standaardsoftware niet doet: je eigen inkoopprijzen meewegen, koppelen aan een ERP dat niemand ondersteunt, of logica draaien die specifiek is voor jouw assortiment. Dan betaal je één keer voor iets dat precies past, in plaats van maandelijks voor iets dat het half doet.
Standaardsoftware is verstandig als je nodig hebt wat iedereen nodig heeft: voorraad synchroon houden, orders binnenhalen, prijzen doorzetten. Dat is een opgelost probleem en het zelf bouwen levert je niets op behalve onderhoud.
Waar het in de praktijk op uitkomt: de meeste bedrijven hebben allebei nodig. De standaardsoftware doet het gewone werk, en daarnaast staat een eigen koppeling voor het stuk dat eigen is.
Geschikt voor: verkopers die tegen de grenzen van een standaardpakket aanlopen, een ERP of WMS draaien dat niet ondersteund wordt, of logica nodig hebben die hun eigen inkoopprijzen kent. In Channel manager of eigen koppeling staat uitgewerkt waar die grens meestal ligt.
Veelgestelde vragen
Waar vind ik mijn bol API-key?
In je bol verkoopaccount onder Instellingen → API-instellingen maak je een API-client aan. Je krijgt daar een client ID en een client secret. Dat zijn geen API-keys die je rechtstreeks meestuurt: je wisselt ze op login.bol.com/token om voor een access token, en dát token gaat mee in de Authorization-header. Het secret wordt één keer getoond. Sla het op in een secretmanager en niet in je broncode.
Is er een sandbox of testomgeving voor de bol API?
Ja. De demo-omgeving draait op https://api.bol.com/retailer-demo/ en gebruikt vaste voorbeelddata. Handig om je verwerking van de responsformaten te testen, maar hij bootst geen echte orderstroom na: je kunt er geen realistische voorraadrace of retourafhandeling mee testen. Voor die dingen heb je een echt account met een paar testartikelen nodig.
Hoe lang blijft een versie van de Retailer API geldig?
Hier gaat veel verouderde informatie over rond: dat er twee keer per jaar een nieuwe API-versie zou uitkomen. Dat klopt niet meer. v10 was de laatste keer dat de héle API in één keer op een nieuw versienummer ging. Sindsdien versiebeheert bol per resource, dus endpoints veranderen los van elkaar. Praktisch gevolg: je kunt niet één keer per jaar migreren en klaar zijn, je moet de releasenotes per resource volgen.
Wat is het verschil tussen de Retailer API en de Advertiser API?
De Retailer API gaat over verkopen: orders, verzendingen, retouren, aanbiedingen, voorraad, facturen. De Advertiser API gaat alleen over gesponsorde producten: campagnes aanmaken en prestatierapportages ophalen. Ze hebben eigen rate limits en een eigen autorisatie. Wil je advertentiekosten meenemen in je marge per product, dan heb je ze allebei nodig.
Waarom worden mijn voorraadupdates op bol soms niet doorgevoerd?
Bijna altijd omdat de processStatus niet wordt nagebeld. Een voorraadupdate is asynchroon: je krijgt een 200 OK op je verzoek en een processStatusId terug, maar de wijziging is pas echt doorgevoerd als die status op SUCCESS staat. Blijft hij op FAILURE hangen en kijkt niemand, dan denk je te synchroniseren terwijl er niets gebeurt. Wij zijn koppelingen tegengekomen die maandenlang op een deel van het assortiment stilstonden zonder dat het opviel.
Hoe ga ik om met de asynchrone verwerking van de bol Retailer API?
Sla de processStatusId op bij de actie die hem veroorzaakte, en bel de status na tot hij niet meer PENDING is, met oplopende wachttijden in plaats van een strakke lus. Meestal is dat binnen een halve minuut. Behandel FAILURE als een melding die een mens moet lezen en TIMEOUT als “onstatus onbekend” en niet als mislukt, want de actie kan alsnog zijn doorgevoerd. Statusrecords blijven ongeveer 24 uur bewaard, dus een nachtelijke batch die ze de volgende dag ophaalt zit te dicht op die grens.
Kan ik voorraad realtime bijwerken via de API?
Bijna. /retailer/offers/*/stock mag 50 keer per seconde aangeroepen worden, dus aan de kant van de limiet zit je niet snel vast. De vertraging zit erin dat de aanroep asynchroon is: je krijgt een processStatusId terug en de wijziging is pas echt doorgevoerd als die status op SUCCESS staat, meestal binnen een halve minuut. Voor voorraadbewaking betekent dat je een veiligheidsmarge moet aanhouden op snellopers, want in die halve minuut kan er nog verkocht worden.
- Channel manager of eigen koppeling · wanneer standaardsoftware ophoudt
- Repricing en de buy box op bol · prijzen aanpassen zonder je marge op te eten
- 12 automations voor bol-verkopers · wat je met deze API kunt bouwen
- Een API-koppeling laten maken · wat het kost en hoe zo'n traject loopt
- Overselling voorkomen · waarom een bevestigde update hier het verschil maakt
- Alle bol API rate limits · dagelijks gecontroleerd, met de geschiedenis
- Marge per verkoopkanaal · waar de commissie-endpoints voor dienen
Benieuwd of ons Automation Eco-System™ bij jouw bedrijf past?
In een vrijblijvend gesprek brengen we in kaart welke systemen jouw business nodig heeft.
Gratis 1-op-1 call met Job Lenselink