Cette page t'a-t-elle aidé ?
Cette page t'a-t-elle aidé ?
Intégrer
Une API minimale pour piloter Gilbert depuis votre propre backend : créer des utilisateurs finaux, dialoguer avec eux, lire leur mémoire persistante, la supprimer. Pensée pour un chatbot embarqué dans votre produit, sans UI Gilbert.
Dernière mise à jour : 12 juillet 2026
| Endpoint | Description |
|---|---|
| POST /api/headless/v1/users | Find-or-create d'un utilisateur final à partir de votre identifiant. |
| POST /api/headless/v1/chat | Envoie un message, reçoit une réponse en stream NDJSON, avec sortie structurée optionnelle. |
| GET /api/headless/v1/memory | Liste la mémoire persistante d'un utilisateur final (100 souvenirs les plus récents). |
| DELETE /api/headless/v1/users | Supprime un utilisateur final et purge toute sa mémoire. |
Chaque requête porte un header Authorization: Bearer <clé>. La clé est une clé workspace de scope headless:chat, distincte des clés historiques (notify, MCP) : ces dernières sont inertes sur les endpoints headless, même valides par ailleurs.
Une seule clé active à la fois par couple workspace + scope. Préversion privée : il n'existe pas encore d'écran Console dédié au scope headless:chat. Un admin du workspace la génère en appelant POST /api/workspace/{id}/api-key/rotate avec un corps {"scope": "headless:chat"} (session admin requise, même route que la clé MCP legacy, distinguée par ce paramètre). La réponse contient la clé en clair une seule fois, copiez-la immédiatement.
Crée l'utilisateur final s'il n'existe pas encore pour ce workspace, sinon retourne l'existant (find-or-create idempotent). external_user_id est votre identifiant interne (par exemple l'id utilisateur icon), jamais un email ni une donnée sensible.
curl -X POST https://gilbert.solveholding.com/api/headless/v1/users \
-H "Authorization: Bearer $GILBERT_HEADLESS_KEY" \
-H "Content-Type: application/json" \
-d '{
"external_user_id": "icon-user-4821",
"display_name": "Camille"
}'{
"external_user_id": "icon-user-4821",
"created": true
}Champs : external_user_id (string, requis, 1 à 256 caractères), display_name (string, optionnel). 400 si external_user_id est vide, manquant ou dépasse 256 caractères.
Il n'est pas nécessaire d'appeler cet endpoint avant /chat : le premier message d'un external_user_id inconnu crée l'utilisateur au passage. Un appel explicite reste utile pour provisionner un compte en avance ou récupérer created: false comme sonde d'existence.
Envoie un message au nom d'un utilisateur final et retourne un stream application/x-ndjson, une ligne JSON par event. Le vocabulaire d'events reprend celui de l'API standard (text-delta, tool-call, tool-result, finish) et en ajoute deux, documentés plus bas : structured_output et error.
curl -N -X POST https://gilbert.solveholding.com/api/headless/v1/chat \
-H "Authorization: Bearer $GILBERT_HEADLESS_KEY" \
-H "Content-Type: application/json" \
-d '{
"external_user_id": "icon-user-4821",
"message": "Quels evenements as-tu retenus de mes preferences ?"
}'{"type":"text-delta","text":"Tu"}
{"type":"text-delta","text":" as"}
{"type":"text-delta","text":" aime"}
{"type":"text-delta","text":" les afterworks tech a Lyon."}
{"type":"finish","finishReason":"stop","usage":{"inputTokens":210,"outputTokens":18}}Champs : external_user_id (string, requis), message (string, requis, 1 à 32 000 caractères), output_schema (objet, optionnel, voir ci-dessous). 400 si message est vide ; 400 ou 413 au-delà de 32 000 caractères.
La mémoire de l'utilisateur final est activée par défaut : Gilbert retient les préférences et faits marquants entre deux appels, comme en mode personnel.
Marque blanche. Dans ses réponses, l'assistant se présente sous le nom d'assistant configuré pour le workspace (workspaces.assistant_name, par défaut « Gilbert »), pas sous « Gilbert » en dur. Un intégrateur comme Meety expose ainsi l'API sous sa propre marque.
Fournissez un JSON Schema d'objet (type: object, properties) pour forcer Gilbert à répondre avec des données exploitables directement, sans parsing de prose. C'est le mode conseillé pour recréer un événement externe (Meetup, Eventbrite, etc.) sous forme de champs structurés.
curl -N -X POST https://gilbert.solveholding.com/api/headless/v1/chat \
-H "Authorization: Bearer $GILBERT_HEADLESS_KEY" \
-H "Content-Type: application/json" \
-d '{
"external_user_id": "icon-user-4821",
"message": "Recree cet evenement : https://www.meetup.com/lyon-tech/events/12345",
"output_schema": {
"type": "object",
"properties": {
"titre": { "type": "string" },
"description": { "type": "string" },
"date": { "type": "string" },
"heure": { "type": "string" },
"en_ligne": { "type": "boolean" },
"adresse": { "type": "string" },
"photo": { "type": "string" }
},
"required": ["titre", "date", "heure", "en_ligne"]
}
}'{"type":"text-delta","text":"..."}
{"type":"tool-call","toolName":"fetch_url","toolCallId":"call_abc","input":{"url":"https://www.meetup.com/lyon-tech/events/12345"}}
{"type":"tool-result","toolCallId":"call_abc","output":"..."}
{"type":"structured_output","data":{
"titre": "Afterwork Tech Lyon",
"description": "Rencontre mensuelle des developpeurs lyonnais.",
"date": "2026-08-14",
"heure": "19:00",
"en_ligne": false,
"adresse": "12 rue de la Republique, 69002 Lyon",
"photo": "https://meetup.com/photos/xyz.jpg"
}}
{"type":"finish","finishReason":"stop","usage":{"inputTokens":640,"outputTokens":112}}Le stream se termine par un event {"type":"structured_output","data":{...}} avant le finish. output_schema invalide (pas un objet, pas de properties) : 400 immédiat, avant tout appel modèle. Si la sortie du modèle ne respecte pas le schéma, Gilbert retente une fois avec l'erreur de validation renvoyée au modèle ; en cas de deuxième échec, un event error de code structured_output_invalid clôt le stream (voir la section erreurs ci-dessous).
Liste les souvenirs persistants d'un utilisateur final, les plus récents en premier, jusqu'à 100 entrées. Le contenu est déchiffré côté serveur avant retour : aucune clé de chiffrement ne transite côté client.
curl https://gilbert.solveholding.com/api/headless/v1/memory?external_user_id=icon-user-4821 \
-H "Authorization: Bearer $GILBERT_HEADLESS_KEY"{
"memories": [
{
"id": "6f1e...c92a",
"kind": "preference",
"content": "Aime les afterworks tech a Lyon.",
"created_at": "2026-07-10T18:22:00Z"
}
]
}404, code end_user_not_found, si external_user_id n'existe pas pour ce workspace. La lecture est strictement scopée à cet utilisateur : aucune fuite cross-utilisateur possible, même en cas d'erreur côté appelant.
Cet endpoint sert aussi d'export : il n'existe pas d'endpoint d'export dédié en v1, GET memory couvre ce besoin.
Supprime définitivement un utilisateur final : sa mémoire, ses messages et ses sessions sont purgés en cascade. Opération irréversible, à utiliser pour honorer un droit à l'oubli ou nettoyer un compte de test.
curl -X DELETE "https://gilbert.solveholding.com/api/headless/v1/users?external_user_id=icon-user-4821" \
-H "Authorization: Bearer $GILBERT_HEADLESS_KEY"{
"deleted": true
}404, code end_user_not_found, si l'utilisateur n'existe pas déjà. Sinon {"deleted": true}.
external_user_id.Au-delà du plafond d'utilisateurs : 403, code end_user_cap_reached. Au-delà du rythme de création : 429, code end_user_creation_rate_limited.
Deux familles bien distinctes : les codes HTTP classiques (avant que le stream ne démarre) et les events error à l'intérieur du flux NDJSON de /chat, une fois les en-têtes déjà envoyés en 200.
| Statut | Code | Sens |
|---|---|---|
| 400 | validation_error | Champ requis manquant, vide, trop long, ou output_schema mal formé. |
| 401 | - | Clé absente, inconnue ou révoquée. |
| 403 | scope_missing | Clé valide mais de mauvais type ou mauvais scope. |
| 403 | end_user_cap_reached | Plafond de 5 000 utilisateurs finaux atteint pour ce workspace. |
| 404 | end_user_not_found | external_user_id inconnu pour ce workspace (memory, delete). |
| 413 | - | Message au-delà de 32 000 caractères. |
| 429 | end_user_creation_rate_limited | Plus de 100 créations d'utilisateurs finaux en une heure pour ce workspace. |
Une fois le stream /chat démarré, la réponse HTTP est déjà à 200 : une erreur survenant en cours de route n'a pas de code HTTP à elle, elle arrive comme une ligne NDJSON de type error, qui clôt le stream.
{"type":"error","code":"workspace_llm_unavailable","message":"La cle LLM du workspace est invalide ou indisponible."}workspace_llm_unavailable : le workspace a sa propre clé de fournisseur LLM (BYOLLM) et le repli vers la clé centrale Gilbert est désactivé pour ce workspace ; l'appel échoue de façon explicite plutôt que de basculer silencieusement sur une clé qui n'est pas la vôtre.
{"type":"error","code":"structured_output_invalid","message":"La sortie ne correspond pas au schema fourni apres relance."}structured_output_invalid : après une relance, la sortie du modèle ne respecte toujours pas output_schema. Pas de deuxième retry automatique côté serveur.