Journal d'audit

Chaque appel authentifié que vous passez à l'API Staff & Go est consigné. GET /api/v1/client/audit/entries vous rend ce journal — le vôtre, et rien d'autre.

C'est ce qui vous permet de répondre à votre client lorsqu'il vous demande, au titre du RGPD, ce que vous avez fait pour son compte et quand.

Ce que « le vôtre » veut dire

Le journal est rattaché à l'identifiant avec lequel vous vous authentifiez — le client OAuth — et non à votre compte partenaire dans son ensemble. Si vous détenez plusieurs clients (un par environnement, un par client final, un dédié à une reprise), chacun a son propre journal et aucun ne lit celui d'un autre, même lorsque deux d'entre eux interviennent pour la même société.

Le rattachement portant désormais sur le client et non plus sur une société unique, un identifiant mandaté sur plusieurs établissements obtient lui aussi son journal. Il était jusqu'ici refusé, faute d'une société unique à laquelle le rattacher.

Les sociétés sur lesquelles vous êtes mandaté aujourd'hui comptent toujours. Un identifiant relit les appels qu'il a faits pour les établissements sur lesquels il est mandaté maintenant — pas ceux sur lesquels il l'était avant. Si nous restreignons son périmètre à la demande de votre client final, les appels faits pour la société qu'il ne couvre plus quittent son journal immédiatement, au lieu d'y rester jusqu'au bout de la durée de conservation. Rouvrez le périmètre et ils reviennent : rien n'est supprimé, seulement borné.

Une conséquence à connaître : les appels passés alors qu'un identifiant était mandaté sur plusieurs établissements sont enregistrés sans société — il n'y en a pas une seule pour laquelle ils ont été faits. Ceux-là restent dans le journal de cet identifiant quel que soit son périmètre ensuite. Ce sont ses propres appels, et ils ne portent rien qui puisse être confronté à une société.

Une exception, et elle est transitoire. Les appels enregistrés avant ce rattachement ne portent que la société pour laquelle ils ont été faits, pas l'identifiant qui les a émis. Ces lignes anciennes sont rendues à n'importe lequel de vos identifiants mandatés sur cette société — donc si deux de vos clients travaillent pour le même client final, chacun voit encore les appels anciens de l'autre. Rien ne franchit la limite de votre compte partenaire, et tout ce qui est enregistré à partir de maintenant est séparé par identifiant. La valeur manquante ne peut pas être reconstituée après coup : ces lignes ne sont donc pas ré-étiquetées, elles disparaissent avec la durée de conservation.

Un identifiant qui ne porte ni l'un ni l'autre est refusé (403) : pas d'identifiant de client — jeton émis avant son déploiement — et plusieurs établissements, il ne reste rien sur quoi borner le journal, et nous préférons refuser que répondre en y mêlant l'activité d'un autre. Demandez-nous de déployer l'identifiant sur ce client et le journal s'ouvre, sans rien changer chez vous.

Ce que le journal contient

Des métadonnées uniquement : l'instant de l'appel, le verbe, le chemin, le statut de la réponse, la durée de traitement, la clé d'idempotence, et une empreinte SHA-256 du corps de requête.

Le corps lui-même n'est jamais conservé, ni les cookies, ni l'en-tête Authorization. L'empreinte suffit à prouver quel contenu a été soumis sans en garder un octet — utile pour lever un doute sur un import : recalculez le SHA-256 du fichier que vous croyez avoir envoyé et comparez.

Appeler

Scope requis : audit-entries:read.

curl -H "Authorization: Bearer $TOKEN" \
  "https://api.staffngo.com/api/v1/client/audit/entries?from=2026-07-01T00:00:00Z&to=2026-07-31T23:59:59Z&method=POST"
{
  "items": [
    {
      "traceId": "0af7651916cd43dd8448eb211c80319c",
      "occurredAt": "2026-07-28T09:14:22.104Z",
      "method": "POST",
      "path": "/api/v2/client/app/payroll/distribution/trigger",
      "statusCode": 200,
      "durationMs": 431,
      "bodyHash": "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9",
      "idempotencyKey": "2026-07-payroll-run-3"
    }
  ],
  "nextCursor": "MTQ4Mg=="
}

Filtres

Paramètre Effet
from, to Bornes sur l'instant de l'appel, en ISO-8601 UTC. Au plus 31 jours d'écart.
method Verbe HTTP, ex. POST.
statusCode Statut de la réponse, ex. 200.
limit Taille de page. Défaut 50, plafonnée à 200 : une valeur plus grande est ramenée au plafond, sans erreur.
cursor Jeton de continuation, repris tel quel du nextCursor de la page précédente.

Un paramètre absent ne filtre pas. from et to demandés à plus de 31 jours d'écart sont refusés (400) plutôt que tronqués : croire avoir lu une année en n'ayant lu qu'un mois est pire qu'une erreur.

Pagination

Les appels sont rendus du plus récent au plus ancien. Tant que nextCursor n'est pas null, il reste une page : redemandez la même URL en ajoutant cursor=<nextCursor>.

Le curseur est opaque — ne le décodez pas, ne le fabriquez pas. Il repose sur une clé de tri, pas sur un décalage : le journal grossit pendant que vous le parcourez, et un offset vous ferait sauter ou relire des lignes à chaque nouvel appel enregistré.

Deux autres limites à connaître

Les appels anonymes n'y figurent pas. L'ingestion de badgeages (/badge/*) est ouverte sans jeton — un lecteur physique n'en détient pas. Ces appels sont bien journalisés, mais sans partenaire ni société rattachés : ils ne peuvent donc être rendus à personne. Si votre intégration ne fait que du badgeage, votre journal est vide, et c'est normal.

Le journal est purgé. Les lignes plus anciennes que la durée de conservation configurée disparaissent. Exportez ce dont vous avez besoin au fil de l'eau plutôt qu'au moment où on vous le demande.