Endpoints

Workflows

Créer, exécuter, publier et surveiller des workflows, décider de leurs approbations et les démarrer depuis des webhooks.

Afficher en Markdown

Un workflow est un processus automatisé composé d'étapes : un déclencheur démarre une exécution, et les étapes qui le suivent appellent des outils, exécutent des assistants, créent des branches, bouclent, envoient des requêtes HTTP, attendent l'approbation d'une personne et définissent le résultat. L'API des workflows permet à votre application de lister les workflows, de les exécuter avec une progression en direct, de lire les exécutions passées, de décider des approbations, de modifier et publier des workflows, et de démarrer des workflows publiés depuis une URL de webhook publique.

Chaque appel s'exécute au nom de l'utilisateur propriétaire de la clé API, avec les permissions, les organisations et les crédits de cet utilisateur. Les exécutions démarrées via l'API exécutent le brouillon du workflow (la définition actuelle) ; les versions publiées sont exécutées par les plannings, les webhooks et les déclencheurs d'enregistrements booster.

Portées et accès

Portée Autorise
ayeto.workflow Lister et lire les workflows, les exécuter (y compris en streaming), annuler des exécutions, lister et lire les exécutions, le catalogue, la validation, la prévisualisation de planning, l'historique des révisions, l'export, les approbations (lister, compter, lire, décider).
ayeto.workflow.write Créer, mettre à jour et supprimer des workflows, supprimer des exécutions, les informations de déploiement (contiennent les secrets des webhooks), publier, activer, régénérer les secrets des webhooks, restaurer une révision, importer, copier, l'assistant builder.
* Tout.

Les portées ne s'incluent pas l'une l'autre : une clé qui doit à la fois lire et modifier des workflows a besoin des deux. Une clé sans la portée requise reçoit 401 avec API key is invalid ; voir authentification.

En plus de la portée, chaque workflow vérifie qui peut faire quoi :

Qui Peut
Propriétaire (le créateur, ou un membre du groupe propriétaire) Tout.
Utilisateur avec qui il est partagé en écriture Le lire, le modifier, l'exécuter, le publier, l'exporter, le copier et le supprimer.
Utilisateur avec qui il est partagé en lecture Le lire, le valider, voir ses révisions. L'exécuter, l'exporter ou le copier uniquement si le partage accorde la permission workflow.run, workflow.export ou workflow.copy.

Un workflow qui appartient à une organisation s'exécute dans cette organisation (ses crédits et son stockage), l'utilisateur doit donc y être membre avec un accès en écriture.

Concepts

Définition

La définition d'un workflow est un graphe orienté acyclique : une liste de nodes et une liste d'edges.

json
{
  "nodes": [
    {
      "id": "start",
      "type": "trigger.manual",
      "name": "Start",
      "params": {
        "input_schema": {
          "type": "object",
          "properties": {"customer": {"type": "string"}, "question": {"type": "string"}},
          "required": ["question"]
        }
      },
      "position": {"x": 0, "y": 0}
    },
    {
      "id": "answer",
      "type": "assistant.run",
      "name": "Draft an answer",
      "params": {
        "assistant_id": "3f6c1a2e-8b4d-4e7a-9c1f-2d5e6a7b8c90",
        "prompt": "Answer {{ input.customer }}: {{ input.question }}"
      },
      "position": {"x": 0, "y": 160}
    },
    {
      "id": "result",
      "type": "output",
      "name": "Result",
      "params": {"value": {"answer": "{{ steps.answer.output.text }}"}},
      "position": {"x": 0, "y": 320}
    }
  ],
  "edges": [
    {"source": "start", "target": "answer", "source_handle": null},
    {"source": "answer", "target": "result", "source_handle": null}
  ]
}
Champ Type Description
nodes[].id chaîne Identifiant du nœud, unique dans le workflow : lettres, chiffres et _, au plus 64 caractères, ne commençant pas par un chiffre. Les étapes suivantes font référence à son résultat par {{ steps.<id>.output }}.
nodes[].type chaîne Type de nœud, voir types de nœuds.
nodes[].name chaîne Libellé affiché dans l'éditeur.
nodes[].params objet Paramètres du type de nœud ; leur schéma JSON se trouve dans le catalogue.
nodes[].position objet {x, y} sur le canevas de l'éditeur, ou null. Sans effet sur les exécutions.
edges[].source chaîne Nœud dont part l'arête.
edges[].target chaîne Nœud dans lequel entre l'arête.
edges[].source_handle chaîne Sortie du nœud source dont part l'arête : null pour la sortie par défaut, une sortie nommée (true / false d'une condition, un cas d'un switch, item / done d'une boucle, approved / rejected / timeout d'une approbation), ou error pour continuer lorsque l'étape source échoue.

Une définition comporte au plus 200 nœuds, au moins un déclencheur, aucun cycle et aucune arête entrant dans un déclencheur. Utilisez valider pour la vérifier.

Les paramètres de type chaîne sont des templates (syntaxe Jinja, évalués dans un bac à sable). Ils peuvent lire :

Variable Contenu
input L'entrée de l'exécution (la sortie du déclencheur).
steps.<id>.output Résultat d'une étape précédente ; également steps.<id>.success, .status, .text, .error, .file_ids.
workflow {id, name}.
run {id}.
now Heure de début de l'exécution (ISO 8601, UTC).
loop À l'intérieur du corps d'une boucle : item, index, count, parent.

Un paramètre constitué d'une seule {{ expression }} conserve le type natif de la valeur (un objet reste un objet) ; une variable non définie est une erreur de l'étape.

Types de nœuds

La liste complète, avec le schéma JSON des paramètres de chaque nœud et les outils qu'une étape tool.call peut utiliser, est fournie par le catalogue. Vue d'ensemble :

Type Catégorie Ce qu'il fait
trigger.manual déclencheur Démarre une exécution à la demande (application, API). Le paramètre facultatif input_schema décrit l'entrée de l'exécution.
trigger.schedule déclencheur Démarre le workflow publié selon un planning cron.
trigger.webhook déclencheur Démarre le workflow publié lorsque son URL de webhook est appelée.
trigger.booster_record déclencheur Démarre le workflow publié lorsqu'un enregistrement de la base de données d'un panneau Booster est créé, mis à jour ou supprimé.
tool.call action Appelle un outil d'IA avec les paramètres donnés.
assistant.run action Exécute une tâche sur un assistant dans une nouvelle conversation.
http.request action Envoie une requête HTTP à une URL publique.
notify action Envoie un e-mail à l'utilisateur au nom duquel l'exécution s'effectue.
file.to_text action Lit des fichiers (documents, images, audio) sous forme de texte.
human.approval logique Attend qu'une personne approuve ou rejette, éventuellement avec un formulaire.
condition logique Continue sur true ou false selon une expression.
switch logique Continue sur l'une de plusieurs sorties nommées, ou sur otherwise.
ai.condition logique Pose une question oui/non à un modèle de classification ; continue sur true ou false.
ai.choice logique Demande à un modèle de classification laquelle de plusieurs options convient.
loop logique Exécute les étapes situées derrière sa sortie item une fois par élément d'une liste, puis continue sur done.
transform logique Construit une valeur à partir des résultats précédents.
output logique Définit le résultat de l'exécution. N'a pas d'arêtes sortantes.

Brouillon et version publiée

La definition enregistrée sur le workflow est le brouillon. Chacune de ses modifications est conservée sous forme de révision. Les exécutions démarrées via l'API (et depuis l'application) exécutent le brouillon.

