> ## 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.

# Changer le statut (activer / mettre en pause)

> Idempotent : re-pauser une automatisation déjà en pause renvoie 200. Le corps n'accepte que `active` et `paused` (toute autre valeur → 400 `invalid_request`). 422 `automation_not_controllable` si l'automatisation est actuellement `draft` ou `error` : elle n'est pas pilotable par l'API tant qu'elle n'a pas été mise en état depuis l'application. Pas encore servi par l'API réelle (voir « Disponibilité ») : `404 route_not_found` en attendant.




## OpenAPI

````yaml /openapi/openapi-v1-draft.yaml patch /automations/{id}
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}:
    patch:
      summary: Changer le statut (activer / mettre en pause)
      description: >
        Idempotent : re-pauser une automatisation déjà en pause renvoie 200. Le
        corps n'accepte que `active` et `paused` (toute autre valeur → 400
        `invalid_request`). 422 `automation_not_controllable` si
        l'automatisation est actuellement `draft` ou `error` : elle n'est pas
        pilotable par l'API tant qu'elle n'a pas été mise en état depuis
        l'application. Pas encore servi par l'API réelle (voir « Disponibilité
        ») : `404 route_not_found` en attendant.
      operationId: updateAutomationStatus
      parameters:
        - $ref: '#/components/parameters/AutomationId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - status
              properties:
                status:
                  type: string
                  enum:
                    - active
                    - paused
            example:
              status: paused
      responses:
        '200':
          description: Statut mis à jour (ou déjà dans cet état)
          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/Automation'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          description: L'automatisation est en `draft` ou `error` — non pilotable par l'API
          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_controllable
                  message: >-
                    Cette automatisation est en brouillon ou en erreur :
                    activez-la d'abord depuis l'application
                  details:
                    status: draft
        '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
  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:
    Automation:
      type: object
      required:
        - id
        - name
        - type
        - provider
        - agent_id
        - agent_name
        - status
        - updated_at
      properties:
        id:
          type: string
          description: >-
            Identifiant opaque préfixé `aut_`. Stable pour une automatisation
            donnée.
        name:
          type: string
          description: >
            Libellé tel que l'application l'affiche. Pour une automatisation
            sociale il est composé (« Réponse aux commentaires — Agent SAV »).
        type:
          $ref: '#/components/schemas/AutomationType'
        provider:
          type: string
          description: >
            Valeur brute du connecteur. Servis aujourd'hui : `facebook`,
            `instagram`, `instagram_page`. D'autres valeurs (ex. `hubspot`)
            arriveront avec `crm_source`. À traiter comme une chaîne libre.
        agent_id:
          type: string
          description: Identifiant opaque d'agent, préfixé `agt_`.
        agent_name:
          type: string
        status:
          $ref: '#/components/schemas/AutomationStatus'
        updated_at:
          type: string
          format: date-time
    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`…).
    AutomationType:
      type: string
      description: >
        `social_comments`, `social_story`, `social_messages` et `lead_ads`
        désignent les réseaux Meta (Facebook, Instagram). Les canaux WhatsApp et
        e-mail ne sont pas exposés dans cette version ; ils auront leur propre
        type, annoncé le moment venu. `crm_source` = automatisation déclenchée
        par un CRM (pas encore servie).
      enum:
        - social_comments
        - social_story
        - social_messages
        - lead_ads
        - crm_source
    AutomationStatus:
      type: string
      description: >
        `active` : tourne. `paused` : mise en pause depuis l'application (ou par
        `PATCH`). `draft` : jamais activée. `error` : arrêtée sur une erreur
        (compte déconnecté, jeton révoqué…). Une automatisation dont le compte a
        été désabonné n'apparaît pas dans l'API.
      enum:
        - active
        - paused
        - draft
        - error
    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.

````