Français
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.
| Champ | Type | Requis |
|---|---|---|
templates | object[] | 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
| Nom | Où | Type | Requis |
|---|---|---|---|
id | chemin | string | oui |
Réponses
200 — Le template.
| Champ | Type | Requis |
|---|---|---|
template | object | oui |
graph | object | oui |
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
| Nom | Où | Type | Requis |
|---|---|---|---|
id | chemin | string | oui |
Corps de la requête (application/json)
| Champ | Type | Requis |
|---|---|---|
name | string | non |
Schéma JSON
json
{
"type": "object",
"properties": { "name": { "type": "string", "minLength": 1, "maxLength": 200 } }
}Réponses
201 — L’identifiant du nouveau workflow.
| Champ | Type | Requis |
|---|---|---|
workflowId | string (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)
| Champ | Type | Requis |
|---|---|---|
workflowId | string (uuid) | oui |
name | string | oui |
description | string | oui |
category | string | null | non |
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.
| Champ | Type | Requis |
|---|---|---|
template | object | oui |
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
| Nom | Où | Type | Requis |
|---|---|---|---|
id | chemin | string | oui |
Corps de la requête (application/json)
| Champ | Type | Requis |
|---|---|---|
name | string | non |
description | string | non |
category | string | null | non |
enabled | boolean | non |
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.
| Champ | Type | Requis |
|---|---|---|
template | object | oui |
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
| Nom | Où | Type | Requis |
|---|---|---|---|
id | chemin | string | oui |
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.