GLS webhook koppelen aan je TMS: stap voor stap
Stap-voor-stap: GLS NL track & trace webhook koppelen aan je TMS, met velden, JSON-payload, een pollingfallback en de meest voorkomende foutmelding.
Wat je na deze koppeling hebt
Na deze koppeling ontvangt je TMS automatisch statusupdates per pakket van GLS Nederland, zonder dat iemand handmatig het GLS-portaal moet checken. Concreet: statussen als "Afgeleverd", "Onderweg" of "Aangekondigd bij GLS" verschijnen automatisch in je TMS-dashboard, bijgehouden per zending. Deze handleiding laat je zien hoe je GLS koppelen aan TMS in de praktijk aanpakt, inclusief de polling-fallback voor als de webhook een keer wegvalt.
We hebben op dit blog al DPD, PostNL, DHL en bpost behandeld. GLS stond nog open, terwijl het als lokale carrier prima in het rijtje past voor NL/BE-verladers met een parcel-zwaar profiel. De GLS-documentatie staat gewoon publiek op api-portal.gls.nl, dus je kunt dit zonder NDA of accountmanager-gedoe naast je scherm openzetten terwijl je meebouwt.
Wat je nodig hebt voordat je begint
Zonder deze vier dingen kom je niet verder dan de documentatiepagina. Zorg dat je ze klaar hebt liggen voor je aan stap 1 begint.
- Een GLS-klantnummer en je MyGLS-gebruikersnaam en -wachtwoord. Deze zijn nodig om requests naar de API succesvol te versturen, want elk request bevat username en password in de body.
- Een account op api-portal.gls.nl. Om te interacteren met de API en API-keys te krijgen voor test- en productiesites, is een gebruikersaccount binnen het developer portal vereist.
- Een publiek bereikbare HTTPS-server voor je webhook-ontvanger, iets wat je zelf hebt geconfigureerd en dat direct benaderbaar is vanaf het internet.
- Duidelijkheid over welk GLS-contract je hebt. GLS Nederland en GLS Belgium/Luxemburg zijn twee losse integraties, met een apart klantcontract en eigen inlogportaal. Bedien je zowel NL als BE, dan bouw je dit twee keer.
De koppeling stap voor stap
Zeven stappen, van aanvraag tot productie. Reken op een dag ontwikkelwerk als je al ervaring hebt met vergelijkbare carrier-webhooks, en twee tot drie als dit je eerste is.
- Vraag GLS API-toegang aan via je accountmanager. Je hebt je klantnummer en MyGLS-inloggegevens nodig. Zonder geldig contract komt er geen productiesleutel, hoe goed je testomgeving ook werkt.
- Maak een account op api-portal.gls.nl en abonneer op de juiste producten. Voor deze koppeling wil je zowel de Track & Trace API als eventueel de Shipping API. De GLS Shipping API is een RESTful web service voor het printen van labels en het aanleveren van verzenddata, beschikbaar voor elke klant die zijn systeem direct wil koppelen. Door je op een product te abonneren krijg je losse test- en productiesleutels.
- Werk eerst volledig in de testomgeving. Binnen het portal staan test- en productieomgeving apart beschreven bij de producten, met eigen eindpunten en velddocumentatie. Bouw en verifieer je hele flow in test voordat je ook maar aan productie denkt.
- Zet je webhook-ontvanger op. Via de Track&Trace webhook is het mogelijk om automatisch real-time updates te ontvangen over de status van jouw pakketten, zodra er iets wijzigt zoals een aflevering, een bezorger onderweg, of een handtekening bij ontvangst. Als je hier gebruik van wilt maken dien je aan jouw kant een webserver te hebben geconfigureerd welke direct benaderbaar is vanaf het internet. Geef die URL door aan GLS en zij versturen je real-time updates voor al je pakketten, via een HTTP post waarin een JSON-bestand in de body van het request wordt meegestuurd. Elk pakket krijgt zijn eigen request; bij meerdere updates voor één pakket krijg je dus ook meerdere POST's.
- Map de JSON-velden naar je TMS-statuscodes. Een echt voorbeeld van zo'n payload bevat velden als "EventId", "EventNo", "ReasonNo", "DescriptionNL", "DescriptionEN", "Country", "Depot", "DepotName", "Date" en "IsPhysical". Gebruik
ReasonNoenDescriptionNLom je eigen statusmodel te vullen: een event met "ReasonNo":100, "DescriptionNL":"Aangekondigd bij GLS" zet je bijvoorbeeld op "Aangekondigd", terwijl je "Afgeleverd" herkent aan het aflever-event metIsPhysical: true. Bouw je mapping op basis vanReasonNo, niet op de vrije tekst inDescriptionNL, want die kan per GLS-versie licht wijzigen. - Bouw een pollingfallback via de Track & Trace API. Dit is je vangnet voor als een webhook-event zoekraakt. Het eindpunt is
POST /api/parcel/v1/details, en volgens de voorbeeldpayload op de portal-homepage stuur je username, password en een array van ParcelNumbers mee. Zo haal je in één call de actuele status op voor een hele batch pakketten, wat je kunt draaien als cronjob (bijvoorbeeld elke 30 minuten voor open zendingen). - Test end-to-end met een echte testzending. Verifieer dat het webhook-event binnenkomt op je endpoint, dat de status in je TMS matcht met wat in MyGLS staat, en dat er geen dubbele regels in je log verschijnen. Pas als dat drie keer op rij klopt, zet je de productie-API-key live.
Hoe je weet dat het werkt
Plaats een testzending en kijk of binnen enkele minuten na de eerste scan een webhook-POST op je endpoint binnenkomt. Check of het ParcelNo en EventId in je TMS-log staan, en dat er geen duplicaten ontstaan bij een tweede of derde update van hetzelfde pakket.
Sla daarvoor EventId op als unieke sleutel en negeer een tweede POST met hetzelfde ID. Dit heet idempotency, en het is precies het patroon dat brede webhook-architecturen aanraden: providers retry on failure, so the same event can arrive more than once, en zonder een check op een unieke identifier kun je dezelfde statuswijziging dubbel verwerken.
Storing: wat als je endpoint een fout teruggeeft?
De korte versie: bevestig razendsnel met een 200-status en verwerk pas daarna, en leun op de pollingfallback als vangnet voor gemiste events. GLS' eigen webhook-documentatie beschrijft geen ingebouwd retrybeleid zoals sommige grote SaaS-providers dat hebben. Geeft je server een 500 of een timeout terug, dan is er reëel risico dat het event niet automatisch opnieuw wordt aangeboden.
Dat maakt het extra belangrijk om je handler zo te bouwen dat hij nooit crasht op zware verwerking. De structurele fix is bekend uit bredere webhook-architecturen: verify the signature, persist the raw event durably, return 2xx immediately, and process asynchronously. Concreet: sla de ruwe payload eerst op in een queue of tabel, stuur direct een 200 terug naar GLS, en verwerk de statusupdate daarna in een achtergrondproces. Zo voorkom je dat een bug in je eigen verwerkingslogica leidt tot een endpoint dat GLS als kapot beschouwt.
Twee dingen om apart te noemen als praktisch afbreukrisico:
- Signature-mismatch bij toekomstige signing. Een klassieke fout is dat je de geparste JSON gebruikt in plaats van de ruwe request body om een handtekening te verifiëren. GLS signt de webhook nu niet, maar mocht dat veranderen, bewaar dan altijd de raw body naast de geparste versie. Het is sowieso een goede gewoonte voor elke carrier-webhook die je bouwt.
- Gemiste events door een tijdelijke server-outage. Dit is precies waarom stap 6, de polling-fallback, geen overbodige luxe is. Draai een periodieke check op openstaande zendingen ouder dan, zeg, twee uur zonder statusupdate, en haal die actief op via
/api/parcel/v1/details.
GLS in je bredere multicarrier-opzet
Zet je GLS naast PostNL, DPD en bpost, dan loop je snel tegen hetzelfde probleem aan: elke carrier heeft zijn eigen veldnamen, zijn eigen JSON-structuur en zijn eigen kijk op wanneer een pakket "onderweg" versus "afgeleverd" is. Bouw je dat voor vier carriers apart, dan onderhoud je vier keer dezelfde mapping-logica, met vier keer de kans op een vergeten edge case.
Platforms als nShift, Sendcloud, ShippyPro en Cargoson bestaan grotendeels om dat verschil weg te normaliseren tot één statusmodel. Een webhookfunctie in een TMS zorgt dat je systeem automatisch wordt genotificeerd zodra belangrijke events plaatsvinden, zoals zendingstatusupdates, nieuwe boekingen of wijzigingen in een zending. In de praktijk betekent dat: je bouwt één mapping naar je eigen interne statussen, en het platform vertaalt de carrier-specifieke velden (of dat nu GLS' ReasonNo is of een ander veld bij een andere vervoerder) naar dat model. Voor teams die vooral tijd willen besparen op onderhoud is dat een reële afweging tegen zelf bouwen, al blijft de aanpak in deze tutorial nuttig als je begrijpt wat er onder de motorkap gebeurt, of als je zelf maar één of twee carriers hoeft te koppelen.
Kort samengevat
Zeven stappen: toegang aanvragen bij je accountmanager, account maken op api-portal.gls.nl en abonneren op de juiste producten, alles eerst in test bouwen, je webhook-ontvanger opzetten en de URL doorgeven aan GLS, de JSON-velden mappen naar je eigen statussen op basis van ReasonNo, een pollingfallback bouwen via POST /api/parcel/v1/details, en pas na een schone end-to-end test live gaan.
Het grootste afbreukrisico is dat GLS geen ingebouwde retrygarantie biedt op de webhook. Bouw daarom altijd de polling-fallback mee, ook als de webhook in 99% van de gevallen prima werkt. Dat laatste procent is precies waar een gemiste "Afgeleverd"-status een klant onnodig laat wachten op een track & trace-mail die nooit komt.