Publier copie le brouillon dans une nouvelle version immuable (1, 2, ...) et active le workflow. Tant que le workflow est actif, ses déclencheurs automatiques (planning, webhook, enregistrement booster) démarrent des exécutions de la version publiée, au nom de l'utilisateur qui l'a publiée ou activée en dernier (run_as). Modifier le brouillon par la suite ne change pas ce qu'exécutent les déclencheurs tant que vous ne publiez pas à nouveau.

Statuts d'exécution

Une exécution enregistre l'entrée, l'état de chaque étape et le résultat. Son status :

Statut Signification
queued Démarrée par un déclencheur, ou exécution en pause dont l'étape en attente a reçu son résultat ; attend un worker en arrière-plan.
running En cours d'exécution.
waiting En pause : une étape attend quelque chose d'extérieur à l'exécution (l'approbation d'une personne). Les autres branches sont terminées. L'exécution reprend en arrière-plan dès que l'étape reçoit son résultat.
success Terminée.
failed Une étape a échoué sans arête error, une limite a été dépassée, ou l'exécution n'a pas pu démarrer.
cancelled Annulée alors qu'elle était waiting ou queued.

Les étapes s'exécutent dès que toutes les étapes qui les précèdent sont terminées, de sorte que les branches indépendantes s'exécutent en parallèle. Une étape dont toutes les arêtes entrantes sont inactives (une branche non empruntée) est skipped. Une étape en échec qui a une arête error continue par celle-ci ; sans elle, l'exécution échoue (les étapes déjà en cours se terminent d'abord).

Les exécutions sont supprimées après une période de rétention (90 jours par défaut), avec les conversations et les fichiers créés par leurs étapes. Les exécutions en pause sont conservées jusqu'à leur fin.

Processus d'approbation

Une étape human.approval ouvre une approbation et met l'exécution en pause. Les personnes qui peuvent en décider sont l'utilisateur au nom duquel l'exécution s'effectue et les membres de l'organisation du workflow désignés dans l'étape ; ils sont notifiés dans l'application et par e-mail. Une approbation affiche un titre, un message et éventuellement un formulaire (un schéma JSON plat avec des valeurs préremplies). La décision (approuver avec les données du formulaire, ou rejeter) devient la sortie de l'étape et l'exécution continue sur approved ou rejected. Une approbation dont personne ne décide à temps expire : l'exécution continue sur timeout lorsque cette sortie est connectée, sinon l'étape échoue. Voir approbations.

Fichiers dans l'entrée d'une exécution

Un champ de l'input_schema du déclencheur manuel déclaré comme {"type": "object", "format": "file"} contient un fichier. Envoyez-le dans l'entrée de l'exécution soit directement en base64 :

json
{
  "invoice": {
    "filename": "invoice-1042.pdf",
    "mime_type": "application/pdf",
    "data": "data:application/pdf;base64,JVBERi0xLjcKJcfsj6IKNSAwIG9iago8PC9MZW5ndGg..."
  }
}

soit par l'id d'un fichier que l'utilisateur possède déjà ("invoice": "7b1e2c3d-..." ou {"file_id": "7b1e2c3d-..."}). data est du base64 brut ou une data URL ; name peut être utilisé à la place de filename et content_type à la place de mime_type. La limite de taille des uploads et le quota de stockage s'appliquent.

Dans l'exécution, la valeur devient les métadonnées de pièce jointe du fichier, qui sont aussi la forme sous laquelle les étapes renvoient des fichiers :

json
{
  "file_id": "7b1e2c3d-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
  "filename": "invoice-1042.pdf",
  "content_type": "application/pdf",
  "file_url": "https://ayeto.ai/api/v1/public/file/read?id=7b1e2c3d-4a5b-4c6d-8e7f-9a0b1c2d3e4f&secret=...",
  "size": 48213
}

file_url télécharge le fichier. Les fichiers envoyés en base64 appartiennent à l'exécution et sont supprimés avec elle ; un fichier désigné par son id reste celui de l'utilisateur et n'est pas supprimé avec l'exécution. La même forme base64 est acceptée dans les champs fichier d'un formulaire d'approbation et dans le corps des webhooks.

Limites

Les valeurs par défaut ci-dessous peuvent varier selon le déploiement.

Limite Valeur par défaut
Nœuds par workflow 200
Entrée d'une exécution 200 000 caractères de JSON
Étapes exécutées par exécution (chaque élément de boucle compte) 500
Durée d'une exécution (les pauses pour approbation ne comptent pas) 1 800 secondes
Étapes exécutées simultanément dans une exécution 4
Éléments par boucle 100
Sortie enregistrée d'une étape 200 000 caractères de JSON (2 000 dans le corps d'une boucle)
Exécutions en file d'attente par workflow 50
Intervalle de planning le plus court 5 minutes
Délai pour décider d'une approbation 72 heures par défaut, au plus 720
Rétention des exécutions 90 jours
Révisions conservées par workflow 100

Objet workflow

Le workflow renvoyé par les endpoints de lecture, de création et de mise à jour. Il comporte aussi les champs communs (id, created, updated, permissions, ...).

Champ Type Description
name chaîne Nom.
description chaîne Description.
organization_id UUID Organisation à laquelle appartient le workflow, null pour un workflow personnel. Fixée à la création.
definition objet La définition du brouillon.
sharing tableau d'objets Utilisateurs avec qui il est partagé : {user_email, write, scopes}. scopes peut accorder aux partages en lecture {"workflow.run": true, "workflow.export": true, "workflow.copy": true}.
group_sharing tableau d'objets Groupes avec qui il est partagé : {group_id, write, scopes}.
last_run objet Dernière exécution terminée ou en pause : {run_id, status, finished_at, credits}, ou null. Lecture seule.
published_version entier Dernière version publiée, null s'il n'a jamais été publié. Lecture seule.
published_at horodatage Date de la dernière publication. Lecture seule.
active booléen Les déclencheurs automatiques de la version publiée sont activés. Lecture seule ; voir activer.
run_as UUID Utilisateur au nom duquel s'effectuent les exécutions automatiques. Lecture seule.

Lister et lire les workflows

Endpoints POST /api/v3/workflow/find<br>POST /api/v3/workflow/count<br>POST /api/v3/workflow/get?entity_id=<workflow id>
Portée ayeto.workflow
Limite de débit par défaut

find renvoie les workflows dont l'utilisateur est propriétaire ou qui sont partagés avec lui, sous forme de tableau de workflows, du plus récent au plus ancien sauf autre tri. count renvoie le nombre de workflows correspondants sous forme d'entier. Les deux acceptent le corps de requête habituel (filters, sort_key, sort_order, limit_from, limit_to) ; envoyez {} pour tout obtenir. Chaque workflow est renvoyé avec sa définition complète, paginez donc les longues listes.

get renvoie un workflow ; l'id est un paramètre de requête et le corps est vide.

Filtres utiles : ["organization_id", "==", "<organization id>"], ["organization_id", "==", null] (personnels), ["active", "==", true], ["name", "regex", "invoice"].

bash
curl -X POST "https://ayeto.ai/api/v3/workflow/find" \
  -H "uni-api-key: $AYETO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"filters": [["active", "==", true]], "sort_key": "updated.timestamp", "sort_order": 1, "limit_from": 0, "limit_to": 20}'
bash
curl -X POST "https://ayeto.ai/api/v3/workflow/get?entity_id=5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a" \
  -H "uni-api-key: $AYETO_API_KEY"
