Wat je stuurt
Eén JSON-object. Alles wat je meegeeft wordt onderdeel van de casus; alles samen is maximaal 4.000 tekens.
| Veld | Type | Verplicht | Omschrijving |
|---|---|---|---|
case_date | string (YYYY-MM-DD) | Ja | De datum waarop de regels gelezen moeten worden. Niet in de toekomst, niet vóór 2000-01-01. |
description | string | Ja | De casus in gewone taal. Tussen 20 en 4.000 tekens. |
language | "nl" | "en" | Ja | De taal van het antwoord. |
absence_day | integer | Nee | De hoeveelste verzuimdag het is, geteld vanaf de eerste ziektedag. |
previous_interventions | string[] | Nee | Wat er al is geprobeerd. Maximaal tien regels van elk 300 tekens. |
manager_context | string | Nee | Wat de leidinggevende zegt of wil. Maximaal 1.000 tekens. |
occupational_health_status | string | Nee | De stand van zaken bij de bedrijfsarts. Maximaal 500 tekens. |
reference | string | Nee | Je eigen kenmerk voor de casus. Wordt de referentie van het dossier; zonder kenmerk genereert SIA er een. |
employee_role | string | Nee | De functie van de werknemer, bijvoorbeeld "magazijnmedewerker". Nooit een naam. Maximaal 80 tekens. |
first_sick_day | string (YYYY-MM-DD) | Nee | De eerste ziektedag, op of voor case_date. Met deze datum berekent SIA zelf de poortwachtertermijnen, geeft ze terug als timeline en neemt de volgende deadline daaruit over. |
events | object[] | Nee | Wat er sinds de eerste ziektedag is gebeurd: { kind, date, sanction_weeks }. kind is full_recovery, relapse, partial_recovery, second_track, deskundigenoordeel of loonsanctie; sanction_weeks (1 tot 52) alleen bij een loonsanctie. Alleen samen met first_sick_day, maximaal twintig. |
confirm_free_text | boolean | Nee | SIA controleert vrije tekst op termen die lijken op een diagnose, medische details, een leeftijd, een geslacht of details over derden. Bij een treffer volgt 422 free_text_confirmation met de treffers per veld. Haal ze weg, of stuur hetzelfde verzoek opnieuw met true als de tekst klopt. |
triage | object | Nee | De triagekaart uit het portaal: { factors, boundary, next_step_owner, signals }. factors uit medical (alleen het proces), conflict, workload, performance, organisational, personal, unclear; boundary uit self, company_doctor, labour_expert, legal, mediation, sia_human; next_step_owner is case_manager, manager, hr of external. Wordt bij de casus bewaard en door de analyse gelezen. Met boundary sia_human en geen andere factor dan unclear gaat de casus direct naar een expert: er draait geen analyse en er wordt niets geteld. Je krijgt 202 met status awaiting_confirmation en de aanbeveling van SIA (expert_recommendation). Er wordt via de API geen expertticket geopend: de eigenaar van de casus bevestigt de expertbeoordeling in SIA via confirm_url. |
department | string | Nee | De afdeling, zoals op het casusformulier. Hooguit 120 tekens. |
absence_type | "full" | "partial" | Nee | Volledig of gedeeltelijk verzuim. |
client_employer_id | uuid | Nee | De klantwerkgever waarvoor de casus is, uit je eigen werkruimte. SIA gebruikt dan het geheugen en profiel van die klant naast dat van de werkruimte, en van geen andere klant. |
Wat je terugkrijgt
Dezelfde velden als elk antwoord en elke analyse in het portaal, de spine.
| Veld | Type | Omschrijving |
|---|---|---|
case_id | uuid | Het dossier. Hiermee haal je de analyse later weer op. |
category | string | answer, insufficient_information, expert_judgement_required of refused. |
assessment | string | Wat hier volgens SIA werkelijk aan de hand is. |
reasoning | string | De juridische en procedurele redenering, met verwijzingen [1] naar de bronnen hieronder. |
action | string | De volgende stap: wat, door wie, wanneer. |
deadline | object | null | { date, label, days_from_case_date }, of null als er geen volgende datum is. Het aantal dagen wordt door SIA berekend en is null als er geen datum staat. Met first_sick_day komt de datum uit de berekende tijdlijn, niet van het model. |
risk | string | Wat er misgaat als de actie uitblijft. |
sources | array | { title, version, article, status } per bron. Alleen bronnen die daadwerkelijk zijn gebruikt en gecontroleerd. |
confidence | "low" | "medium" | "high" | Hoe zeker SIA van deze analyse is. |
escalation | object | { required, reason, to }. to is expert_review of null. Bij required: true hoort deze casus ook bij een mens. |
missing_information | string[] | De één tot drie vragen die SIA beantwoord wil zien voordat het verdergaat. Leeg als die er niet zijn. |
ai_generated | true | Altijd true: de blokken in ai_blocks zijn geschreven door SIA, een AI-systeem (AI-verordening art. 50). Toon ze in je eigen systeem als AI-uitvoer. |
ai_notice | string | Een korte AI-melding in de taal van het antwoord, om naast de blokken te tonen. |
ai_blocks | string[] | De velden die SIA heeft geschreven: category, assessment, reasoning, action, deadline, risk, confidence, escalation en missing_information. sources, credits en timeline zijn geen AI-tekst. |
credits | object | { charged, balance }: het verbruik van deze aanroep en wat er over is, in eenheden. Bij een GET is charged altijd 0. Het veld heet in v1 nog credits. |
timeline | object[] | null | De poortwachtertermijnen, berekend vanaf first_sick_day: { key, rule, week, due, status, basis, shiftedBy, until }. status is upcoming, due_soon, overdue of done; basis is het artikel of de paragraaf van de Werkwijzer. null als er geen first_sick_day is meegestuurd. |
Een voorbeeld
Vervang sia.example.com door het adres van je eigen werkruimte.
Aanroep
curl -X POST https://sia.example.com/api/v1/intelligence \
-H "Authorization: Bearer sia_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"case_date": "2026-09-10",
"absence_day": 62,
"description": "Een medewerker is op 10 juli uitgevallen na een conflict met zijn leidinggevende over de roosterindeling. Er is nog geen plan van aanpak opgesteld.",
"previous_interventions": [
"Gesprek met HR op 24 juli"
],
"manager_context": "De leidinggevende wil een vaststellingsovereenkomst bespreken.",
"occupational_health_status": "Spreekuur op 5 augustus; geen medische beperkingen.",
"language": "nl",
"reference": "WT-0447",
"employee_role": "magazijnmedewerker"
}'Antwoord
{
"case_id": "2d83f619-e968-489d-935a-362f6907de11",
"category": "expert_judgement_required",
"assessment": "Op verzuimdag 62 ontbreekt het plan van aanpak, terwijl het spreekuur van de bedrijfsarts op 5 augustus vermoedelijk aanleiding gaf om dit uiterlijk twee weken later op te stellen.",
"reasoning": "De wettelijke termijn is twee weken na het oordeel van de bedrijfsarts wanneer er mogelijkheden zijn om terugkeer naar arbeid te bevorderen [3]. Omdat niet duidelijk is of op 5 augustus een formele probleemanalyse of schriftelijk oordeel is uitgebracht, is de precieze grondslag van de termijn nog te bevestigen.",
"action": "Stel vandaag samen met de werknemer een schriftelijk plan van aanpak op en leg de afzonderlijke vraag over de vaststellingsovereenkomst ter beoordeling voor aan een SIA-expert (SIA Expert Review).",
"deadline": {
"date": "2026-09-10",
"label": "Onverwijld herstellen van het ontbrekende plan van aanpak",
"days_from_case_date": 0
},
"risk": "Zonder actie blijven concrete re-integratiedoelen, termijnen, evaluatieafspraken en verantwoordelijkheden ontbreken en blijft het re-integratiedossier onvolledig.",
"sources": [
{
"title": "Regeling procesgang eerste en tweede ziektejaar",
"version": "2025-07-01",
"article": "Regeling procesgang eerste ziektejaar > Artikel 4. Het plan van aanpak",
"status": "legal_requirement"
},
{
"title": "Werkwijzer Poortwachter",
"version": "2022-08-01",
"article": "3.2 Onderdelen re-integratieverslag",
"status": "official_guidance"
}
],
"confidence": "medium",
"escalation": {
"required": true,
"reason": "Het bespreken en beoordelen van een vaststellingsovereenkomst vraagt om menselijke juridische beoordeling door een SIA-expert en moet gescheiden blijven van de verzuimbegeleiding.",
"to": "expert_review"
},
"missing_information": [
"Is op 5 augustus een formele probleemanalyse of een schriftelijk advies van de bedrijfsarts uitgebracht?",
"Ligt er al een concreet voorstel voor een vaststellingsovereenkomst?"
],
"ai_generated": true,
"ai_notice": "Gegenereerd door SIA, een AI-systeem. Dit is een advies, geen besluit: een mens beoordeelt het voordat er iets gebeurt. Geen medisch of juridisch advies.",
"ai_blocks": ["category", "assessment", "reasoning", "action", "deadline", "risk", "confidence", "escalation", "missing_information"],
"credits": {
"charged": 0,
"balance": 1220
}
}Categorieën
Elk antwoord zegt zelf van welke soort het is, zodat je systeem er iets anders mee kan doen.
| Waarde | Betekenis |
|---|---|
answer | Een antwoord op de casus zoals die is voorgelegd. |
insufficient_information | SIA raadt niet. De vragen die nodig zijn staan in missing_information; stuur ze beantwoord opnieuw in. |
expert_judgement_required | De casus hoort bij een mens. escalation.to is expert_review en escalation.reason zegt waarom. |
refused | Buiten de grens: medisch, privacygevoelig of formeel-juridisch. Het antwoord zegt in gewone taal waarom. |
Bronstatus
Elke bron draagt haar eigen gezag. Wetgeving en officiële richtlijnen gaan vóór praktijk en oordeel als die elkaar tegenspreken, en het antwoord zegt dat dan ook.
| Waarde | Betekenis |
|---|---|
legal_requirement | Wetgeving. Niet onderhandelbaar. |
official_guidance | Richtlijnen van de overheid of UWV, zoals de Werkwijzer Poortwachter. |
sia_best_practice | Het eigen materiaal van de praktijk: protocollen, sjablonen, brieven. |
expert_judgement | Het redeneerkader en de casusbibliotheek van de SIA-expert zelf. |
licensed_source | Ingekocht of gelicentieerd materiaal. |
sia_concept | Eigen materiaal van de praktijk dat nog niet volledig is geverifieerd. |
Verbruik en limieten
Een analyse telt als 5 eenheden verbruik, en pas als er ook echt een antwoord is: bij category insufficient_information of expert_judgement_required is charged 0 en telt er niets. Is het verbruik van je werkruimte op, dan antwoordt het endpoint 402 met code credits en wat er nog over is. Ophalen met GET telt niet mee. Het JSON-veld en de foutcode heten in v1 nog credits, zodat bestaande koppelingen blijven werken; ze gaan over hetzelfde verbruik.
Per sleutel gelden 30 analyses per tien minuten, met een eigen budget voor het ophalen. Over de limiet volgt 429 met een Retry-After-header.
Foutcodes
401 missing_keyGeen Authorization-header, of geen Bearer-schema.401 invalid_keyDe sleutel is onbekend of ingetrokken.400 invalid_requestDe velden kloppen niet. errors zegt per veld wat eraan mankeert.402 creditsHet verbruik van je werkruimte is op. Het object credits geeft balance en required, in eenheden.429 rate_limitedTe veel aanroepen. Retry-After zegt hoe lang.429 spend_capJe werkruimte heeft de verwerkingslimiet van vandaag bereikt. Die gaat om middernacht (Amsterdamse tijd) weer open; Retry-After zegt hoe lang. Er is niets geanalyseerd of geteld.402 trial_expiredDe proefperiode of het abonnement van je werkruimte is afgelopen, dus de werkruimte is alleen-lezen. Nieuwe analyses wachten tot er een abonnement is; lezen blijft werken.403 workspace_deletedDeze werkruimte is verwijderd, dus de sleutels werken niet meer.404 case_not_foundGeen geanalyseerd dossier van jou met dat id.401 key_expiredDe sleutel is verlopen. Maak een nieuwe aan.403 insufficient_scopeDe sleutel mist de scope die dit endpoint vraagt.400 invalid_idempotency_keyDe Idempotency-Key is leeg, te lang of bevat ongeldige tekens.409 idempotency_in_progressEen aanroep met deze Idempotency-Key loopt nog.422 idempotency_mismatchDeze Idempotency-Key is al gebruikt met een andere body.422 free_text_confirmationVrije tekst bevat termen die SIA niet nodig heeft. hits noemt per treffer het veld (field), het soort (kind) en de term. Stuur opnieuw zonder die termen, of met confirm_free_text: true.422 pii_detectedDe tekst bevat persoonsgegevens zoals een BSN, e-mailadres of telefoonnummer. Dit kan niet worden bevestigd: haal ze weg.422 expert_review_unavailableDe triage stuurt de casus direct naar een SIA-expert (sia_human), maar expertbeoordeling staat uit voor je werkruimte. Er is niets geopend of geteld.409 reference_takenJe werkruimte heeft al een casus met deze referentie. Er is niets geanalyseerd of geteld.400 client_employer_unknownEr is geen actieve klantwerkgever met deze client_employer_id in je werkruimte.409 no_case_ownerNiemand in de werkruimte kan eigenaar van de casus zijn: de eigenaar en maker van de sleutel zijn weg en er is geen actieve eigenaar.504 provider_timeoutDe analyse duurde te lang en is gestopt. Er is niets geteld; probeer het opnieuw.400 invalid_jsonDe body is geen leesbare JSON.403 plan_requiredDe API hoort niet bij het abonnement van deze werkruimte (alleen Organisation).403 module_disabledDe API-module staat uit voor deze werkruimte.403 workspace_suspendedSIA heeft deze werkruimte gepauzeerd; de sleutels werken tijdelijk niet.500 analysis_failedDe analyse is aan onze kant misgegaan. Er is niets geteld; probeer het opnieuw.
Scopes en vervaldatum
Een sleutel mag alleen wat je hem bij het aanmaken geeft. Sleutels van vóór deze versie hebben beide scopes en verlopen niet.
| Waarde | Betekenis |
|---|---|
analysis:write | Casussen laten analyseren met POST /api/v1/intelligence. Telt mee voor verbruik. |
analysis:read | Opgeslagen analyses ophalen met GET /api/v1/intelligence/{case_id}. |
Een sleutel kan een laatste geldige dag krijgen. Daarna antwoordt elke aanroep 401 met code key_expired; een sleutel zonder de juiste scope krijgt 403 met code insufficient_scope. Bij elke aanroep worden het tijdstip en het IP-adres bewaard, zodat je in Instellingen ziet welke sleutel nog gebruikt wordt.
Idempotentie
Een analyse telt mee voor verbruik, dus opnieuw proberen na een time-out mag niet dubbel tellen. Stuur daarom bij POST een Idempotency-Key-header mee: een eigen, unieke waarde per casus, zoals een UUID.
- Dezelfde sleutel met dezelfde body binnen 24 uur geeft het opgeslagen antwoord terug, met de header Idempotent-Replayed: true. Er wordt niets opnieuw geanalyseerd of afgeschreven.
- Dezelfde sleutel met een andere body geeft 422 met code idempotency_mismatch.
- Loopt de eerste aanroep nog, dan volgt 409 met code idempotency_in_progress. Probeer het na een paar seconden opnieuw.
- Alleen een geslaagde analyse wordt bewaard. Na een fout is de sleutel weer vrij, zodat je dezelfde sleutel opnieuw kunt gebruiken.
Aanroep met Idempotency-Key
curl -X POST https://sia.example.com/api/v1/intelligence \
-H "Authorization: Bearer sia_YOUR_KEY" \
-H "Idempotency-Key: 6f1d2c0e-4b8a-4e59-9a3b-2f7c1d9e8a41" \
-H "Content-Type: application/json" \
-d @case.jsonWebhooks
In plaats van te pollen kun je SIA een bericht laten sturen naar een https-adres van jezelf. Webhooks stel je in bij Instellingen → API.
| Waarde | Betekenis |
|---|---|
analysis.completed | Een analyse is klaar, via de API of via het scherm. data bevat case_id, case_date, category, confidence, escalation_required, source (api of app) en ai_generated met een ai_notice, omdat de categorie, de zekerheid en de escalatie uitvoer van SIA zijn. |
expert_review.answered | Een SIA-expert heeft een vraag uit je werkruimte beantwoord. data bevat ticket_id en answer_id. |
- Elke levering is een POST met een JSON-body en de headers SIA-Event, SIA-Delivery, SIA-API-Version en SIA-Signature. Antwoord binnen 5 seconden met een 2xx-status.
- Lukt een levering niet, dan probeert SIA het opnieuw met oplopende wachttijden (1, 4, 16, 64 en 256 minuten), tot 6 pogingen in totaal. SIA-Delivery blijft bij elke poging gelijk, zodat je dubbele leveringen kunt herkennen.
- Na 20 mislukte pogingen op rij wordt het adres uitgeschakeld en krijgen de eigenaren van de werkruimte een e-mail. Weer inschakelen kan in Instellingen.
- Met de knop Testbericht sturen ontvang je een webhook.test-bericht, ondertekend zoals elke echte levering.
Een levering
POST /your/endpoint HTTP/1.1
Content-Type: application/json
SIA-Event: analysis.completed
SIA-Delivery: 0b7e3c1a-5d2f-4e8b-9c6a-1f2e3d4c5b6a
SIA-API-Version: 2026-09-23
SIA-Signature: t=1758614400,v1=5d41402abc4b2a76b9719d911017c592...
{
"id": "0b7e3c1a-5d2f-4e8b-9c6a-1f2e3d4c5b6a",
"type": "analysis.completed",
"created_at": "2026-09-23T08:00:00Z",
"api_version": "2026-09-23",
"data": {
"case_id": "2d83f619-e968-489d-935a-362f6907de11",
"case_date": "2026-09-10",
"category": "answer",
"confidence": "medium",
"escalation_required": false,
"source": "api",
"ai_generated": true,
"ai_notice": "Gegenereerd door SIA, een AI-systeem. Dit is een advies, geen besluit: een mens beoordeelt het voordat er iets gebeurt. Geen medisch of juridisch advies."
}
}De handtekening controleren
SIA-Signature heeft de vorm t=<unix-tijd>,v1=<hex>. v1 is een HMAC-SHA256 met het geheim van het adres als sleutel, over de tijd, een punt en de ruwe body. Reken dezelfde waarde uit, vergelijk in constante tijd en weiger berichten waarvan t meer dan vijf minuten afwijkt. Gebruik de body precies zoals ontvangen, vóór het parsen.
Node.js
import { createHmac, timingSafeEqual } from 'node:crypto';
// rawBody: the request body exactly as received, before JSON.parse.
export function verifySia(rawBody, header, secret, toleranceSeconds = 300) {
const parts = Object.fromEntries(header.split(',').map((p) => p.split('=')));
const t = Number(parts.t);
if (!Number.isInteger(t) || Math.abs(Date.now() / 1000 - t) > toleranceSeconds) return false;
const expected = createHmac('sha256', secret).update(`${t}.${rawBody}`).digest();
const given = Buffer.from(parts.v1 ?? '', 'hex');
return given.length === expected.length && timingSafeEqual(given, expected);
}Python
import hashlib, hmac, time
# raw_body: the request body as bytes, exactly as received.
def verify_sia(raw_body: bytes, header: str, secret: str, tolerance: int = 300) -> bool:
parts = dict(p.split("=", 1) for p in header.split(","))
t = int(parts.get("t", "0"))
if abs(time.time() - t) > tolerance:
return False
signed = f"{t}.".encode() + raw_body
expected = hmac.new(secret.encode(), signed, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, parts.get("v1", ""))Versies en uitfasering
Elk antwoord van /api/v1 draagt de header SIA-API-Version: 2026-09-23. Velden toevoegen, nieuwe events en nieuwe foutcodes gebeuren binnen deze versie; lees daarom velden die je niet kent niet als fout. Alles wat een bestaande integratie kan breken, komt in een nieuwe versie met een nieuwe datum.
Een versie of veld dat verdwijnt, kondigen we minstens 12 maanden van tevoren aan, op deze pagina en per e-mail aan de eigenaren van werkruimtes met een actieve sleutel.