Skip to content

Templates ​

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/templates ​

Lister les templates de l’instance

Ce que le membre peut installer. Un administrateur reçoit la même forme, templates désactivés compris.

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

Réponses

200 — Les templates.

ChampTypeRequis
templatesobject[]oui
Schéma JSON
json
{
  "type": "object",
  "properties": {
    "templates": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "name": { "type": "string" },
          "description": { "type": "string" },
          "category": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
          "enabled": { "type": "boolean" },
          "nodeTypes": { "type": "array", "items": { "type": "string" } },
          "requiresProviders": { "type": "array", "items": { "type": "string" } },
          "createdBy": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid",
                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
              },
              { "type": "null" }
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
          },
          "installCount": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 }
        },
        "required": [
          "id",
          "name",
          "description",
          "category",
          "enabled",
          "nodeTypes",
          "requiresProviders",
          "createdBy",
          "createdAt",
          "updatedAt",
          "installCount"
        ],
        "additionalProperties": false
      }
    }
  },
  "required": [ "templates" ],
  "additionalProperties": false
}

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.

GET /api/v1/templates/{id} ​

Lire un template et son graphe

Le graphe voyage pour que l’installation soit un choix éclairé. Pour un membre, un template désactivé est le même 404 qu’un identifiant inconnu.

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

Paramètres

NomOùTypeRequis
idcheminstringoui

Réponses

200 — Le template.

ChampTypeRequis
templateobjectoui
graphobjectoui
Schéma JSON
json
{
  "type": "object",
  "properties": {
    "template": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string",
          "format": "uuid",
          "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
        },
        "name": { "type": "string" },
        "description": { "type": "string" },
        "category": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
        "enabled": { "type": "boolean" },
        "nodeTypes": { "type": "array", "items": { "type": "string" } },
        "requiresProviders": { "type": "array", "items": { "type": "string" } },
        "createdBy": {
          "anyOf": [
            {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            },
            { "type": "null" }
          ]
        },
        "createdAt": {
          "type": "string",
          "format": "date-time",
          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
        },
        "updatedAt": {
          "type": "string",
          "format": "date-time",
          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
        },
        "installCount": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 }
      },
      "required": [
        "id",
        "name",
        "description",
        "category",
        "enabled",
        "nodeTypes",
        "requiresProviders",
        "createdBy",
        "createdAt",
        "updatedAt",
        "installCount"
      ],
      "additionalProperties": false
    },
    "graph": {
      "type": "object",
      "properties": {
        "id": {},
        "workflowId": {},
        "nodes": {
          "readOnly": true,
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "id": {},
              "type": { "type": "string", "minLength": 1, "maxLength": 128 },
              "version": {
                "type": "integer",
                "exclusiveMinimum": 0,
                "maximum": 9007199254740991
              },
              "name": { "type": "string", "minLength": 1, "maxLength": 200 },
              "params": {
                "default": {},
                "type": "object",
                "propertyNames": { "type": "string" },
                "additionalProperties": {}
              },
              "onError": {
                "default": "fail",
                "type": "string",
                "enum": [ "fail", "continue", "errorPort" ]
              },
              "retry": {
                "type": "object",
                "properties": {
                  "maxAttempts": { "type": "integer", "minimum": 1, "maximum": 10 },
                  "delayMs": { "type": "integer", "minimum": 1000, "maximum": 3600000 }
                },
                "required": [ "maxAttempts" ],
                "additionalProperties": false
              },
              "timeoutMs": { "type": "integer", "minimum": 5000, "maximum": 1800000 },
              "position": {
                "type": "object",
                "properties": { "x": { "type": "number" }, "y": { "type": "number" } },
                "required": [ "x", "y" ],
                "additionalProperties": false
              },
              "disabled": { "type": "boolean" },
              "notes": { "type": "string", "maxLength": 2000 }
            },
            "required": [ "id", "type", "version", "name", "params", "onError" ],
            "additionalProperties": false
          }
        },
        "connections": {
          "readOnly": true,
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "from": {},
              "output": { "type": "string" },
              "to": {},
              "input": { "type": "string" },
              "kind": { "type": "string", "enum": [ "data", "service" ] }
            },
            "required": [ "from", "output", "to" ],
            "additionalProperties": false
          }
        },
        "notes": {
          "readOnly": true,
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "id": { "type": "string", "minLength": 1, "maxLength": 64 },
              "text": { "default": "", "type": "string", "maxLength": 4000 },
              "position": {
                "type": "object",
                "properties": { "x": { "type": "number" }, "y": { "type": "number" } },
                "required": [ "x", "y" ],
                "additionalProperties": false
              },
              "size": {
                "default": { "width": 240, "height": 160 },
                "type": "object",
                "properties": {
                  "width": { "type": "number", "minimum": 120, "maximum": 2000 },
                  "height": { "type": "number", "minimum": 80, "maximum": 2000 }
                },
                "required": [ "width", "height" ],
                "additionalProperties": false
              },
              "color": {
                "default": "jaune",
                "type": "string",
                "enum": [ "jaune", "menthe", "ciel", "rose", "lavande" ]
              }
            },
            "required": [ "id", "text", "position", "size", "color" ],
            "additionalProperties": false
          }
        },
        "pins": {
          "type": "object",
          "propertyNames": { "type": "string", "minLength": 1, "maxLength": 64 },
          "additionalProperties": {
            "type": "object",
            "properties": {
              "output": {},
              "port": { "type": "string" },
              "pinnedAt": { "type": "string", "minLength": 1, "maxLength": 64 }
            },
            "required": [ "output", "pinnedAt" ],
            "additionalProperties": false
          }
        }
      },
      "required": [ "id", "workflowId", "nodes", "connections" ],
      "additionalProperties": false
    }
  },
  "required": [ "template", "graph" ],
  "additionalProperties": false
}

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 — templates.not_found. 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/templates/{id}/install ​

