Ceci est une traduction automatique du document original en anglais. En cas de divergence entre cette traduction et la version originale anglaise, la version anglaise fera foi. Consulter la version originale en anglais


API Publique

Caiioo inclut une API REST qui vous permet de tout contrôler par programmation : exécuter des agents, gérer des outils, planifier des tâches, et plus encore. L'API réside sur le même serveur local qui alimente l'application de bureau et le pont du navigateur.

URL de base : http://localhost:3847/v1

Authentification : Deux façons de s'authentifier, toutes deux conditionnées par l'activation de l'API dans les paramètres :

Pour les consommateurs externes (scripts, intégrations, curl) : Définissez un jeton d'accès API dans Paramètres > Accès API, puis utilisez-le comme jeton Bearer :

curl -H "Authorization: Bearer VOTRE_JETON_API" http://localhost:3847/v1/providers

Pour l'application locale (automatique) : L'application de bureau Caiioo, les extensions de navigateur et les applications mobiles s'authentifient automatiquement via l'en-tête d'authentification relais existant (X-Relay-Auth). Aucune configuration manuelle n'est nécessaire — l'application gère cela en arrière-plan.

Configuration :

  1. Ouvrez les Paramètres de Caiioo > Accès API
  2. Activez l'option Activer l'API publique
  3. Définissez un jeton d'accès API (n'importe quelle chaîne de votre choix — traitez-la comme un mot de passe)
  4. Utilisez ce jeton dans toutes les requêtes API

L'API est disponible sur localhost et via le relais privé. Consultez GET /v1/auth/info (aucune authentification requise) pour connaître le statut actuel et les instructions de configuration.

Fournisseurs et Modèles

Découvrez quels fournisseurs de LLM sont configurés et quels modèles sont disponibles.

Lister les fournisseurs :

GET /v1/providers

Renvoie tous les types de fournisseurs configurés (Anthropic, OpenAI, Google, OpenRouter, Ollama, Poe, MLX, Baseten, et d'autres au fur et à mesure de leur ajout) avec les drapeaux de capacités (supportsVision, supportsToolCalling, supportsStreaming, etc.) et si une clé API est configurée.

Lister les modèles pour un fournisseur :

GET /v1/providers/anthropic/models

Renvoie le catalogue de modèles pour ce fournisseur. Chaque modèle inclut id, displayName et contextLength si disponible.

Catalogue complet de tous les fournisseurs :

GET /v1/models

Fusionne les modèles de chaque fournisseur configuré en une seule liste. Les fournisseurs sans clé API sont ignorés et listés dans warnings.

Agents

Les agents sont le cœur de caiioo. Chaque agent est un Mode — une personnalité configurée avec ses propres instructions système, outils, variables et skills.

Lister tous les agents :

GET /v1/agents

Renvoie les agents intégrés (Shopping, Workplace, General) et tous les agents personnalisés que vous avez créés. Chacun est marqué avec source: \"builtin\" ou source: \"custom\".

Créer un agent personnalisé :

POST /v1/agents
Content-Type: application/json

{
  \"id\": \"mon-agent-de-recherche\",
  \"branding\": {
    \"name\": \"Agent de recherche\",
    \"description\": \"Recherche sur le web et résume les résultats\"
  },
  \"defaultSettings\": {
    \"systemPrompt\": \"Vous êtes un assistant de recherche. Citez toujours vos sources.\",
    \"enabledTools\": { \"web_browsing\": true, \"search_tools\": true }
  },
  \"settingLevels\": {}
}

Renvoie 201 avec l'agent créé. Une horloge vectorielle est jointe automatiquement pour la synchronisation.

Mettre à jour un agent :

PATCH /v1/agents/mon-agent-de-recherche
Content-Type: application/json

