> ## Documentation Index
> Fetch the complete documentation index at: https://developers.0flaw.fr/llms.txt
> Use this file to discover all available pages before exploring further.

# Synchroniser une liste d'employés

> Réconcilie votre liste RH avec 0flaw en un appel : crée les nouveaux, met à jour
les existants, réactive les archivés, et — **uniquement si vous le demandez** —
désactive ceux absents de la liste.

L'opération est **idempotente** : rejouer la même liste ne crée aucun doublon.
Le rapprochement se fait sur `external_id` s'il est fourni, sinon sur l'email.
Fournir un `external_id` stable est fortement recommandé : c'est ce qui permet
de suivre un employé même si son email change.

Commencez par `dry_run: true` pour obtenir le rapport complet sans rien écrire.



## OpenAPI

````yaml /openapi.json post /api/v1/employees/sync
openapi: 3.1.0
info:
  title: API 0flaw
  version: 1.0.0
  description: >-
    API publique de 0flaw : provisionnez vos employés depuis votre SIRH/AD et
    recevez

    les événements de sécurité dans votre SIEM.


    ## Authentification

    Toutes les requêtes exigent une clé API, créée depuis votre dashboard

    (Réglages → Clés API). Transmettez-la dans l'en-tête `Authorization` :


    ```

    Authorization: Bearer 0flaw_live_xxxxxxxx

    ```


    L'en-tête `x-api-key` est également accepté. Une clé est **scopée à une
    seule

    entreprise** : elle ne peut jamais lire ni modifier les données d'une autre.


    ## Limites de débit

    600 requêtes par tranche de 15 minutes et par clé. Les en-têtes
    `RateLimit-*`

    accompagnent chaque réponse ; un dépassement renvoie `429`.


    ## Gestion des erreurs

    Fiez-vous au champ `code` (stable) et non au `message` (susceptible
    d'évoluer).
  contact:
    name: Support 0flaw
    url: https://app.0flaw.fr
servers:
  - url: https://api.0flaw.fr
    description: Production
security:
  - apiKey: []
tags:
  - name: Général
    description: Vérification d'accès et introspection de la clé
  - name: Employés
    description: 'Provisioning : création, mise à jour, désactivation, invitations'
  - name: Résultats
    description: Campagnes de phishing et leurs résultats (scope read:results)
  - name: Radar
    description: Risk scores par axe (scope read:scores)
  - name: Formations
    description: Statut des formations des employés (scope read:trainings)
paths:
  /api/v1/employees/sync:
    post:
      tags:
        - Employés
      summary: Synchroniser une liste d'employés
      description: >-
        Réconcilie votre liste RH avec 0flaw en un appel : crée les nouveaux,
        met à jour

        les existants, réactive les archivés, et — **uniquement si vous le
        demandez** —

        désactive ceux absents de la liste.


        L'opération est **idempotente** : rejouer la même liste ne crée aucun
        doublon.

        Le rapprochement se fait sur `external_id` s'il est fourni, sinon sur
        l'email.

        Fournir un `external_id` stable est fortement recommandé : c'est ce qui
        permet

        de suivre un employé même si son email change.


        Commencez par `dry_run: true` pour obtenir le rapport complet sans rien
        écrire.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SyncRequest'
            example:
              employees:
                - external_id: hr-4821
                  email: jane.doe@acme.com
                  nom: Doe
                  prenom: Jane
                  secteur: Finance
                - email: john.smith@acme.com
                  nom: Smith
                  prenom: John
              deactivate_absent: false
              dry_run: false
      responses:
        '200':
          description: Rapport de synchronisation
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SyncResponse'
              example:
                ok: true
                dry_run: false
                summary:
                  received: 2
                  created: 1
                  updated: 1
                  reactivated: 0
                  deactivated: 0
                  skipped: 0
                  failed: 0
                quota:
                  cap: 200
                  renewal_before: 42
                  renewal_after: 43
                  seats_requested: 1
                results:
                  - external_id: hr-4821
                    email: jane.doe@acme.com
                    action: created
                    id: b1e…
                  - external_id: null
                    email: john.smith@acme.com
                    action: updated
                    id: c2f…
        '400':
          description: Corps de requête invalide
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                message: Email invalide
                code: VALIDATION_ERROR
        '401':
          description: Clé API absente ou invalide
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                message: Clé API invalide ou révoquée
                code: API_KEY_INVALID
        '403':
          description: >-
            Scope manquant, ou quota de sièges dépassé (aucune écriture n'a été
            faite)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                message: Quota maximum atteint (200/200 sièges facturés).
                code: QUOTA_MAXIMUM_ATTEINT
        '413':
          description: Plus de 1000 employés dans un seul appel
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                message: Trop d'employés (1500). Maximum 1000 par appel.
                code: TOO_MANY_RECORDS
        '429':
          description: Quota de requêtes dépassé pour cette clé
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                message: Trop de requêtes, réessayez plus tard.
                code: RATE_LIMIT_EXCEEDED
      security:
        - apiKey:
            - write:employees
components:
  schemas:
    SyncRequest:
      type: object
      required:
        - employees
      properties:
        employees:
          type: array
          minItems: 1
          maxItems: 1000
          items:
            $ref: '#/components/schemas/EmployeeRecord'
        deactivate_absent:
          type: boolean
          default: false
          description: >-
            ⚠️ Archive tous les employés actifs **absents** de la liste.
            N'activez ce mode que si la liste envoyée est exhaustive : un export
            partiel archiverait tout le reste de votre effectif.
            L'administrateur par défaut est toujours préservé.
        send_invitation:
          type: boolean
          default: false
          description: Envoie l'email d'accès aux employés **créés** par cet appel
        dry_run:
          type: boolean
          default: false
          description: >-
            Renvoie le rapport complet sans rien écrire. À utiliser avant un
            premier import.
    SyncResponse:
      type: object
      properties:
        ok:
          type: boolean
        dry_run:
          type: boolean
        summary:
          $ref: '#/components/schemas/SyncSummary'
        quota:
          type: object
          properties:
            cap:
              type:
                - integer
                - 'null'
              description: '`null` si votre offre est illimitée'
            renewal_before:
              type: integer
            renewal_after:
              type: integer
            seats_requested:
              type: integer
              description: Sièges nécessaires (créations + réactivations)
            would_exceed:
              type: boolean
              description: 'En `dry_run` uniquement : le lot dépasserait le quota'
        results:
          type: array
          items:
            $ref: '#/components/schemas/SyncResultItem'
    ErrorResponse:
      type: object
      properties:
        message:
          type: string
          description: Message lisible par un humain
        code:
          type: string
          description: Code stable, à utiliser pour la logique client
      required:
        - message
        - code
    EmployeeRecord:
      type: object
      required:
        - email
        - nom
        - prenom
      properties:
        external_id:
          type: string
          maxLength: 191
          description: >-
            Identifiant de l'employé dans VOTRE système. Clé de rapprochement
            prioritaire : la fournir permet de suivre un employé même si son
            email change.
        email:
          type: string
          format: email
        nom:
          type: string
          minLength: 1
          maxLength: 100
        prenom:
          type: string
          minLength: 1
          maxLength: 100
        fonction:
          type: string
          maxLength: 100
        telephone:
          type: string
          maxLength: 30
        adresse:
          type: string
          maxLength: 255
        secteur:
          type: string
          maxLength: 150
          description: Nom du secteur — créé automatiquement s'il n'existe pas
        secteur_id:
          oneOf:
            - type: string
              maxLength: 64
            - type: integer
          description: Alternative à `secteur`
        active:
          type: boolean
          description: '`false` archive cet employé'
    SyncSummary:
      type: object
      properties:
        received:
          type: integer
        created:
          type: integer
        updated:
          type: integer
        reactivated:
          type: integer
        deactivated:
          type: integer
        skipped:
          type: integer
          description: 'Employés déjà à jour : aucune écriture'
        failed:
          type: integer
    SyncResultItem:
      type: object
      properties:
        external_id:
          type:
            - string
            - 'null'
        email:
          type: string
        action:
          type: string
          enum:
            - created
            - updated
            - reactivated
            - skipped
            - deactivated
            - failed
        id:
          type: string
          description: Identifiant 0flaw de l'employé
        error:
          type: string
          description: >-
            Présent si `action = failed`. Notamment
            `email_conflict_other_tenant` (l'email appartient à une autre
            entreprise) ou `duplicate_in_payload`.
        planned:
          type: boolean
          description: 'Présent en `dry_run` : action qui serait effectuée'
  securitySchemes:
    apiKey:
      type: http
      scheme: bearer
      description: >-
        Clé API créée depuis le dashboard (Réglages → Clés API). L'en-tête
        `x-api-key: <clé>` est accepté en alternative à `Authorization: Bearer
        <clé>`.

````