API

Lees uw paspoorten en uw ketenregister uit, voeg leveranciers toe en laat u door ons waarschuwen zodra er iets verandert. De API hoort bij Plus. De sleutel maakt u aan in Mijn Ketenpas onder API; hij wordt één keer getoond.

Sleutel aanmaken in Mijn Ketenpas

Aanmelden

Elk verzoek draagt de sleutel als bearer-token. Antwoorden zijn json, ook bij een fout.

curl https://ketenpas.nl/api/v1/paspoorten \
  -H "Authorization: Bearer kp_uw_sleutel"

Limieten

120 verzoeken per minuut per organisatie, over alle routes samen. Uitnodigingen tellen daarnaast apart: 25 per uur, dezelfde emmer als het scherm gebruikt.

Entiteiten

Een sleutel hoort bij één organisatie. Werkt u met entiteiten, dan maakt u per entiteit een eigen sleutel aan; de API van de moeder toont geen gegevens van een dochter.

Routes

  • GET /api/v1/paspoorten

    Alle paspoorten van uw organisatie, met score, geldigheid en de deelbare link.

  • POST /api/v1/paspoorten/{id}/intrekken

    Trekt een paspoort in. De gedeelde link stopt meteen met werken, ook bij wie hem al had.

  • GET /api/v1/keten

    Uw ketenregister: elke leverancier met status, score en geldigheid.

  • POST /api/v1/keten

    Voegt een leverancier toe. Met "uitnodigen": true gaat de uitnodiging meteen de deur uit.

  • POST /api/v1/keten/{id}/uitnodiging

    Stuurt de uitnodiging (opnieuw) naar een leverancier die al in het register staat.

  • DELETE /api/v1/keten/{id}

    Haalt een leverancier uit het register. De uitnodigingslink loopt daarna dood.

Een paspoort

VeldTypeBetekent
iduuidHet id dat u bij intrekken meegeeft.
labelstring | nullDe eigen naam die u het paspoort gaf.
status"geldig" | "verlopen" | "ingetrokken"Alleen bij geldig is de link bruikbaar.
scorenumber0 tot 100, op de volledige vragenlijst.
niveaustringDe tekstuele uitslag die bij de score hoort.
beoordeeldOpstringISO 8601, de datum van de scan erachter.
geldigTotstringISO 8601.
ingetrokkenOpstring | nullISO 8601, leeg zolang het paspoort loopt.
urlstring | nullDe deelbare link; leeg zodra het paspoort niet meer geldig is.

Een leverancier

VeldTypeBetekent
iduuidHet id voor de routes hieronder.
naamstring
emailstringWaar de uitnodiging heen gaat.
contactpersoonstring | null
status"uitgenodigd" | "gekoppeld" | "vervallen"Uitgenodigd is ook de stand van wie nog niets ontving.
scorenumber | nullGevuld zodra er een geldig paspoort aan hangt.
niveaustring | null
beoordeeldOpstring | nullISO 8601.
geldigTotstring | nullISO 8601.
notitiestring | nullUw eigen aantekening bij deze leverancier.

Een leverancier toevoegen

naam en email zijn verplicht, contactpersoon en notitie mogen. Staat het adres al in uw register, dan komt er geen tweede rij bij maar een 409 met het id van de bestaande; een nachtelijke synchronisatie bouwt zo geen dubbelen op.

curl -X POST https://ketenpas.nl/api/v1/keten \
  -H "Authorization: Bearer kp_uw_sleutel" \
  -H "Content-Type: application/json" \
  -d '{"naam":"Van Dijk Techniek","email":"security@vandijk.nl","uitnodigen":true}'

Fouten

Elke fout is json met één veld: fout, met een zin erin die u kunt loggen. De statuscode is waar u op stuurt.

CodeBetekent
400De body is geen json, of een verplicht veld ontbreekt.
401Geen of onbekende sleutel.
403De sleutel is geldig maar het plan niet, of uw ketenlimiet is bereikt.
404Het id bestaat niet, of hoort bij een andere organisatie.
409De actie kan niet meer: al ingetrokken, of het adres staat al in uw register.
429Te veel verzoeken. Zie de limieten hierboven.
502Wij konden de uitnodiging niet versturen. De leverancier staat er wel.

Webhooks

In plaats van elke minuut het register op te halen, kunt u één https-adres opgeven waar wij aanbellen. Dat stelt u in onder API in Mijn Ketenpas; daar staat ook het geheim en de uitkomst van de laatste poging.

GebeurtenisWanneer
leverancier.gekoppeldEen leverancier heeft zijn paspoort met u gedeeld.
leverancier.vervallenHet gekoppelde paspoort van een leverancier is verlopen of ingetrokken. Wordt één keer gestuurd, in de nachtelijke ronde.
testHet testbericht vanaf de knop in Mijn Ketenpas.
POST https://uw-systeem.nl/ketenpas
X-Ketenpas-Gebeurtenis: leverancier.gekoppeld
X-Ketenpas-Handtekening: t=1785926400,v1=9f2c...

{
  "gebeurtenis": "leverancier.gekoppeld",
  "verstuurdOp": "2026-08-05T09:20:00.000Z",
  "gegevens": {
    "leverancier": {
      "id": "8f1d...",
      "naam": "Van Dijk Techniek",
      "email": "security@vandijk.nl"
    }
  }
}

De handtekening controleren

Elk bericht draagt de header X-Ketenpas-Handtekening met een tijdstempel en een hmac-sha256 over tijdstempel, punt, en de letterlijke body. Reken hem na met uw geheim en vergelijk in constante tijd. Wijs een bericht af waarvan de tijdstempel meer dan vijf minuten oud is.

const [t, v1] = kop.split(",").map((deel) => deel.split("=")[1]);
const verwacht = crypto
  .createHmac("sha256", geheim)
  .update(`${t}.${ruweBody}`)
  .digest("hex");

const klopt =
  verwacht.length === v1.length &&
  crypto.timingSafeEqual(Buffer.from(verwacht), Buffer.from(v1)) &&
  Math.abs(Date.now() / 1000 - Number(t)) < 300;

Wat wij beloven en wat niet

Wij proberen drie keer: meteen, na twee seconden en na acht seconden, met vijf seconden geduld per poging. Antwoordt u met 2xx, dan zijn we klaar; met 4xx stoppen we meteen, want dat wordt over acht seconden niet beter. Ligt uw kant er langer uit, dan is dat bericht weg: wij bewaren geen wachtrij. Gebruik GET /api/v1/keten als bodem onder uw administratie en de webhook om het sneller te weten.

Versies

Het pad draagt de versie. Binnen v1 komen er alleen velden bij, nooit weg; een veld dat verdwijnt of van betekenis verandert, wordt v2. Schrijf uw kant dus zo dat onbekende velden geen probleem zijn.