{ \"branding\": { \"name\": \"Agent de recherche\", \"description\": \"Description mise à jour\" } }

Fusionne le correctif dans l'agent existant et incrémente l'horloge vectorielle. Les agents intégrés renvoient 403 — ils sont en lecture seule.

Supprimer un agent :

DELETE /v1/agents/mon-agent-de-recherche

Suppression logicielle via « tombstone » (se synchronise sur les appareils). Renvoie 204.

Exécution des agents

C'est l'étape principale — invoquer un agent pour traiter un message.

Mode synchrone

Attendre la réponse complète :

POST /v1/runs
Content-Type: application/json

{
  "agentId": "general",
  "input": { "message": "Quel temps fait-il à Paris aujourd'hui ?" },
  "mode": "sync"
}

Retourne 200 avec { content, usage, status: "completed" } une fois que l'agent a terminé. Si l'agent rencontre une erreur, retourne 500 avec { error, status: "error" }.

Mode asynchrone

Lancer et oublier — utile pour les tâches de longue durée :

POST /v1/runs
Content-Type: application/json

{
  "agentId": "my-research-agent",
  "input": { "message": "Rédiger une analyse de 2000 mots sur les tendances des énergies renouvelables" },
  "mode": "async"
}

Retourne 202 immédiatement avec { runId, threadId, status: "running" }.

Vérifier le statut (polling) :

GET /v1/runs/{runId}

Retourne { run: { runId, threadId, agentId, status, createdAt, content?, usage?, error? } }. Le statut est l'un des suivants : running, completed, error, ou cancelled.

Flux d'événements en temps réel (SSE) :

GET /v1/runs/{runId}/events

Retourne un text/event-stream avec chaque événement de l'agent au fur et à mesure : GENERATION_STARTED, STREAMING_CONTENT, appels d'outils, activité des sous-agents et l'événement terminal (GENERATION_COMPLETE, GENERATION_ERROR, ou GENERATION_CANCELLED). Le flux se termine après l'événement terminal.

Annuler une exécution :

POST /v1/runs/{runId}/cancel

Retourne { run: { ..., status: "cancelled" } }.

Threads

Les Threads sont des conversations. Chaque exécution d'agent se déroule au sein d'un thread, et les threads persistent d'une session à l'autre. L'API vous permet de lister, lire, créer et gérer les threads par programmation.

Lister tous les threads (métadonnées uniquement) :

GET /v1/threads

Renvoie les threads du profil actuel avec les messages supprimés pour des raisons de performance. Chaque thread inclut id, title, createdAt, updatedAt, modeId, archived, et les statistiques d'utilisation.

Obtenir un thread avec tous les messages :

GET /v1/threads/{id}

Renvoie le thread complet incluant son tableau messages — chaque message utilisateur, réponse de l'assistant, appel d'outil et résultat d'outil.

Obtenir uniquement les messages :

GET /v1/threads/{id}/messages

Renvoie uniquement le tableau messages — plus léger que l'objet thread complet lorsque vous avez seulement besoin de la conversation.

Créer un thread :

POST /v1/threads
Content-Type: application/json

{ "title": "Research project", "modeId": "general" }

Renvoie 201 avec le nouveau thread. Par défaut, l'API ne change PAS le thread actif de l'application — passez "setActive": true dans le corps si vous souhaitez ce comportement. Le nouveau thread apparaît immédiatement dans la barre latérale (via diffusion WebSocket).

Mettre à jour un thread :

PATCH /v1/threads/{id}
Content-Type: application/json

{ "title": "Renamed project", "archived": true }

Champs modifiables : title, modeId, archived, lastUsedModel. Les modifications sont diffusées dans la barre latérale en temps réel.

Supprimer un thread :

DELETE /v1/threads/{id}

Supprime le thread de manière réversible (tombstone pour la synchronisation). Renvoie 204. Les threads supprimés sont déplacés vers la corbeille et peuvent être récupérés jusqu'à ce que la corbeille soit vidée.

Thread actif :

GET /v1/threads/active            # Renvoie { threadId }
PUT /v1/threads/active            # Corps : { "threadId": "..." }

Gestion de la corbeille :

GET /v1/threads/trash/count       # Renvoie { count }
POST /v1/threads/trash/empty      # Renvoie { deletedCount, protectedCount }

Les threads protégés (conservés via le bouton de rétention des données) sont exclus du vidage de la corbeille.

Continuer une conversation via l'API : Pour envoyer un message de suivi à un thread existant, utilisez POST /v1/runs avec l'ID du thread :

POST /v1/runs
Content-Type: application/json

{
  "agentId": "general",
  "threadId": "existing-thread-id",
  "input": { "message": "Follow up on that last point" },
  "mode": "sync"
}

L'agent voit l'historique complet de la conversation à partir du thread.

Pièces jointes

Les pièces jointes sont des fichiers liés aux fils de discussion — captures d'écran, PDF, documents, images téléchargées, artefacts générés. L'API vous permet de les lister, télécharger, téléverser et gérer.

Lister toutes les pièces jointes (métadonnées uniquement) :

GET /v1/attachments

Renvoie les métadonnées des pièces jointes pour le profil actuel. Les champs lourds (dataUrl, extractedContent, extractedImages) sont supprimés — utilisez les points de terminaison de détail ou de contenu pour ceux-là.

Lister les pièces jointes pour un fil spécifique :

GET /v1/threads/{threadId}/attachments

Obtenir les métadonnées d'une pièce jointe :

GET /v1/attachments/{id}

Renvoie les métadonnées complètes incluant extractedContent (texte OCR, markdown analysé), contentType, fileName, size, et un drapeau hasContent. Le binaire brut n'est PAS inclus — utilisez le point de terminaison /content pour cela.

Télécharger le binaire d'une pièce jointe :

GET /v1/attachments/{id}/content

Renvoie le fichier brut avec les en-têtes Content-Type et Content-Disposition corrects. Redirigez ceci vers un fichier :

curl -o sortie.pdf \
  -H "Authorization: Bearer $API_TOKEN" \
  http://localhost:3847/v1/attachments/{id}/content

Téléverser une pièce jointe :

POST /v1/attachments
Content-Type: application/json

{
  "threadId": "id-du-fil",
  "type": "user_upload",
  "contentType": "application/pdf",
  "fileName": "rapport.pdf",
  "description": "Rapport trimestriel",
  "dataUrl": "data:application/pdf;base64,JVBERi0xLjQ..."
}

Le dataUrl est une URL de données encodée en base64. Renvoie 201 avec le nouvel ID de pièce jointe. La pièce jointe est liée au fil spécifié.

Mettre à jour les métadonnées d'une pièce jointe :

PATCH /v1/attachments/{id}
Content-Type: application/json

{ "description": "Description mise à jour", "fileName": "nouveau-nom.pdf" }

Supprimer une pièce jointe :

DELETE /v1/attachments/{id}

Suppression douce via un marqueur d'effacement. Renvoie 204.

Serveurs MCP

Gérez vos connexions aux serveurs MCP (Model Context Protocol) — les serveurs qui permettent aux agents d'accéder à des outils externes et à des sources de données.

Lister les serveurs configurés :

GET /v1/mcp-servers

Renvoie toutes les configurations de serveurs MCP pour le profil actuel. Les champs sensibles (authToken, env, credentialId) sont retirés de la réponse.

Obtenir la configuration d'un serveur :

GET /v1/mcp-servers/{id}

Ajouter un nouveau serveur MCP :

POST /v1/mcp-servers
Content-Type: application/json

{
  "id": "my-server",
  "name": "My MCP Server",
  "command": "npx",
  "args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/files"],
  "serverType": "local"
}

