Composer un flux
Créer, valider, essayer et suivre un flux d'automatisation par l'API — le contrat qu'un agent IA ou un script suit pour composer un flux sans passer par l'écran.
Un flux automatise une suite d'étapes : quand un événement se produit (un contact créé, un formulaire envoyé, un appel reçu), il agit (envoie un email, crée une carte, lance un parcours…). Ce chapitre décrit ce que l'API accepte pour en composer un, ce qu'elle refuse, et dans quel ordre l'appeler. Il s'adresse à un agent IA ou à un script ; l'écran du concepteur de flux fait la même chose.
Ce qu'il faut savoir avant le premier appel
- Un flux est une donnée. Son graphe entier — étapes, liens, variables, déclencheurs — est un document JSON écrit d'un bloc : vous le composez, l'API le juge.
- Un modèle, et ses exécutions. Un flux dont
IsTemplatevauttrueest le modèle ; chaque exécution est un autre flux (IsTemplateàfalse,TemplateId= le modèle) qui porte sa propre copie du graphe, chaque étape et chaque lien avec son état. Suivre une exécution, c'est relire son graphe. - L'API agit au nom d'un utilisateur, avec ses droits : elle ne voit, ne modifie et ne publie que ce qu'il pourrait.
- Concevoir n'est pas publier. Tout utilisateur crée un flux et y travaille tant qu'il est inactif. L'activer,
enregistrer le graphe d'un flux actif, ou changer ses réglages demande d'être administrateur de l'organisation du flux ; sinon
le refus est un
422portant la violationPublicationReservee, et rien n'est écrit. Désactiver ne demande que le droit de modifier. Un agent crée inactif ("Publish": false), montre le flux et son test à blanc, et laisse l'activation à un administrateur — même quand son utilisateur en est un. - L'identité d'exécution (
RunAsMode) se choisit à la création :0l'utilisateur à l'origine de l'événement (sinon le propriétaire du modèle),1le propriétaire du modèle. Elle ne se change ensuite que par un utilisateur qui a le droit d'administrer le flux. - Une exécution ne lit que ce que son identité peut voir : la fiche de départ et chaque fiche qu'un champ traverse
(
{{Contact_ParentCompany_Name}}demande d'accéder au contact et à sa société). Un champ qu'elle ne peut pas lire reste visible tel quel dans un texte, et fait refuser le filtre d'une boucle. Une boucle ne parcourt que les fiches que l'identité voit. - Le serveur numérote les étapes : sur un flux neuf, 1, 2, 3… dans l'ordre du tableau
Nodes; sur un flux existant, les étapes nouvelles prennent les numéros suivants, et une étape connue garde le sien. Vous pouvez donc citer{{Flow_FlowAction[3]_Output_LastName}}dès la première écriture. - Les identifiants des étapes et des déclencheurs sont les vôtres : des GUID quelconques, uniques dans le graphe, que les liens citent. À la création d'un flux, chaque déclencheur reçoit un identifiant neuf : relisez le graphe que rend la création.
- Les dates sont en UTC, avec
Z; les énumérations s'écrivent par leur nombre ("ExitMode": 1).
Le cycle recommandé
| Appel | Pourquoi | |
|---|---|---|
| 1 | GET https://staging-api.docage.com/FlowActions |
Le catalogue des actions et le schéma de leurs réglages — voir Les actions et les champs. |
| 2 | GET https://staging-api.docage.com/Flows/Fields/{type}?mode=read&depth=2 |
Les chemins de champs valides pour un type (mode : read, write ou writeCreation). |
| 3 | GET https://staging-api.docage.com/Flows/References/Types?search=…, GET https://staging-api.docage.com/Flows/References/{type}?search=… |
Trouver la clé d'un type de fiche, l'identifiant d'une fiche ou d'un modèle, d'après son nom — voir ci-dessous. |
| 4 | POST https://staging-api.docage.com/Flows/Validate, avec le graphe |
Le verdict complet, sans rien écrire : 200 et [], ou 422 et la liste des violations. Corrigez et recommencez jusqu'à 200. |
| 5 | POST https://staging-api.docage.com/Flows/CreateFromGraph |
Créer le flux, son graphe et ses déclencheurs en une écriture ; 201. |
| 6 | POST https://staging-api.docage.com/Flows/{id}/DryRun/{entityId} |
Le test à blanc sur une vraie fiche : le graphe tel qu'il se serait déroulé, rien d'écrit. |
| 7 | POST https://staging-api.docage.com/Flows/{id}/Launch/{entityId} |
Lancer le flux à la main (il doit avoir un déclencheur « Manuel ») ; 200 et l'identifiant de l'exécution. |
| 8 | GET https://staging-api.docage.com/Flows/{id}/Graph?withNames=true |
Lire une exécution — voir Valider et suivre. |
Les autres appels :
PUT https://staging-api.docage.com/Flows/{id}/Graph?publish=falseremplace le graphe d'un modèle ; un modèle actif n'accepte qu'un graphe valide, etpublish=truele valide, l'enregistre et l'active en une écriture (422et rien d'écrit s'il ne l'est pas).POST https://staging-api.docage.com/Flows/{id}/Validatejuge un graphe contre un flux existant, avec ses numéros et ses réglages.POST https://staging-api.docage.com/Flows/{id}/PublishetPOST https://staging-api.docage.com/Flows/{id}/Unpublishactivent et désactivent un modèle.POST https://staging-api.docage.com/Flows/{id}/Arrangerange les étapes sur le canevas ;GET https://staging-api.docage.com/Flows/{id}/Fieldsrend les chemins propres au flux (fiches écoutées, sorties des étapes, variables) ;GET https://staging-api.docage.com/Flows/LinkedTo/{type}/{id}les flux qui touchent une fiche.QUERY https://staging-api.docage.com/Flows, avec{ "TemplateId": "<modèle>", "IsTemplate": false, "Take": 50 }, liste les exécutions d'un modèle.POST https://staging-api.docage.com/Flows/Duplicatecopie des modèles : la copie naît inactive, ses déclencheurs sous des identifiants neufs.
Le corps générique (POST https://staging-api.docage.com/Flows, PUT https://staging-api.docage.com/Flows/{id}) ne porte que la fiche d'un modèle — nom, description, droits :
il refuse un graphe et tout état d'exécution (422). Le graphe passe par CreateFromGraph et PUT …/Graph.
Trouver un identifiant d'après un nom
Une demande dit « le groupe Clients VIP », « l'étape Gagné », « les véhicules » ; le graphe veut un identifiant, ou une clé exacte. Ces lectures se font avec les droits de l'utilisateur :
| Appel | Rend |
|---|---|
GET https://staging-api.docage.com/Flows/References/Types?search=véhic |
[{ Key, Name, PluralName, Family }] : Key est ce qui s'écrit dans EntityTypeName (« Contact », « DEAL », « Vehicule ») ; Family vaut Core, CustomObject ou PipelineItem. |
GET https://staging-api.docage.com/Flows/References/{Key}?search=Bienvenue&templates=true&take=20 |
[{ Id, Name, EntityTypeName, IsTemplate, IsSystem }], triées par nom, 50 au plus ; templates=true cherche parmi les modèles (modèles système compris). L'en-tête Docage-TotalItems dit le nombre de réponses. |
GET https://staging-api.docage.com/Flows/References/Pipeline/{id}/Choices |
Les étapes (Stages) et les motifs d'échec (FailureReasons) d'un pipeline, dans l'ordre. |
- Plus d'une réponse : le nom est ambigu. Demandez lequel à l'utilisateur, en lui montrant les noms — ne prenez jamais le premier.
- Aucune réponse : la fiche n'existe pas, ou l'utilisateur ne la voit pas. Dites-le ; ne composez pas le flux avec un identifiant de remplacement.
- Une clé de type se recopie à la casse près : « vehicule » n'est pas « Vehicule ».
Créer un flux
POST https://staging-api.docage.com/Flows/CreateFromGraph
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9…
Content-Type: application/json
{
"Name": "Accueil des nouveaux contacts",
"Description": "Envoie l'email de bienvenue, puis crée la tâche de suivi.",
"ErrorPolicy": 0, "ErrorBranchFinalStatus": 0, "ConcurrencyMode": 0, "RunAsMode": 0,
"MaxRunsPerTargetPerDay": null, "MaxCreditsPerDay": null, "RunRetentionDays": 90,
"Publish": false,
"Graph": { "Nodes": [], "Links": [], "Variables": [], "Triggers": [], "Canvas": {} }
}curl -X POST "https://staging-api.docage.com/Flows/CreateFromGraph" \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9…" \
-H "Content-Type: application/json" \
-d '{
"Name": "Accueil des nouveaux contacts",
"Description": "Envoie l'\''email de bienvenue, puis crée la tâche de suivi.",
"ErrorPolicy": 0,
"ErrorBranchFinalStatus": 0,
"ConcurrencyMode": 0,
"RunAsMode": 0,
"MaxRunsPerTargetPerDay": null,
"MaxCreditsPerDay": null,
"RunRetentionDays": 90,
"Publish": false,
"Graph": {"Nodes": [], "Links": [], "Variables": [], "Triggers": [], "Canvas": {}}
}'using HttpClient client = new();
using HttpRequestMessage request = new(HttpMethod.Post, "https://staging-api.docage.com/Flows/CreateFromGraph");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
request.Content = new StringContent("""
{
"Name": "Accueil des nouveaux contacts",
"Description": "Envoie l'email de bienvenue, puis crée la tâche de suivi.",
"ErrorPolicy": 0,
"ErrorBranchFinalStatus": 0,
"ConcurrencyMode": 0,
"RunAsMode": 0,
"MaxRunsPerTargetPerDay": null,
"MaxCreditsPerDay": null,
"RunRetentionDays": 90,
"Publish": false,
"Graph": {
"Nodes": [],
"Links": [],
"Variables": [],
"Triggers": [],
"Canvas": {}
}
}
""", Encoding.UTF8, "application/json");
using HttpResponseMessage response = await client.SendAsync(request);
string result = await response.Content.ReadAsStringAsync();
if (!response.IsSuccessStatusCode)
throw new HttpRequestException(result);const response = await fetch("https://staging-api.docage.com/Flows/CreateFromGraph", {
method: "POST",
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"Name": "Accueil des nouveaux contacts",
"Description": "Envoie l'email de bienvenue, puis crée la tâche de suivi.",
"ErrorPolicy": 0,
"ErrorBranchFinalStatus": 0,
"ConcurrencyMode": 0,
"RunAsMode": 0,
"MaxRunsPerTargetPerDay": null,
"MaxCreditsPerDay": null,
"RunRetentionDays": 90,
"Publish": false,
"Graph": {"Nodes": [], "Links": [], "Variables": [], "Triggers": [], "Canvas": {}}
})
});
const text = await response.text();
if (!response.ok) throw new Error(text);
const result = text ? JSON.parse(text) : null;Nameest obligatoire.IsEnabled,OwnerDocageUserId,IsTemplateet le dernier numéro d'étape sont posés par le serveur.RunRetentionDays: absent, les exécutions sont gardées 90 jours ;null, sans limite ; zéro ou moins est refusé.MaxRunsPerTargetPerDayetMaxCreditsPerDay:nullest sans limite, zéro est refusé.ErrorPolicy:0s'arrêter,1continuer,2suivre la branche d'erreur.ErrorBranchFinalStatus: le statut d'une exécution dont une étape a échoué et a suivi sa branche d'erreur,0en échec ou1réussie.ConcurrencyMode:0en parallèle,1une seule exécution active par fiche,2en file.- Avec
"Publish": true, un graphe qui a des violations est refusé (422) et rien n'est écrit. Avecfalse, le flux est enregistré inactif, et la réponse porte quand même les violations. - La réponse,
201, est{ Outcome, FlowId, Graph, Violations }:Graphest le graphe numéroté, tel qu'il est enregistré.
La forme du graphe et de ses déclencheurs est décrite par Le graphe, la configuration des étapes par Les actions et les champs, les conditions par Les conditions et les filtres, et ce qui suit la création par Valider et suivre.
Dans ce chapitre
-
Le graphe
Les étapes d'un flux, les liens qui les relient, les aiguillages et les déclencheurs — la forme exacte du graphe que l'API accepte.
-
Les actions et les champs
Configurer une étape d'action — le catalogue, la forme de chaque réglage, la fiche visée, les grilles « champ → valeur » — et citer un champ ou une variable.
-
Les conditions et les filtres
Écrire la condition d'un lien, d'un déclencheur ou d'une attente, et le filtre d'une boucle — le format, ce qu'il accepte, et ce qu'il refuse.
-
Valider et suivre
Lire les violations qu'oppose l'API à un graphe et les corriger, essayer un flux sur une fiche, puis suivre et piloter ses exécutions.