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/conversationsTutte 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/workspacesGli spazi che questa credenziale può seguire, con il ruolo in ciascuno.
GET/visitantesChi 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}/messagesCronologia dei messaggi (visitatore, agente umano, IA, sistema).
POST/{id}/messagesInvia un messaggio nella conversazione come agente.
POST/{id}/assignAssegna la conversazione a un agente umano o a un reparto.
POST/{id}/resolveChiudi 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-caseStato del caso che questa conversazione ha aperto nella bacheca di supporto del Portale, con le sue risposte. Si consulta in tempo reale.
POST/{id}/readSegnare la conversazione come letta dal team (contatore dei non letti).
POST/{id}/reopenRiaprire una conversazione chiusa mantenendo lo storico. Senza questo, una chiusura per errore non aveva ritorno.
POST/{id}/archiveArchivia o togli dall'archivio. Esce dalla posta senza chiudersi né perdere nulla; il corpo è {valor:true|false}.
POST/{id}/pinFissa in alto o rilascia. Le fissate aprono la prima pagina della posta. Corpo: {valor:true|false}.
POST/{id}/muteSilenzia gli avvisi per N ore, o {horas:null} per tornare a sentirla.
POST/{id}/unreadLasciarla 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}/forwardInoltrare 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}/reactionReagire 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}/locationInviare 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-cardInviare 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}/copilotoIl 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}/copilotoFare 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}/enviarInviare 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}/resumenChiedere 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}/historialDi 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-sourcesFonti di conoscenza collegate a questo agente.
POST/{id}/knowledge-sourcesCollega una fonte di conoscenza a questo agente.
GET/{aiAgentId}Un agente IA: istruzioni, soglia di confidenza, strumenti e reparto.

Conoscenza (RAG) /knowledge-sources

POST/documentIndicizza un documento come conoscenza fondata.
POST/urlIndicizza un URL.
GET/{id}Stato e metadati della fonte.
DELETE/{id}Rimuovi una fonte e i suoi vettori.
POST/{id}/reindexRileggere 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}/aprobarApprovare una proposta: diventa attiva e registra chi l’ha approvata (amministratore).
POST/{id}/rechazarRifiutare una proposta (amministratore).
POST/probarAnteprima: cosa risponderebbe la scheda a una domanda, con punteggio e fascia (opzionale: includere le proposte).
POST/recalcularRicalcolare 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}/credentialsImposta le credenziali di un canale.
PUT/{id}/statusAbilita o disabilita un canale.
POST/Creare un canale.
GET/{channelId}Un canale con tipo, stato e impostazioni.
GET/{channelId}/snippetL’unica riga che il cliente incolla nel suo sito. Tutto il resto si configura qui.
GET/{channelId}/configLa configurazione della chat: il pubblicato (`config`) e ciò che questo canale sovrascrive (`settings`). Sono cose diverse.
PUT/{channelId}/configSalvare la configurazione. Salvare e pubblicare sono lo stesso passo: se la CDN fallisce, fallisce il PUT.
POST/{channelId}/config/publishRipubblicare la configurazione sulla CDN senza modificarla.
POST/{channelId}/avatarCaricare il volto dell’assistente (≤512 KB). Va su R2 ed è servito dalla CDN.
POST/republicar-todosRipubblicare tutti i canali del workspace. Lo fa il cron quando cambia il pacchetto di stringhe; questo evita l’attesa.
PUT/{channelId}/modoLa 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}/autoI 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}/tarjetaIl 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}/horarioL’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/agentsElenca gli agenti umani del workspace.
POST/agents/{userId}/departmentsMetti un agente in un reparto.
GET/departmentsElenca i reparti.
PUT/departments/{id}/routing-rulesImposta le regole di instradamento delle conversazioni in entrata.
POST/agentsInvitare una persona nel workspace, con ruolo e reparti.
GET/agents/{userId}Una persona del team.
POST/departmentsCreare un reparto con le sue regole di instradamento.
GET/departments/{id}Un reparto.

Webhook, chiavi, fatturazione, statistiche /webhooks · /api-keys · /billing · /analytics

POST/webhooksRegistra un endpoint; ricevi il suo segreto di firma una sola volta.
DELETE/webhooks/{id}Rimuovi un endpoint.
POST/api-keysCrea una chiave (sola lettura o lettura-scrittura).
DELETE/api-keys/{id}Revoca una chiave immediatamente.
GET/billing/subscriptionPiano, risoluzioni IA incluse e uso del periodo.
GET/analyticsMetriche aggregate del workspace.
GET/webhooksElencare gli endpoint webhook.
GET/webhooks/{id}/deliveriesStorico delle consegne di un webhook, con i tentativi. È ciò che dice se l’errore è vostro o nostro.
GET/api-keysElencare le chiavi. Il segreto non viene mai restituito: solo il prefisso.

Strumenti dell'agente /conversations/{id} · /canned-responses · /tags · /presence

GET/conversations/{id}/notesNote interne della conversazione. Il visitatore non le vede mai.
POST/conversations/{id}/notesAggiungere una nota interna.
DELETE/conversations/{id}/notes/{noteId}Eliminare una nota interna.
GET/canned-responsesRisposte predefinite del workspace, con la loro scorciatoia.
POST/canned-responsesCreare una risposta predefinita.
PATCH/canned-responses/{cannedId}Modificare una risposta predefinita.
DELETE/canned-responses/{cannedId}Eliminare una risposta predefinita.
POST/presenceBattito 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/presenceC’è qualcuno online adesso? È ciò che decide se un passaggio attende o viene deviato.
GET/ai-usageConsumo di inferenza del workspace per giorno e le conversazioni più costose.
GET/tagsEtichette del workspace.
GET/conversations/{id}/tagsEtichette di una conversazione.
POST/conversations/{id}/tagsEtichettare una conversazione. Crea l’etichetta se non esisteva.
DELETE/conversations/{id}/tags/{tagId}Rimuovere un’etichetta dalla conversazione.
POST/conversations/{id}/transferTrasferire la conversazione a un reparto. Prevale sulle regole di instradamento: un trasferimento manuale non si annulla da solo.
POST/contacts/{contactId}/blockBloccare un contatto. Riceve un 403 senza dettagli: a chi abusa non si spiega come è stato rilevato.
GET/canned-responses/categoriesLe categorie già usate nelle risposte predefinite (testo libero), per il completamento automatico.
POST/canned-responses/{cannedId}/useAnnotare 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}/attachmentsCaricare un allegato come agente. Allowlist rigida e 10 MB: non entra nulla che un browser possa eseguire.
GET/conversations/{id}/attachmentsAllegati 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/registerRegistrare il token push di un dispositivo, per avvisare una persona quando l’IA trasferisce. Fuori dal prefisso workspace: `/v1/devices/register`.
POST/workspacesCreare un workspace. Fuori dal prefisso: `/v1/workspaces`.
GET/workspaces/{workspaceId}/retencion/ensayoLa 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/visitantesChi 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}/invitarInvitare 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-ticketUn 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/catalogoQuali 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/llamadasIl 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-cursoLe chiamate in corso in questo momento.
GET/aparcadasLe chiamate parcheggiate, in attesa che qualcuno le riprenda.
GET/grabaciones/{id}/audioL’audio di una registrazione, servito tramite l’API (senza link pubblico) e senza cache. Il centralino registra chi l’ha ascoltata.
GET/extensionesGli interni che il pannello può usare come telefono (quelli riservati non compaiono).
POST/webphone-sesionRegistrare 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.requestedL'IA ha deciso che le serve un umano — il momento esatto, con il riepilogo.
conversation.resolvedUna 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à.