Pour les serveurs HTTP distants, utilisez "url" au lieu de "command" :

{
  "id": "remote-server",
  "name": "Remote API",
  "url": "https://my-mcp-server.example.com/sse",
  "serverType": "remote"
}

Mettre à jour un serveur :

PATCH /v1/mcp-servers/{id}
Content-Type: application/json

{ "name": "Renamed Server", "args": ["-y", "@mcp/server-v2"] }

Activer/désactiver un serveur :

POST /v1/mcp-servers/{id}/toggle
Content-Type: application/json

{ "enabled": false }

Supprimer un serveur :

DELETE /v1/mcp-servers/{id}

Gestion des processus

Pour les serveurs MCP locaux (stdio), vous pouvez gérer le processus du serveur directement.

Lister les processus en cours d'exécution :

GET /v1/mcp-servers/processes

Renvoie les processus serveurs actifs avec le pid, startedAt, et le statut running.

Démarrer un serveur :

POST /v1/mcp-servers/{id}/start

Lit la commande/args/env depuis la configuration du serveur et lance le processus. Renvoie le statut du processus.

Arrêter un serveur :

POST /v1/mcp-servers/{id}/stop

Arrête proprement le processus du serveur (SIGTERM avec repli sur SIGKILL).

Appeler une méthode JSON-RPC directement :

POST /v1/mcp-servers/{id}/call
Content-Type: application/json

{ "method": "tools/list", "params": {} }

Envoie une requête JSON-RPC 2.0 brute au serveur et renvoie le résultat. Utile pour le débogage ou pour appeler des méthodes non exposées via l'API des outils.