json
{
  "id": "5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a",
  "name": "Customer question",
  "description": "Drafts an answer to a customer question",
  "organization_id": null,
  "definition": {"nodes": ["..."], "edges": ["..."]},
  "sharing": [],
  "group_sharing": [],
  "last_run": {"run_id": "c2a1b0d9-8e7f-4a6b-9c5d-4e3f2a1b0c9d", "status": "success", "finished_at": 1759401234567, "credits": 0.42},
  "published_version": 3,
  "published_at": 1759300000000,
  "active": true,
  "run_as": "0f1e2d3c-4b5a-4968-8776-655443322110",
  "created": {"timestamp": 1759000000000, "user_id": "0f1e2d3c-4b5a-4968-8776-655443322110"},
  "updated": {"timestamp": 1759400000000, "user_id": "0f1e2d3c-4b5a-4968-8776-655443322110"}
}

Un workflow qui n'existe pas ou n'est pas visible pour l'utilisateur renvoie 404.

Créer un workflow

Endpoint POST /api/v3/workflow/create
Portée ayeto.workflow.write
Limite de débit par défaut
Champ Type Obligatoire Description
name chaîne Oui Nom.
description chaîne Non Description.
organization_id UUID Non Le créer dans cette organisation ; l'utilisateur doit y avoir un accès en écriture. À omettre pour un workflow personnel.
definition objet Non La définition. Par défaut : un seul déclencheur manuel avec l'id start.
sharing tableau d'objets Non Partages avec des utilisateurs, voir l'objet workflow.
group_sharing tableau d'objets Non Partages avec des groupes.

Renvoie le workflow créé. La définition est enregistrée telle quelle, même si elle n'est pas valide ; validez-la avant de l'exécuter. La création d'un workflow enregistre aussi sa première révision et crée l'assistant builder de l'utilisateur.

bash
curl -X POST "https://ayeto.ai/api/v3/workflow/create" \
  -H "uni-api-key: $AYETO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "Customer question", "description": "Drafts an answer to a customer question"}'

Mettre à jour un workflow

Endpoint POST /api/v3/workflow/update
Portée ayeto.workflow.write
Limite de débit par défaut
Champ Type Obligatoire Description
id UUID Oui Le workflow.
name chaîne Non Nouveau nom.
description chaîne Non Nouvelle description.
definition objet Non Nouvelle définition du brouillon ; remplace toute la définition.
sharing tableau d'objets Non Remplace les partages avec des utilisateurs.
group_sharing tableau d'objets Non Remplace les partages avec des groupes.

Seuls les champs que vous envoyez sont modifiés. L'organisation, l'état de publication et la dernière exécution ne peuvent pas être modifiés ici. Chaque modification de la définition est enregistrée comme révision ; la version publiée reste inchangée jusqu'à ce que vous publiiez à nouveau. Renvoie le workflow mis à jour.

Pour modifier un nœud, lisez le workflow, modifiez sa definition et renvoyez-la. Deux clients qui mettent à jour le même workflow en même temps écrasent mutuellement leur définition.

Supprimer un workflow

Endpoint POST /api/v3/workflow/delete?entity_id=<workflow id>
Portée ayeto.workflow.write
Limite de débit par défaut

Supprime le workflow avec toutes ses exécutions (et les conversations et fichiers qu'elles ont créés), ses révisions, ses versions publiées, ses déclencheurs et ses assistants builder. Renvoie l'id supprimé sous forme de chaîne JSON.

Catalogue

Endpoint POST /api/v3/workflow/catalog
Portée ayeto.workflow
Limite de débit par défaut

Renvoie les éléments à partir desquels les workflows peuvent être construits : chaque type de nœud avec le schéma JSON de ses paramètres, et les outils qu'une étape tool.call peut appeler. Pas de corps de requête.

Champ Type Description
node_types[].type chaîne Type de nœud, par exemple http.request.
node_types[].title chaîne Nom affiché.
node_types[].description chaîne Ce que fait le nœud et à quoi ressemble sa sortie.
node_types[].category chaîne trigger, action ou logic.
node_types[].is_trigger booléen Le nœud démarre des exécutions.
node_types[].terminal booléen Le nœud termine une branche (pas d'arêtes sortantes).
node_types[].handles tableau de chaînes Sorties nommées ; vide signifie une seule sortie par défaut. Chaque nœud qui n'est pas un déclencheur a aussi la sortie error. Pour un switch, les sorties sont les noms de ses cas plus otherwise.
node_types[].params_schema objet Schéma JSON de params.
tools[].name chaîne Nom de l'outil pour le paramètre tool de tool.call.
tools[].display_name chaîne Nom affiché.
tools[].description chaîne Description.
tools[].category chaîne Catégorie.
tools[].icon chaîne Nom de l'icône.
tools[].input_schema objet Schéma JSON des params de l'outil.

Valider un workflow

Endpoint POST /api/v3/workflow/validate
Portée ayeto.workflow
Limite de débit par défaut
Champ Type Obligatoire Description
workflow_id UUID Oui Le workflow.

Valide le brouillon pour l'utilisateur appelant (y compris le fait que l'utilisateur puisse utiliser les assistants et les panneaux Booster auxquels il fait référence).

json
{
  "valid": false,
  "issues": [
    {"severity": "error", "message": "Node 'answer' has no output 'true' (outputs: default, error)", "node_id": "answer", "edge": {"source": "answer", "target": "result", "source_handle": "true"}},
    {"severity": "warning", "message": "Node 'draft' is not reachable from any trigger and never runs", "node_id": "draft", "edge": null}
  ]
}

valid vaut false lorsqu'il existe au moins un problème de sévérité error ; les erreurs bloquent les exécutions et la publication, les avertissements non.

Exécuter un workflow

Endpoint POST /api/v3/workflow/run
Portée ayeto.workflow
Limite de débit par défaut

Exécute le brouillon au nom de l'utilisateur appelant et répond lorsque l'exécution est terminée ou en pause.

Requête

Champ Type Obligatoire Description
workflow_id UUID Oui Le workflow.
input objet Non L'entrée de l'exécution. Pour un déclencheur manuel, elle doit correspondre à son input_schema ; les clés listées dans required doivent être présentes. Au plus 200 000 caractères en JSON.
trigger_node_id chaîne Non Déclencheur à partir duquel démarrer. Par défaut : le premier trigger.manual, sinon le premier déclencheur de n'importe quel type.

Démarrer à partir d'un déclencheur de planning, de webhook ou d'enregistrement booster exécute le brouillon manuellement, ce qui est utile pour les tests : passez l'entrée que le déclencheur produirait, par exemple {"body": {...}, "query": {}, "headers": {}} pour un déclencheur webhook.

L'utilisateur a besoin du droit d'exécuter le workflow (voir portées et accès). Avant le démarrage de l'exécution, le brouillon est validé ; un brouillon invalide est rejeté avec 422. Une clé d'entrée obligatoire manquante ne rejette pas la requête : l'exécution est créée et échoue à son étape de déclencheur (Missing input: <keys>).

La requête répond à la fin de l'exécution, ce qui peut prendre plusieurs minutes (jusqu'à la limite de durée d'exécution). Pour les exécutions longues ou une progression en direct, utilisez le streaming. Lorsqu'une étape attend une approbation, la réponse revient avec status: "waiting" ; suivez l'exécution avec obtenir l'exécution.

Réponse

200 OK avec l'exécution.

Exemples

bash
curl -X POST "https://ayeto.ai/api/v3/workflow/run" \
  -H "uni-api-key: $AYETO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "workflow_id": "5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a",
    "input": {"customer": "Jana Novak", "question": "When will order 1042 be delivered?"}
  }'
