Ga naar inhoud

Klanten-API

Met de klanten-API krijgt je server leestoegang tot de vestigingen, feestdagen, werknemers, uitzendkrachten, teams, taken, gepubliceerde shifts en tijdsregistraties van één werkgever. De API gebruikt OAuth 2.0 client credentials via HTTPS. De productie-URL is https://workforce-api.vesta.services.

Vesta activeert API-toegang per werkgever. Een werkgeversbeheerder opent in het werkgeversportaal Instellingen > Integraties > API-toegang. Zolang de toegang niet actief is, toont dat tabblad API-toegang is niet actief en een knop API-toegang aanvragen die Vesta een e-mail stuurt.

  1. Meld je aan in het werkgeversportaal als werkgeversbeheerder.
  2. Open Instellingen > Integraties > API-toegang en kies Integratie aanmaken.
  3. Geef een naam op en selecteer alleen de machtigingen die de software nodig heeft.
  4. Kopieer de client-ID en het clientgeheim naar de geheimenkluis van je server en kies daarna Ik heb het geheim bewaard. Het geheim wordt maar één keer getoond.

Kopieer op dezelfde pagina ook de Werkgever-ID: die staat in elke data-URL.

  • Een integratie hoort bij de werkgever en leest alleen de gegevens van die werkgever.
  • De machtigingen liggen vast bij het aanmaken. Wil je ze wijzigen, maak dan een nieuwe integratie aan en trek de oude in.
  • Een werkgever kan tot 25 actieve integraties hebben.
  • Houd het clientgeheim en de toegangstokens op je server. Zet ze nooit in browsercode, mobiele apps, URL’s of logs.

Stuur POST /oauth/customer/token met een formuliergecodeerde body. Vraag één of meer scopes aan, gescheiden door spaties. Authenticeer met HTTP Basic:

curl --request POST "https://workforce-api.vesta.services/oauth/customer/token" \
  --user "$VESTA_CLIENT_ID:$VESTA_CLIENT_SECRET" \
  --data-urlencode 'grant_type=client_credentials' \
  --data-urlencode 'scope=establishments:read planning:read'

Of stuur de gegevens in de body (client_secret_post):

curl --request POST "https://workforce-api.vesta.services/oauth/customer/token" \
  --data-urlencode 'grant_type=client_credentials' \
  --data-urlencode "client_id=$VESTA_CLIENT_ID" \
  --data-urlencode "client_secret=$VESTA_CLIENT_SECRET" \
  --data-urlencode 'scope=establishments:read planning:read'
{ "access_token": "eyJhbGciOi...", "token_type": "Bearer", "expires_in": 300 }

Een token is 300 seconden geldig. Er is geen refreshtoken: gebruik het token voor elke aanvraag tot kort voor het verloopt en vraag dan met dezelfde gegevens een nieuw aan.

Een geweigerde tokenaanvraag geeft een OAuth-foutbody terug, zoals { "error": "invalid_scope" }:

Fout Status Wanneer
invalid_request 400 Een verplichte parameter ontbreekt of is ongeldig, of de gegevens staan zowel in de header als in de body.
invalid_client 401 Onbekende client-ID, fout geheim, of een integratie die is ingetrokken of waarvan het geheim is vernieuwd.
unauthorized_client 400 De gegevens kloppen, maar API-toegang is niet meer actief voor de werkgever.
invalid_scope 400 Geen scope, een onbekende scope, een scope die de integratie niet heeft, of een scope waarvan de werkgever de module niet meer heeft.
unsupported_grant_type 400 grant_type is niet client_credentials.

Herhaal invalid_client en unauthorized_client niet automatisch: die vragen een wijziging in het portaal.

Elke scope vereist actieve API-toegang. Sommige vereisen ook een productmodule.

Scope Machtiging in het portaal Endpoints Vereist ook
establishments:read Vestigingen lezen /establishments, /public-holidays
employees:read Werknemers lezen /employees
agency-workers:read Uitzendkrachten lezen /agency-workers
planning:read Planning lezen /teams, /tasks, /shifts Module Planning
time-entries:read Tijdsregistraties lezen /time-entries Module Tijdsregistratie

Alle endpoints zijn GET-aanvragen onder https://workforce-api.vesta.services/api/customer/v1/employers/{employerId} en vereisen de header Authorization: Bearer <access_token>.

Endpoint Geeft terug Query
/establishments Vestigingen met hun IANA-tijdzone limit, cursor
/public-holidays Feestdagen van één jaar en de dag waarop de werkgever elke feestdag toekent, na een eventuele vervanging year (2000 tot 2100, verplicht)
/employees Werknemers: alleen naam en actief-vlag limit, cursor
/agency-workers Uitzendkrachten van de uitzendbureaus waarmee de werkgever werkt limit, cursor
/teams Teams limit, cursor
/tasks Planningstaken limit, cursor
/shifts Gepubliceerde shifts from, to, limit, cursor
/time-entries Tijdsregistraties from, to, limit, cursor
curl "https://workforce-api.vesta.services/api/customer/v1/employers/$VESTA_EMPLOYER_ID/shifts?from=2026-10-01&to=2026-10-31" \
  --header "Authorization: Bearer $VESTA_ACCESS_TOKEN"