Outils & Boîtes à outils

Parcourez et invoquez les outils utilisés par les agents — navigation web, recherche, calendrier, Gmail, Slate, et plus encore.

Lister les boîtes à outils (groupées) :

GET /v1/toolkits

Renvoie les outils intégrés groupés par catégorie (Productivité, Recherche, Utilitaires, etc.) et tous les serveurs MCP connectés en tant que boîtes à outils distinctes, chacune avec ses actions listées.

Lister tous les outils (plat) :

GET /v1/tools
GET /v1/tools?source=embedded   # Uniquement les outils intégrés
GET /v1/tools?source=mcp        # Uniquement les outils de serveur MCP

Obtenir les détails d'un outil avec le schéma d'entrée :

GET /v1/tools/calculator

Renvoie le JSON Schema de l'outil pour ses paramètres d'entrée, afin que vous puissiez valider avant l'invocation.

Invoquer un outil directement :

POST /v1/tools/calculator/invoke
Content-Type: application/json

{ "input": { "expression": "sqrt(144) + 3^2" } }

Renvoie { result }. L'entrée est validée par rapport au schéma de l'outil — une entrée invalide renvoie 422 avec les détails. Les outils MCP distants renvoient 501 avec le conseil d'utiliser /v1/runs à la place (ils nécessitent le transport par sous-processus de l'agent).

Connecteurs

Gérez les intégrations OAuth — Google, Microsoft, GitHub, Notion, Slack, et plus encore.

Parcourir les intégrations disponibles :

GET /v1/connectors/catalog

Renvoie tous les fournisseurs OAuth enregistrés avec leur nom, catégorie et portées par défaut.

Lister vos comptes connectés :

GET /v1/connectors

Renvoie les connexions actives pour le profil actuel. Les jetons ne sont jamais exposés — uniquement les métadonnées (fournisseur, e-mail, statut, portées, horodatages).

Vérifier la santé d'une connexion :

POST /v1/connectors/{id}/test

Renvoie { health: { status, isTokenExpired, canRefresh } }.

Supprimer une connexion :

DELETE /v1/connectors/{id}