python
import json
import os
import requests

response = requests.post(
    "https://ayeto.ai/api/v3/workflow/run",
    headers={"uni-api-key": os.environ["AYETO_API_KEY"]},
    json={
        "workflow_id": "5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a",
        "input": {"customer": "Jana Novak", "question": "When will order 1042 be delivered?"},
    },
    timeout=1900,
)
response.raise_for_status()
run = response.json()
if run["status"] == "success":
    print(json.loads(run["output_json"]) if run["output_json"] else None)
else:
    print(run["status"], run["error"])
javascript
const response = await fetch("https://ayeto.ai/api/v3/workflow/run", {
  method: "POST",
  headers: {
    "uni-api-key": process.env.AYETO_API_KEY,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    workflow_id: "5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a",
    input: { customer: "Jana Novak", question: "When will order 1042 be delivered?" },
  }),
});
if (!response.ok) throw new Error((await response.json()).detail);
const run = await response.json();
const output = run.output_json ? JSON.parse(run.output_json) : null;
console.log(run.status, output ?? run.error);

Objet exécution

Une exécution comporte les champs communs, plus :

Champ Type Description
workflow_id UUID Le workflow.
organization_id UUID Organisation dans laquelle l'exécution a eu lieu, ou null.
version entier Version publiée exécutée ; null pour une exécution du brouillon.
trigger_node_id chaîne Déclencheur à partir duquel l'exécution a démarré.
trigger_type chaîne Son type de nœud, par exemple trigger.manual, trigger.webhook.
trigger_depth entier Nombre d'exécutions déclenchées par des enregistrements booster qui précèdent celle-ci dans une chaîne.
automatic booléen Démarrée par un déclencheur (planning, webhook, enregistrement booster), et non par une personne.
input_json chaîne L'entrée de l'exécution sous forme de texte JSON.
status chaîne Voir statuts d'exécution.
started_at horodatage Moment où l'exécution a commencé ; null tant qu'elle est en file d'attente.
active_since horodatage Début de l'exécution en cours (après une pause, la reprise).
finished_at horodatage Moment où elle s'est terminée, ou null.
steps tableau d'étapes État de chaque étape démarrée ou ignorée, dans l'ordre d'exécution.
output_json chaîne Le résultat (valeur de la dernière étape output atteinte) sous forme de texte JSON ; vide s'il n'y en a pas.
error chaîne Raison de l'échec de l'exécution.
credits nombre Crédits dépensés par l'exécution jusqu'à présent.

created.user_id est l'utilisateur au nom duquel l'exécution s'est effectuée.

Objet étape

Champ Type Description
node_id chaîne Le nœud.
node_type chaîne Son type.
status chaîne running, waiting, success, failed ou skipped.
started_at horodatage Début, null pour une étape ignorée.
finished_at horodatage Fin.
handle chaîne Sortie sur laquelle l'exécution a continué : null (par défaut), une sortie nommée, ou error.
output_json chaîne Sortie de l'étape sous forme de texte JSON, plafonnée à 200 000 caractères (2 000 dans le corps d'une boucle).
output_truncated booléen La sortie a été coupée au plafond ; output_json n'est alors pas du JSON valide.
text chaîne Résultat lisible ou texte de statut.
error chaîne Raison de l'échec de l'étape.
file_ids tableau d'UUID Fichiers produits par l'étape.
conversation_id UUID Conversation créée par une étape assistant.run ; lisible via les conversations.
iteration tableau d'entiers Pour une étape dans le corps d'une boucle, les index des éléments, de la boucle la plus externe vers l'intérieur ; vide sinon. Une étape dans une boucle apparaît une fois par élément.

Exemple :

json
{
  "id": "c2a1b0d9-8e7f-4a6b-9c5d-4e3f2a1b0c9d",
  "workflow_id": "5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a",
  "organization_id": null,
  "version": null,
  "trigger_node_id": "start",
  "trigger_type": "trigger.manual",
  "trigger_depth": 0,
  "automatic": false,
  "input_json": "{\"customer\": \"Jana Novak\", \"question\": \"When will order 1042 be delivered?\"}",
  "status": "success",
  "started_at": 1759401220011,
  "active_since": 1759401220011,
  "finished_at": 1759401234567,
  "steps": [
    {
      "node_id": "start", "node_type": "trigger.manual", "status": "success",
      "started_at": 1759401220020, "finished_at": 1759401220031, "handle": null,
      "output_json": "{\"customer\": \"Jana Novak\", \"question\": \"When will order 1042 be delivered?\"}",
      "output_truncated": false, "text": "", "error": "", "file_ids": [], "conversation_id": null, "iteration": []
    },
    {
      "node_id": "answer", "node_type": "assistant.run", "status": "success",
      "started_at": 1759401220040, "finished_at": 1759401234400, "handle": null,
      "output_json": "{\"text\": \"Dear Jana, order 1042 ships on Friday ...\", \"data\": null, \"files\": []}",
      "output_truncated": false, "text": "Dear Jana, order 1042 ships on Friday ...", "error": "",
      "file_ids": [], "conversation_id": "8e2f4a6c-1b3d-4e5f-8a7b-9c0d1e2f3a4b", "iteration": []
    },
    {
      "node_id": "result", "node_type": "output", "status": "success",
      "started_at": 1759401234410, "finished_at": 1759401234420, "handle": null,
      "output_json": "{\"answer\": \"Dear Jana, order 1042 ships on Friday ...\"}",
      "output_truncated": false, "text": "", "error": "", "file_ids": [], "conversation_id": null, "iteration": []
    }
  ],
  "output_json": "{\"answer\": \"Dear Jana, order 1042 ships on Friday ...\"}",
  "error": "",
  "credits": 0.42,
  "created": {"timestamp": 1759401220000, "user_id": "0f1e2d3c-4b5a-4968-8776-655443322110"}
}

Exécution en streaming

Endpoint POST /api/v3/workflow/run/stream
Portée ayeto.workflow
Limite de débit par défaut

Même requête que pour exécuter un workflow, mais la réponse transmet en streaming les événements de l'exécution au fur et à mesure. L'exécution se poursuit sur le serveur jusqu'à son terme même si le client se déconnecte ; lisez ensuite le résultat avec obtenir l'exécution.

Les erreurs d'accès et de validation (pas d'accès, brouillon invalide, entrée trop volumineuse) sont renvoyées sous forme d'erreur HTTP normale avant le début du stream.

Format de transmission

La réponse (Content-Type: text/event-stream) est une suite d'objets JSON écrits les uns à la suite des autres sans séparateurs (pas de lignes SSE data:) ; voir streaming. Chaque objet est un chunk :

json
{"timestamp": 1759401220012, "data": {"type": "run_start", "run_id": "c2a1b0d9-8e7f-4a6b-9c5d-4e3f2a1b0c9d", "node_id": null, "node_type": null, "status": "running", "handle": null, "text": "", "error": "", "output_json": "", "iteration": []}, "error": null}
  • data est un événement de l'exécution (ci-dessous).
  • data: "" est un chunk de maintien de connexion (keep-alive), envoyé environ chaque seconde tant qu'il ne se passe rien. Ignorez-le.
  • Un chunk dont error est renseigné ({"status", "text", "detail"}) signale une erreur qui a mis fin au stream.

