> ## Documentation Index
> Fetch the complete documentation index at: https://docs.agentova.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Historique d'exécutions d'une automatisation

> Pas encore servi par l'API réelle (voir « Disponibilité »).



## OpenAPI

````yaml /openapi/openapi-v1-draft.yaml get /automations/{id}/runs
openapi: 3.0.3
info:
  title: Agentova Public API
  version: 1.0.0-draft.2
  description: >
    API publique Agentova v1 (DRAFT). Source de vérité machine pour le contrat
    décrit dans 4-CONTRAT-API.md. Statut : draft validé par le référent — toute
    modification est annoncée aux deux devs, jamais de changement silencieux.


    ## Conventions valables sur toute l'API

    - **Identifiants** : chaînes OPAQUES, préfixées par leur type (`aut_`
      automatisation, `agt_` agent, `run_` exécution, `lea_` lead, `whk_`
      abonnement, `evt_` événement). Un connecteur les stocke et les renvoie
      tels quels ; il ne les valide ni ne les interprète jamais (ni longueur,
      ni alphabet). Ce ne sont PAS des UUID.

    - **Erreurs** : corps constant `{ "error": { "code", "message", "details" }
    }`
      pour toute réponse 4xx/5xx. Le `code` est stable et énuméré
      (`ErrorCode`), le `message` est en français et peut changer, `details`
      nomme le paramètre fautif quand il y en a un.

    - **Pagination** : par curseur opaque (`limit` ≤ 100, défaut 25). Réponse
      `{ data, has_more, next_cursor }`. `cursor` absent ou égal au mot `null`
      = première page. Un `limit` hors bornes est refusé (400), pas corrigé.

    - **Paramètres de requête inconnus** : ignorés (jamais 400), pour qu'un
      connecteur écrit pour une version future reste compatible.

    - **Quota** : en-têtes `X-RateLimit-Limit`, `X-RateLimit-Remaining` et
      `X-RateLimit-Reset` (secondes restantes, pas un horodatage) sur TOUTES les
      réponses, 401 et 403 compris ; `429` + `Retry-After` au-delà.

    - **Dates** : ISO 8601, UTC, suffixe `Z`.

    - **Cache** : `Cache-Control: no-store` sur toute réponse (données
      personnelles).


    ## Disponibilité dans l'API réelle (état au 2026-09-15)

    Servi aujourd'hui : `GET /automations` et `GET /automations/{id}` pour la
    famille sociale Meta (`social_*`, `lead_ads` ; providers `facebook`,
    `instagram`, `instagram_page`).

    À venir, dans cet ordre : `PATCH /automations/{id}`, la famille
    `crm_source`, `GET /leads`, `GET /runs` et `GET /automations/{id}/runs`, les
    webhooks. Une route du contrat pas encore servie répond `404
    route_not_found` — jamais 405 : un connecteur ne doit pas y lire une faute
    de sa part. La bascule du mock vers l'API réelle (URL, workspace de test,
    clés) est annoncée par le référent au jalon 80 %.

    Clés : une seule famille en v1, `agk_live_…`. Pas de clé `agk_test_` dans
    cette version du contrat.


    ## Changements draft.1 → draft.2 (2026-09-15, annoncés aux deux devs)

    Aucune route, aucun champ ni aucune valeur d'énumération ne change. Le
    draft.2 PRÉCISE ce que le draft.1 laissait implicite, d'après
    l'implémentation réelle : format des identifiants (préfixés, opaques — la
    mention « UUID » du texte 4-CONTRAT-API est retirée) ; liste fermée des
    codes d'erreur ; réponse 400 sur les paramètres invalides ; en-têtes de
    quota sur toutes les réponses ; sémantique de `cursor=null` et des
    paramètres inconnus ; sens de `403` (accès du workspace au service, pas un
    droit par clé) ; sémantique des statuts ; périmètre Meta de la famille
    `social_*` ; format de livraison des webhooks (`callbacks`) et signature ;
    section « Disponibilité » ; en-têtes (`Cache-Control`, `X-RateLimit-*`)
    déclarés sur chaque réponse ; `data` et `secret` requis ; codes
    `automation_not_controllable` (422) et `webhook_not_found` (404) ; 403 et
    429 déclarés sur toute opération ; champs requis de `Run`, `Lead`, `Webhook`
    ; livraison webhook typée par événement (`discriminator`) et sans
    authentification Bearer héritée.
