Aller au contenu

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.

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.

  1. Connectez-vous au portail employeur en tant qu’administrateur de l’employeur.
  2. Ouvrez Paramètres > Intégrations > Accès API et choisissez Créer une intégration.
  3. Saisissez un nom et sélectionnez uniquement les autorisations dont le logiciel a besoin.
  4. 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.

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

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.

  • from et to sont des dates obligatoires au format YYYY-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.
  • limit va de 1 à 200, 100 par défaut. Une liste renvoie { "items": [...], "nextCursor": "..." }. Envoyez nextCursor comme cursor, avec les mêmes autres paramètres, jusqu’à ce que nextCursor soit null. 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.

Il n’y a ni flux de modifications ni filtre modifiedSince. Pour rester synchronisé :

  1. Relisez la période que vous conservez, par exemple les deux dernières semaines et les quatre prochaines semaines de shifts, jusqu’à ce que nextCursor soit null.
  2. Mettez à jour ou ajoutez chaque enregistrement selon son id.
  3. Seulement après la dernière page, considérez comme supprimé tout id conservé 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.

  • Chaque id est un UUID qui reste identique d’une lecture à l’autre, y compris pour les pointages.
  • startsAt, endsAt et les heures de pause sont des heures locales avec le décalage UTC de l’établissement, par exemple 2026-10-03T22:00:00+02:00. Les champs qui se terminent par Utc sont en UTC.
  • Seuls les shifts publiés sont renvoyés. date est le jour planifié. Un shift qui dépasse minuit se termine le jour suivant. plannedMinutes est le temps réellement écoulé entre startsAt et endsAt, moins breakMinutes : 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. fillType vaut Internal pour un employé ou External pour un intérimaire ou un travailleur externe.
  • Le status d’un pointage vaut Working, OnBreak, Completed ou Cancelled. endsAt est vide tant que le pointage est ouvert, et workedMinutes n’est présent qu’avec Completed. shiftId renvoie au shift publié sur lequel le pointage a été effectué, s’il existe. reviewedAtUtc est 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 son employeeId.
  • Les employés contiennent uniquement firstName, lastName et isActive : ni numéro de registre national, ni compte bancaire, ni coordonnées, ni date de naissance.
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.

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.