Medlemsdataoverfoersel Webhook API
Medlemsdataoverførsel giver eksterne systemer mulighed for at modtage opdateringer om medlemsdata via webhooks. Når der sker ændringer i medlemsoplysninger, sender systemet automatisk HTTP POST requests til registrerede webhook endpoints.
Dette gør det muligt for eksterne partnere at holde deres egne systemer synkroniseret med aktuelle medlemsdata uden at skulle lave gentagne API-kald.
Kom i gang
Registrer dit webhook endpoint
For at modtage webhooks skal du først få registreret dit endpoint hos DI.
Kontakt DI med følgende oplysninger:
- Din webhook URL (skal være HTTPS)
- Hvilke events du ønsker at modtage samt evt. hvilken version
- Version af webhook kan muligvis være bestemt af DI
- Kontaktinformation for support
Implementer endpoint
Dit endpoint skal:
- Acceptere HTTP POST requests
- Returnere status code 200 for at bekræfte modtagelse
- Respondere inden for [INDTAST TIMEOUT] sekunder
- Håndtere idempotens (samme event kan sendes flere gange)
- Være uafhængig af tidligere webhooks (Se race conditions)
- Have åbnet op for adgang fra DI's IP
Payload
Alle webhook requests sendes som HTTP POST med Content-Type: application/json.
Alle webhooks er dokumenteret via. OpenAPI v3.1.1 som har support for dokumentering af webhooks (https://learn.openapis.org/examples/v3.1/webhook-example.html).
Request Headers
Alle webhooks vil indholde følgende request headers
| HeaderName | Beskrivelse |
|---|---|
X-Webhook-Name | Navnet på webhooken |
X-Webhook-Version | Version på webhooken |
X-Event-ID | Event'ets ID. Hvis du har flere endpoints registeret på samme event vil ID'et være ens på tværs af dem |
X-Webhook-Request-Id | Webhook requestet's ID. Hvis du har flere endpoints registeret på samme event vil ID'et være forskellig på tværs af dem |
X-Webhook-Signature | Signature til verificering af oprindelse |
NOTE Vi anbefaler altid at tjekke om
X-Webhook-NameogX-Webhook-Versioner det man forventer.
Request Body
Hver Webhook Event sender forskellig request body, men vil som udgangspunkt altid være et JSON objekt.
For at se de enkeltes request body skal du kigge i dokumentationen for eventet.
Response
Successfulde
Hvis dit endpoint er i stand til successfuldt at håndtere requestet skal det sende "200 OK" tilbage.
Response body er optionel, men vi anbefaler ikke at sende noget
Fejlende
Alle fejlende status koder vil blive registeret som fejlende kald og vil blive planlagt til at blive udsendt igen på et senere tidspunkt.
NOTE: Der er ikke muligt stoppe genkørsler ved at sende et bestemt fejl response tilbage.
Genkørsler
Som udgangspunkt vil vi forsøge [X] antal gange.
- Første gang [intet delay fra initial udsendelsestidspunkt]
- Anden gang [X antal delay fra initial udsendelsestidspunkt]
- Tredje gang [X+Y antal delay fra initial udsendelsestidspunkt]
Hvis et endpointet er fejlet alle gangene vil vi stoppe med automatisk at kalde endpointet. Det vil dog stadig være muligt at få flere genkørsler hvis DI manuelt laver en ny genkørsel.
Andet
Det er anbefalet at man kan håndtere duplicated requests - både sucessfulde og fejlene - da det er muligt at genkøre allerede successfulde webhook requests. Til dette kan man eksempelvis benytte sig af "Inbox"-pattern og bruge X-Event-Id som identifier eller tjekke om ens handlinger allerede er udført.
Webhook Events
Medlemsdataoverførsel sender webhooks for følgende event types:
| Event Type | Beskrivelse |
|---|---|
Indmeldelse | Et medlem er blevet indmeldt<<link>> |
ForhaandsIndmeldelse | Et medlem er blevet indmeldt, men deres overenskomster er ikke trådt i kraft<<link>> |
TiltraedelsesIndmeldelse | Et medlem er blevet indmeldt, men deres nuværende overenskomster gør at de har karans og deres overenskomster træder først i kraft senere<<link>> |
Udmeldelse | Et hovedforhold er blevet udmeldt<<link>> |
TilmeldingAfAfdeling | En afdeling er blevet medlem<<link>> |
AfmeldingAfAfdeling | En afdeling er afmeldt/udmeldt<<link>> |
Fusion | 2 eller flere virksomheder er fusioneret<<link>> |
Race conditions
DI udstiller ingen garanti for rækkefølgen af modtagene webhooks, det er derfor vigtigt at dit endpoint ikke er afhængig af tidligere forventet webhooks.
Et eksempel på dette ville være at man ved "TilmeldingAfAfdeling" forventer at hovedforholdet allerede har haft sendt en "Indmeldelse". Ofte vil dette ske således
- "Indmeldelse" sendt på Hovedforhold.
- Håndtering af "Indmeldelse".
- "TilmeldingAfAfdeling" sendt på Afdeling.
- Håndtering af "TilmeldingAfAfdeling".
Men hvis dit endpoint for "Indmeldelse" fejler, så vil det sådan her ud
- "Indmeldelse" sendt på Hovedforhold.
- Håndtering af "Indmeldelse" fejler.
- "TilmeldingAfAfdeling" sendt på Afdeling.
- Håndtering af "TilmeldingAfAfdeling".
- Håndtering af "Indmeldelse" fejler [genkørsel 2].
- Håndtering af "Indmeldelse" successfuldt [genkørsel 3].
dermed vil evt. registeringer fra "Indmeldelse" ikke være registeret når "TilmeldingAfAfdeling" udføres.
NOTE: Som udgangspunkt vil payloads være designet til at kunne supportere uafhængighed, men hvis der er nogen bestemte behov skal du tage fat i DI og så kan vi finde en løsning.
Verificering af request oprindelse [optional, men anbefales]
Eftersom at dit endpoint kan eksistere på det åbne internet, så vil det være muligt for uvedkommende at sende requests til endpointet og dermed forurene jeres handlinger.
For at forhindre dette kan man vælge enten kun at modtage requests fra DI's IP adresse via. en allowlist/whitelist. Dette anbefales dog ikke, da IP fra DI kan ændre sig og skaber en unødvendig afhængighed til DI.
Verificering via. X-Webhook-Signature
Vi anbefaler at man benytter sig at request headeren X-Webhook-Signature til at verficiere at det request man har modtaget er fra os.
Ved registering af endpoint hos DI vil man få tildelt en "secret" som skal bruges til at verficere signaturen.
X-Webhook-Signature == Base64(HMAC-SHA256(Secret + WebhookRequestId)
WebhookRequestId bliver sendt til endpointet via. X-Webhook-Request-Id-headeren.
var secret = "my_secret";
var webhookRequestId = RequestHeaders["X-Webhook-Request-Id"]
var expectedSignature = Convert.ToBase64String(
SHA256.HashData(
Encoding.UTF8.GetBytes(secret + webhookRequestId)
)
);
var actualSignature = RequestHeaders["X-Webhook-Signature"];
if (!expectedSignature.Equals(actualSignature)) {
throw new UnauthorizedAccessException("Invalid signature");
}
// .. du har adgang :)
Versionering
DI garanterer at der ikke laves breaking changes på de forskellige besked formater via versionering af webhooks. Nye properties på beskeder kan tilføjes uden ændring i versionsnummer (minor changes), men fjernelse af properties eller ændring i formatet (breaking change) vil resulterer i en ny version af webhooken.
Hvis en Webhook Event's payload skema ændre sig vil det foregår via. minor changes - hvilket vil betyde at vi ikke ændrer på det eksisterende, men f.eks. tilføjer nye properties i payloaden.
Hvis der en nødvendighed fra DI's side som resulterer i breaking changes, så vil version nummeret på Webhook ændre sig.
Eksempler minor changes (ingen version-bump):
- Tilføjelse af nye properties.
- Tilføjelse af nye enum-værdier.
Eksempler breaking changes (ny version):
- Fjernelse af properties.
- Omdøbning af properties.
- Ændring af datatyper.
- Required property bliver optional.
NOTE Ved ny version vil DI kontakte jer og der vil blive lagt en plan for dette.
Andet
Hvornår bliver mit endpoint triggeret?
Medlemsdataoverfoersel har nogle regler om hvornår dit endpointet bliver triggeret. Det vil være når vi mener at det er relevant for dig på baggrund af regler defineret sammen med DI.
NOTE Kontakt DI hvis du har ændringer til de regler
Test af endpoint implementering
Medlemsdataoverfoersel udstiller ikke en mulighed for at teste ens endpoints. DI har lavet et eksempel projekt (<>) som man kan bruge som udgangspunkt.
NOTE Når I er klar til at gå i produktion med jeres endpoint vil dette foregå sammen med DI
Bliver jeg notificeret ved fejl?
Medlemsdataoverfoersel giver ikke automatisk notification hvis vi oplever at jeres endpoint gentagene gange fejler.
På nuværende tidspunkt overvåger vi manuelt fejlene endpoints og hvis vi ligger mærke til problemer vi vil tage fat i jer.
Mit endpoint har været nede i en periode hvordan kan jeg komme i sync?
Medlemsdataoverfoersel udstiller på nuværende tidspunkt ikke en mulighed for at man selv kan genkøre fejlene endpoints, og man vil derfor være nødt til at tage fat i DI.