Skip to content

Approbations ​

Les routes sont relatives à <PUBLIC_BASE_URL> ; les corps de requête et de réponse sont en JSON sauf mention contraire. L’authentification, les portées, la pagination et le format des erreurs sont décrits dans les guides de l’API REST.

GET /api/v1/approvals ​

Lister mes approbations

En attente par défaut ; l’historique sur demande avec status. Chaque ligne porte son contexte (question, workflow, extrait du déclencheur). Avec messageId, les approbations d’un message, en une seule page.

Accès — Session de membre ou clé d’API portant approvals:read.

Paramètres

NomOùTypeRequis
statusrequête"pending" | "approved" | "rejected" | "expired"non
messageIdrequêtestringnon
cursorrequêtestringnon
limitrequêteintegernon

Réponses

200 — Une page d’approbations.

ChampTypeRequis
approvalsobject[]oui
nextCursorstring | nulloui
Schéma JSON
json
{
  "type": "object",
  "properties": {
    "approvals": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": { "type": "string" },
          "status": {
            "type": "string",
            "enum": [ "pending", "approved", "rejected", "expired" ]
          },
          "title": { "type": "string" },
          "details": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
          "executionId": { "type": "string" },
          "workflowId": { "type": "string" },
          "workflowName": { "type": "string" },
          "nodeId": { "type": "string" },
          "trigger": {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "messageId": { "type": "string" },
                  "fromName": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
                  "fromEmail": { "type": "string" },
                  "subject": { "type": "string" },
                  "receivedAt": { "type": "string" }
                },
                "required": [
                  "messageId",
                  "fromName",
                  "fromEmail",
                  "subject",
                  "receivedAt"
                ],
                "additionalProperties": false
              },
              { "type": "null" }
            ]
          },
          "expiresAt": { "type": "string" },
          "decidedBy": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
          "decidedAt": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
          "createdAt": { "type": "string" }
        },
        "required": [
          "id",
          "status",
          "title",
          "details",
          "executionId",
          "workflowId",
          "workflowName",
          "nodeId",
          "trigger",
          "expiresAt",
          "decidedBy",
          "decidedAt",
          "createdAt"
        ],
        "additionalProperties": false
      }
    },
    "nextCursor": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }
  },
  "required": [ "approvals", "nextCursor" ],
  "additionalProperties": false
}

400 — La requête ne respecte pas son schéma.

401 — Aucune session ni clé d’API valide (auth.unauthenticated).

403 — Refusé : rôle insuffisant (auth.forbidden), portée manquante (api_key.scope_missing, details.required la nomme) ou route fermée aux clés (api_key.session_required).

429 — La clé d’API dépasse son débit (api_key.rate_limited) ; Retry-After dit quand réessayer.

Codes d’erreur — request.bad_request. Les codes communs (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) s’appliquent à toutes les routes ; voir Erreurs.

POST /api/v1/approvals/{id}/decide ​

Trancher une approbation

Approuver ou rejeter depuis l’application. La réponse est l’approbation dans son nouvel état, pas l’exécution : la décision enfile une reprise, la suite arrive par le canal temps réel. Déjà tranchée : 409.

Accès — Session de membre ou clé d’API portant approvals:write.

Paramètres

NomOùTypeRequis
idcheminstringoui

Corps de la requête (application/json)

ChampTypeRequis
decision"approve" | "reject"oui
Schéma JSON
json
{
  "type": "object",
  "properties": { "decision": { "type": "string", "enum": [ "approve", "reject" ] } },
  "required": [ "decision" ]
}

Réponses

200 — L’approbation, tranchée.

ChampTypeRequis
approvalobjectoui
resumedbooleanoui
Schéma JSON
json
{
  "type": "object",
  "properties": {
    "approval": {
      "type": "object",
      "properties": {
        "id": { "type": "string" },
        "status": {
          "type": "string",
          "enum": [ "pending", "approved", "rejected", "expired" ]
        },
        "title": { "type": "string" },
        "details": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
        "executionId": { "type": "string" },
        "workflowId": { "type": "string" },
        "workflowName": { "type": "string" },
        "nodeId": { "type": "string" },
        "trigger": {
          "anyOf": [
            {
              "type": "object",
              "properties": {
                "messageId": { "type": "string" },
                "fromName": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
                "fromEmail": { "type": "string" },
                "subject": { "type": "string" },
                "receivedAt": { "type": "string" }
              },
              "required": [ "messageId", "fromName", "fromEmail", "subject", "receivedAt" ],
              "additionalProperties": false
            },
            { "type": "null" }
          ]
        },
        "expiresAt": { "type": "string" },
        "decidedBy": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
        "decidedAt": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
        "createdAt": { "type": "string" }
      },
      "required": [
        "id",
        "status",
        "title",
        "details",
        "executionId",
        "workflowId",
        "workflowName",
        "nodeId",
        "trigger",
        "expiresAt",
        "decidedBy",
        "decidedAt",
        "createdAt"
      ],
      "additionalProperties": false
    },
    "resumed": { "type": "boolean" }
  },
  "required": [ "approval", "resumed" ],
  "additionalProperties": false
}

400 — La requête ne respecte pas son schéma.

401 — Aucune session ni clé d’API valide (auth.unauthenticated).

403 — Refusé : rôle insuffisant (auth.forbidden), portée manquante (api_key.scope_missing, details.required la nomme) ou route fermée aux clés (api_key.session_required).

429 — La clé d’API dépasse son débit (api_key.rate_limited) ; Retry-After dit quand réessayer.

Cette opération accepte un en-tête Idempotency-Key : rejouer la même requête avec la même clé rend la réponse d’origine au lieu d’agir deux fois. Voir Idempotence.

Codes d’erreur — request.bad_request, approval.not_found, approval.already_decided. Les codes communs (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) s’appliquent à toutes les routes ; voir Erreurs.

Exemple de requête

json
{ "decision": "approve" }

Exemple de réponse (200)

json
{
  "approval": {
    "id": "0192f1c2-3b4d-7e8f-9a0b-1c2d3e4f5a6b",
    "executionId": "0192f1c2-3b4d-7e8f-9a0b-1c2d3e4f5a6c",
    "workflowId": "0192f1c2-3b4d-7e8f-9a0b-1c2d3e4f5a6d",
    "workflowName": "Quotes over 5k",
    "title": "Send the quote to ACME?",
    "status": "approved",
    "createdAt": "2026-10-04T09:00:00.000Z",
    "expiresAt": "2026-10-05T09:00:00.000Z",
    "decidedAt": "2026-10-04T09:12:00.000Z"
  },
  "resumed": true
}

GET /api/v1/approvals/t/{token}/{decision} ​

Trancher une approbation depuis un lien d’email

Les boutons vert et rouge du mail (approve ou reject). Pas de session : le jeton est l’autorisation, consommé une fois. La réponse est une page HTML autonome ; un second clic montre la décision qui tient. Limité en débit par IP ; 404 pour un jeton inconnu.

Accès — Autorisée par le jeton porté dans l’URL.

Paramètres

NomOùTypeRequis
tokencheminstringoui
decisionchemin"approve" | "reject"oui

Réponses

200 — La page de résultat.

Type de contenu : text/html

404 — Jeton ou décision inconnus.