{"openapi":"3.1.0","info":{"title":"Agreli API","version":"1.0.0","description":"Hosted Employee Onboarding: maak een onboarding aan, stuur de medewerker naar hosted_url, en volg de voortgang via webhooks.\n\nAuthenticatie met een API-sleutel als Bearer-token. Sleutels met hrs_test_ werken in je sandbox (fictieve medewerkers, opgevangen berichten, gesimuleerde salarisverwerking). Een sleutel handelt als de gebruiker die hem maakte, binnen één organisatie en met de gekozen rechten (scopes). Webhooks bevatten geen persoonsgegevens: haal details op met de API.\n\nVersies: elke sleutel en elk webhookadres onthoudt de API-versie van het moment van aanmaken (nu 2026-10-01). Kies per verzoek een andere met de kop Agreli-Version (bekend: 2026-10-01); het antwoord noemt de gebruikte versie in Agreli-Version. Nieuwe velden, events en endpoints komen er zonder nieuwe versie bij; alleen een wijziging die bestaande code breekt krijgt een nieuwe datumversie. Een oude versie blijft minstens 12 maanden na de opvolger werken."},"servers":[{"url":"https://app.agreli.nl/api/public"}],"security":[{"bearer":[]}],"paths":{"/v1/organizations":{"get":{"summary":"Organisaties die deze sleutel mag gebruiken","description":"Een werkgeverssleutel: de eigen organisatie. Een sleutel van een API-partner: alle werkgevers die de partner hebben toegelaten, met de rechten die ze gaven. Gebruik het id in de kop Agreli-Organization.","x-required-scope":"organization:read","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"const":"list"},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","examples":["org_…"]},"object":{"const":"organization"},"name":{"type":"string"},"permissions":{"type":"array","items":{"type":"string"}}}}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]}}}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/v1/organization":{"get":{"summary":"Organisatie, vestigingen, templates en toegestane domeinen","x-required-scope":"organization:read","parameters":[{"name":"Agreli-Organization","in":"header","required":false,"schema":{"type":"string","examples":["org_…"]},"description":"Alleen voor sleutels van een API-partner: de werkgever namens wie je werkt. Verplicht als de partner meer dan één werkgever heeft."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Organization"}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/v1/onboardings":{"get":{"summary":"Onboardings","description":"Nieuwste eerst, ook geannuleerde (filter met status). Een API-partner ziet alleen de onboardings die via zijn eigen sleutels liepen.","x-required-scope":"onboardings:read","parameters":[{"name":"status","in":"query","schema":{"type":"string","enum":["pending_employee","in_review","contract_ready","awaiting_employee_signature","awaiting_employer_signature","processing","action_required","completed","cancelled"]}},{"name":"reference","in":"query","schema":{"type":"string"}},{"name":"updated_since","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"starting_after","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"const":"list"},"data":{"type":"array","items":{"$ref":"#/components/schemas/Onboarding"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]}}}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}},"post":{"summary":"Hosted onboarding aanmaken","description":"Alleen met een lopende proef of een abonnement van wie betaalt (anders 403 subscription_required).","x-required-scope":"onboardings:write","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":200},"description":"Zelfde sleutel en inhoud binnen 24 uur geeft hetzelfde antwoord. Loopt het eerste verzoek nog, dan 409 idempotency_in_progress: probeer het zo opnieuw."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOnboarding"}}}},"responses":{"201":{"description":"Aangemaakt","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatedOnboarding"}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/v1/onboardings/{id}":{"get":{"summary":"Eén onboarding met stappen en documenten","x-required-scope":"onboardings:read","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Onboarding"}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}},"patch":{"summary":"Referentie en metadata bijwerken","description":"Voegt metadata samen; null verwijdert een sleutel. Gegevens van de medewerker wijzig je niet via de API (field_not_updatable). De data_version blijft gelijk, dus goedkeuringen blijven geldig.","x-required-scope":"onboardings:write","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":200},"description":"Zelfde sleutel en inhoud binnen 24 uur geeft hetzelfde antwoord. Loopt het eerste verzoek nog, dan 409 idempotency_in_progress: probeer het zo opnieuw."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"reference":{"type":["string","null"],"maxLength":200},"metadata":{"type":"object","maxProperties":20,"additionalProperties":{"type":["string","number","boolean","null"]},"description":"Je eigen kenmerken, bijvoorbeeld een vacature-id (sleutels: letters, cijfers, _ . -, hooguit 40 tekens; tekst hooguit 500). Komt terug in de API en in webhooks. Geen persoonsgegevens: e-mail, IBAN, BSN en telefoonnummers worden geweigerd (metadata_personal_data)."}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Onboarding"}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/v1/onboardings/{id}/hosted-link":{"post":{"summary":"Nieuwe hosted link (de vorige vervalt)","x-required-scope":"onboardings:write","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":200},"description":"Zelfde sleutel en inhoud binnen 24 uur geeft hetzelfde antwoord. Loopt het eerste verzoek nog, dan 409 idempotency_in_progress: probeer het zo opnieuw."}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"expires_in_hours":{"type":"integer","minimum":1,"maximum":336},"send_invitation":{"type":"boolean","default":false}}}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HostedLink"}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/v1/onboardings/{id}/cancel":{"post":{"summary":"Annuleren","x-required-scope":"onboardings:write","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":200},"description":"Zelfde sleutel en inhoud binnen 24 uur geeft hetzelfde antwoord. Loopt het eerste verzoek nog, dan 409 idempotency_in_progress: probeer het zo opnieuw."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Onboarding"}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/v1/onboardings/{id}/identity-verification":{"post":{"summary":"ID-controle bevestigen (als manager)","description":"Staat standaard uit: een eigenaar zet goedkeuren via de API aan bij Instellingen, API en webhooks (anders 403 api_approvals_disabled).","x-required-scope":"approvals:write","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":200},"description":"Zelfde sleutel en inhoud binnen 24 uur geeft hetzelfde antwoord. Loopt het eerste verzoek nog, dan 409 idempotency_in_progress: probeer het zo opnieuw."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Onboarding"}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/v1/onboardings/{id}/approvals":{"post":{"summary":"Goedkeuren als de eigenaar van de sleutel","description":"Vierogen: één persoon kan niet twee rollen vervullen. data_version moet gelijk zijn aan de gecontroleerde versie. Staat standaard uit: een eigenaar zet goedkeuren via de API aan bij Instellingen, API en webhooks (anders 403 api_approvals_disabled).","x-required-scope":"approvals:write","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":200},"description":"Zelfde sleutel en inhoud binnen 24 uur geeft hetzelfde antwoord. Loopt het eerste verzoek nog, dan 409 idempotency_in_progress: probeer het zo opnieuw."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["role","data_version"],"properties":{"role":{"enum":["manager","payroll_reviewer","owner"]},"data_version":{"type":"integer"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Onboarding"}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/v1/onboardings/{id}/contract":{"post":{"summary":"Contract maken en ter ondertekening versturen","x-required-scope":"contracts:write","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":200},"description":"Zelfde sleutel en inhoud binnen 24 uur geeft hetzelfde antwoord. Loopt het eerste verzoek nog, dan 409 idempotency_in_progress: probeer het zo opnieuw."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Onboarding"}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/v1/onboardings/{id}/documents":{"get":{"summary":"Documenten","x-required-scope":"documents:read","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"const":"list"},"data":{"type":"array","items":{"$ref":"#/components/schemas/Document"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]}}}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/v1/onboardings/{id}/documents/{documentId}":{"get":{"summary":"Document downloaden","description":"Kopieën van identiteitsbewijzen alleen voor de salarisadministratie. Elke download staat in de audit.","x-required-scope":"documents:read","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"documentId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Het bestand","content":{"application/pdf":{},"image/png":{},"image/jpeg":{}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/v1/employees":{"get":{"summary":"Medewerkers","x-required-scope":"employees:read","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"starting_after","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"const":"list"},"data":{"type":"array","items":{"$ref":"#/components/schemas/Employee"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]}}}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/v1/approvals":{"get":{"summary":"Wat jij nu kunt goedkeuren","x-required-scope":"approvals:read","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"const":"list"},"data":{"type":"array","items":{"$ref":"#/components/schemas/OpenApproval"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]}}}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/v1/integrations":{"get":{"summary":"Koppelingen en synchronisatiestatus","x-required-scope":"integrations:read","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/v1/webhooks":{"get":{"summary":"Webhookadressen","x-required-scope":"webhooks:manage","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"const":"list"},"data":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEndpoint"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]}}}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}},"post":{"summary":"Webhookadres toevoegen","description":"Het geheim (whsec_…) staat alleen in dit antwoord.","x-required-scope":"webhooks:manage","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":200},"description":"Zelfde sleutel en inhoud binnen 24 uur geeft hetzelfde antwoord. Loopt het eerste verzoek nog, dan 409 idempotency_in_progress: probeer het zo opnieuw."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri"},"description":{"type":"string"},"events":{"type":"array","items":{"enum":["contract.sent","contract.signed","contract.signed_by_employee","integration.sync_failed","integration.sync_succeeded","onboarding.approval_given","onboarding.approval_required","onboarding.approved","onboarding.cancelled","onboarding.completed","onboarding.contract_signed","onboarding.created","onboarding.employee_submitted","onboarding.failed","onboarding.invitation_sent","onboarding.returned","onboarding.started","onboarding.submitted","onboarding.terms_changed","payroll.completed"]},"description":"Leeg = alle gebeurtenissen."}}}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpoint"}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/v1/webhooks/{id}":{"get":{"summary":"Eén webhookadres met recente afleveringen","x-required-scope":"webhooks:manage","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpoint"}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}},"delete":{"summary":"Verwijderen","x-required-scope":"webhooks:manage","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":200},"description":"Zelfde sleutel en inhoud binnen 24 uur geeft hetzelfde antwoord. Loopt het eerste verzoek nog, dan 409 idempotency_in_progress: probeer het zo opnieuw."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/v1/webhooks/{id}/test":{"post":{"summary":"Testbericht (ping) sturen","x-required-scope":"webhooks:manage","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":200},"description":"Zelfde sleutel en inhoud binnen 24 uur geeft hetzelfde antwoord. Loopt het eerste verzoek nog, dan 409 idempotency_in_progress: probeer het zo opnieuw."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/v1/webhooks/{id}/rotate-secret":{"post":{"summary":"Geheim vernieuwen","description":"Het nieuwe geheim (alleen in dit antwoord) ondertekent direct. Het vorige ondertekent nog overlap_hours mee als tweede v1 in Agreli-Signature, zodat je zonder gemiste webhooks overstapt. 0 = het vorige is direct ongeldig.","x-required-scope":"webhooks:manage","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":200},"description":"Zelfde sleutel en inhoud binnen 24 uur geeft hetzelfde antwoord. Loopt het eerste verzoek nog, dan 409 idempotency_in_progress: probeer het zo opnieuw."}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"overlap_hours":{"type":"integer","minimum":0,"maximum":168,"default":24}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpoint"}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/v1/webhooks/{id}/deliveries":{"get":{"summary":"Afleverlog van één adres","description":"Nieuwste eerst. Afleveringen blijven 30 dagen zichtbaar.","x-required-scope":"webhooks:manage","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"status","in":"query","schema":{"enum":["pending","in_progress","succeeded","failed","dead"]}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"starting_after","in":"query","schema":{"type":"string"},"description":"next_cursor van de vorige pagina."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"const":"list"},"data":{"type":"array","items":{"$ref":"#/components/schemas/WebhookDelivery"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]}}}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/v1/webhooks/{id}/deliveries/{deliveryId}/retry":{"post":{"summary":"Aflevering opnieuw versturen","description":"Met hetzelfde event-id en dezelfde inhoud, dus je kunt ontdubbelen. Kan bij geslaagde, mislukte en definitief mislukte afleveringen.","x-required-scope":"webhooks:manage","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"deliveryId","in":"path","required":true,"schema":{"type":"string","examples":["whd_…"]}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":200},"description":"Zelfde sleutel en inhoud binnen 24 uur geeft hetzelfde antwoord. Loopt het eerste verzoek nog, dan 409 idempotency_in_progress: probeer het zo opnieuw."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookDelivery"}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/v1/events":{"get":{"summary":"Gebeurtenissen (om gemiste webhooks na te lopen)","description":"Dezelfde gebeurtenissen als de webhooks, met hetzelfde id en dezelfde inhoud, ook als je geen webhookadres hebt. Oudste eerst; bewaard 30 dagen. Bewaar het laatste id en vraag daarna op met starting_after.","x-required-scope":"onboardings:read","parameters":[{"name":"Agreli-Organization","in":"header","required":false,"schema":{"type":"string","examples":["org_…"]},"description":"Alleen voor sleutels van een API-partner: de werkgever namens wie je werkt. Verplicht als de partner meer dan één werkgever heeft."},{"name":"since","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"type","in":"query","schema":{"enum":["contract.sent","contract.signed","contract.signed_by_employee","integration.sync_failed","integration.sync_succeeded","onboarding.approval_given","onboarding.approval_required","onboarding.approved","onboarding.cancelled","onboarding.completed","onboarding.contract_signed","onboarding.created","onboarding.employee_submitted","onboarding.failed","onboarding.invitation_sent","onboarding.returned","onboarding.started","onboarding.submitted","onboarding.terms_changed","payroll.completed"]}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"starting_after","in":"query","schema":{"type":"string"},"description":"next_cursor van de vorige pagina."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"const":"list"},"data":{"type":"array","items":{"$ref":"#/components/schemas/Event"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]}}}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/v1/sandbox/onboardings/{id}/advance":{"post":{"summary":"Sandbox: volgende stap naspelen","description":"Alleen met een testsleutel. Vult de gegevens in, keurt goed met testgebruikers, tekent en rondt de gesimuleerde salarisverwerking af.","x-required-scope":"onboardings:write","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":200},"description":"Zelfde sleutel en inhoud binnen 24 uur geeft hetzelfde antwoord. Loopt het eerste verzoek nog, dan 409 idempotency_in_progress: probeer het zo opnieuw."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"step":{"type":"string"},"onboarding":{"$ref":"#/components/schemas/Onboarding"}}}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}}},"webhooks":{"onboardingEvent":{"post":{"summary":"Gebeurtenis","description":"Kop Agreli-Signature: t=<unix>,v1=<hex>. Controleer HMAC-SHA256(secret, \"<t>.<body>\") en weiger berichten ouder dan 5 minuten. Tijdens het vernieuwen van het geheim staan er twee v1-waarden in de kop; accepteer het bericht als er één klopt. Ontdubbel op id: bij een fout proberen we het opnieuw na 1, 5, 30, 120, 360, 720 en 1440 minuten. Gebeurtenissen: onboarding.created, onboarding.invitation_sent, onboarding.started, onboarding.employee_submitted (ook als onboarding.submitted), onboarding.approval_required, onboarding.returned, onboarding.approval_given, onboarding.approved, onboarding.terms_changed, contract.sent, contract.signed_by_employee, onboarding.contract_signed (ook als contract.signed), integration.sync_succeeded (ook als payroll.completed), integration.sync_failed, onboarding.failed, onboarding.completed, onboarding.cancelled, ping. Een API-partner krijgt de gebeurtenissen van onboardings die via zijn sleutel liepen, zolang de werkgever de partner toelaat; organization_id zegt van welke werkgever.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}}},"responses":{"200":{"description":"Ontvangen (elke 2xx telt)"}}}}},"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer","description":"hrs_live_… of hrs_test_…. Een API-partner geeft bij elk verzoek de kop Agreli-Organization mee (zie GET /v1/organizations)."}},"responses":{"Error":{"description":"Fout","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limited","api_error"]},"code":{"type":"string"},"message":{"type":"string"},"request_id":{"type":"string"}}}}}}}}},"schemas":{"Organization":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"locations":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","examples":["loc_…"]},"name":{"type":"string"},"city":{"type":"string"}}}},"templates":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"contract_type":{"type":"string"},"cao":{"type":"string"}}}},"branding":{"type":"object","properties":{"color":{"type":["string","null"]},"logo_url":{"type":["string","null"]}}},"allowed_origins":{"type":"array","items":{"type":"string","examples":["https://jouwapp.nl"]},"description":"Domeinen voor return_url en inbedden (embed.js). Alleen te wijzigen in het developer dashboard, niet met een API-sleutel."}}},"CreateOnboarding":{"type":"object","required":["employee","employment"],"properties":{"reference":{"type":"string","maxLength":200,"description":"Je eigen kenmerk; komt terug in de API en in webhooks."},"metadata":{"type":"object","maxProperties":20,"additionalProperties":{"type":["string","number","boolean"]},"description":"Je eigen kenmerken, bijvoorbeeld een vacature-id (sleutels: letters, cijfers, _ . -, hooguit 40 tekens; tekst hooguit 500). Komt terug in de API en in webhooks. Geen persoonsgegevens: e-mail, IBAN, BSN en telefoonnummers worden geweigerd (metadata_personal_data)."},"employee":{"type":"object","required":["first_name","last_name","email"],"properties":{"first_name":{"type":"string"},"last_name":{"type":"string"},"email":{"type":"string","format":"email"},"phone":{"type":"string"}}},"employment":{"type":"object","required":["position","start_date","location_id","template_id","hours_per_week","hourly_wage_cents"],"properties":{"position":{"type":"string"},"start_date":{"type":"string","format":"date"},"location_id":{"type":"string"},"template_id":{"type":"string"},"contract_type":{"enum":["on_call","fixed_term","permanent"],"description":"Standaard die van de template."},"hours_per_week":{"type":"number","minimum":0,"maximum":60},"hourly_wage_cents":{"type":"integer","minimum":1}}},"options":{"type":"object","properties":{"send_invitation":{"type":"boolean","default":false,"description":"true: wij mailen de medewerker de link. false: jij stuurt de medewerker naar hosted_url."},"expires_in_hours":{"type":"integer","minimum":1,"maximum":336,"default":336},"return_url":{"type":"string","format":"uri","description":"Na afronden kan de medewerker hierheen terug. Alleen https, op een domein uit allowed_origins (van de werkgever, of van de API-partner); anders 422 return_url_not_allowed."}}}}},"CreatedOnboarding":{"type":"object","properties":{"id":{"type":"string","examples":["onb_…"]},"object":{"const":"onboarding"},"status":{"const":"pending_employee"},"hosted_url":{"type":"string","description":"De medewerker opent deze link en bevestigt met een eenmalige code."},"expires_at":{"type":"string","format":"date-time"},"invitation_sent":{"type":"boolean"},"reference":{"type":["string","null"]},"metadata":{"type":"object","maxProperties":20,"additionalProperties":{"type":["string","number","boolean"]},"description":"Je eigen kenmerken, bijvoorbeeld een vacature-id (sleutels: letters, cijfers, _ . -, hooguit 40 tekens; tekst hooguit 500). Komt terug in de API en in webhooks. Geen persoonsgegevens: e-mail, IBAN, BSN en telefoonnummers worden geweigerd (metadata_personal_data)."}}},"HostedLink":{"type":"object","properties":{"onboarding_id":{"type":"string"},"hosted_url":{"type":"string"},"expires_at":{"type":"string","format":"date-time"},"invitation_sent":{"type":"boolean"}}},"Onboarding":{"type":"object","properties":{"id":{"type":"string"},"status":{"enum":["pending_employee","in_review","contract_ready","awaiting_employee_signature","awaiting_employer_signature","processing","action_required","completed","cancelled"]},"waiting_on":{"type":"array","items":{"type":"string"}},"employee":{"type":"object"},"employment":{"type":"object"},"data_version":{"type":"integer"},"approvals":{"type":"object"},"contract":{"type":"object"},"payroll":{"type":["object","null"]},"hosted_link":{"type":["object","null"]},"reference":{"type":["string","null"]},"metadata":{"type":"object","maxProperties":20,"additionalProperties":{"type":["string","number","boolean"]},"description":"Je eigen kenmerken, bijvoorbeeld een vacature-id (sleutels: letters, cijfers, _ . -, hooguit 40 tekens; tekst hooguit 500). Komt terug in de API en in webhooks. Geen persoonsgegevens: e-mail, IBAN, BSN en telefoonnummers worden geweigerd (metadata_personal_data)."},"return_url":{"type":["string","null"]},"source":{"enum":["dashboard","api"]},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"steps":{"type":"array","items":{"type":"object"}},"documents":{"type":"array","items":{"$ref":"#/components/schemas/Document"}}}},"Document":{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string"},"title":{"type":["string","null"]},"uploaded_at":{"type":"string"},"downloadable":{"type":"boolean"}}},"Employee":{"type":"object","properties":{"id":{"type":"string"},"first_name":{"type":"string"},"last_name":{"type":"string"},"position":{"type":"string"},"location_id":{"type":"string"},"start_date":{"type":"string"},"onboarding":{"type":"object"}}},"OpenApproval":{"type":"object","properties":{"onboarding_id":{"type":"string"},"data_version":{"type":"integer"},"can_approve_as":{"type":"array","items":{"type":"string"}},"blocked_by":{"type":"array","items":{"type":"string"}}}},"WebhookEndpoint":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string"},"events":{"type":"array","items":{"type":"string"}},"status":{"enum":["enabled","disabled"]},"api_version":{"type":"string","description":"Versie van de payloads naar dit adres."},"previous_secret_expires_at":{"type":["string","null"],"format":"date-time","description":"Na een vernieuwing: tot wanneer het vorige geheim nog meeondertekent."},"secret":{"type":"string","description":"Alleen bij aanmaken en vernieuwen."},"recent_deliveries":{"type":"array","items":{"$ref":"#/components/schemas/WebhookDelivery"}}}},"WebhookDelivery":{"type":"object","properties":{"id":{"type":"string","examples":["whd_…"]},"object":{"const":"webhook_delivery"},"event_id":{"type":"string","examples":["evt_…"]},"event_type":{"type":"string"},"status":{"enum":["pending","in_progress","succeeded","failed","dead"]},"attempts":{"type":"integer"},"last_status_code":{"type":["integer","null"]},"last_error":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"},"delivered_at":{"type":["string","null"],"format":"date-time"},"next_attempt_at":{"type":["string","null"],"format":"date-time"}}},"Event":{"type":"object","properties":{"id":{"type":"string","examples":["evt_…"]},"object":{"const":"event","description":"Alleen in GET /v1/events."},"type":{"enum":["contract.sent","contract.signed","contract.signed_by_employee","integration.sync_failed","integration.sync_succeeded","onboarding.approval_given","onboarding.approval_required","onboarding.approved","onboarding.cancelled","onboarding.completed","onboarding.contract_signed","onboarding.created","onboarding.employee_submitted","onboarding.failed","onboarding.invitation_sent","onboarding.returned","onboarding.started","onboarding.submitted","onboarding.terms_changed","payroll.completed","ping"]},"api_version":{"type":"string","description":"Bij webhooks die van het adres; bij GET /v1/events die van het verzoek."},"created_at":{"type":"string","format":"date-time"},"organization_id":{"type":"string","examples":["org_…"],"description":"De werkgever waar de onboarding bij hoort."},"data":{"type":"object","properties":{"onboarding_id":{"type":"string"},"reference":{"type":["string","null"]},"metadata":{"type":"object","maxProperties":20,"additionalProperties":{"type":["string","number","boolean"]},"description":"Je eigen kenmerken, bijvoorbeeld een vacature-id (sleutels: letters, cijfers, _ . -, hooguit 40 tekens; tekst hooguit 500). Komt terug in de API en in webhooks. Geen persoonsgegevens: e-mail, IBAN, BSN en telefoonnummers worden geweigerd (metadata_personal_data)."},"data_version":{"type":["integer","null"]},"role":{"type":"string","description":"Bij onboarding.approval_given."},"returned_to":{"type":"string","description":"Bij onboarding.returned."},"kind":{"enum":["invitation","new_link","reminder"],"description":"Bij onboarding.invitation_sent."},"connector":{"type":["string","null"],"description":"Bij integration.*: nmbrs, afas, loket, manual, …"},"error_code":{"type":["string","null"],"description":"Bij integration.sync_failed en onboarding.failed."}}}}}}}}