Événements

Chaque événement a les champs type, run_id, node_id, node_type, status, handle, text, error, output_json et iteration ; ceux qui portent une valeur dépendent du type.

type Signification Champs renseignés
run_start L'exécution a démarré. status: "running"
step_start Une étape a démarré. node_id, node_type, status: "running", iteration
step_progress Texte de progression d'une étape en cours (un outil ou un assistant au travail). node_id, node_type, text, iteration
step_waiting Une étape attend (une approbation). Les autres branches continuent. node_id, node_type, status: "waiting", text, output_json (pour une approbation {approval_id, expires_at, assignees})
step_end Une étape s'est terminée ou a été ignorée. node_id, node_type, status (success, failed, skipped), handle, text, error, output_json, iteration
run_waiting L'exécution est en pause ; le stream se termine sans run_end. status: "waiting", text (ids des étapes en attente, séparés par des virgules)
run_end L'exécution est terminée ; dernier événement. status (success, failed), error, output_json

Les événements des branches parallèles et des éléments de boucle s'entremêlent ; utilisez node_id et iteration pour les distinguer.

Exemples

bash
curl -N -X POST "https://ayeto.ai/api/v3/workflow/run/stream" \
  -H "uni-api-key: $AYETO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"workflow_id": "5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a", "input": {"question": "When will order 1042 be delivered?"}}'

Python, en découpant le stream en objets JSON avec raw_decode :

python
import json
import os
import requests

decoder = json.JSONDecoder()

def events(response):
    """Yield the run events of a streamed response."""
    buffer = ""
    for piece in response.iter_content(chunk_size=None, decode_unicode=True):
        buffer += piece
        while True:
            buffer = buffer.lstrip()
            if not buffer:
                break
            try:
                chunk, end = decoder.raw_decode(buffer)
            except json.JSONDecodeError:
                break  # incomplete object, wait for more data
            buffer = buffer[end:]
            if chunk.get("error"):
                raise RuntimeError(chunk["error"]["detail"])
            if chunk.get("data"):
                yield chunk["data"]

with requests.post(
    "https://ayeto.ai/api/v3/workflow/run/stream",
    headers={"uni-api-key": os.environ["AYETO_API_KEY"]},
    json={"workflow_id": "5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a", "input": {"question": "When will order 1042 be delivered?"}},
    stream=True,
    timeout=(10, 120),
) as response:
    response.raise_for_status()
    response.encoding = "utf-8"
    for event in events(response):
        if event["type"] == "step_end":
            print(f"{event['node_id']}: {event['status']} {event['error']}")
        elif event["type"] == "run_waiting":
            print("paused, waiting for:", event["text"])
        elif event["type"] == "run_end":
            print("run", event["status"], event["output_json"] or event["error"])

JavaScript, en découpant le stream par le suivi des accolades hors des chaînes :

javascript
async function* runEvents(response) {
  const reader = response.body.pipeThrough(new TextDecoderStream()).getReader();
  let buffer = "";
  while (true) {
    const { value, done } = await reader.read();
    if (done) return;
    buffer += value;
    let depth = 0, inString = false, escaped = false, start = -1, consumed = 0;
    for (let i = 0; i < buffer.length; i++) {
      const c = buffer[i];
      if (inString) {
        if (escaped) escaped = false;
        else if (c === "\\") escaped = true;
        else if (c === '"') inString = false;
      } else if (c === '"') inString = true;
      else if (c === "{") { if (depth++ === 0) start = i; }
      else if (c === "}" && --depth === 0) {
        const chunk = JSON.parse(buffer.slice(start, i + 1));
        consumed = i + 1;
        if (chunk.error) throw new Error(chunk.error.detail);
        if (chunk.data) yield chunk.data;
      }
    }
    buffer = buffer.slice(consumed);
  }
}

const response = await fetch("https://ayeto.ai/api/v3/workflow/run/stream", {
  method: "POST",
  headers: { "uni-api-key": process.env.AYETO_API_KEY, "Content-Type": "application/json" },
  body: JSON.stringify({
    workflow_id: "5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a",
    input: { question: "When will order 1042 be delivered?" },
  }),
});
if (!response.ok) throw new Error((await response.json()).detail);
for await (const event of runEvents(response)) {
  if (event.type === "step_start") console.log("running", event.node_id);
  if (event.type === "step_end") console.log(event.node_id, event.status, event.error);
  if (event.type === "run_waiting") console.log("paused, waiting for", event.text);
  if (event.type === "run_end") console.log("done", event.status, event.output_json || event.error);
}

Annuler une exécution

Endpoint POST /api/v3/workflow/run/cancel
Portée ayeto.workflow
Limite de débit par défaut
Champ Type Obligatoire Description
run_id UUID Oui L'exécution.

Annule une exécution qui est waiting ou queued. Ses étapes en attente échouent et leurs approbations en attente sont annulées. L'utilisateur au nom duquel l'exécution s'est effectuée et les utilisateurs ayant un accès en écriture au workflow peuvent l'annuler. Une exécution running ne peut pas être annulée (422) ; elle se termine d'elle-même ou à la limite de durée d'exécution. Renvoie l'exécution annulée.

Exécutions

Endpoints POST /api/v3/workflow/runs/find<br>POST /api/v3/workflow/runs/count<br>POST /api/v3/workflow/runs/get?entity_id=<run id>
Portée ayeto.workflow
Limite de débit par défaut
Endpoint POST /api/v3/workflow/runs/delete?entity_id=<run id>
Portée ayeto.workflow.write
Limite de débit par défaut

Ces endpoints voient les exécutions effectuées au nom de l'utilisateur de la clé API : les exécutions que l'utilisateur a démarrées, et les exécutions automatiques des workflows que l'utilisateur a publiés ou activés. Les exécutions des autres utilisateurs sont signalées comme introuvables.

find renvoie un tableau d'exécutions et count un entier ; les deux acceptent le corps de requête. Les exécutions incluent toutes leurs étapes et sorties, paginez donc toujours. get renvoie une exécution (corps vide). delete supprime une exécution avec les conversations et fichiers créés par ses étapes ainsi que ses approbations, et renvoie son id ; supprimer une exécution en pause y met fin.

Filtres utiles :

Objectif Filtre
Exécutions d'un workflow ["workflow_id", "==", "5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a"]
Exécutions en pause ["status", "==", "waiting"]
Exécutions en échec ["status", "==", "failed"]
Exécutions issues du webhook ["trigger_type", "==", "trigger.webhook"]
Exécutions de la version publiée uniquement ["version", "!=", null]
Démarrées depuis un instant donné ["created.timestamp", ">=", 1759363200000]
bash
curl -X POST "https://ayeto.ai/api/v3/workflow/runs/find" \
  -H "uni-api-key: $AYETO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"filters": [["workflow_id", "==", "5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a"]], "sort_key": "created.timestamp", "sort_order": 1, "limit_from": 0, "limit_to": 10}'

Pour suivre une exécution en pause ou en file d'attente, interrogez get jusqu'à ce que son status soit success, failed ou cancelled.

Approbations

Les endpoints d'approbation servent aux personnes qui décident : tout utilisateur désigné par une étape d'approbation peut les utiliser, sans autre permission sur le workflow. La clé API doit tout de même avoir la portée ayeto.workflow.

Endpoints POST /api/v3/workflow/approval/find<br>POST /api/v3/workflow/approval/get<br>POST /api/v3/workflow/approval/decide
Portée ayeto.workflow
Limite de débit par défaut
Endpoint POST /api/v3/workflow/approval/count
Portée ayeto.workflow
Limite de débit élevée

