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/conversationsToutes 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/workspacesLes espaces que cette clé peut gérer, avec son rôle dans chacun.
GET/visitantesQui 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}/messagesHistorique des messages (visiteur, agent humain, IA, système).
POST/{id}/messagesEnvoyer un message dans la conversation en tant qu'agent.
POST/{id}/assignAffecter la conversation à un agent humain ou à un département.
POST/{id}/resolveClore 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}/readMarquer la conversation comme lue par l’équipe (compteur de non-lues).
POST/{id}/reopenRouvrir une conversation close en conservant l’historique. Sans cela, une clôture par erreur était sans retour.
POST/{id}/archiveArchiver 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}/muteCouper les alertes pendant N heures, ou {horas:null} pour les réactiver.
POST/{id}/unreadLa 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}/forwardTransfé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}/reactionRé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}/locationEnvoyer 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-cardEnvoyer 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}/copilotoLe 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}/copilotoPoser 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}/enviarEnvoyer 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}/resumenDemander 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}/historialSur 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-sourcesSources de connaissance rattachées à cet agent.
POST/{id}/knowledge-sourcesRattacher une source de connaissance à cet agent.
GET/{aiAgentId}Un agent IA : instructions, seuil de confiance, outils et département.

Connaissance (RAG) /knowledge-sources

POST/documentIndexer un document comme connaissance ancrée.
POST/urlIndexer une URL.
GET/{id}Statut et métadonnées de la source.
DELETE/{id}Supprimer une source et ses vecteurs.
POST/{id}/reindexRelire 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}/aprobarApprouver une proposition : elle devient active et garde qui l’a approuvée (administrateur).
POST/{id}/rechazarRejeter une proposition (administrateur).
POST/probarAperçu : ce que la fiche répondrait à une question, avec sa note et sa tranche (option : inclure les propositions).
POST/recalcularRecalculer 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}/credentialsDéfinir les identifiants d'un canal.
PUT/{id}/statusActiver 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}/snippetLa ligne unique que le client colle sur son site. Tout le reste se configure ici.
GET/{channelId}/configLa configuration du chat : ce qui est publié (`config`) et ce que ce canal surcharge (`settings`). Ce sont deux choses distinctes.
PUT/{channelId}/configEnregistrer la configuration. Enregistrer et publier ne font qu’un : si le CDN échoue, le PUT échoue.
POST/{channelId}/config/publishRepublier la configuration sur le CDN sans la modifier.
POST/{channelId}/avatarTéléverser le visage de l’assistant (≤512 Ko). Stocké dans R2 et servi par le CDN.
POST/republicar-todosRepublier tous les canaux de l’espace. Le cron le fait quand le pack de textes change ; ceci évite d’attendre.
PUT/{channelId}/modoLe 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}/autoLes 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}/tarjetaLa 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}/horarioLes 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/agentsLister les agents humains du workspace.
POST/agents/{userId}/departmentsPlacer un agent dans un département.
GET/departmentsLister les départements.
PUT/departments/{id}/routing-rulesDéfinir les règles de routage des conversations entrantes.
POST/agentsInviter une personne à l’espace, avec son rôle et ses départements.
GET/agents/{userId}Un membre de l’équipe.
POST/departmentsCré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/webhooksEnregistrer un endpoint ; vous recevez son secret de signature une seule fois.
DELETE/webhooks/{id}Supprimer un endpoint.
POST/api-keysCréer une clé (lecture seule ou lecture-écriture).
DELETE/api-keys/{id}Révoquer une clé immédiatement.
GET/billing/subscriptionPlan, résolutions d'IA incluses et consommation de la période.
GET/analyticsMétriques agrégées du workspace.
GET/webhooksLister les points de terminaison webhook.
GET/webhooks/{id}/deliveriesHistorique des livraisons d’un webhook, avec les reprises. C’est ce qui dit si l’échec vient de vous ou de nous.
GET/api-keysLister 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}/notesNotes internes de la conversation. Le visiteur ne les voit jamais.
POST/conversations/{id}/notesAjouter une note interne.
DELETE/conversations/{id}/notes/{noteId}Supprimer une note interne.
GET/canned-responsesRéponses enregistrées de l’espace de travail, avec leur raccourci.
POST/canned-responsesCré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/presenceBattement 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/presenceY a-t-il quelqu’un en ligne ? C’est ce qui décide si un transfert attend ou est dévié.
GET/ai-usageConsommation 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}/transferTransfé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}/blockBloquer 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/categoriesLes catégories déjà utilisées dans les réponses prédéfinies (texte libre), pour l’autocomplétion.
POST/canned-responses/{cannedId}/useNoter 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}/attachmentsTé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}/attachmentsPiè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/registerEnregistrer 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/workspacesCréer un espace de travail. Hors préfixe : `/v1/workspaces`.
GET/workspaces/{workspaceId}/retencion/ensayoLa 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/visitantesQui 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}/invitarInviter 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-ticketUn 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/catalogoQuelles 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/llamadasLe 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-cursoLes appels en cours en ce moment.
GET/aparcadasLes appels parqués, en attente d’être repris.
GET/grabaciones/{id}/audioL’audio d’un enregistrement, servi via l’API (sans lien public) et sans cache. Le standard enregistre qui l’a écouté.
GET/extensionesLes extensions que le panneau peut utiliser comme téléphone (les réservées n’apparaissent pas).
POST/webphone-sesionEnregistrer 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.createdUne nouvelle conversation a démarré sur n'importe quel canal.
message.createdUn message est arrivé (visiteur, humain, IA ou système).
handoff.requestedL'IA a décidé qu'il lui faut un humain — l'instant exact, avec le résumé.
conversation.resolvedUne 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é.