Leveringen via de API
Maak, lees en wijzig leveringen met veldtabellen en complete voorbeelden.
Gebruik https://api.vlows.io met een key uit de console. Lezen vereist deliveries:read; aanmaken, wijzigen, gebeurtenissen en pogingen vereisen deliveries:write. Selecteer beide rechten als je koppeling schrijft én leest.
Gebruik een geregistreerde vervoerder
Vraag je contactpersoon bij vlows welke vervoerderscodes voor je organisatie beschikbaar zijn. Laat ontbrekende vervoerders eerst toevoegen. De code is uniek binnen je organisatie; je neemt hem exact over in courier.
curl --fail-with-body --silent --show-error \
'https://api.vlows.io/account/v1/couriers' \
-H "Authorization: Bearer $API_KEY"
Je stuurt geen body of filters. Het antwoord is een lijst met code en name per vervoerder, bijvoorbeeld {"data":[{"code":"demo","name":"Demo vervoerder"}],"error":null}. Dit is een voorbeeld; gebruik een code uit je eigen antwoord.
Een levering aanmaken
Aanvraag: POST /deliveries/v1/parcels.
| Plaats | Veld | Verplicht? | Invullen |
|---|---|---|---|
| Header | Authorization |
Ja | Bearer <jouw-api-key>. |
| Header | Content-Type |
Ja voor deze JSON-aanvraag | application/json. |
| Header | Idempotency-Key |
Ja | Nieuwe unieke sleutel van 8–128 bytes; bewaar voor retries. |
| Body | courier |
Ja | Geregistreerde vervoerderscode. |
| Body | country |
Ja | Exact "NL". |
| Body | postal_code |
Ja | Nederlandse postcode als tekst, bijvoorbeeld "9901KB". |
| Body | number |
Ja | Huisnummer als tekst, bijvoorbeeld "16". |
| Body | Overige pakketvelden | Nee of voorwaardelijk | Zie alle 41 velden. |
API_URL=https://api.vlows.io
curl --fail-with-body --silent --show-error \
-X POST "$API_URL/deliveries/v1/parcels" \
-H "Authorization: Bearer $API_KEY" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: levering-voorbeeld-0001' \
--data '{"courier":"demo","country":"NL","postal_code":"9901KB","number":"16","parcel_weight":1200}'
Vervang vervoerder en adres door de gegevens die je wilt registreren. Een geslaagde aanvraag slaat een levering op en geeft 201 terug. Bewaar data.entry_id voor vervolgaanvragen en de responseheader ETag voor versiecontrole. Een herhaling van exact dezelfde aanvraag met dezelfde idempotentiesleutel maakt geen tweede levering.
Uitgebreid voorbeeld
Dit voorbeeld voegt afmetingen, planning en een gepland bezorgadres toe. De tijden zijn 16 oktober 2026, 08:00–10:00 UTC. Gebruik je eigen werkelijke planning. Het is geen verplichte lijst: laat optionele gegevens weg die je niet kent.
{
"courier": "demo",
"country": "NL",
"postal_code": "9901KB",
"number": "16",
"parcel_length": 300,
"parcel_width": 200,
"parcel_height": 150,
"parcel_weight": 1200,
"time_slot_period_start": 1792137600,
"time_slot_period_end": 1792144800,
"delivery_status": 0,
"service_type": 1,
"delivery_vehicle": "bestelbus",
"planned_country": "NL",
"planned_postal_code": "9901KB",
"planned_number": "16",
"planned_location_type": 0
}
Wil je deze JSON versturen, bewaar hem als levering.json. Gebruik dezelfde POST-aanvraag als hierboven en vervang het --data-argument door --data-binary @levering.json. Kies voor iedere nieuwe levering een nieuwe idempotentiesleutel.
Dit betekent een pakket van 30 × 20 × 15 cm en 1,2 kg, met expressservice, bezorging aan de deur en status aangemeld. delivery_attempts wordt 0 omdat je geen historische pogingen hebt meegegeven. time_delivered en delivered_* ontbreken omdat er nog geen aflevering is vastgelegd.
Bij de response vind je ook version, created_at, updated_at en adrescontroles. address.status: "not_found" betekent dat het opgegeven adres niet exact is gevonden; lees de adresuitkomst ook als de levering succesvol is geregistreerd.
Een bestaande afgeleverde levering importeren
Bij de eerste registratie kun je een historische levering met status 4 aanleveren. Dan is time_delivered verplicht. Historische pogingslots zijn optioneel; als je ze invult, beginnen ze bij 1 en bevatten ze steeds tijd en uitkomst.
{
"courier": "demo",
"country": "NL",
"postal_code": "9901KB",
"number": "16",
"delivery_status": 4,
"time_delivered": 1792141200,
"delivered_country": "NL",
"delivered_postal_code": "9901KB",
"delivered_number": "16",
"delivered_location_type": 0,
"delivery_attempts": 2,
"time_attempt_1": 1792137600,
"attempt_1_outcome": 1,
"attempt_1_reason": 1,
"time_attempt_2": 1792141200,
"attempt_2_outcome": 0,
"attempt_2_reason": 0
}
Dit beschrijft twee pogingen: eerst niet thuis, daarna afgeleverd. delivery_attempts: 2 komt exact overeen met de twee ingevulde slots. De actuele aflevertijd en status zijn expliciet meegegeven. Gebruik voor een al bestaande levering de pogingenaanvraag om een nieuwe waarneming toe te voegen; maak niet nogmaals dezelfde levering aan.
Een levering opvragen
Aanvraag: GET /deliveries/v1/parcels/{id}.
Vervang {id} door de ontvangen entry_id. Stuur alleen de Authorization-header; er zijn geen body of filters nodig.
ENTRY_ID='<ontvangen-entry_id>'
curl --fail-with-body --silent --show-error -i \
"https://api.vlows.io/deliveries/v1/parcels/$ENTRY_ID" \
-H "Authorization: Bearer $API_KEY"
-i toont ook de headers. Noteer ETag, bijvoorbeeld "3", als je wilt wijzigen. data bevat de levering met de actuele versie en adrescontroles. Een onbekend of niet-toegankelijk ID geeft 404; een ongeldig UUID-formaat geeft 400.
Lijstfilters en paginering
Aanvraag: GET /deliveries/v1/parcels. Geen JSON-body. Alle filters zijn optioneel.
| Queryveld | Formaat | Standaard | Voorbeeld en gedrag |
|---|---|---|---|
limit |
Geheel getal 1–100 | 50 | limit=25 vraagt maximaal 25 resultaten. |
status |
Geheel getal 0–5 | Alle statussen | status=2 voor onderweg. |
courier |
Vervoerderscode als tekst | Alle vervoerders | courier=demo; exacte code uit jouw organisatie. |
cursor |
Ongewijzigde ontvangen cursor | Eerste pagina | Neem data.next_cursor uit het vorige antwoord over. |
curl --fail-with-body --silent --show-error --get \
'https://api.vlows.io/deliveries/v1/parcels' \
-H "Authorization: Bearer $API_KEY" \
--data-urlencode 'limit=25' \
--data-urlencode 'status=2' \
--data-urlencode 'courier=demo'
Het antwoord heeft data.items en data.next_cursor. De nieuwste registraties komen eerst. Zolang next_cursor niet leeg is, vraag je de volgende pagina op met dezelfde filters plus die cursor. Je hoeft de cursor niet zelf te ontleden of te maken.
Een lege items-lijst is geldig. Als next_cursor leeg is, ben je klaar. De lijst is bedoeld voor bladeren; haal voor complete actuele adrescontroles het detail van de gewenste levering op. Er is geen vrij tekstzoekveld of filter op klantnaam.
Een levering wijzigen
Aanvraag: PATCH /deliveries/v1/parcels/{id}. Gebruik een key met deliveries:write, de juiste UUID in het pad en Content-Type: application/json.
- Lees de levering en de actuele
ETagvia GET. - Kies alleen velden met PATCH ja in de veldgids.
- Stuur de ETag letterlijk mee als
If-Match, inclusief dubbele aanhalingstekens. - Verwerk het antwoord en bewaar de nieuwe versie.
curl --fail-with-body --silent --show-error \
-X PATCH "https://api.vlows.io/deliveries/v1/parcels/$ENTRY_ID" \
-H "Authorization: Bearer $API_KEY" \
-H 'Content-Type: application/json' \
-H 'If-Match: "3"' \
--data '{"parcel_weight":1500,"parcel_height":180}'
Vervang "3" door de werkelijk ontvangen ETag. In dit voorbeeld veranderen alleen gewicht en hoogte. Weggelaten velden blijven bestaan. Met null kun je een toegestaan optioneel numeriek veld wissen; optionele tekst maak je leeg met "". Bij gekoppelde velden moet het resultaat geldig blijven.
Een geslaagde wijziging geeft 200, de bijgewerkte levering en een nieuwe ETag. Een ontbrekende of verouderde If-Match geeft 412. Lees dan opnieuw en beoordeel je wijziging. Ook een adreshercontrole kan de versie verhogen.
Je kunt de vervoerder, status, aflevertijd, pogingenteller, afgeleverde adresvelden of historische pogingslots niet met PATCH wijzigen. Gebruik gebeurtenissen en pogingen voor voortgang en nieuwe bezorguitkomsten.
Veelgemaakte invoerfouten
| Invoer | Waarom gaat het mis? | Correctie |
|---|---|---|
"parcel_weight":"1200" |
Een getal als tekst. | Gebruik 1200. |
"number":16 |
Huisnummer is juist een tekstveld. | Gebruik "16". |
Alleen time_slot_period_start |
Het einde ontbreekt. | Stuur beide grenzen. |
delivery_status: 4 zonder tijd |
Afgeleverd vereist een aflevertijd. | Voeg time_delivered toe. |
time_delivered bij status 2 |
Een onderwegstatus mag geen aflevertijd hebben. | Laat de aflevertijd weg. |
Eén historisch slot en delivery_attempts: 3 |
Teller klopt niet met de ingevoerde slots. | Laat teller weg of gebruik 1. |
parcel_id of entry_id in de body |
Geen toegestane invoervelden. | Gebruik het ontvangen entry_id alleen in vervolgpaden. |
Niet geregistreerde courier |
De vervoerder hoort nog niet bij je organisatie. | Gebruik een bestaande code of laat registratie regelen. |