Objet approbation

Champs communs, plus :

Champ Type Description
workflow_id UUID Le workflow.
workflow_name chaîne Son nom au moment de l'ouverture de l'approbation.
run_id UUID L'exécution en pause.
node_id chaîne L'étape d'approbation.
organization_id UUID Organisation du workflow, ou null.
status chaîne pending, approved, rejected, expired (personne n'a décidé à temps) ou cancelled (l'exécution s'est terminée avant).
title chaîne Ce qu'il faut décider.
message chaîne Détails (Markdown).
form_schema objet Schéma JSON du formulaire ({"type": "object", "properties": {...}, "required": [...]}) avec des champs plats de type string, number, integer, boolean, ou un fichier ({"type": "object", "format": "file"}) ; null lorsqu'il n'y a pas de formulaire.
form_values objet Valeurs préremplies, par nom de champ.
allow_reject booléen L'approbation peut être rejetée. Lorsque false, l'étape ne fait que recueillir le formulaire.
assignee_user_ids tableau d'UUID Utilisateurs qui peuvent décider.
expires_at horodatage Échéance.
timeout_continues booléen À l'expiration, l'exécution continue sur timeout ; sinon l'étape échoue.
decision_data objet Les données du formulaire de la décision.
comment chaîne Commentaire de la décision.
decided_by objet {id, email, name} de la personne qui a décidé, ou null.
decided_at horodatage Moment de la décision ou de l'expiration.

Lister les approbations

Requête :

Champ Type Obligatoire Description
status chaîne Non Uniquement les approbations ayant ce statut, par exemple pending.
limit_from entier Non Index du premier élément. Par défaut 0.
limit_to entier Non Index suivant le dernier élément, de 1 à 200. Par défaut 50.

Renvoie {"items": [<approval>, ...], "total": <number>} avec les approbations dont l'utilisateur peut décider (ou a décidé), de la plus récente à la plus ancienne. total est le nombre de toutes les approbations correspondantes.

Compter les approbations en attente

Pas de corps de requête. Renvoie {"pending": 3}, le nombre d'approbations qui attendent la décision de l'utilisateur. Adapté à l'interrogation périodique d'un badge.

Obtenir une approbation

Champ Type Obligatoire Description
approval_id UUID Oui L'approbation.

Renvoie l'approbation. Les utilisateurs qui peuvent en décider et ceux qui peuvent lire son workflow peuvent l'obtenir.

Décider d'une approbation

Champ Type Obligatoire Description
approval_id UUID Oui L'approbation.
decision chaîne Oui approve ou reject.
data objet Non Données du formulaire (approbation uniquement). Les champs que vous n'envoyez pas conservent leurs valeurs préremplies ; les champs absents du formulaire sont ignorés. Au plus 20 000 caractères en JSON. Les champs fichier acceptent la forme base64 décrite dans fichiers dans l'entrée d'une exécution.
comment chaîne Non Commentaire, au plus 2 000 caractères.

Seuls les utilisateurs de assignee_user_ids peuvent décider, et uniquement tant que l'approbation est pending et avant expires_at. Les données du formulaire sont validées par rapport à form_schema. La décision devient la sortie de l'étape d'approbation :

json
{
  "decision": "approved",
  "data": {"amount": 1200, "note": "OK for this quarter"},
  "comment": "Approved",
  "decided_by": {"id": "0f1e2d3c-4b5a-4968-8776-655443322110", "email": "jana@example.com", "name": "Jana Novak"},
  "decided_at": 1759405000000,
  "approval_id": "e4d3c2b1-a0f9-4e8d-9c7b-6a5f4e3d2c1b"
}

L'exécution reprend en arrière-plan au nom de l'utilisateur au nom duquel elle s'effectuait (et non de celui qui a décidé) ; son statut passe de waiting à queued puis à running. Renvoie l'approbation décidée.

bash
curl -X POST "https://ayeto.ai/api/v3/workflow/approval/decide" \
  -H "uni-api-key: $AYETO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "approval_id": "e4d3c2b1-a0f9-4e8d-9c7b-6a5f4e3d2c1b",
    "decision": "approve",
    "data": {"amount": 1200, "note": "OK for this quarter"},
    "comment": "Approved"
  }'

Publication et déclencheurs

Ces endpoints nécessitent un accès en écriture au workflow.

Informations de déploiement

Endpoint POST /api/v3/workflow/deployment
Portée ayeto.workflow.write
Limite de débit par défaut
Champ Type Obligatoire Description
workflow_id UUID Oui Le workflow.

Renvoie l'état de publication. Il contient les URL des webhooks avec leurs secrets, c'est pourquoi il nécessite la portée d'écriture.

Champ Type Description
published_version entier Dernière version publiée, ou null.
published_at horodatage Date de publication.
active booléen Les déclencheurs automatiques sont activés.
run_as UUID Utilisateur au nom duquel s'effectuent les exécutions automatiques.
draft_changed booléen Le brouillon diffère de la version publiée (positions des nœuds mises à part) ; toujours true lorsque rien n'est publié.
triggers tableau d'objets Déclencheurs automatiques de la version publiée, voir ci-dessous.
signing_secret chaîne Clé qui signe les requêtes des étapes http.request avec sign: true ; vide lorsqu'aucune étape ne signe.

Champs d'un déclencheur :

