Web Services (REST)
Un Web Service est une connexion API REST configurée. Une fois mis en place, vous l'assignez à un agent comme outil, le LLM de l'agent l'appelle en cours de conversation quand nécessaire, en passant les paramètres collectés via le dialogue et en utilisant la réponse pour continuer l'appel.
Créer un web service
- Allez sur Dashboard → Comptes → [compte] → Connexions → Web Services
- Cliquez sur New web service
- Saisissez un Name (étiquette interne, ex :
CRM API) et une Description optionnelle - Saisissez la Base URL, l'endpoint racine partagé par toutes les actions (ex :
https://api.yourcrm.com/v2). Sans slash final. - Sélectionnez une méthode d'authentification (voir ci-dessous)
- Cliquez sur Enregistrer
Méthodes d'authentification
Le auth_type contrôle comment les credentials sont attachés à chaque requête faite par ce service.
| auth_type | En-tête envoyé | Quand l'utiliser |
|---|---|---|
none |
- | APIs publiques ou endpoints accessibles en interne (aucune auth requise) |
bearer |
Authorization: Bearer TOKEN |
APIs qui acceptent un jeton durable collé une fois (jeton d'accès personnel, jeton d'API, JWT sans expiration) |
basic |
Authorization: Basic BASE64(user:pass) |
APIs legacy qui utilisent HTTP Basic Authentication |
api_key |
Nom d'en-tête personnalisé que vous configurez (ex : X-API-Key: KEY) |
APIs qui utilisent un en-tête de clé propriétaire plutôt qu'Authorization |
oauth2_client_credentials |
Authorization: Bearer ACCESS_TOKEN, obtenu et renouvelé par la plateforme |
API protégées par un serveur d'autorisation OAuth 2.0 (Keycloak, Microsoft Entra ID, Auth0, Okta, une passerelle d'API) qui délivre des jetons de courte durée à partir d'un ID client et d'un secret |
custom |
Toute combinaison de paramètres d'authentification personnalisés que vous définissez | APIs avec des schémas d'authentification non standard que les autres types ne couvrent pas |
OAuth 2.0 (client credentials)
Choisissez ce type quand votre API attend un jeton d'accès de courte durée que votre serveur d'autorisation délivre en échange d'un ID client et d'un secret (le flux OAuth 2.0 client credentials). Vous saisissez :
- URL du jeton : le point de terminaison de jeton de votre serveur d'autorisation. Il doit utiliser
https. - ID client et secret client.
- Scope, facultatif : séparés par des espaces, si votre serveur les exige.
- Dans Paramètres avancés, facultatif : une audience (certains fournisseurs exigent ici l'identifiant de l'API), la méthode d'authentification du client (un en-tête HTTP Basic, par défaut, ou les identifiants dans le corps de la requête) et des paramètres supplémentaires envoyés avec chaque demande de jeton.
La plateforme demande un jeton avant le premier appel, le met en cache, le renouvelle peu avant son expiration et l'envoie en Authorization: Bearer. Si votre API refuse un jeton en HTTP 401 avant l'expiration annoncée, la plateforme en demande un nouveau et relance l'appel une fois. Vous n'avez jamais à coller ni à renouveler un jeton vous-même.
Le secret client est stocké chiffré et ne quitte jamais la plateforme : les agents ne reçoivent que le jeton de courte durée. Modifier la configuration invalide immédiatement le jeton en cours. Tester dans le formulaire de connexion indique si un jeton a été obtenu et sa durée de validité, ou pourquoi le serveur d'autorisation a refusé la demande.
Les flux OAuth dans lesquels un utilisateur se connecte et approuve l'accès (authorization code) ne sont pas pris en charge pour les services web. Pour les applications du catalogue, utilisez les connecteurs Composio, qui s'en chargent pour vous.
Les credentials sont stockés chiffrés (AES-256-CBC) et ne sont jamais exposés dans les réponses API ou les logs. Le runtime de l'agent les récupère au moment de l'appel.
Actions
Chaque web service a une ou plusieurs actions, des endpoints API spécifiques que l'agent peut invoquer. Une action définit la méthode HTTP, le chemin, et les paramètres dynamiques que le LLM remplira depuis le contexte de la conversation.
Un Web Service n'est que la connexion : l'URL de base et la méthode d'authentification. Il ne fait rien seul. Chaque Action est un endpoint sous cette URL de base (méthode HTTP + chemin). L'agent n'appelle jamais le Web Service directement, il appelle une Action, que la plateforme résout en URL de base + chemin de l'action. Un Web Service sans action ne donne rien à atteindre à l'agent.
Champs d'une action
| Champ | Description |
|---|---|
| Name | Un nom court pour l'action (ex : get_customer, create_ticket). Il nomme aussi la variable de sortie de l'action, gardez-le donc court ; la phrase qui explique ce que fait l'action va dans Description. |
| Description | Explique ce que fait l'action, le LLM lit cette description pour décider quand et comment invoquer l'action. Soyez précis. |
| Method | Méthode HTTP : GET, POST, PUT, PATCH, DELETE |
| Path | Chemin ajouté à la base URL (ex : /customers) |
| Paramètres dynamiques | Paramètres que le LLM remplit au runtime depuis la conversation. Chacun a un name, une description, un type (string, integer, number ou boolean, par défaut string) et un drapeau required. La description indique au LLM quelle valeur fournir. |
Structure JSON d'une action
{
"id": "get_customer",
"name": "Get customer",
"method": "GET",
"path": "/customers",
"description": "Rechercher un client par son numéro de compte",
"dynamicParams": [
{
"name": "account_id",
"type": "string",
"description": "Le numéro de compte du client, collecté auprès de l'appelant",
"required": true
}
]
}
Le type déclaré sert deux objectifs. Il est ajouté au JSON Schema vu par le LLM, afin que le modèle sache s'il doit fournir du texte, un nombre ou un booléen. Et avant l'envoi de la requête HTTP, la plateforme convertit la valeur pour qu'elle corresponde : integer devient un entier (les flottants à valeur entière comme "90.0" deviennent 90), number devient un flottant, tandis que string et les paramètres non déclarés sont laissés intacts, de sorte que les identifiants à zéros initiaux et les numéros de téléphone (ex : "007", "+33612345678") ne sont jamais corrompus. Les booléens ne sont jamais convertis.
Assigner à un agent
Après avoir créé un web service, assignez-le à un agent pour que le LLM puisse l'invoquer pendant les appels :
- Ouvrez l'éditeur de flux et double-cliquez sur le nœud Welcome (défaut pour tout l'agent) ou sur un nœud Agent (pour le limiter à ce nœud)
- Allez dans l'onglet Connections du nœud → section Web Services, trouvez votre web service et activez les actions à rendre disponibles
- Dans le prompt système de ce nœud, décrivez quand l'agent doit invoquer chaque action
- Enregistrez le flux, puis Make live quand vous êtes prêt pour de vrais appelants
La description de l'action est le champ le plus important pour le tool calling. Une description vague mène le LLM à invoquer l'action au mauvais moment ou avec de mauvais paramètres. Écrivez-la comme une instruction : « Utilise cette action pour récupérer le plan d'abonnement d'un client quand l'appelant demande son plan ou sa facturation. »
Fonctionnement du tool calling pendant un appel
Quand une action de web service est activée sur un agent :
- Le LLM reçoit la définition de l'action (name, description, paramètres) en parallèle de la conversation
- Quand le LLM décide d'invoquer l'action, il fournit les valeurs de paramètres requises depuis la conversation
- La plateforme émet la requête HTTP vers votre API, l'appelant entend une brève pause (typiquement sous 500 ms pour des APIs rapides)
- La réponse JSON est repassée au LLM, qui l'utilise pour formuler son prochain énoncé
- L'appel complet, paramètres de requête, corps de réponse, et timing, est journalisé dans
call.tool_calls
Mapping de réponse, nettoyage et « Conserver la réponse complète »
Dans les réglages Avancé d'une action, le mapping de réponse copie des champs de la réponse JSON dans des variables via JSONPath (par exemple $.data[0].customer.first_name → customer_first_name). Utilisez-les dans les prompts avec {{customer_first_name}}.
Listes d’éléments. Quand l’action renvoie une liste de longueur variable (une commande pour un appelant, dix pour un autre), cliquez sur Liste d’éléments sur la ligne de mapping, indiquez le chemin de la liste (par exemple $.data[*]) et choisissez les quelques champs à garder pour chaque élément, chacun avec son propre nettoyage. La variable contient alors une ligne courte par élément, et {{name_count}} le nombre d’éléments renvoyés (0 s’il n’y en a aucun). Utilisée comme outil avec Conserver la réponse complète désactivé, l’agent reçoit ces enregistrements courts au lieu de la réponse entière. C’est la même option que dans les actions de démarrage, voir Listes d’éléments.
Mettre en place une liste sur une action :
- Ouvrez Accounts, choisissez le compte, puis Connections. Sur votre web service, cliquez sur Actions et ouvrez l'action.
- Cliquez sur Advanced. Désactivez Keep full response : l'agent ne reçoit alors que ce que vous mappez, au lieu de la réponse complète.
- Cliquez sur Add mapping : le chemin de la liste (
$.data[*]), puis le nom de la variable (repairs). - Cliquez sur List of items sur la ligne, et ajoutez les champs à garder, comme ci-dessus.
- Cliquez sur Save Actions.
Chaque ligne de mapping a une liste Nettoyage, la même que dans les actions de démarrage. Elle transforme la valeur avant de la stocker, pour que la voix la lise naturellement :
- minuscules : une marque ou une catégorie en MAJUSCULES (
SAMSUNG) serait sinon épelée lettre par lettre - Nombre, FR :
56000devient56 000et se lit comme un nombre - Majuscule à chaque mot, majuscule en début de phrase, suppression des espaces aux extrémités ou de tous les espaces, chiffres uniquement, et formats de nombre anglais et espagnol
Conserver la réponse complète (activé par défaut) stocke aussi toute la réponse dans la variable de sortie de l'action et la renvoie en entier à l'agent. Désactivez-le quand la réponse est volumineuse et que vous avez mappé les champs utiles : l'agent ne reçoit alors que les valeurs mappées, et aucune variable de réponse complète n'est créée. Une grosse réponse dont l'agent n'a pas besoin peut lui faire perdre le fil de la conversation et le faire se répéter. Si rien n'est mappé, ou si aucun champ mappé ne figure dans la réponse (une réponse « introuvable » par exemple), l'agent reçoit quand même la réponse complète.
Si un sous-agent a besoin des données avant de dire quoi que ce soit, récupérez-les avec un nœud API en mode Web Service placé juste avant le sous-agent, plutôt qu'avec un appel d'outil. Les variables mappées sont alors prêtes dès sa première phrase, sans tour de conversation supplémentaire. Voir Nœuds.
Masquer au modèle. Chaque ligne de mapping dispose d'un interrupteur Masquer au modèle (désactivé par défaut). La valeur reste enregistrée dans la variable et peut servir dans les messages parlés (par exemple un message de transition), mais l'IA ne la voit jamais : elle ne peut donc pas la dire une seconde fois. L'option s'applique que Conserver la réponse complète soit activé ou non : le champ est aussi retiré de la réponse complète que reçoit l'IA.
Doit venir de l'appelant. Chaque paramètre dispose d'un interrupteur Doit venir de l'appelant (désactivé par défaut). L'IA ne peut alors envoyer qu'une valeur que l'appelant a réellement dite lors de ses derniers tours de parole (un oui/non seulement après une question). À utiliser pour des mots qui doivent être ceux de l'appelant, comme un code ou un nom, jamais pour un texte que l'IA rédige elle-même (corps de SMS ou d'e-mail). Si l'IA envoie une valeur que l'appelant n'a pas dite, la requête n'est pas envoyée et l'IA est invitée à obtenir d'abord cette valeur de l'appelant.
Seulement si l'appelant le demande. Chaque action dispose d'un interrupteur Seulement si l'appelant le demande (désactivé par défaut). Activez-le pour une action qui ne doit s'exécuter qu'à la demande de l'appelant, comme l'envoi d'un SMS : l'IA est invitée à ne l'appeler que lorsque l'appelant la demande explicitement, et la plateforme ne la lance plus automatiquement dès que l'appelant a donné les informations nécessaires (ce qu'elle fait sinon pour une étape qui ne propose qu'une seule action qui envoie ou modifie quelque chose). L'éditeur d'action le suggère, ou un paramètre de confirmation marqué Doit venir de l'appelant, pour une action qui envoie ou modifie des données et n'a ni l'un ni l'autre.
Exemple : recherche CRM
Web service : CRM API, action : Get customer (nécessite account_id).
Extrait du prompt système :
Utilise l'action « Get customer » pour rechercher le compte de l'appelant dès qu'il
fournit son numéro de compte. Après la recherche, confirme son nom et son plan actuel.
Si la recherche échoue, excuse-toi et propose de le transférer vers un agent humain.
Conversation :
Agent : « Bonjour, je suis Alex. Quel est votre numéro de compte ? »
Appelant : « C'est ACC-1234. »
[L'agent invoque Get customer → l'API retourne { name: "Marie Dupont", plan: "premium", status: "active" }]
Agent : « Très bien, Marie. Vous êtes sur le plan premium, en quoi puis-je vous aider ? »
L'appel API, les paramètres, la réponse et la latence sont stockés dans call.tool_calls sur l'enregistrement d'appel et visibles dans la vue de détail d'appel.
Gestion d'erreurs
Si l'appel API échoue (timeout, HTTP 4xx/5xx, erreur de connexion), l'échec est journalisé dans call.tool_calls avec les détails de l'erreur. Le LLM reçoit un signal d'erreur structuré qui lui permet de réagir intelligemment et, si votre prompt système inclut une instruction de repli, il s'excusera et continuera la conversation ou proposera de transférer l'appelant.
Sur une réponse HTTP 4xx ou 5xx, l'erreur renvoyée au LLM ne se limite pas au code de statut : elle inclut la ligne de statut et le corps de la réponse (tronqué à environ 1000 caractères), ainsi qu'une instruction indiquant à l'assistant comment la gérer. L'agent peut ainsi réagir au message d'erreur réel de l'API, par exemple en redemandant une valeur que l'API a rejetée, plutôt que de s'excuser aveuglément.
{
"status": "FAILED",
"error_type": "rejected_arguments",
"error": "Client error '400 Bad Request' for url 'https://api.yourcrm.com/v2/customers' | response_body: {\"error\":\"account_id must be numeric\"}",
"instruction_for_assistant": "The external service REJECTED the arguments as invalid — nothing was written. Do NOT tell the user the action succeeded. Read the validation error in the result (it names the offending field and often the allowed values), correct ONLY those field(s), and call the tool again. Leave the fields that were accepted unchanged."
}
Le champ error_type indique à l'assistant de quel type d'échec il s'agit. Une réponse 4xx (client/validation) renvoie rejected_arguments : le service externe a rejeté les arguments comme invalides, rien n'a été écrit ; l'agent lit l'erreur, corrige uniquement le(s) champ(s) qu'elle nomme, puis rappelle l'outil. network est réservé aux véritables échecs de connectivité — absence de réponse, timeouts ou erreurs serveur 5xx — où les arguments étaient corrects et où une nouvelle tentative peut réussir.
Incluez toujours une instruction de repli dans le prompt système pour chaque action d'outil :
Si l'action « Get customer » échoue ou ne retourne aucune donnée, dis :
« Je n'arrive pas à accéder à votre compte pour le moment. Je vous mets en relation
avec notre équipe de support. » et route vers un agent humain.