La création de nouvelles connexions nécessite le flux OAuth interactif via l'interface de l'application ou les routes /auth/*.

Déclencheurs

Planifiez l'exécution automatique des agents — briefings quotidiens, rapports hebdomadaires, surveillance basée sur des intervalles.

Lister les déclencheurs :

GET /v1/triggers

Créer un déclencheur planifié :

POST /v1/triggers
Content-Type: application/json

{
  "name": "Briefing matinal",
  "prompt": "Résume mes e-mails non lus et mon calendrier d'aujourd'hui",
  "modeId": "general",
  "schedule": { "type": "daily", "time": "08:00" }
}

Types de planification pris en charge :

  • { "type": "interval", "minutes": 60 } — toutes les N minutes (min 15, max 1440)
  • { "type": "daily", "time": "09:00" } — quotidiennement à une heure précise
  • { "type": "weekly", "day": "mon", "time": "09:00" } — hebdomadairement
  • { "type": "weekdays", "time": "08:30" } — du lundi au vendredi
  • { "type": "daysOfWeek", "days": ["mon", "wed", "fri"], "time": "10:00" } — jours spécifiques
  • { "type": "monthly", "dayOfMonth": 1, "time": "09:00" } — mensuellement
  • { "type": "manual" } — uniquement lorsqu'il est déclenché via l'API

Lancer un déclencheur manuellement :

POST /v1/triggers/{id}/fire

Renvoie 202 avec un threadId pour l'exécution résultante.

Mettre à jour ou supprimer :

PATCH /v1/triggers/{id}
DELETE /v1/triggers/{id}

Webhooks

Les déclencheurs Webhook permettent à des services externes (CI/CD, surveillance, constructeurs de formulaires) de déclencher l'exécution d'un agent via HTTP.

Créer un déclencheur webhook :

POST /v1/triggers
Content-Type: application/json

{
  "name": "Hook de déploiement",
  "prompt": "Un déploiement a eu lieu : {{webhook.body}}",
  "modeId": "general",
  "kind": "webhook"
}

Renvoie 201 avec un webhookSecret et un webhookPath. Conservez le secret — vous en aurez besoin pour signer les charges utiles.

Envoyer un webhook :

# Calculer le HMAC-SHA256 du corps brut de la requête
SIGNATURE=$(echo -n '{"repo":"mon-app","branch":"main"}' | openssl dgst -sha256 -hmac "$WEBHOOK_SECRET" | awk '{print $2}')

POST /v1/webhooks/{triggerId}
Content-Type: application/json
X-Webhook-Signature: $SIGNATURE

{"repo": "mon-app", "branch": "main"}

Le point de terminaison du webhook ne nécessite PAS d'authentification bearer — il utilise la vérification HMAC à la place. Renvoie 202 avec le threadId de l'exécution lancée. L'espace réservé {{webhook.body}} dans le prompt du déclencheur est remplacé par le corps brut de la requête.

Fonctions personnalisées

Créez vos propres outils que les agents peuvent appeler. Les fonctions sont écrites en JavaScript ou Python et s'exécutent dans un bac à sable (sandbox).

Lister les fonctions :

GET /v1/functions

Créer une fonction :

POST /v1/functions
Content-Type: application/json

{
  "name": "calculer_imc",
  "description": "Calculer l'Indice de Masse Corporelle à partir de la taille et du poids",
  "language": "javascript",
  "source": "return { imc: (input.weightKg / (input.heightM * input.heightM)).toFixed(1) };",
  "inputSchema": {
    "type": "object",
    "properties": {
      "weightKg": { "type": "number" },
      "heightM": { "type": "number" }
    },
    "required": ["weightKg", "heightM"]
  }
}

Les fonctions JavaScript reçoivent input et doivent retourner un résultat. Les fonctions Python définissent une variable result :

# Exemple Python
result = {"imc": round(input["weightKg"] / (input["heightM"] ** 2), 1)}

Exécuter une fonction directement :

POST /v1/functions/{id}/execute
Content-Type: application/json

{ "input": { "weightKg": 75, "heightM": 1.80 } }

Sécurité : JavaScript s'exécute dans le bac à sable vm de Node (pas d'accès au système de fichiers ou au réseau, délai d'expiration de 10s). Python s'exécute comme un sous-processus avec un délai d'expiration de 30s. Les deux valident l'entrée avant l'exécution.

Mettre à jour ou supprimer :

PATCH /v1/functions/{id}
DELETE /v1/functions/{id}

Workflows

Orchestrez plusieurs agents dans un DAG (graphe orienté acyclique) — exécutez les étapes en parallèle lorsque c'est possible, et injectez les résultats des étapes précédentes dans les suivantes.

Valider un graphe de workflow :

POST /v1/workflows/validate
Content-Type: application/json

{
  "graph": {
    "nodes": [
      { "id": "research", "agentId": "general", "prompt": "Rechercher les tendances des énergies renouvelables" },
      { "id": "analyze", "agentId": "general", "prompt": "Rechercher les prix des concurrents" },
      { "id": "report", "agentId": "general", "prompt": "Rédiger un rapport combinant : {{outputs.research}} et {{outputs.analyze}}", "dependsOn": ["research", "analyze"] }
    ]
  }
}

Retourne { valid: true/false, errors: [...] }. Vérifie les cycles, les identifiants en double et les références de dépendance manquantes.

Exécuter un workflow :

POST /v1/workflows/execute
Content-Type: application/json

{
  "graph": {
    "nodes": [
      { "id": "research", "agentId": "general", "prompt": "Rechercher les tendances des énergies renouvelables" },
      { "id": "summarize", "agentId": "general", "prompt": "Résumer : {{outputs.research}}", "dependsOn": ["research"] }
    ]
  }
}

Retourne { status: "completed", outputs: { research: "...", summarize: "..." }, nodeResults: {...} }.

Les nœuds indépendants (sans dépendances communes) s'exécutent en parallèle. L'espace réservé {{outputs.nodeId}} dans le prompt d'un nœud est remplacé par le contenu de sortie du nœud amont nommé. Chaque nœud est une exécution complète d'agent, il peut donc utiliser des outils, naviguer sur le web et accéder à toutes les capacités de l'agent cible.

Bases de connaissances

Organisez des documents en collections consultables que les agents peuvent référencer.

Lister les bases de connaissances :

GET /v1/knowledge/bases

Créer une base de connaissances :

POST /v1/knowledge/bases
Content-Type: application/json

{ "name": "Articles de recherche" }

Renvoie 201 avec l'ID de la nouvelle base.

Télécharger un document vers une base de connaissances :

POST /v1/knowledge/bases/{id}/documents
Content-Type: application/json

{
  "fileName": "article-recherche.pdf",
  "contentType": "application/pdf",
  "dataUrl": "data:application/pdf;base64,JVBERi0xLjQ...",
  "description": "Tendances des énergies renouvelables 2026"
}

Le champ dataUrl est une URL de données encodée en base64. Renvoie 201 avec les métadonnées du document.

Lister les documents d'une base de connaissances :

GET /v1/knowledge/bases/{id}/documents

Rechercher dans une base de connaissances :

POST /v1/knowledge/bases/{id}/search
Content-Type: application/json

{ "query": "énergie renouvelable" }

Renvoie les documents correspondants basés sur le nom du fichier et la description. La recherche sémantique (vectorielle) arrivera dans une future version.

Supprimer un document ou une base de connaissances :

DELETE /v1/knowledge/bases/{id}/documents/{docId}
DELETE /v1/knowledge/bases/{id}

Exporter et importer des agents

Partagez des agents sous forme de packages portables — entre appareils, équipes ou via le Community Hub.

Exporter un agent :

POST /v1/agents/{id}/export

Renvoie un package JSON contenant la définition de l'agent, les exigences d'outils (dérivées des outils activés), les exigences de connecteurs (quels fournisseurs OAuth sont nécessaires) et les modèles de déclencheurs. Les métadonnées de synchronisation sont supprimées — le package est un plan propre et autonome.

Importer un agent :

POST /v1/agents/import
Content-Type: application/json

{
  \"package\": {
    \"$schema\": \"caiioo.agent.package/v1\",
    \"agent\": {
      \"id\": \"agent-de-recherche-partage\",
      \"branding\": { \"name\": \"Agent de recherche\", \"description\": \"De l'équipe\" },
      \"defaultSettings\": { \"systemPrompt\": \"Vous recherchez des choses.\" },
      \"settingLevels\": {}
    },
    \"toolRequirements\": [
      { \"toolId\": \"web_browsing\", \"enabled\": true },
      { \"toolId\": \"search_tools\", \"enabled\": true }
    ]
  }
}

Renvoie 201 avec l'agent installé. Les collisions d'ID avec des agents intégrés ou existants renvoient 409.

Gestion des erreurs

L'API utilise les codes de statut HTTP standard :

Code Signification
200 Succès
201 Créé
202 Accepté (opération asynchrone démarrée)
204 Supprimé (aucun contenu)
400 Mauvaise requête — vérifiez le champ error pour les détails
401 Non autorisé — secret de session manquant ou invalide
403 Interdit — ex: tentative de modification d'un agent intégré
404 Non trouvé
409 Conflit — ex: l'ID de l'agent existe déjà
422 Erreur de validation — l'entrée ne correspond pas au schéma de l'outil
500 Erreur serveur — vérifiez le champ error
501 Non implémenté — la fonctionnalité existe mais n'est pas disponible par ce biais
503 Service indisponible — stockage ou fournisseur non prêt

Toutes les réponses d'erreur incluent { "error": "message lisible par l'homme" }.

Exemple de démarrage rapide

Voici un flux de travail complet : créer un agent, l'exécuter et diffuser les résultats.

# 1. Créer un agent personnalisé
curl -X POST http://localhost:3847/v1/agents \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "quick-summarizer",
    "branding": { "name": "Quick Summarizer" },
    "defaultSettings": {
      "systemPrompt": "Résumez toute entrée de manière concise en 3 points.",
      "enabledTools": { "web_browsing": true }
    },
    "settingLevels": {}
  }'

# 2. L'exécuter de manière asynchrone
RUN=$(curl -s -X POST http://localhost:3847/v1/runs \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "agentId": "quick-summarizer", "input": { "message": "Résumer https://fr.wikipedia.org/wiki/Intelligence_artificielle" }, "mode": "async" }')

RUN_ID=$(echo $RUN | jq -r '.runId')

# 3. Diffuser les événements
curl -N http://localhost:3847/v1/runs/$RUN_ID/events \
  -H "Authorization: Bearer $API_TOKEN"

# 4. Exporter l'agent pour le partager
curl -X POST http://localhost:3847/v1/agents/quick-summarizer/export \
  -H "Authorization: Bearer $API_TOKEN"

This guide is maintained by the Caiioo team using Slate, our built-in editor.