Een token werkt alleen op de URL’s van zijn eigen werkgever. De API-referentie beschrijft elk veld.

  • from en to zijn verplichte datums in YYYY-MM-DD tussen 2000 en 2100. Beide zijn inbegrepen. Een bereik omvat maximaal 93 dagen.
  • Shifts worden geselecteerd op hun geplande datum. Tijdsregistraties worden geselecteerd op de lokale dag waarop ze begonnen in hun eigen vestiging, de dag die workDate toont.
  • limit ligt tussen 1 en 200, standaard 100. Een lijst geeft { "items": [...], "nextCursor": "..." } terug. Stuur nextCursor mee als cursor, met dezelfde andere parameters, tot nextCursor null is. Een cursor is ondoorzichtig en werkt alleen op de lijst, werkgever en periode die hem teruggaven.
  • Pagina’s zijn geen momentopname. Een record dat wijzigt terwijl je bladert, kan ontbreken of twee keer terugkomen; de volgende volledige leesbeurt zet dat recht.

Er is geen wijzigingsfeed en geen filter modifiedSince. Zo blijf je synchroon:

  1. Lees het datumvenster dat je bijhoudt opnieuw, bijvoorbeeld de voorbije twee weken en de komende vier weken aan shifts, en blader tot nextCursor null is.
  2. Werk elk record bij of voeg het toe op basis van id.
  3. Beschouw pas na de laatste pagina elke bewaarde id in dat venster die niet terugkwam als verwijderd. Een shift die verdwijnt, is verwijderd of niet meer gepubliceerd.

Referentielijsten zijn klein: lees ze op dezelfde manier volledig opnieuw. Gearchiveerde werknemers verdwijnen uit /employees; gebruik voor al de rest isActive.

  • Elke id is een UUID die bij elke leesbeurt gelijk blijft, ook bij tijdsregistraties.
  • startsAt, endsAt en pauzetijden zijn lokale tijden met de UTC-offset van de vestiging, bijvoorbeeld 2026-10-03T22:00:00+02:00. Velden die eindigen op Utc zijn in UTC.
  • Shifts zijn alleen gepubliceerde shifts. date is de geplande dag. Een shift die na middernacht doorloopt, eindigt op de volgende dag. plannedMinutes is de tijd die echt verstrijkt tussen startsAt en endsAt, zonder breakMinutes: een nachtshift tijdens de overgang naar zomer- of wintertijd telt een uur meer of minder dan de kloktijden doen vermoeden. fillType is Internal voor een werknemer of External voor een uitzendkracht of externe kracht.
  • De status van een tijdsregistratie is Working, OnBreak, Completed of Cancelled. endsAt is leeg zolang een registratie open is, en workedMinutes staat er alleen bij Completed. shiftId verwijst naar de gepubliceerde shift waarop gewerkt werd, als die er is. reviewedAtUtc is ingevuld zodra de werkgever de registratie heeft nagekeken. Geannuleerde registraties blijven bewaard als historiek en tellen niet als gewerkte tijd.
  • Shifts en tijdsregistraties in een verwijderde vestiging worden weggelaten. Een verwijzing naar een verwijderd team, een verwijderde taak, een verwijderd uitzendbureau of een verwijderde uitzendkracht is null, net zoals dat record uit zijn eigen lijst verdwijnt. Een gearchiveerde werknemer is de uitzondering: shifts en tijdsregistraties behouden hun employeeId.
  • Werknemers bevatten alleen firstName, lastName en isActive: geen rijksregisternummer, bankrekening, contactgegevens of geboortedatum.
Aanvragen Limiet Geteld per
Tokenaanvragen 30 per 60 seconden IP-adres en client-ID. Met client_secret_post delen alle tokenaanvragen van één IP-adres één budget.
Gegevensaanvragen 600 per 60 seconden Werkgever, gedeeld door al zijn integraties

De algemene limiet van Vesta van 500 aanvragen per minuut per IP-adres geldt ook. Boven een limiet antwoordt de API met 429 en een header Retry-After in seconden: wacht minstens zo lang. Door tokens te hergebruiken blijf je ruim binnen het tokenbudget.

Gegevensendpoints geven fouten terug als problem details (application/problem+json).

Status Betekenis Wat te doen
400 Een parameter ontbreekt of is ongeldig, zoals from, to, year of limit. Pas de aanvraag aan.
401 Het token ontbreekt, is ongeldig of verlopen, de integratie is ingetrokken of vernieuwd, de werkgever verloor API-toegang, of geen enkele scope van het token is nog beschikbaar. Vraag één keer een nieuw token aan. Wordt dat geweigerd, stop dan.
403 Het token hoort bij een andere werkgever, mist de scope, of de werkgever verloor de module die de scope leest. Controleer de werkgever-ID en de scopes.
422 to ligt voor from, een datum ligt buiten 2000 tot 2100, het bereik is langer dan 93 dagen, of de cursor is ongeldig of hoort bij een andere lijst, werkgever of periode. Pas de aanvraag aan.
429 Een limiet is bereikt. Wacht volgens Retry-After.
5xx Vesta kon niet antwoorden. Probeer opnieuw met oplopende, gespreide wachttijden.

Op API-toegang biedt het menu van elke integratie Geheim vernieuwen en Toegang intrekken. Laatst gebruikt toont wanneer de integratie het laatst een token kreeg.

  • Geheim vernieuwen toont één keer een nieuw geheim. Het oude geheim en elk token dat ermee werd uitgegeven, werken onmiddellijk niet meer. Werk je server dus meteen bij.
  • Toegang intrekken schakelt de integratie en al haar tokens definitief uit. Intrekken kan ook nadat API-toegang is beëindigd.
  • In een supportsessie, waarin medewerkers van Vesta in je portaal werken, kun je geen integraties aanmaken of geheimen vernieuwen. Intrekken kan wel.