Champ Type Description
node_id chaîne Le nœud déclencheur.
type chaîne trigger.schedule, trigger.webhook ou trigger.booster_record.
active booléen Le déclencheur se déclenche.
next_run_at horodatage Prochaine heure planifiée (déclencheurs de planning).
last_fired_at horodatage Dernière fois qu'il a démarré une exécution.
url chaîne URL du webhook, secret inclus (déclencheurs webhook).
panel_id UUID Panneau Booster (déclencheurs d'enregistrements booster).
collection chaîne Collection surveillée, * pour toutes (déclencheurs d'enregistrements booster).

Une étape http.request signée envoie l'en-tête X-Ayeto-Signature: sha256=<hex HMAC-SHA256 of the request body> calculé avec signing_secret, afin que le service destinataire puisse le vérifier.

Publier un workflow

Endpoint POST /api/v3/workflow/publish
Portée ayeto.workflow.write
Limite de débit par défaut
Champ Type Obligatoire Description
workflow_id UUID Oui Le workflow.
note chaîne Non Note de la version, au plus 500 caractères.

Valide le brouillon pour l'appelant, l'enregistre comme version suivante, active le workflow et fait de l'appelant l'utilisateur run_as des exécutions automatiques. Les URL de webhook des nœuds déclencheurs qui existaient auparavant restent les mêmes. Renvoie les informations de déploiement. Un brouillon invalide est rejeté avec 422.

Activer ou désactiver

Endpoint POST /api/v3/workflow/activate
Portée ayeto.workflow.write
Limite de débit par défaut
Champ Type Obligatoire Description
workflow_id UUID Oui Le workflow.
active booléen Oui true active les déclencheurs automatiques, false les désactive.

L'activation valide la version publiée pour l'appelant et fait de l'appelant l'utilisateur run_as. Tant que le workflow est inactif, les appels de webhook renvoient 404 et les plannings ne se déclenchent pas. Renvoie les informations de déploiement. Échoue avec 422 lorsque rien n'est publié.

Régénérer le secret d'un webhook

Endpoint POST /api/v3/workflow/trigger/regenerate
Portée ayeto.workflow.write
Limite de débit faible
Champ Type Obligatoire Description
workflow_id UUID Oui Le workflow.
node_id chaîne Oui Le nœud déclencheur webhook de la version publiée.

Attribue un nouveau secret au webhook ; l'ancienne URL cesse immédiatement de fonctionner. Renvoie les informations de déploiement avec la nouvelle URL.

Prévisualiser un planning

Endpoint POST /api/v3/workflow/schedule/preview
Portée ayeto.workflow
Limite de débit élevée
Champ Type Obligatoire Description
cron chaîne Oui Expression cron à cinq champs : minute, heure, jour du mois, mois, jour de la semaine (par exemple 0 8 * * 1-5). Au plus 200 caractères.
timezone chaîne Non Fuseau horaire IANA, par exemple Europe/Prague. Par défaut UTC.

Vérifie un planning pour un nœud trigger.schedule et liste ses prochaines occurrences :

json
{"valid": true, "error": "", "next_runs": [1759471200000, 1759730400000, 1759816800000, 1759903200000, 1759989600000]}

Un planning invalide renvoie 200 avec valid: false et la raison dans error (nombre de champs incorrect, fuseau horaire inconnu, exécutions plus fréquentes que l'intervalle minimal autorisé).

Assistant builder

Endpoint POST /api/v3/workflow/assistant
Portée ayeto.workflow.write
Limite de débit par défaut
Champ Type Obligatoire Description
workflow_id UUID Oui Le workflow.

Chaque utilisateur ayant un accès en écriture dispose de son propre assistant builder pour un workflow : un assistant qui lit, modifie, exécute en test et explique le workflow au fil de la conversation. Cet endpoint renvoie le builder de l'appelant (en le créant s'il n'existe pas) sous forme d'assistant. Dialoguez avec lui via le chat en utilisant son id comme assistant ; cela nécessite une clé avec la portée chat. Ses modifications sont enregistrées comme révisions d'origine builder.

Révisions

Chaque modification de la définition est une révision. Les modifications qui ne font que déplacer des nœuds, effectuées par le même utilisateur en moins de trois minutes, sont fusionnées dans la dernière révision. Les révisions les plus récentes sont conservées (100 par défaut).

Lister les révisions

Endpoint POST /api/v3/workflow/revisions
Portée ayeto.workflow
Limite de débit par défaut
Champ Type Obligatoire Description
workflow_id UUID Oui Le workflow.

Renvoie jusqu'à 100 révisions, de la plus récente à la plus ancienne, sans leurs définitions :

Champ Type Description
id UUID La révision.
created_at horodatage Date de création.
user_id UUID Auteur.
origin chaîne created, editor (l'éditeur de l'application ou cette API), builder (l'assistant builder) ou restore.
changes objet {added_nodes, removed_nodes, changed_nodes, added_edges, removed_edges} : listes d'id de nœuds et nombres d'arêtes par rapport à la révision précédente.
restored_from UUID Pour une restauration, la révision qui a été rétablie.
nodes entier Nombre de nœuds.
edges entier Nombre d'arêtes.

Obtenir une révision

Endpoint POST /api/v3/workflow/revision/get
Portée ayeto.workflow
Limite de débit par défaut
Champ Type Obligatoire Description
workflow_id UUID Oui Le workflow.
revision_id UUID Oui La révision.

Renvoie la révision avec sa définition complète : les champs communs plus workflow_id, definition, origin, changes et restored_from.

Restaurer une révision

Endpoint POST /api/v3/workflow/revision/restore
Portée ayeto.workflow.write
Limite de débit par défaut

Même requête que pour obtenir une révision. Rétablit la définition de la révision comme brouillon ; la restauration est enregistrée comme nouvelle révision (origine restore), elle peut donc être annulée. La version publiée ne change pas. Renvoie le workflow mis à jour.

Export et import

Un export est un document JSON contenant la définition du brouillon, le nom et la description. Les exécutions, les révisions, les versions publiées, l'état des déclencheurs (secrets des webhooks), le secret de signature, l'organisation et les partages ne sont pas exportés. Les assistants auxquels les étapes font référence sont exportés uniquement sous forme d'id.

Exporter un workflow

Endpoint POST /api/v3/workflow/export
Portée ayeto.workflow
Limite de débit par défaut
Champ Type Obligatoire Description
workflow_id UUID Oui Le workflow.
strip_secrets booléen Non Ignoré sur cette API : les identifiants d'accès sont toujours supprimés.

Via une clé API, les valeurs des en-têtes des étapes http.request dont le nom ressemble à un identifiant d'accès (contient auth, token, secret, key, password, cookie, signature ou session) sont toujours vidées ; les noms des en-têtes sont conservés. Les chemins vidés sont listés dans secret_keys. L'utilisateur a besoin d'un accès en écriture, ou d'un partage en lecture avec la permission workflow.export.

json
{
  "version": "1.0",
  "exported_at": 1759405000000,
  "workflow": {
    "name": "Customer question",
    "description": "Drafts an answer to a customer question",
    "definition": {"nodes": ["..."], "edges": ["..."]},
    "from_id": "5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a",
    "secret_keys": ["notify_crm.headers.Authorization"]
  }
}

Importer un workflow

Endpoint POST /api/v3/workflow/import
Portée ayeto.workflow.write
Limite de débit par défaut
Champ Type Obligatoire Description
data objet Oui Un document d'export, tel que renvoyé par l'export.
new_name chaîne Non Nom du nouveau workflow, au plus 200 caractères. Par défaut : le nom exporté.
organization_id UUID Non Le créer dans cette organisation (accès en écriture requis). Par défaut : personnel.

Crée un nouveau workflow non publié appartenant à l'appelant et le valide. Les étapes qui font référence à des éléments que l'appelant ne peut pas utiliser (un assistant d'un autre compte, des identifiants d'accès vidés) ne bloquent pas l'import ; elles sont signalées afin de pouvoir être corrigées.

Champ Type Description
workflow objet Le nouveau workflow.
issues tableau d'objets Problèmes de validation pour l'appelant, comme dans valider.
secret_keys tableau de chaînes Valeurs d'en-têtes à renseigner (<node id>.headers.<name>).

Le format d'export doit avoir la même version majeure (1), et la définition au plus 200 nœuds.

Copier un workflow

Endpoint POST /api/v3/workflow/copy
Portée ayeto.workflow.write
Limite de débit par défaut
Champ Type Obligatoire Description
workflow_id UUID Oui Le workflow à copier.
new_name chaîne Non Nom de la copie. Par défaut : le nom d'origine.
organization_id UUID Non Organisation de la copie. Par défaut : personnel.

Exporte le brouillon et l'importe comme nouveau workflow de l'appelant en un seul appel ; la réponse est la même que pour l'import. L'utilisateur a besoin d'un accès en écriture ou d'un partage en lecture avec la permission workflow.copy. Un utilisateur ayant un accès en écriture à l'original conserve les identifiants d'accès des étapes HTTP ; une copie effectuée grâce à la permission workflow.copy les omet.

Webhooks

Endpoint POST /api/v3/workflow/hook/{trigger_id}/{secret}
Portée aucune : le secret contenu dans l'URL autorise l'appel
Limite de débit webhook par IP, plus une limite par déclencheur (ci-dessous)

Un nœud trigger.webhook d'un workflow publié et actif possède une URL publique. Obtenez-la depuis triggers[].url des informations de déploiement :

https://ayeto.ai/api/v3/workflow/hook/9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d/Xq3v...secret...

Traitez l'URL comme un secret ; toute personne qui la détient peut démarrer des exécutions qui dépensent les crédits de l'utilisateur run_as. En cas de fuite, régénérez-la.

Requête

Envoyez un POST avec un corps JSON et Content-Type: application/json. Un corps d'un autre type de contenu est transmis sous forme de texte (ou analysé, s'il s'agit de JSON). Aucune clé API n'est nécessaire.

L'entrée de l'exécution (la sortie du déclencheur, disponible pour les étapes sous la forme {{ input }}) est :

Champ Type Description
body tout type Le corps de la requête ; {} lorsqu'il est vide.
query objet Paramètres de la chaîne de requête de l'URL.
headers objet Uniquement ces en-têtes de requête, lorsqu'ils sont présents : content-type, user-agent, x-github-event, x-request-id.

Les étapes la lisent sous la forme {{ input.body.order_id }}, {{ input.query.source }} et ainsi de suite. L'entrée est limitée à 200 000 caractères de JSON.

Fichiers dans le corps

Des fichiers peuvent être envoyés dans le corps, à n'importe quelle profondeur (jusqu'à 32 niveaux) :

  • un objet avec des data en base64 et un name ou filename, et aucune autre clé que name, filename, content_type, mime_type, data, size ;
  • une chaîne data URL data:<type>;base64,....

Chaque fichier est enregistré comme fichier de l'exécution (appartenant à l'utilisateur run_as, soumis à la limite de taille des uploads et au quota de stockage) et remplacé dans le corps par ses métadonnées de pièce jointe ({file_id, filename, content_type, file_url, size}). Au plus 10 fichiers par appel.

Réponse

200 OK dès que l'exécution est mise en file d'attente ; l'exécution s'effectue en arrière-plan :

json
{"run_id": "b7c6d5e4-f3a2-4b1c-9d8e-7f6a5b4c3d2e", "status": "queued"}

L'exécution exécute la version publiée au nom de l'utilisateur run_as, qui la voit via les exécutions (trigger_type vaut trigger.webhook, automatic vaut true). Son entrée n'est pas considérée comme fiable : une étape ne lit les fichiers de l'utilisateur que lorsque l'étape les désigne elle-même, jamais parce que le corps du webhook les désigne.

Limitation de débit

Chaque déclencheur accepte au plus 60 appels par minute, 2 000 par heure et 20 000 par jour, quel que soit le nombre d'expéditeurs. Une limite anti-saturation par IP s'applique en plus. Un workflow refuse aussi les nouvelles exécutions tant qu'il a 50 exécutions en file d'attente (par défaut). Les deux répondent 429 ; une réponse de limite de débit comporte Retry-After (en secondes).

Exemple

bash
curl -X POST "https://ayeto.ai/api/v3/workflow/hook/9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d/$WEBHOOK_SECRET?source=shop" \
  -H "Content-Type: application/json" \
  -d '{
    "order_id": 1042,
    "customer": {"name": "Jana Novak", "email": "jana@example.com"},
    "invoice": {"filename": "invoice-1042.pdf", "content_type": "application/pdf", "data": "JVBERi0xLjcKJcfsj6IK..."}
  }'

Erreurs

Les erreurs ont le corps JSON {"detail": "..."}. Les erreurs d'authentification, de limite de débit et les erreurs serveur sont décrites dans les conventions.

Statut Signification
401 La clé API est absente, invalide ou n'a pas la portée requise (API key is invalid).
403 L'utilisateur n'a pas accès au workflow, ou n'a pas la permission ou l'appartenance à l'organisation requise par l'opération.
404 Le workflow, l'exécution, la révision, l'approbation ou le webhook n'existe pas ou n'est pas visible pour l'utilisateur.
422 La requête est invalide, ou l'opération n'est pas possible dans l'état actuel (detail en indique la raison).
423 Le workflow ou l'exécution est en cours de modification par une autre requête ; réessayez dans un instant.
429 Trop de requêtes (avec Retry-After), ou trop d'exécutions en file d'attente.
500 Erreur serveur.

Erreurs propres aux workflows :

Statut detail Cause
403 permission denied Le compte de l'utilisateur n'est pas autorisé à lire ou à écrire des workflows ou des exécutions.
403 You do not have access to this workflow L'utilisateur n'est pas propriétaire et le workflow n'est pas partagé avec lui (ou il est partagé en lecture alors que l'écriture est nécessaire).
403 This workflow is shared with you without the 'workflow.run' permission Partage en lecture sans la permission d'exécuter (de même pour workflow.export, workflow.copy).
403 User is not a member of the organization Le workflow appartient à une organisation dont l'utilisateur ne fait pas partie.
403 User does not have write permissions in the organization L'utilisateur ne peut pas travailler dans l'organisation du workflow.
404 Workflow not found Le workflow n'existe pas (ou a été supprimé).
404 entity not found get, update, delete CRUD d'un workflow ou d'une exécution qui n'existe pas ou n'appartient pas à l'utilisateur.
404 Workflow run not found Exécution inconnue, ou exécution que l'utilisateur ne peut pas annuler.
404 Revision not found La révision n'existe pas ou appartient à un autre workflow.
404 Approval not found Approbation inconnue, ou l'utilisateur ne peut ni la voir ni en décider.
404 The file of the input '<key>' was not found or is not accessible Un champ fichier désigne un fichier que l'utilisateur ne possède pas.
404 The published workflow has no such webhook trigger Régénération avec un nœud qui n'est pas un déclencheur webhook de la version publiée.
404 Webhook not found Id de déclencheur inconnu ou secret erroné.
404 The workflow of this webhook is not active Le workflow est désactivé ou non publié, ou il a été supprimé.
422 The workflow is not valid: <errors> Exécution, publication ou activation d'une définition comportant des erreurs de validation.
422 '<id>' is not a trigger of the workflow trigger_node_id n'est pas un déclencheur.
422 The workflow has no trigger Aucun déclencheur à partir duquel démarrer.
422 The run input is too large (at most 200000 characters of JSON) Entrée d'exécution ou entrée de webhook au-delà de la limite.
422 The input '<key>' must be one file Un champ fichier contient plusieurs fichiers ou autre chose.
422 The file is not valid base64 data Fichier transmis directement avec un base64 invalide.
422 Too many files (at most 10) Trop de fichiers dans le corps d'un webhook.
422 A <status> run can not be cancelled Annulation d'une exécution qui n'est ni waiting ni queued.
422 Publish the workflow first Activation sans version publiée.
422 Unsupported workflow export format <version> Import d'un export ayant une autre version majeure.
422 The workflow has too many steps (<n>, at most 200) Import d'une définition dépassant la limite de nœuds.
422 The approval is <status> already Décision sur une approbation qui n'est plus en attente.
422 The time to decide the approval is over Décision après expires_at.
422 The approval can not be rejected reject alors que allow_reject vaut false.
422 Step '<node id>' of the run does not wait L'exécution a cessé d'attendre (annulée, en échec) avant la décision.
422 The form data is too large (at most 20000 characters of JSON) Données de décision au-delà de la limite.
429 Too many requests Limite de débit, y compris la limite de webhook par déclencheur ; voir Retry-After.
429 The workflow already has <n> runs waiting Appel de webhook alors que la file d'attente du workflow est pleine.

L'échec d'une étape n'est pas une erreur HTTP : l'exécution revient avec status: "failed" et la raison dans error ainsi que dans le champ error de l'étape en échec.