Construisez sur la même API que celle sur laquelle nous construisons
Tout ce que fait la plateforme — conversations, contacts, agents d'IA, connaissance, analytique — repose sur cette API REST. Il n'y a pas de meilleure API privée derrière : c'est la seule. URL de base : `https://api.inteligenciaviva.com/v1`.
Démarrage rapide : votre première requête en 60 secondes
Créez une clé d'API dans votre workspace, exportez-la et listez vos conversations. Les clés ont une portée par workspace et peuvent être en lecture seule ou en lecture-écriture.
curl https://api.inteligenciaviva.com/v1/workspaces/WORKSPACE_ID/conversations \
-H "Authorization: Bearer sk_live_..."
Chaque réponse est du JSON. Les endpoints de collection renvoient des tableaux `data` ; les erreurs renvoient un objet `error` avec `code` et `message` et le statut HTTP correspondant.
L'API gratuite — sans compte, sans clé
La couche gratuite parle API elle aussi. `POST /v1/free/widget-snippet` reçoit exactement la même configuration que celle que construit le générateur visuel de la page Gratuit et renvoie le snippet HTML prêt à coller — sans authentification, sans inscription. Servez-vous-en pour générer des widgets en lot pour les sites de vos clients, régénérer des embeds depuis la CI quand les horaires changent, ou simplement pour toucher l'API avant de payer un centime.
curl -X POST https://api.inteligenciaviva.com/v1/free/widget-snippet \
-H "Content-Type: application/json" \
-d @widget-config.json
# → { "snippet": "<link rel=\"stylesheet\" ..." }
Authentification
Chaque requête porte une clé d'API dans l'en-tête `Authorization` comme jeton Bearer. Les clés se créent et se révoquent depuis l'API elle-même ou depuis le panneau, par workspace — révoquer une clé coupe son accès immédiatement.
Les endpoints de session au niveau du compte (inscription, connexion, accès Google, échange de ticket, profil et suppression de compte sous `/v1/auth`) alimentent nos propres apps ; pour les intégrations serveur-à-serveur, préférez toujours les clés d'API de workspace aux sessions utilisateur.
Authorization: Bearer sk_live_...
Référence des ressources
Toutes les routes ci-dessous partent de `https://api.inteligenciaviva.com/v1/workspaces/{workspaceId}`, sauf mention contraire. C'est la surface réellement montée du backend actuel — pas une aspiration.
Boîte inter-espaces /inbox
| GET | /conversations | Toutes les conversations de TOUS les espaces gérés par cette clé, en une seule liste triée par activité. |
| GET | /conversations/{id} | Une conversation cherchée dans tous vos espaces, sans savoir dans lequel elle est. Renvoie son workspace_id. |
| GET | /workspaces | Les espaces que cette clé peut gérer, avec son rôle dans chacun. |
| GET | /visitantes | Qui navigue EN CE MOMENT sur tous vos espaces, avec la page lue et s’il discute déjà. Un instantané, pas un historique : non paginé. Un espace qui ne répond pas ne fait pas tomber la liste : il figure dans `casas_sin_responder`. |
Conversations /conversations
| GET | / | Lister les conversations, filtrables par état. |
| GET | /{id} | Une conversation avec son état, son canal, son contact et son affectation. |
| GET | /{id}/messages | Historique des messages (visiteur, agent humain, IA, système). |
| POST | /{id}/messages | Envoyer un message dans la conversation en tant qu'agent. |
| POST | /{id}/assign | Affecter la conversation à un agent humain ou à un département. |
| POST | /{id}/resolve | Clore la conversation. Si l'IA l'a close seule, elle compte comme résolution facturable. |
| POST | / | Ouvrir une conversation hors du widget (par exemple pour migrer un fil existant). |
| GET | /{id}/ai-turns | « D’où sort-il ça ? » — le journal de chaque tour d’IA : sur quoi il s’est appuyé, quel modèle, combien de temps et pourquoi il a transféré. |
| GET | /{id}/portal-case | État du dossier que cette conversation a ouvert sur le tableau de support du Portail, avec ses réponses. Interrogé en direct : l’état change sur l’autre tableau. |
| POST | /{id}/read | Marquer la conversation comme lue par l’équipe (compteur de non-lues). |
| POST | /{id}/reopen | Rouvrir une conversation close en conservant l’historique. Sans cela, une clôture par erreur était sans retour. |
| POST | /{id}/archive | Archiver ou désarchiver. Elle quitte la boîte sans être clôturée ni rien perdre ; le corps est {valor:true|false}. |
| POST | /{id}/pin | Épingler en haut ou détacher. Les épinglées ouvrent la première page de la boîte. Corps : {valor:true|false}. |
| POST | /{id}/mute | Couper les alertes pendant N heures, ou {horas:null} pour les réactiver. |
| POST | /{id}/unread | La laisser non lue : le repère de lecture recule derrière le dernier message du client. |
| POST | /{id}/typing | « En train d’écrire… » vers le client : sur WhatsApp c’est Meta qui le reçoit, sur le chat web le widget du visiteur. Sans corps ; toujours 204 (sans effet sur les canaux qui ne le gèrent pas) et 404 si la conversation n’existe pas. |
| POST | /{id}/messages/{messageId}/forward | Transférer un message vers une autre conversation du même espace, avec sa pièce jointe (copiée, pas partagée). Corps : `{to_conversation_id}`. Il part comme message de l’agent. |
| PUT | /{id}/messages/{messageId}/reaction | Réagir avec un emoji à un message WhatsApp ; remplace la réaction précédente de l’entreprise et `{emoji:null}` la retire. WhatsApp uniquement (API de Meta), et seulement sur un message déjà confirmé par Meta : sinon 400. |
| POST | /{id}/location | Envoyer une position par WhatsApp : `{lat, lon, name?, address?, reply_to_message_id?}`. Elle part d’abord chez Meta : si Meta la refuse, rien ne reste dans le fil. WhatsApp uniquement. |
| POST | /{id}/contact-card | Envoyer une carte de contact par WhatsApp : `{name:{formatted_name}, phones?, emails?, reply_to_message_id?}`. Comme la position : Meta d’abord, puis le fil. WhatsApp uniquement. |
| GET | /{id}/copiloto | Le copilote de l’agent : ce que l’IA a suggéré pour cette conversation et ce qui a été échangé avec elle. Réservé à l’équipe : le client ne le voit pas. |
| POST | /{id}/copiloto | Poser une question à l’IA en privé sur cette conversation (`{content}`, jusqu’à 4 000 caractères). Elle répond À L’AGENT, pas au client : rien ne part par le canal. 503 `copilot_unavailable` si elle ne peut pas répondre. |
| POST | /{id}/copiloto/{sugerenciaId}/enviar | Envoyer au client une suggestion du copilote, telle quelle ou modifiée (`{content}` facultatif). Elle part comme message de l’agent, avec son auteur humain. Une suggestion ne s’envoie qu’une fois : la seconde donne 409 `ya_enviada`. |
| POST | /{id}/resumen | Demander le résumé de la conversation (ouverte ou fermée) et mettre à jour la fiche du contact. Coûte une tâche du KIT ; le redemander sans nouveaux messages ne facture pas une seconde fois. S’il n’y a pas de résumé, la réponse dit pourquoi (`motivo`, `codigo`). |
Contacts /contacts
| GET | / | Lister les contacts. |
| GET | /{id} | Un contact avec ses identités et son historique de conversations. |
| GET | /{id}/historial | Sur quoi portaient ses dernières demandes : les dernières conversations avec leur résumé (`?limit=`, jusqu’à 25), les totaux et la fiche du contact. L’ouvrir ne génère pas la fiche manquante, car cela coûte de l’argent : on la demande avec `?generar=1`. |
Agents d'IA /ai-agents
| GET | / | Lister les agents d'IA du workspace. |
| POST | / | Créer un agent d'IA : instructions, département, seuil de confiance. |
| PATCH | /{id} | Mettre à jour les instructions, le seuil ou le département. |
| GET | /{id}/knowledge-sources | Sources de connaissance rattachées à cet agent. |
| POST | /{id}/knowledge-sources | Rattacher une source de connaissance à cet agent. |
| GET | /{aiAgentId} | Un agent IA : instructions, seuil de confiance, outils et département. |
Connaissance (RAG) /knowledge-sources
| POST | /document | Indexer un document comme connaissance ancrée. |
| POST | /url | Indexer une URL. |
| GET | /{id} | Statut et métadonnées de la source. |
| DELETE | /{id} | Supprimer une source et ses vecteurs. |
| POST | /{id}/reindex | Relire une source URL sans la supprimer : si le téléchargement échoue, rien n’est touché. |
| GET | / | Lister les sources de connaissance avec leur état d’indexation. |
Fiche de l’entreprise /ficha
| GET | / | Lister les unités (filtres ?estado= et ?tipo=) avec les seuils des tranches. |
| POST | / | Créer une unité : question, variantes, réponse approuvée, URL et langue. Un administrateur ou une clé la publie ; un agent la propose. L’IA ne publie jamais. |
| GET | /{id} | Voir une unité. |
| PATCH | /{id} | Modifier une unité ; changer la question ou les variantes recalcule son embedding. |
| DELETE | /{id} | Supprimer une unité (administrateur). |
| POST | /{id}/aprobar | Approuver une proposition : elle devient active et garde qui l’a approuvée (administrateur). |
| POST | /{id}/rechazar | Rejeter une proposition (administrateur). |
| POST | /probar | Aperçu : ce que la fiche répondrait à une question, avec sa note et sa tranche (option : inclure les propositions). |
| POST | /recalcular | Recalculer les embeddings manquants ou qui ne correspondent plus au texte (administrateur). |
Canaux /channels
| GET | / | Lister les canaux. En production aujourd'hui : chat web et API ; d'autres se connectent au fil des lancements. |
| PUT | /{id}/credentials | Définir les identifiants d'un canal. |
| PUT | /{id}/status | Activer ou désactiver un canal. |
| POST | / | Créer un canal. |
| GET | /{channelId} | Un canal avec son type, son état et ses réglages. |
| GET | /{channelId}/snippet | La ligne unique que le client colle sur son site. Tout le reste se configure ici. |
| GET | /{channelId}/config | La configuration du chat : ce qui est publié (`config`) et ce que ce canal surcharge (`settings`). Ce sont deux choses distinctes. |
| PUT | /{channelId}/config | Enregistrer la configuration. Enregistrer et publier ne font qu’un : si le CDN échoue, le PUT échoue. |
| POST | /{channelId}/config/publish | Republier la configuration sur le CDN sans la modifier. |
| POST | /{channelId}/avatar | Téléverser le visage de l’assistant (≤512 Ko). Stocké dans R2 et servi par le CDN. |
| POST | /republicar-todos | Republier tous les canaux de l’espace. Le cron le fait quand le pack de textes change ; ceci évite d’attendre. |
| PUT | /{channelId}/modo | Le mode de prise en charge du canal : `{modo:"humano"|"hibrido"|"ia"}`. Il décide si l’IA parle au client. Valable pour tout type de canal (WhatsApp, Telegram, e-mail, widget). Réservé aux administrateurs. |
| PUT | /{channelId}/auto | Les messages automatiques du canal : `{bienvenida, fueraDeHorario}` (jusqu’à 1 000 caractères chacun ; `null` efface). Celui hors horaires utilise les horaires du canal. Réservé aux administrateurs. |
| PUT | /{channelId}/tarjeta | La carte de contact que l’agent peut envoyer depuis ce canal : `{tarjetaContacto:{name:{formatted_name}, phones?, emails?}}`, avec au moins un téléphone ou un e-mail ; `null` la retire. WhatsApp uniquement. Réservé aux administrateurs. |
| PUT | /{channelId}/horario | Les horaires d’ouverture : `{officeHours:{tz, dias:{lun:[["09:00","17:00"]], …}, festivos:["MM-DD" ou "YYYY-MM-DD"]}}` ; `null` les retire (24/7). Ce qui est illisible est refusé avec 400 en indiquant l’erreur. Renvoie `abiertoAhora`, calculé par le serveur. Réservé aux administrateurs. |
Agents humains et départements /agents · /departments
| GET | /agents | Lister les agents humains du workspace. |
| POST | /agents/{userId}/departments | Placer un agent dans un département. |
| GET | /departments | Lister les départements. |
| PUT | /departments/{id}/routing-rules | Définir les règles de routage des conversations entrantes. |
| POST | /agents | Inviter une personne à l’espace, avec son rôle et ses départements. |
| GET | /agents/{userId} | Un membre de l’équipe. |
| POST | /departments | Créer un département avec ses règles de routage. |
| GET | /departments/{id} | Un département. |
Webhooks, clés, facturation, analytique /webhooks · /api-keys · /billing · /analytics
| POST | /webhooks | Enregistrer un endpoint ; vous recevez son secret de signature une seule fois. |
| DELETE | /webhooks/{id} | Supprimer un endpoint. |
| POST | /api-keys | Créer une clé (lecture seule ou lecture-écriture). |
| DELETE | /api-keys/{id} | Révoquer une clé immédiatement. |
| GET | /billing/subscription | Plan, résolutions d'IA incluses et consommation de la période. |
| GET | /analytics | Métriques agrégées du workspace. |
| GET | /webhooks | Lister les points de terminaison webhook. |
| GET | /webhooks/{id}/deliveries | Historique des livraisons d’un webhook, avec les reprises. C’est ce qui dit si l’échec vient de vous ou de nous. |
| GET | /api-keys | Lister les clés. Le secret n’est jamais renvoyé : seulement son préfixe. |
Outils de l'agent /conversations/{id} · /canned-responses · /tags · /presence
| GET | /conversations/{id}/notes | Notes internes de la conversation. Le visiteur ne les voit jamais. |
| POST | /conversations/{id}/notes | Ajouter une note interne. |
| DELETE | /conversations/{id}/notes/{noteId} | Supprimer une note interne. |
| GET | /canned-responses | Réponses enregistrées de l’espace de travail, avec leur raccourci. |
| POST | /canned-responses | Créer une réponse enregistrée. |
| PATCH | /canned-responses/{cannedId} | Modifier une réponse enregistrée. |
| DELETE | /canned-responses/{cannedId} | Supprimer une réponse enregistrée. |
| POST | /presence | Battement de présence : déclare qu’une personne est disponible. Session uniquement — une clé d’API qui bat n’est pas quelqu’un devant l’écran, et elle est rejetée avec 400. |
| GET | /presence | Y a-t-il quelqu’un en ligne ? C’est ce qui décide si un transfert attend ou est dévié. |
| GET | /ai-usage | Consommation d’inférence de l’espace par jour et les conversations les plus coûteuses. |
| GET | /tags | Étiquettes de l’espace de travail. |
| GET | /conversations/{id}/tags | Étiquettes d’une conversation. |
| POST | /conversations/{id}/tags | Étiqueter une conversation. Crée l’étiquette si elle n’existait pas. |
| DELETE | /conversations/{id}/tags/{tagId} | Retirer une étiquette de la conversation. |
| POST | /conversations/{id}/transfer | Transférer la conversation à un département. Prime sur les règles de routage : un transfert manuel ne s’annule pas tout seul. |
| POST | /contacts/{contactId}/block | Bloquer un contact. Il reçoit un 403 sans détail : on n’explique pas à un abuseur comment il a été détecté. |
| GET | /canned-responses/categories | Les catégories déjà utilisées dans les réponses prédéfinies (texte libre), pour l’autocomplétion. |
| POST | /canned-responses/{cannedId}/use | Noter qu’une réponse prédéfinie a été utilisée (compteur et dernière utilisation). Toujours 204, qu’elle existe ou non : c’est de la télémétrie d’usage, pas une action. |
Pièces jointes, appareils et espaces /conversations/{id}/attachments · /devices · /workspaces
| POST | /conversations/{id}/attachments | Téléverser une pièce jointe en tant qu’agent. Liste blanche stricte et 10 Mo : rien d’exécutable par un navigateur. |
| GET | /conversations/{id}/attachments | Pièces jointes d’une conversation. |
| GET | /attachments/{attachmentId} | Télécharger une pièce jointe. Servie avec des en-têtes stricts et `nosniff` ; seuls images et audio s’affichent en ligne. |
| POST | /devices/register | Enregistrer le jeton push d’un appareil, pour alerter une personne lors d’un transfert par l’IA. Hors préfixe d’espace : `/v1/devices/register`. |
| POST | /workspaces | Créer un espace de travail. Hors préfixe : `/v1/workspaces`. |
| GET | /workspaces/{workspaceId}/retencion/ensayo | La simulation de purge : combien de conversations et de pièces jointes (et d’octets) la rétention supprimerait, sans rien effacer. `?days=` interroge sur un délai pas encore enregistré. Administrateur et `analytics:read` requis. Route complète : `/v1/workspaces/{workspaceId}/retencion/ensayo`. |
Visiteurs en direct et temps réel /visitantes · /stream-ticket
| GET | /visitantes | Qui navigue en ce moment sur les sites de cet espace : page, langue, depuis quand, et s’il a déjà le chat ouvert ou une conversation. |
| POST | /visitantes/{visitorId}/invitar | Inviter un visiteur à ouvrir le chat, avec un `{mensaje}` facultatif (sinon, le message d’accueil du widget dans sa langue). Ne crée pas de conversation et ne consomme pas d’IA : la conversation naît quand le visiteur répond. 404 `no_esta` s’il est parti ; 409 `ya_conversa` s’il discute déjà. |
| POST | /stream-ticket | Un ticket pour ouvrir le WebSocket du stream avec `?ticket=` sans mettre le jeton dans l’URL. Il dure 60 s et ne sert qu’une fois. Valable avec une session ou une clé d’API. |
Capacités du KIT /conversations/{id}/kit
| GET | / | Les tâches du KIT lancées dans cette conversation, avec leur état. Les lister fait aussi le point sur celles en attente. |
| GET | /catalogo | Quelles capacités du KIT peuvent être lancées sur une pièce jointe (`?attachment_id=`) ou sur le fil, avec recherche (`?q=`, `?lang=`). Lecture seule : ne coûte rien. |
| POST | / | Lancer une capacité du KIT (`{action, attachment_id?, params?}`) sur une pièce jointe ou sur le fil. Le résultat revient en NOTE INTERNE, jamais au client. Cela coûte de l’argent du portefeuille du KIT, et la même demande n’est jamais facturée deux fois. 202 avec la tâche en file. |
Téléphone (VOICE) /voice
| GET | /llamadas | Le journal d’appels du standard de l’espace (`?limite=` jusqu’à 200, `?antes_de=` pour paginer). Portée `voice:read` ; 404 si l’espace n’a pas de standard. |
| GET | /llamadas-en-curso | Les appels en cours en ce moment. |
| GET | /aparcadas | Les appels parqués, en attente d’être repris. |
| GET | /grabaciones/{id}/audio | L’audio d’un enregistrement, servi via l’API (sans lien public) et sans cache. Le standard enregistre qui l’a écouté. |
| GET | /extensiones | Les extensions que le panneau peut utiliser comme téléphone (les réservées n’apparaissent pas). |
| POST | /webphone-sesion | Enregistrer le navigateur comme téléphone d’une extension (`{extension_id}`) : renvoie un identifiant SIP éphémère, que le standard renouvelle à chaque échange. Portée `voice:write`. La clé du standard ne quitte jamais le serveur. |
Exemples réels
Envoyer un message d'agent (curl)
curl -X POST \
https://api.inteligenciaviva.com/v1/workspaces/$WS/conversations/$CONV/messages \
-H "Authorization: Bearer $IV_KEY" \
-H "Content-Type: application/json" \
-d '{"content": "Hi! I checked your order — it ships tomorrow."}'Lister les conversations (JavaScript)
const res = await fetch(
`https://api.inteligenciaviva.com/v1/workspaces/${WS}/conversations`,
{ headers: { Authorization: `Bearer ${process.env.IV_KEY}` } }
);
const { data } = await res.json();Vérifier la signature d'un webhook (Node)
import { createHmac, timingSafeEqual } from "node:crypto";
function verify(secret, rawBody, header, toleranceSec = 300) {
const { t, v1 } = Object.fromEntries(
header.split(",").map((p) => p.split("="))
);
if (Math.abs(Date.now() / 1000 - Number(t)) > toleranceSec) return false;
const expected = createHmac("sha256", secret)
.update(`${t}.${rawBody}`)
.digest("hex");
return timingSafeEqual(Buffer.from(expected), Buffer.from(v1));
}
Webhooks
Enregistrez un endpoint HTTPS et nous lui envoyons chaque événement en POST, signé. L'en-tête est `iv-signature: t=<unix>,v1=<hex>`, où `v1` est le HMAC-SHA256 de `<timestamp>.<corps brut>` avec le secret de votre endpoint — rejetez tout ce qui a plus de 5 minutes (protection contre le rejeu). Les livraisons échouées sont retentées automatiquement avec une signature fraîche, jusqu'à 5 tentatives.
| conversation.created | Une nouvelle conversation a démarré sur n'importe quel canal. |
| message.created | Un message est arrivé (visiteur, humain, IA ou système). |
| handoff.requested | L'IA a décidé qu'il lui faut un humain — l'instant exact, avec le résumé. |
| conversation.resolved | Une conversation s'est close ; vous indique si l'IA l'a close seule. |
Chaque livraison et son statut sont enregistrés — un webhook auquel on ne peut pas se fier est pire que pas de webhook du tout.
Streaming en temps réel
Pour les interfaces en direct, ouvrez un WebSocket vers le stream du workspace et recevez les événements de conversation au moment où ils se produisent — le même canal qu'utilisent nos propres apps d'agent.
wss://api.inteligenciaviva.com/v1/workspaces/{workspaceId}/stream
Erreurs et limites
Les erreurs sont du HTTP classique : `400` requête malformée, `401` clé absente ou invalide, `403` clé sans la portée requise, `404` ressource absente de ce workspace, `429` limite de débit (patientez et réessayez avec du jitter), `5xx` de notre faute — réessayez les requêtes idempotentes. Le corps porte toujours un `error.code` et un `error.message` lisible par un humain. Les limites de débit sont par clé et généreuses pour les intégrations réelles.
Foire aux questions
Cette documentation est-elle aspirationnelle ou la surface réelle ?
Réelle. Elle est écrite contre les routes montées du backend actuel. Quand quelque chose ici dit « à venir », c'est que ça n'existe pas encore — nous ne documentons pas du vent.
Faut-il un plan payant pour utiliser l'API ?
Oui — l'API fait partie de la plateforme payante (Pro l'inclut). Le Widget gratuit et le plugin WordPress sont client-side et n'ont besoin d'aucune API.
Quelle est la différence entre les clés en lecture seule et en lecture-écriture ?
Les clés en lecture seule peuvent lister et consulter mais jamais modifier — idéales pour les dashboards et la BI. Les clés en lecture-écriture peuvent créer des messages, des contacts, des agents d'IA et de la configuration.
Comment être informé des nouveaux messages — polling ou webhooks ?
Les webhooks (`message.created`) pour les serveurs, le stream WebSocket pour les interfaces en direct. Le polling fonctionne, mais vous atteindrez les limites de débit avant d'atteindre le temps réel.
Comment vérifier exactement qu'un webhook vient bien de vous ?
Recalculez le HMAC-SHA256 de `<t>.<corps brut>` avec le secret de votre endpoint et comparez-le en temps constant avec la valeur `v1` de l'en-tête `iv-signature` ; rejetez si `t` a plus de 300 secondes. Le code fonctionnel est sur cette page.
Que se passe-t-il si mon endpoint de webhooks est hors service ?
Nous enregistrons la livraison échouée et réessayons automatiquement avec un timestamp et une signature frais, jusqu'à 5 tentatives. Si l'endpoint a été supprimé ou désactivé entre-temps, les tentatives s'arrêtent proprement.
L'IA peut-elle escalader vers mon propre système ?
Oui — c'est le rôle de `handoff.requested`. Il se déclenche au moment où la conversation passe à une personne (le visiteur l'a demandé, il y a eu des signes de crise ou de frustration, ou la réponse ne s'appuyait pas sur les connaissances), avec le résumé de la conversation, pour que vous préveniez quelqu'un ou ouvriez un ticket dans un autre système.
Quels canaux puis-je piloter via l'API aujourd'hui ?
Le chat web est en production de bout en bout, et tout ce qui figure dans cette référence fonctionne aujourd'hui. Telegram et d'autres canaux de messagerie se connecteront au même modèle de conversation au fil des lancements — votre intégration ne changera pas.
Y a-t-il un SDK ?
Un SDK Flutter fait tourner notre propre app d'agent et sert de base au SDK white-label d'Enterprise. Côté serveur, la surface REST est volontairement simple — n'importe quel client HTTP fonctionne sans wrapper.
Où signaler un bug de l'API ou un manque dans cette documentation ?
Écrivez à l@inteligenciaviva.com. Une documentation qui ment est aussi un bug — nous la traitons avec la même sévérité.