API client
L’API client donne à votre serveur un accès en lecture seule aux établissements, jours fériés, employés, intérimaires, équipes, tâches, shifts publiés et pointages d’un seul employeur. Elle utilise OAuth 2.0 client credentials via HTTPS. L’URL de production est https://workforce-api.vesta.services.
Activer l’accès API
Section intitulée « Activer l’accès API »Vesta active l’accès API par employeur. Un administrateur de l’employeur ouvre Paramètres > Intégrations > Accès API dans le portail employeur. Tant que l’accès n’est pas actif, cet onglet affiche L’accès API n’est pas actif et un bouton Demander l’accès API qui envoie un e-mail à Vesta.
Créer une intégration
Section intitulée « Créer une intégration »- Connectez-vous au portail employeur en tant qu’administrateur de l’employeur.
- Ouvrez Paramètres > Intégrations > Accès API et choisissez Créer une intégration.
- Saisissez un nom et sélectionnez uniquement les autorisations dont le logiciel a besoin.
- Copiez l’identifiant client et le secret client dans le coffre à secrets de votre serveur, puis choisissez J’ai conservé le secret. Le secret n’est affiché qu’une seule fois.
Copiez aussi l’Identifiant employeur sur la même page : il figure dans chaque URL de données.
- Une intégration appartient à l’employeur et ne lit que les données de cet employeur.
- Les autorisations sont fixées à la création. Pour les modifier, créez une nouvelle intégration et révoquez l’ancienne.
- Un employeur peut avoir jusqu’à 25 intégrations actives.
- Gardez le secret client et les jetons d’accès sur votre serveur. Ne les placez jamais dans du code navigateur, une application mobile, une URL ou des journaux.
Demander un jeton d’accès
Section intitulée « Demander un jeton d’accès »Envoyez POST /oauth/customer/token avec un corps encodé en formulaire. Demandez un ou plusieurs scopes, séparés par des espaces. Authentifiez-vous avec 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'
Ou envoyez les identifiants dans le corps (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 }
Un jeton est valable 300 secondes. Il n’y a pas de jeton de renouvellement : réutilisez le jeton pour chaque appel jusqu’à peu avant son expiration, puis demandez-en un nouveau avec les mêmes identifiants.
Une demande de jeton refusée renvoie un corps d’erreur OAuth, par exemple { "error": "invalid_scope" } :
| Erreur | Statut | Quand |
|---|---|---|
invalid_request |
400 | Un paramètre obligatoire manque ou est invalide, ou les identifiants sont envoyés à la fois dans l’en-tête et dans le corps. |
invalid_client |
401 | Identifiant client inconnu, secret erroné, ou intégration révoquée ou dont le secret a été renouvelé. |
unauthorized_client |
400 | Les identifiants sont valides, mais l’accès API n’est plus actif pour l’employeur. |
invalid_scope |
400 | Aucun scope, un scope inconnu, un scope que l’intégration n’a pas, ou un scope dont l’employeur n’a plus le module. |
unsupported_grant_type |
400 | grant_type n’est pas client_credentials. |
Ne relancez pas automatiquement invalid_client ni unauthorized_client : ces erreurs demandent une modification dans le portail.
Chaque scope nécessite un accès API actif. Certains nécessitent aussi un module produit.
| Scope | Autorisation dans le portail | Endpoints | Nécessite aussi |
|---|---|---|---|
establishments:read |
Lire les établissements | /establishments, /public-holidays |
|
employees:read |
Lire les employés | /employees |
|
agency-workers:read |
Lire les intérimaires | /agency-workers |
|
planning:read |
Lire la planification | /teams, /tasks, /shifts |
Module Planning |
time-entries:read |
Lire les pointages | /time-entries |
Module Enregistrement du temps |
Endpoints
Section intitulée « Endpoints »Tous les endpoints sont des requêtes GET sous https://workforce-api.vesta.services/api/customer/v1/employers/{employerId} et exigent l’en-tête Authorization: Bearer <access_token>.
| Endpoint | Renvoie | Paramètres |
|---|---|---|
/establishments |
Établissements avec leur fuseau horaire IANA | limit, cursor |
/public-holidays |
Jours fériés d’une année et la date à laquelle l’employeur accorde chacun, après remplacement éventuel | year (2000 à 2100, obligatoire) |
/employees |
Employés : nom et indicateur actif uniquement | limit, cursor |
/agency-workers |
Intérimaires des agences avec lesquelles l’employeur travaille | limit, cursor |
/teams |
Équipes | limit, cursor |
/tasks |
Tâches de planification | limit, cursor |
/shifts |
Shifts publiés | from, to, limit, cursor |
/time-entries |
Pointages | 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"
Un jeton ne fonctionne que sur les URL de son propre employeur. La référence API décrit chaque champ.
Dates et pagination
Section intitulée « Dates et pagination »fromettosont des dates obligatoires au formatYYYY-MM-DD, entre 2000 et 2100. Les deux sont incluses. Une période couvre au maximum 93 jours.- Les shifts sont sélectionnés selon leur date planifiée. Les pointages sont sélectionnés selon le jour local où ils ont commencé dans leur propre établissement, le jour indiqué par
workDate. limitva de 1 à 200, 100 par défaut. Une liste renvoie{ "items": [...], "nextCursor": "..." }. EnvoyeznextCursorcommecursor, avec les mêmes autres paramètres, jusqu’à ce quenextCursorsoitnull. Un curseur est opaque et ne fonctionne que sur la liste, l’employeur et la période qui l’ont renvoyé.- La pagination n’est pas un instantané. Un enregistrement modifié pendant la lecture peut manquer ou revenir deux fois ; la lecture complète suivante corrige cela.
Rester synchronisé
Section intitulée « Rester synchronisé »Il n’y a ni flux de modifications ni filtre modifiedSince. Pour rester synchronisé :
- Relisez la période que vous conservez, par exemple les deux dernières semaines et les quatre prochaines semaines de shifts, jusqu’à ce que
nextCursorsoitnull. - Mettez à jour ou ajoutez chaque enregistrement selon son
id. - Seulement après la dernière page, considérez comme supprimé tout
idconservé dans cette période qui n’a pas été renvoyé. Un shift qui disparaît a été supprimé ou dépublié.
Les listes de référence sont petites : relisez-les entièrement de la même manière. Les employés archivés disparaissent de /employees ; pour le reste, utilisez isActive.
Signification des données
Section intitulée « Signification des données »- Chaque
idest un UUID qui reste identique d’une lecture à l’autre, y compris pour les pointages. startsAt,endsAtet les heures de pause sont des heures locales avec le décalage UTC de l’établissement, par exemple2026-10-03T22:00:00+02:00. Les champs qui se terminent parUtcsont en UTC.- Seuls les shifts publiés sont renvoyés.
dateest le jour planifié. Un shift qui dépasse minuit se termine le jour suivant.plannedMinutesest le temps réellement écoulé entrestartsAtetendsAt, moinsbreakMinutes: un shift de nuit pendant un changement d’heure compte une heure de plus ou de moins que ses heures d’horloge ne le laissent penser.fillTypevautInternalpour un employé ouExternalpour un intérimaire ou un travailleur externe. - Le
statusd’un pointage vautWorking,OnBreak,CompletedouCancelled.endsAtest vide tant que le pointage est ouvert, etworkedMinutesn’est présent qu’avecCompleted.shiftIdrenvoie au shift publié sur lequel le pointage a été effectué, s’il existe.reviewedAtUtcest renseigné dès que l’employeur a vérifié le pointage. Les pointages annulés sont conservés pour l’historique et ne comptent pas comme temps travaillé. - Les shifts et pointages d’un établissement supprimé sont omis. Une référence à une équipe, une tâche, une agence ou un intérimaire supprimé vaut
null, comme cet enregistrement disparaît de sa propre liste. Un employé archivé fait exception : les shifts et pointages conservent sonemployeeId. - Les employés contiennent uniquement
firstName,lastNameetisActive: ni numéro de registre national, ni compte bancaire, ni coordonnées, ni date de naissance.
Limites de débit
Section intitulée « Limites de débit »| Requêtes | Limite | Comptée par |
|---|---|---|
| Demandes de jeton | 30 par 60 secondes | Adresse IP et identifiant client. Avec client_secret_post, toutes les demandes de jeton d’une même adresse IP partagent un seul budget. |
| Requêtes de données | 600 par 60 secondes | Employeur, partagée par toutes ses intégrations |
La limite générale de Vesta de 500 requêtes par minute par adresse IP s’applique aussi. Au-delà d’une limite, l’API répond 429 avec un en-tête Retry-After en secondes : attendez au moins ce délai. En réutilisant les jetons, vous restez largement sous le budget des demandes de jeton.
Les endpoints de données renvoient les erreurs sous forme de problem details (application/problem+json).
| Statut | Signification | Que faire |
|---|---|---|
400 |
Un paramètre manque ou est invalide, comme from, to, year ou limit. |
Corrigez la requête. |
401 |
Le jeton manque, est invalide ou a expiré, l’intégration a été révoquée ou renouvelée, l’employeur a perdu l’accès API, ou aucun scope du jeton n’est encore disponible. | Demandez une fois un nouveau jeton. S’il est refusé, arrêtez. |
403 |
Le jeton appartient à un autre employeur, n’a pas le scope, ou l’employeur a perdu le module que ce scope lit. | Vérifiez l’identifiant employeur et les scopes. |
422 |
to précède from, une date est hors de 2000 à 2100, la période dépasse 93 jours, ou le curseur est invalide ou appartient à une autre liste, un autre employeur ou une autre période. |
Corrigez la requête. |
429 |
Une limite de débit est atteinte. | Attendez selon Retry-After. |
5xx |
Vesta n’a pas pu répondre. | Réessayez avec des délais croissants et aléatoires. |
Renouveler ou révoquer
Section intitulée « Renouveler ou révoquer »Dans Accès API, le menu de chaque intégration propose Renouveler le secret et Révoquer l’accès. Dernière utilisation indique quand l’intégration a reçu un jeton pour la dernière fois.
- Renouveler le secret affiche une seule fois un nouveau secret. L’ancien secret et chaque jeton émis avec lui cessent immédiatement de fonctionner : mettez donc votre serveur à jour sans attendre.
- Révoquer l’accès désactive définitivement l’intégration et tous ses jetons. La révocation reste possible après la fin de l’accès API.
- Une session de support, dans laquelle l’équipe Vesta agit dans votre portail, ne peut pas créer d’intégrations ni renouveler de secrets. Elle peut révoquer.