Costruisci sulla stessa API su cui costruiamo noi
Tutto quello che fa la piattaforma — conversazioni, contatti, agenti IA, conoscenza, statistiche — gira su questa API REST. Non c'è un'API privata migliore dietro: questa è l'unica. URL base: `https://api.inteligenciaviva.com/v1`.
Quickstart: la tua prima richiesta in 60 secondi
Crea una chiave API nel tuo workspace, esportala ed elenca le tue conversazioni. Le chiavi hanno ambito per workspace e possono essere in sola lettura o in lettura-scrittura.
curl https://api.inteligenciaviva.com/v1/workspaces/WORKSPACE_ID/conversations \
-H "Authorization: Bearer sk_live_..."
Ogni risposta è JSON. Gli endpoint di collezione restituiscono array `data`; gli errori restituiscono un oggetto `error` con `code` e `message` e lo stato HTTP corrispondente.
L'API gratuita — senza account, senza chiave
Anche il livello gratuito parla API. `POST /v1/free/widget-snippet` riceve esattamente la stessa configurazione che il generatore visuale costruisce nella pagina Gratis e restituisce lo snippet HTML pronto da incollare — senza autenticazione, senza registrazione. Usala per generare widget in blocco per i siti dei clienti, rigenerare gli embed dalla CI quando cambiano gli orari, o semplicemente per toccare l'API prima di pagare un centesimo.
curl -X POST https://api.inteligenciaviva.com/v1/free/widget-snippet \
-H "Content-Type: application/json" \
-d @widget-config.json
# → { "snippet": "<link rel=\"stylesheet\" ..." }
Autenticazione
Ogni richiesta porta una chiave API nell'header `Authorization` come token Bearer. Le chiavi si creano e si revocano dall'API stessa o dal pannello, per workspace — revocare una chiave taglia il suo accesso immediatamente.
Gli endpoint di sessione a livello di account (registrazione, login, accesso con Google, scambio di ticket, profilo ed eliminazione dell'account sotto `/v1/auth`) alimentano le nostre stesse app; per le integrazioni server-to-server preferisci sempre le chiavi API di workspace alle sessioni utente.
Authorization: Bearer sk_live_...
Riferimento delle risorse
Tutte le rotte qui sotto pendono da `https://api.inteligenciaviva.com/v1/workspaces/{workspaceId}` salvo dove indicato. Questa è la superficie reale montata del backend attuale — niente di aspirazionale.
Posta combinata /inbox
| GET | /conversations | Tutte le conversazioni di TUTTI gli spazi che questa credenziale segue, in un unico elenco ordinato per attività. |
| GET | /conversations/{id} | Una conversazione cercata in tutti i tuoi spazi, senza sapere in quale si trova. Restituisce il workspace_id. |
| GET | /workspaces | Gli spazi che questa credenziale può seguire, con il ruolo in ciascuno. |
| GET | /visitantes | Chi sta navigando ADESSO in tutti i tuoi workspace, con la pagina che legge e se sta già conversando. Una foto del momento, non una cronologia: non è paginata. Un workspace che non risponde non fa cadere l’elenco: finisce in `casas_sin_responder`. |
Conversazioni /conversations
| GET | / | Elenca le conversazioni, filtrabili per stato. |
| GET | /{id} | Una conversazione con stato, canale, contatto e assegnazione. |
| GET | /{id}/messages | Cronologia dei messaggi (visitatore, agente umano, IA, sistema). |
| POST | /{id}/messages | Invia un messaggio nella conversazione come agente. |
| POST | /{id}/assign | Assegna la conversazione a un agente umano o a un reparto. |
| POST | /{id}/resolve | Chiudi la conversazione. Se l'IA l'ha chiusa da sola, conta come risoluzione fatturabile. |
| POST | / | Aprire una conversazione fuori dal widget (per esempio per migrare un thread esistente). |
| GET | /{id}/ai-turns | «Da dove l’ha preso?» — il registro di ogni turno di IA: su cosa si è basata, con quale modello, quanto ha impiegato e perché ha trasferito. |
| GET | /{id}/portal-case | Stato del caso che questa conversazione ha aperto nella bacheca di supporto del Portale, con le sue risposte. Si consulta in tempo reale. |
| POST | /{id}/read | Segnare la conversazione come letta dal team (contatore dei non letti). |
| POST | /{id}/reopen | Riaprire una conversazione chiusa mantenendo lo storico. Senza questo, una chiusura per errore non aveva ritorno. |
| POST | /{id}/archive | Archivia o togli dall'archivio. Esce dalla posta senza chiudersi né perdere nulla; il corpo è {valor:true|false}. |
| POST | /{id}/pin | Fissa in alto o rilascia. Le fissate aprono la prima pagina della posta. Corpo: {valor:true|false}. |
| POST | /{id}/mute | Silenzia gli avvisi per N ore, o {horas:null} per tornare a sentirla. |
| POST | /{id}/unread | Lasciarla non letta: il segno di lettura torna dietro all'ultimo messaggio del cliente. |
| POST | /{id}/typing | «Sta scrivendo…» verso il cliente: su WhatsApp lo riceve Meta, nella chat web il widget del visitatore. Senza corpo; sempre 204 (nei canali che non lo supportano non fa nulla) e 404 se la conversazione non esiste. |
| POST | /{id}/messages/{messageId}/forward | Inoltrare un messaggio a un’altra conversazione dello stesso workspace, con il suo allegato (copiato, non condiviso). Corpo: `{to_conversation_id}`. Esce come messaggio dell’agente. |
| PUT | /{id}/messages/{messageId}/reaction | Reagire con un emoji a un messaggio WhatsApp; sostituisce la reazione precedente dell’azienda e `{emoji:null}` la toglie. Solo WhatsApp (API di Meta) e solo su un messaggio già confermato da Meta: altrimenti 400. |
| POST | /{id}/location | Inviare una posizione via WhatsApp: `{lat, lon, name?, address?, reply_to_message_id?}`. Va prima a Meta: se Meta la rifiuta, nel thread non resta nulla. Solo WhatsApp. |
| POST | /{id}/contact-card | Inviare un biglietto da visita via WhatsApp: `{name:{formatted_name}, phones?, emails?, reply_to_message_id?}`. Come la posizione: prima Meta, poi il thread. Solo WhatsApp. |
| GET | /{id}/copiloto | Il copilota dell’agente: ciò che l’IA ha suggerito per questa conversazione e ciò che si è detto con lei. È privato del team: il cliente non lo vede. |
| POST | /{id}/copiloto | Fare all’IA una domanda privata su questa conversazione (`{content}`, fino a 4.000 caratteri). Risponde ALL’AGENTE, non al cliente: nulla esce dal canale. 503 `copilot_unavailable` se non può rispondere. |
| POST | /{id}/copiloto/{sugerenciaId}/enviar | Inviare al cliente un suggerimento del copilota, così com’è o modificato (`{content}` facoltativo). Esce come messaggio dell’agente, con il suo autore umano. Un suggerimento si invia una sola volta: il secondo invio dà 409 `ya_enviada`. |
| POST | /{id}/resumen | Chiedere il riassunto della conversazione (aperta o chiusa) e aggiornare con esso la scheda del contatto. Costa un’attività del KIT; richiederlo senza nuovi messaggi non addebita di nuovo. Se non c’è riassunto, restituisce il perché (`motivo`, `codigo`). |
Contatti /contacts
| GET | / | Elenca i contatti. |
| GET | /{id} | Un contatto con le sue identità e la cronologia delle conversazioni. |
| GET | /{id}/historial | Di cosa trattavano le sue ultime richieste: le ultime conversazioni con il loro riassunto (`?limit=`, fino a 25), i totali e la scheda del contatto. Aprirla non genera la scheda mancante, perché costa denaro: si richiede a parte con `?generar=1`. |
Agenti IA /ai-agents
| GET | / | Elenca gli agenti IA del workspace. |
| POST | / | Crea un agente IA: istruzioni, reparto, soglia di confidenza. |
| PATCH | /{id} | Aggiorna istruzioni, soglia o reparto. |
| GET | /{id}/knowledge-sources | Fonti di conoscenza collegate a questo agente. |
| POST | /{id}/knowledge-sources | Collega una fonte di conoscenza a questo agente. |
| GET | /{aiAgentId} | Un agente IA: istruzioni, soglia di confidenza, strumenti e reparto. |
Conoscenza (RAG) /knowledge-sources
| POST | /document | Indicizza un documento come conoscenza fondata. |
| POST | /url | Indicizza un URL. |
| GET | /{id} | Stato e metadati della fonte. |
| DELETE | /{id} | Rimuovi una fonte e i suoi vettori. |
| POST | /{id}/reindex | Rileggere una fonte URL senza eliminarla: se il download fallisce, non si tocca nulla. |
| GET | / | Elencare le fonti di conoscenza con il loro stato di indicizzazione. |
Scheda dell’attività /ficha
| GET | / | Elencare le unità (filtri ?estado= e ?tipo=) con le soglie delle fasce. |
| POST | / | Creare un’unità: domanda, varianti, risposta approvata, URL e lingua. Un amministratore o una chiave la pubblica; un agente la propone. L’IA non pubblica mai. |
| GET | /{id} | Vedere un’unità. |
| PATCH | /{id} | Modificare un’unità; cambiare la domanda o le varianti ricalcola l’embedding. |
| DELETE | /{id} | Eliminare un’unità (amministratore). |
| POST | /{id}/aprobar | Approvare una proposta: diventa attiva e registra chi l’ha approvata (amministratore). |
| POST | /{id}/rechazar | Rifiutare una proposta (amministratore). |
| POST | /probar | Anteprima: cosa risponderebbe la scheda a una domanda, con punteggio e fascia (opzionale: includere le proposte). |
| POST | /recalcular | Ricalcolare gli embedding mancanti o non più allineati al testo (amministratore). |
Canali /channels
| GET | / | Elenca i canali. Vivi oggi: chat web e API; altri si collegano man mano che escono. |
| PUT | /{id}/credentials | Imposta le credenziali di un canale. |
| PUT | /{id}/status | Abilita o disabilita un canale. |
| POST | / | Creare un canale. |
| GET | /{channelId} | Un canale con tipo, stato e impostazioni. |
| GET | /{channelId}/snippet | L’unica riga che il cliente incolla nel suo sito. Tutto il resto si configura qui. |
| GET | /{channelId}/config | La configurazione della chat: il pubblicato (`config`) e ciò che questo canale sovrascrive (`settings`). Sono cose diverse. |
| PUT | /{channelId}/config | Salvare la configurazione. Salvare e pubblicare sono lo stesso passo: se la CDN fallisce, fallisce il PUT. |
| POST | /{channelId}/config/publish | Ripubblicare la configurazione sulla CDN senza modificarla. |
| POST | /{channelId}/avatar | Caricare il volto dell’assistente (≤512 KB). Va su R2 ed è servito dalla CDN. |
| POST | /republicar-todos | Ripubblicare tutti i canali del workspace. Lo fa il cron quando cambia il pacchetto di stringhe; questo evita l’attesa. |
| PUT | /{channelId}/modo | La modalità di assistenza del canale: `{modo:"humano"|"hibrido"|"ia"}`. Decide se l’IA parla con il cliente. Vale per qualsiasi tipo di canale (WhatsApp, Telegram, e-mail, widget). Solo amministratori. |
| PUT | /{channelId}/auto | I messaggi automatici del canale: `{bienvenida, fueraDeHorario}` (fino a 1.000 caratteri ciascuno; `null` cancella). Quello fuori orario usa l’orario del canale. Solo amministratori. |
| PUT | /{channelId}/tarjeta | Il biglietto da visita che l’agente può inviare da questo canale: `{tarjetaContacto:{name:{formatted_name}, phones?, emails?}}`, con almeno un telefono o un’e-mail; `null` lo toglie. Solo WhatsApp. Solo amministratori. |
| PUT | /{channelId}/horario | L’orario di assistenza: `{officeHours:{tz, dias:{lun:[["09:00","17:00"]], …}, festivos:["MM-DD" o "YYYY-MM-DD"]}}`; `null` lo toglie (24/7). Ciò che non si capisce viene rifiutato con 400 indicando cosa non va. Restituisce `abiertoAhora`, calcolato dal server. Solo amministratori. |
Agenti umani e reparti /agents · /departments
| GET | /agents | Elenca gli agenti umani del workspace. |
| POST | /agents/{userId}/departments | Metti un agente in un reparto. |
| GET | /departments | Elenca i reparti. |
| PUT | /departments/{id}/routing-rules | Imposta le regole di instradamento delle conversazioni in entrata. |
| POST | /agents | Invitare una persona nel workspace, con ruolo e reparti. |
| GET | /agents/{userId} | Una persona del team. |
| POST | /departments | Creare un reparto con le sue regole di instradamento. |
| GET | /departments/{id} | Un reparto. |
Webhook, chiavi, fatturazione, statistiche /webhooks · /api-keys · /billing · /analytics
| POST | /webhooks | Registra un endpoint; ricevi il suo segreto di firma una sola volta. |
| DELETE | /webhooks/{id} | Rimuovi un endpoint. |
| POST | /api-keys | Crea una chiave (sola lettura o lettura-scrittura). |
| DELETE | /api-keys/{id} | Revoca una chiave immediatamente. |
| GET | /billing/subscription | Piano, risoluzioni IA incluse e uso del periodo. |
| GET | /analytics | Metriche aggregate del workspace. |
| GET | /webhooks | Elencare gli endpoint webhook. |
| GET | /webhooks/{id}/deliveries | Storico delle consegne di un webhook, con i tentativi. È ciò che dice se l’errore è vostro o nostro. |
| GET | /api-keys | Elencare le chiavi. Il segreto non viene mai restituito: solo il prefisso. |
Strumenti dell'agente /conversations/{id} · /canned-responses · /tags · /presence
| GET | /conversations/{id}/notes | Note interne della conversazione. Il visitatore non le vede mai. |
| POST | /conversations/{id}/notes | Aggiungere una nota interna. |
| DELETE | /conversations/{id}/notes/{noteId} | Eliminare una nota interna. |
| GET | /canned-responses | Risposte predefinite del workspace, con la loro scorciatoia. |
| POST | /canned-responses | Creare una risposta predefinita. |
| PATCH | /canned-responses/{cannedId} | Modificare una risposta predefinita. |
| DELETE | /canned-responses/{cannedId} | Eliminare una risposta predefinita. |
| POST | /presence | Battito di presenza: dichiara che c’è una persona disponibile. Solo con sessione — una chiave API che batte non è qualcuno davanti allo schermo, e viene rifiutata con 400. |
| GET | /presence | C’è qualcuno online adesso? È ciò che decide se un passaggio attende o viene deviato. |
| GET | /ai-usage | Consumo di inferenza del workspace per giorno e le conversazioni più costose. |
| GET | /tags | Etichette del workspace. |
| GET | /conversations/{id}/tags | Etichette di una conversazione. |
| POST | /conversations/{id}/tags | Etichettare una conversazione. Crea l’etichetta se non esisteva. |
| DELETE | /conversations/{id}/tags/{tagId} | Rimuovere un’etichetta dalla conversazione. |
| POST | /conversations/{id}/transfer | Trasferire la conversazione a un reparto. Prevale sulle regole di instradamento: un trasferimento manuale non si annulla da solo. |
| POST | /contacts/{contactId}/block | Bloccare un contatto. Riceve un 403 senza dettagli: a chi abusa non si spiega come è stato rilevato. |
| GET | /canned-responses/categories | Le categorie già usate nelle risposte predefinite (testo libero), per il completamento automatico. |
| POST | /canned-responses/{cannedId}/use | Annotare che è stata usata una risposta predefinita (contatore e ultimo uso). Sempre 204, che esista o no: è telemetria d’uso, non un’azione. |
Allegati, dispositivi e workspace /conversations/{id}/attachments · /devices · /workspaces
| POST | /conversations/{id}/attachments | Caricare un allegato come agente. Allowlist rigida e 10 MB: non entra nulla che un browser possa eseguire. |
| GET | /conversations/{id}/attachments | Allegati di una conversazione. |
| GET | /attachments/{attachmentId} | Scaricare un allegato. Servito con header rigidi e `nosniff`; solo immagini e audio si mostrano in linea. |
| POST | /devices/register | Registrare il token push di un dispositivo, per avvisare una persona quando l’IA trasferisce. Fuori dal prefisso workspace: `/v1/devices/register`. |
| POST | /workspaces | Creare un workspace. Fuori dal prefisso: `/v1/workspaces`. |
| GET | /workspaces/{workspaceId}/retencion/ensayo | La prova della pulizia: quante conversazioni e allegati (e byte) eliminerebbe la conservazione, senza cancellare nulla. `?days=` chiede di un periodo non ancora salvato. Servono amministratore e `analytics:read`. Percorso completo: `/v1/workspaces/{workspaceId}/retencion/ensayo`. |
Visitatori dal vivo e tempo reale /visitantes · /stream-ticket
| GET | /visitantes | Chi sta navigando adesso nei siti di questo workspace: pagina, lingua, da quando e se ha già la chat aperta o una conversazione. |
| POST | /visitantes/{visitorId}/invitar | Invitare un visitatore ad aprire la chat, con `{mensaje}` facoltativo (senza, il saluto del widget nella sua lingua). Non crea una conversazione né consuma IA: la conversazione nasce quando il visitatore risponde. 404 `no_esta` se è andato via; 409 `ya_conversa` se sta già conversando. |
| POST | /stream-ticket | Un ticket per aprire il WebSocket dello stream con `?ticket=` senza mettere il token nell’URL. Dura 60 s e vale una sola volta. Funziona con sessione o con chiave API. |
Capacità del KIT /conversations/{id}/kit
| GET | / | Le attività del KIT lanciate in questa conversazione, con il loro stato. Elencarle fa anche il punto su quelle in sospeso. |
| GET | /catalogo | Quali capacità del KIT si possono lanciare su un allegato (`?attachment_id=`) o sul thread, con ricerca (`?q=`, `?lang=`). Sola lettura: non costa nulla. |
| POST | / | Lanciare una capacità del KIT (`{action, attachment_id?, params?}`) su un allegato o sul thread. Il risultato torna come NOTA INTERNA, mai al cliente. Costa denaro del portafoglio del KIT, e la stessa richiesta non viene addebitata due volte. 202 con l’attività in coda. |
Telefono (VOICE) /voice
| GET | /llamadas | Il registro chiamate del centralino del workspace (`?limite=` fino a 200, `?antes_de=` per paginare). Ambito `voice:read`; 404 se il workspace non ha centralino. |
| GET | /llamadas-en-curso | Le chiamate in corso in questo momento. |
| GET | /aparcadas | Le chiamate parcheggiate, in attesa che qualcuno le riprenda. |
| GET | /grabaciones/{id}/audio | L’audio di una registrazione, servito tramite l’API (senza link pubblico) e senza cache. Il centralino registra chi l’ha ascoltata. |
| GET | /extensiones | Gli interni che il pannello può usare come telefono (quelli riservati non compaiono). |
| POST | /webphone-sesion | Registrare il browser come telefono di un interno (`{extension_id}`): restituisce una credenziale SIP effimera, che il centralino rinnova a ogni scambio. Ambito `voice:write`. La chiave del centralino non esce mai dal server. |
Esempi reali
Invia un messaggio da agente (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."}'Elenca le conversazioni (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();Verifica la firma di 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));
}
Webhook
Registra un endpoint HTTPS e ti inviamo ogni evento via POST, firmato. L'header è `iv-signature: t=<unix>,v1=<hex>`, dove `v1` è l'HMAC-SHA256 di `<timestamp>.<body grezzo>` con il segreto del tuo endpoint — rifiuta tutto ciò che ha più di 5 minuti (protezione dai replay). Le consegne fallite vengono ritentate automaticamente con una firma fresca, fino a 5 tentativi.
| conversation.created | È iniziata una nuova conversazione su un canale qualsiasi. |
| message.created | È arrivato un messaggio (visitatore, umano, IA o sistema). |
| handoff.requested | L'IA ha deciso che le serve un umano — il momento esatto, con il riepilogo. |
| conversation.resolved | Una conversazione è stata chiusa; ti dice se l'IA l'ha chiusa da sola. |
Ogni consegna e il suo stato restano registrati — un webhook di cui non puoi fidarti è peggio di nessuno.
Streaming in tempo reale
Per le interfacce dal vivo, apri un WebSocket verso lo stream del workspace e ricevi gli eventi delle conversazioni mentre accadono — lo stesso canale che usano le nostre stesse app per agenti.
wss://api.inteligenciaviva.com/v1/workspaces/{workspaceId}/stream
Errori e limiti
Gli errori sono HTTP convenzionale: `400` richiesta malformata, `401` chiave assente o non valida, `403` chiave senza permessi, `404` risorsa non presente in questo workspace, `429` limite di frequenza (attendi e riprova con jitter), `5xx` colpa nostra — riprova le richieste idempotenti. Il body porta sempre un `error.code` e un `error.message` leggibile da un umano. I limiti di frequenza sono per chiave e generosi per le integrazioni reali.
Domande frequenti
Questa documentazione è aspirazionale o è la superficie reale?
Reale. È scritta contro le rotte montate del backend attuale. Quando qui qualcosa dice "in arrivo", vuol dire che non esiste ancora — non documentiamo fumo.
Serve un piano a pagamento per usare l'API?
Sì — l'API fa parte della piattaforma a pagamento (Pro la include). Il Widget gratuito e il plugin per WordPress sono lato client e non hanno bisogno di alcuna API.
Qual è la differenza tra chiavi in sola lettura e in lettura-scrittura?
Le chiavi in sola lettura possono elencare e consultare ma mai modificare — ideali per dashboard e BI. Quelle in lettura-scrittura possono creare messaggi, contatti, agenti IA e configurazione.
Come vengo avvisato dei nuovi messaggi — polling o webhook?
Webhook (`message.created`) per i server, lo stream WebSocket per le interfacce dal vivo. Il polling funziona, ma sbatterai contro i limiti di frequenza prima di arrivare al tempo reale.
Come verifico esattamente che un webhook arriva da voi?
Ricalcola l'HMAC-SHA256 di `<t>.<body grezzo>` con il segreto del tuo endpoint e confrontalo in tempo costante con il valore `v1` dell'header `iv-signature`; rifiuta se `t` ha più di 300 secondi. Il codice funzionante è in questa pagina.
Cosa succede se il mio endpoint webhook è giù?
Registriamo la consegna fallita e riproviamo automaticamente con timestamp e firma freschi, fino a 5 tentativi. Se nel frattempo l'endpoint è stato eliminato o disabilitato, i tentativi si fermano in modo pulito.
L'IA può passare la mano al mio sistema di escalation?
Sì — è a questo che serve `handoff.requested`. Si attiva nel momento in cui la conversazione passa a una persona (il visitatore l'ha chiesto, c'erano segnali di crisi o di frustrazione, o la risposta non si basava sulla conoscenza), con il riepilogo della conversazione, così puoi avvisare qualcuno o aprire un ticket in un altro sistema.
Quali canali posso pilotare tramite l'API oggi?
La chat web è viva da un capo all'altro, e tutto ciò che c'è in questo riferimento funziona oggi. Telegram e altri canali di messaggistica si collegano allo stesso modello di conversazione man mano che escono — la tua integrazione non cambia.
Esiste un SDK?
Un SDK Flutter alimenta la nostra stessa app per agenti ed è la base dell'SDK white-label di Enterprise. Per i server, la superficie REST è volutamente semplice — qualsiasi client HTTP funziona senza wrapper.
Dove segnalo un bug dell'API o una lacuna in questa documentazione?
Scrivi a l@inteligenciaviva.com. Anche una documentazione che mente è un bug — la trattiamo con la stessa severità.