Installer un template en nouveau brouillon

Crée un workflow en brouillon, propriété du membre, à partir d’une copie du graphe du template ; publier reste un geste explicite. Un template qui utilise un type de nœud interdit à ce membre est refusé (409 templates.forbidden_node, les types dans details.nodeTypes).

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

Paramètres

NomOùTypeRequis
idcheminstringoui

Corps de la requête (application/json)

ChampTypeRequis
namestringnon
Schéma JSON
json
{
  "type": "object",
  "properties": { "name": { "type": "string", "minLength": 1, "maxLength": 200 } }
}

Réponses

201 — L’identifiant du nouveau workflow.

ChampTypeRequis
workflowIdstring (uuid)oui
Schéma JSON
json
{
  "type": "object",
  "properties": {
    "workflowId": {
      "type": "string",
      "format": "uuid",
      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
    }
  },
  "required": [ "workflowId" ],
  "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, templates.not_found, templates.forbidden_node. 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
{}

Exemple de réponse (201)

json
{ "workflowId": "0192f1c2-dddd-7000-8000-000000000011" }

POST /api/v1/admin/templates/promote ​

Promouvoir un workflow en template

Fige le graphe du workflow de n’importe quel membre (sa version publiée, ou son brouillon) en template de l’instance. Un graphe qui échoue à la validation est refusé avec 422 templates.invalid_graph et le diagnostic dans details.validation.

Accès — Session de membre ou clé d’API portant admin:write (rôle administrateur requis).

Corps de la requête (application/json)

ChampTypeRequis
workflowIdstring (uuid)oui
namestringoui
descriptionstringoui
categorystring | nullnon
Schéma JSON
json
{
  "type": "object",
  "properties": {
    "workflowId": {
      "type": "string",
      "format": "uuid",
      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
    },
    "name": { "type": "string", "minLength": 1, "maxLength": 120 },
    "description": { "type": "string", "maxLength": 2000 },
    "category": {
      "anyOf": [
        { "type": "string", "minLength": 1, "maxLength": 60 },
        { "type": "null" }
      ]
    }
  },
  "required": [ "workflowId", "name", "description" ]
}

Réponses

201 — Le template.

ChampTypeRequis
templateobjectoui
Schéma JSON
json
{
  "type": "object",
  "properties": {
    "template": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string",
          "format": "uuid",
          "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
        },
        "name": { "type": "string" },
        "description": { "type": "string" },
        "category": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
        "enabled": { "type": "boolean" },
        "nodeTypes": { "type": "array", "items": { "type": "string" } },
        "requiresProviders": { "type": "array", "items": { "type": "string" } },
        "createdBy": {
          "anyOf": [
            {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            },
            { "type": "null" }
          ]
        },
        "createdAt": {
          "type": "string",
          "format": "date-time",
          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
        },
        "updatedAt": {
          "type": "string",
          "format": "date-time",
          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
        },
        "installCount": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 }
      },
      "required": [
        "id",
        "name",
        "description",
        "category",
        "enabled",
        "nodeTypes",
        "requiresProviders",
        "createdBy",
        "createdAt",
        "updatedAt",
        "installCount"
      ],
      "additionalProperties": false
    }
  },
  "required": [ "template" ],
  "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, templates.workflow_not_found, templates.invalid_graph. Les codes communs (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) s’appliquent à toutes les routes ; voir Erreurs.

PUT /api/v1/admin/templates/{id} ​

Modifier les métadonnées d’un template

Partiel, et métadonnées seulement (nom, description, catégorie, actif). category: null l’efface, une clé absente la laisse. Le graphe ne change jamais : promouvoir à nouveau pour un autre.

Accès — Session de membre ou clé d’API portant admin:write (rôle administrateur requis).

Paramètres

NomOùTypeRequis
idcheminstringoui

Corps de la requête (application/json)

ChampTypeRequis
namestringnon
descriptionstringnon
categorystring | nullnon
enabledbooleannon
Schéma JSON
json
{
  "type": "object",
  "properties": {
    "name": { "type": "string", "minLength": 1, "maxLength": 120 },
    "description": { "type": "string", "maxLength": 2000 },
    "category": {
      "anyOf": [
        { "type": "string", "minLength": 1, "maxLength": 60 },
        { "type": "null" }
      ]
    },
    "enabled": { "type": "boolean" }
  }
}

Réponses

200 — Le template, mis à jour.

ChampTypeRequis
templateobjectoui

Même schéma que POST /api/v1/admin/templates/promote.

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, templates.not_found. Les codes communs (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) s’appliquent à toutes les routes ; voir Erreurs.

DELETE /api/v1/admin/templates/{id} ​

Supprimer un template

Les workflows déjà installés depuis lui sont intacts : chacun a reçu sa copie du graphe.

Accès — Session de membre ou clé d’API portant admin:write (rôle administrateur requis).

Paramètres

NomOùTypeRequis
idcheminstringoui

Réponses

204 — Supprimé.

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 — templates.not_found. Les codes communs (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) s’appliquent à toutes les routes ; voir Erreurs.