servers:
  - url: https://api.agentova.ai/v1
    description: >-
      Production (base URL à confirmer — [À CLARIFIER] ; l'URL réelle est
      communiquée avec le workspace de test au jalon 80 %)
security:
  - bearerAuth: []
paths:
  /automations/{id}/runs:
    get:
      summary: Historique d'exécutions d'une automatisation
      description: Pas encore servi par l'API réelle (voir « Disponibilité »).
      operationId: listAutomationRuns
      parameters:
        - $ref: '#/components/parameters/AutomationId'
        - $ref: '#/components/parameters/Limit'
        - $ref: '#/components/parameters/Cursor'
      responses:
        '200':
          description: Liste paginée de runs
          headers:
            Cache-Control:
              $ref: '#/components/headers/Cache-Control'
            X-RateLimit-Limit:
              $ref: '#/components/headers/X-RateLimit-Limit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/X-RateLimit-Remaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/X-RateLimit-Reset'
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/PaginatedResponse'
                  - type: object
                    required:
                      - data
                    properties:
                      data:
                        type: array
                        items:
                          $ref: '#/components/schemas/Run'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/RateLimited'
components:
  parameters:
    AutomationId:
      name: id
      in: path
      required: true
      description: Identifiant opaque `aut_…` tel que renvoyé par l'API.
      schema:
        type: string
    Limit:
      name: limit
      in: query
      description: >-
        Entier entre 1 et 100. Hors bornes ou non entier → 400
        `invalid_request`.
      schema:
        type: integer
        minimum: 1
        maximum: 100
        default: 25
    Cursor:
      name: cursor
      in: query
      description: >
        Curseur opaque reçu dans `next_cursor`. Absent, vide ou égal au mot
        `null` = première page. Illisible → 400 `invalid_request`.
      schema:
        type: string
        nullable: true
  headers:
    Cache-Control:
      description: Toujours `no-store` (données personnelles, aucun cache intermédiaire)
      schema:
        type: string
        enum:
          - no-store
    X-RateLimit-Limit:
      description: Nombre de requêtes autorisées par fenêtre (par clé)
      schema:
        type: integer
    X-RateLimit-Remaining:
      description: Requêtes restantes dans la fenêtre courante
      schema:
        type: integer
    X-RateLimit-Reset:
      description: >-
        Secondes restantes avant la remise à zéro de la fenêtre (PAS un
        horodatage)
      schema:
        type: integer
  schemas:
    PaginatedResponse:
      type: object
      required:
        - has_more
        - next_cursor
      properties:
        has_more:
          type: boolean
        next_cursor:
          type: string
          nullable: true
          description: Curseur opaque de la page suivante ; `null` s'il n'y a pas de suite.
    Run:
      type: object
      required:
        - id
        - automation_id
        - status
        - trigger_type
        - occurred_at
        - actions
        - lead_id
      properties:
        id:
          type: string
          description: Identifiant opaque préfixé `run_`.
        automation_id:
          type: string
          description: Identifiant opaque préfixé `aut_`.
        status:
          type: string
          enum:
            - success
            - partial
            - failed
        trigger_type:
          type: string
          enum:
            - comment
            - story_reply
            - message
            - lead_ads
            - crm_event
        occurred_at:
          type: string
          format: date-time
        actions:
          type: array
          items:
            type: object
            properties:
              type:
                type: string
              status:
                type: string
        lead_id:
          type: string
          nullable: true
          description: Identifiant opaque préfixé `lea_`, ou `null`.
    ErrorResponse:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - code
            - message
            - details
          properties:
            code:
              $ref: '#/components/schemas/ErrorCode'
            message:
              type: string
              description: >-
                En français, destiné à être affiché ; peut changer sans préavis
                (brancher sur `code`).
            details:
              type: object
              description: >-
                Vide (`{}`) ou contexte (`parameter`, `max`, `reason`,
                `retry_after_seconds`…).
    ErrorCode:
      type: string
      description: >
        Codes stables d'erreur. `invalid_request` (400 ; aussi 413 corps trop
        volumineux et 415 type de contenu non supporté, statut HTTP conservé,
        raison dans `details.reason`) · `invalid_api_key` (401) ·
        `workspace_access_denied` (403) · `automation_not_found` (404) ·
        `webhook_not_found` (404) · `route_not_found` (404 : chemin inconnu ou
        route pas encore servie) · `automation_not_controllable` (422 :
        automatisation en `draft` ou `error`) · `rate_limited` (429) ·
        `internal_error` (500, message générique).
      enum:
        - invalid_request
        - invalid_api_key
        - workspace_access_denied
        - automation_not_found
        - webhook_not_found
        - route_not_found
        - automation_not_controllable
        - rate_limited
        - internal_error
  responses:
    BadRequest:
      description: >-
        Paramètre de requête ou corps invalide (`details.parameter` nomme le
        fautif)
      headers:
        Cache-Control:
          $ref: '#/components/headers/Cache-Control'
        X-RateLimit-Limit:
          $ref: '#/components/headers/X-RateLimit-Limit'
        X-RateLimit-Remaining:
          $ref: '#/components/headers/X-RateLimit-Remaining'
        X-RateLimit-Reset:
          $ref: '#/components/headers/X-RateLimit-Reset'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              code: invalid_request
              message: Le paramètre limit doit être un entier entre 1 et 100
              details:
                parameter: limit
                max: 100
    Unauthorized:
      description: Clé absente, mal formée, invalide ou révoquée (indistinguables, exprès)
      headers:
        Cache-Control:
          $ref: '#/components/headers/Cache-Control'
        X-RateLimit-Limit:
          $ref: '#/components/headers/X-RateLimit-Limit'
        X-RateLimit-Remaining:
          $ref: '#/components/headers/X-RateLimit-Remaining'
        X-RateLimit-Reset:
          $ref: '#/components/headers/X-RateLimit-Reset'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              code: invalid_api_key
              message: Clé invalide ou révoquée — créez-en une dans Paramètres → API
              details: {}
    Forbidden:
      description: >
        Clé valide, mais le workspace n'a pas (ou plus) accès au service —
        abonnement bloqué ou absent. Ce n'est pas un droit par clé : il n'y a
        pas de permissions par clé en v1.
      headers:
        Cache-Control:
          $ref: '#/components/headers/Cache-Control'
        X-RateLimit-Limit:
          $ref: '#/components/headers/X-RateLimit-Limit'
        X-RateLimit-Remaining:
          $ref: '#/components/headers/X-RateLimit-Remaining'
        X-RateLimit-Reset:
          $ref: '#/components/headers/X-RateLimit-Reset'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              code: workspace_access_denied
              message: >-
                L'abonnement de cet espace de travail ne permet pas l'accès à
                l'API
              details: {}
    NotFound:
      description: >
        Ressource absente de ce workspace (même réponse qu'elle existe ailleurs
        ou nulle part), OU route inconnue / pas encore servie
        (`route_not_found`).
      headers:
        Cache-Control:
          $ref: '#/components/headers/Cache-Control'
        X-RateLimit-Limit:
          $ref: '#/components/headers/X-RateLimit-Limit'
        X-RateLimit-Remaining:
          $ref: '#/components/headers/X-RateLimit-Remaining'
        X-RateLimit-Reset:
          $ref: '#/components/headers/X-RateLimit-Reset'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              code: automation_not_found
              message: Automatisation introuvable dans ce workspace
              details: {}
    RateLimited:
      description: >-
        Quota dépassé (par clé, ou trop d'échecs d'authentification depuis une
        adresse)
      headers:
        Cache-Control:
          $ref: '#/components/headers/Cache-Control'
        Retry-After:
          description: Secondes avant de réessayer
          schema:
            type: integer
        X-RateLimit-Limit:
          $ref: '#/components/headers/X-RateLimit-Limit'
        X-RateLimit-Remaining:
          $ref: '#/components/headers/X-RateLimit-Remaining'
        X-RateLimit-Reset:
          $ref: '#/components/headers/X-RateLimit-Reset'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              code: rate_limited
              message: Quota de requêtes dépassé — réessayez dans quelques secondes
              details:
                retry_after_seconds: 42
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: agk_live_<32 caractères>
      description: >
        Une clé = un workspace ; la clé détermine le workspace, aucun
        workspace_id ne circule jamais dans les requêtes. Le schéma `Bearer` est
        insensible à la casse. Une clé révoquée est refusée immédiatement.

````