Ti serve sapere come si usa l’app ogni giorno?
Apri la Guida utente.
Questa pagina è il contratto tecnico. Copre i lead in ingresso, i webhook firmati e MCP per gli assistenti, con una mappa di posta, WhatsApp e link pubblico del preventivo.
Le chiavi le creano owner e admin in Impostazioni → Integrazioni. Qui trovi URL, header, JSON, HMAC, retry e catalogo eventi.
Ingresso
POST JSON → lead
Form, ads, Zapier, Make o n8n. Una chiave con permesso lead:write.
In KREO non trovi un marketplace di app native per HubSpot, Slack App Store o gestionali proprietari.
Colleghi i sistemi esterni in modi che puoi verificare: REST con chiave API, webhook HTTPS firmati e MCP per Claude e Cursor.
Poi ci sono i canali del prodotto, cioè posta, webmail, WhatsApp e link pubblico del preventivo.
Stanno in altre parti dell’app e rientrano comunque nel perimetro integrazioni.
Impostazioni → Integrazioni (snippet dopo creazione chiave)
Owner e admin
AI tenant
Impostazioni → AI
Secondo permessi AI
Export CSV
Azioni negli elenchi Clienti, Articoli, Preventivi
Secondo permessi modulo
Quattro famiglie
Ingresso dati: form, ads e Zapier/Make/n8n mandano i lead in POST con una chiave lead:write. Se ti serve, puoi anche leggerli con lead:read.
Uscita eventi: webhook verso gli URL che registri. Puoi filtrare per tipo di evento, oppure lasciare la lista vuota e ricevere tutto ciò che è consegnabile.
Assistenti MCP: protocollo streamable HTTP su /v1/mcp, autenticazione Bearer con chiave MCP e un utente collegato.
Canali e cliente finale: posta, webmail, WhatsApp e pagina pubblica /p/{token} non sostituiscono le API qui sopra. Quando uno stato cambia in KREO, generano comunque eventi di dominio, per esempio preventivo accettato.
Nota sui connettori in dashboard. Le schede Form sito web, Landing & ads, Zapier/Make, Slack, CRM esterno, Google Sheets ed ERP precompilano nomi, permessi e tipi evento.
Sotto c’è sempre una chiave API, un webhook o tutti e due. Slack non verifica la firma HMAC. Se ti serve, filtra in un passaggio intermedio.
L’ERP emette erp.quote.export. Da dashboard puoi lanciare anche un export manuale, che entra nello stesso flusso eventi.
Una sync bidirezionale nativa con i gestionali non esiste.
Chiavi API
Una chiave si crea solo dalla dashboard. Il token in chiaro compare una volta,
alla creazione. Poi resta solo un elenco (nome, permessi, attiva/revocata). Se lo perdi,
revoca e creane un’altra: la revoca è definitiva.
Apri KREO → Impostazioni → Integrazioni.
Crea una chiave, assegna un nome e i permessi necessari.
Copia il token (inizia con kreo_) e conservalo nel secret store del tuo runtime, non nel codice.
Invialo in ogni richiesta pubblica come header X-KREO-API-Key.
Permessi
lead:write
Inserire lead con POST /v1/integrations/public/leads.
lead:read
Elenco, dettaglio e definizioni campi: GET /v1/integrations/public/leads e rotte collegate.
Una chiave può avere uno o entrambi i permessi. Senza il permesso richiesto la risposta è
403 con codice scope_required.
Header assente: 401 api_key_required. Token sbagliato o
revocato: 401 invalid_api_key.
Limiti
Per chiave, a finestra fissa di 60 secondi (valori di default): circa
60 scritture e 120 letture. I due contatori sono separati,
così una sync in lettura non brucia il budget dei form. In caso di superamento:
429 e header Retry-After.
Per collegare Claude o Cursor ci sono anche i permessi mcp:read e mcp:write.
Richiedono un utente collegato alla chiave e seguono i permessi di modulo di quell’utente.
Dettagli, elenco dei tool ed esempi di configurazione li trovi più sotto, nella sezione MCP.
MCP per assistenti esterni
Endpoint pubblico: https://app.kreoquotes.com/v1/mcp
Protocollo: MCP over HTTP streamable, quello usato dai client Claude Desktop e Cursor.
Autenticazione
Header Authorization: Bearer kreo_YOUR_API_KEY
La chiave deve avere mcp:read, mcp:write o entrambi.
Deve anche essere collegata a un utente KREO attivo del tenant. Se non colleghi un utente, la dashboard non crea la chiave.
Il tenant è sempre quello della chiave e non puoi indicarne un altro.
Permessi
mcp:read
Tool di sola lettura e whoami.
mcp:write
Tool di scrittura, proposte massive e conferma azioni.
Contano i permessi di modulo dell’utente collegato. Una chiave MCP non bypassa RBAC.
Tool disponibili
Tool
Descrizione
whoami
Mostra utente collegato, tenant, scope chiave e moduli effettivi.
cerca_clienti
Cerca clienti per testo, restituisce id sintetici.
leggi_cliente
Dettaglio cliente per id.
cerca_articoli
Cerca nel catalogo articoli.
leggi_articolo
Dettaglio articolo per id.
cerca_preventivi
Elenca preventivi con filtri opzionali.
leggi_preventivo
Dettaglio preventivo con righe.
cerca_fornitori
Cerca fornitori.
leggi_fornitore
Dettaglio fornitore.
cerca_lead
Cerca lead CRM.
leggi_lead
Dettaglio lead.
cerca_ordini_acquisto
Elenca ordini d’acquisto.
leggi_ordine_acquisto
Dettaglio ordine d’acquisto.
timeline_comunicazioni_cliente
Email e messaggi recenti sul cliente.
cerca_bozze_email
Bozze email salvate.
leggi_bozza_email
Contenuto bozza per id messaggio.
crea_cliente
Crea anagrafica cliente.
aggiorna_cliente
Aggiorna campi cliente.
crea_articolo
Crea articolo a catalogo.
aggiorna_articolo
Aggiorna articolo.
crea_fornitore
Crea fornitore.
aggiorna_fornitore
Aggiorna fornitore.
crea_lead
Crea lead.
aggiorna_lead
Aggiorna lead.
crea_preventivo
Crea testata preventivo.
aggiungi_riga_preventivo
Aggiunge riga.
aggiorna_riga_preventivo
Modifica riga.
rimuovi_riga_preventivo
Elimina riga.
aggiorna_testata_preventivo
Modifica campi testata.
imposta_stato_preventivo
Transizione di stato ammessa.
salva_bozza_email
Salva bozza email collegata a cliente.
invia_preventivo
Propone invio preventivo (richiede conferma).
invia_email
Propone invio email (richiede conferma).
invia_whatsapp
Propone messaggio WhatsApp (richiede conferma).
aumenta_prezzi_massivo
Propone aumento percentuale prezzi catalogo (richiede conferma).
importa_da_file
Propone import bulk da JSON righe (richiede conferma).
conferma_azione
Esegue una proposta pendente dopo conferma esplicita.
Le operazioni segnate come proposta restano ferme finché non chiami conferma_azione con l’id della proposta.
L’AI in app si comporta allo stesso modo.
Apri Claude → Impostazioni → Connettori → Aggiungi connettore custom e inserisci URL e header qui sopra.
Usa una chiave creata in KREO con scope MCP e utente collegato.
Il token in chiaro lo vedi una sola volta, quando crei la chiave in dashboard.
Conservalo in un posto sicuro sul client e non incollarlo in file pubblici del tuo progetto.
Inviare un lead
POST https://app.kreoquotes.com/v1/integrations/public/leads
Crea un lead nello stato new. Emette
lead.created (e, per compatibilità, l’alias
lead.received solo verso chi lo ha sottoscritto per nome).
La risposta è l’evento inbound, non un oggetto “Lead” nudo: contiene
id, event_type,
payload, status.
Corpo JSON
customer_name
Obbligatorio. 1–200 caratteri. Diventa nome e ragione sociale del lead.
customer_email
Opzionale. Email valida, max 254.
customer_phone
Opzionale. Max 40 caratteri.
message
Opzionale. Note, max 5000. Tipicamente il messaggio del form.
source
Canale. Default api, max 80. Es. sito-web.
external_ref
Opzionale. Id lato tuo (form, ads). Max 120. Utile in coppia con l’idempotenza.
project_name
Opzionale. Conservato nei campi aggiuntivi del lead.
Idempotenza
Header opzionale Idempotency-Key. Stessa chiave, stesso
tenant: KREO non ricrea il lead e restituisce l’evento già registrato. Usalo sui retry
del form o dell’automazione. Senza header, ogni POST è un lead nuovo.
Serve il permesso lead:read. I filtri coincidono con
quelli della sezione Lead in dashboard: se confronti i due elenchi, devono combaciare.
GET …/public/leads
Elenco impaginato. Query:
status,
q,
stale_days (1–365),
assigned (none,
any o id utente),
source,
converted,
limit (1–200, default 50),
offset.
Risposta: items, count,
has_more.
GET …/public/leads/{id}
Dettaglio. Un id di un altro tenant risponde 404 lead_not_found, non 403.
GET …/public/lead-fields
Definizioni dei campi aggiuntivi del tenant (anche disattivati: i valori già scritti restano sui lead).
Ogni lead ha la stessa forma in lettura e nei webhook:
id, anagrafica, status,
assegnatario, note, conversione, timestamp,
custom_fields e
custom_field_labels.
In Impostazioni → Integrazioni registri un URL HTTPS, scegli i tipi di evento
(lista vuota = tutti, tranne gli alias storici) e ricevi un segreto HMAC
una sola volta. Poi si può solo ruotare: la rotazione invalida il segreto precedente.
KREO fa POST con JSON e questi header:
Content-Type
application/json
X-KREO-Event-Id
Id dell’evento. Usalo come chiave di deduplica.
X-KREO-Event-Type
Es. quote.accepted
X-KREO-Event-Origin
app (utente in dashboard),
api (scrittura da chiave),
system (lavoro interno).
Scarta api se l’automazione ha appena scritto lei, per non ciclare.
X-KREO-Timestamp
Unix epoch in secondi, incluso nella firma.
X-KREO-Signature
sha256= seguito dall’hex HMAC-SHA256 di {timestamp}.{raw_body}.
Verifica la firma sul body grezzo della richiesta, non su un JSON
ri-serializzato. Rispondi 2xx entro 10 secondi. Qualsiasi altro status o un timeout
conta come fallimento.
import { createHmac, timingSafeEqual } from 'node:crypto'
export function verifyKreoSignature(secret, timestamp, rawBody, header) {
const expected = createHmac('sha256', secret)
.update(`${timestamp}.`)
.update(rawBody)
.digest('hex')
const provided = String(header || '').replace(/^sha256=/, '')
const a = Buffer.from(expected, 'utf8')
const b = Buffer.from(provided, 'utf8')
return a.length === b.length && timingSafeEqual(a, b)
}
Catalogo eventi
Nel webhook ti iscrivi agli eventi per nome. Se lasci la lista vuota ricevi tutti i tipi consegnabili, esclusi gli eventi interni AI.
Gli eventi AI (ai.proposed_action.* e simili) restano interni e sui webhook non escono mai.
Alias legacy: per i lead arrivati dall’endpoint pubblico, lead.received è un doppione di lead.created.
Lo riceve solo chi lo sottoscrive esplicitamente. Se ascolti «tutto» senza filtri, ricevi un solo evento per ogni nuovo lead.
Preventivi legacy:quote.reverted resta consegnabile. Per le nuove integrazioni usa quote.revised, che lo sostituisce.
Lead
lead.created Ogni nuovo lead, da form, API o dashboard
lead.received Alias storico, solo lead da POST pubblico
lead.updated Modifica che non cambia stadio né assegnatario
lead.status_changed Cambio di stadio nella pipeline lead
lead.assigned Assegnazione o rilascio
lead.deleted Eliminazione, payload con ultima fotografia completa
lead.converted Il lead è diventato cliente
CRM
opportunity.stage_changed L’opportunità è passata a un’altra colonna della pipeline
crm_task.created Attività con scadenza creata (promemoria, richiamata)
crm_task.completed Attività segnata come completata
quote.accepted Preventivo accettato (anche via link pubblico /p/)
quote.rejected Preventivo rifiutato
quote.expired Preventivo scaduto
quote.cancelled Preventivo annullato
quote.revised Aperta nuova revisione collegata
quote.reverted Riportato in bozza (legacy, preferisci quote.revised)
Ordini d’acquisto
purchase_order.created Ordine creato
purchase_order.sent Ordine inviato al fornitore
purchase_order.confirmed Ordine confermato
purchase_order.received Ordine ricevuto
purchase_order.cancelled Ordine annullato
ERP
erp.quote.export Richiesta export verso gestionale (evento, non connettore nativo)
Retry, stati, registro
Ogni consegna webhook crea un evento in uscita tracciato. In Impostazioni → Integrazioni → Log eventi vedi tipo, stato, tentativi, ultimo codice HTTP e messaggio di errore.
Un evento outbound fallito lo puoi rimettere in coda, anche se è finito in dead letter.
Gli eventi inbound, per esempio un lead appena arrivato via API, compaiono nel registro.
Verso l’esterno non si «ri-consegnano», perché descrivono una ricezione già avvenuta.
pendingretrydelivereddead_letterprocessed
Retry: fino a 6 tentativi per endpoint, con backoff esponenziale. Si parte da 30 secondi e tra un tentativo e l’altro non passa mai più di un’ora.
Il timeout HTTP verso il tuo URL è di 10 secondi.
Nessun subscriber: se nessun webhook attivo è iscritto a quell’evento, lo stato può risultare delivered con dettaglio no_subscribers.
Il tuo server non ha sbagliato niente.
Header anti-loop: ogni consegna include X-KREO-Event-Origin (app, api, system), così sai da dove parte.
Link pubblico preventivo
Il cliente apre un link del tipo https://app.kreoquotes.com/p/{token}, una pagina HTML che non chiede login.
Il token è segreto ed è legato a un preventivo in stato inviabile.
Cosa può fare il cliente
Vedere il preventivo e il PDF, poi accettarlo o rifiutarlo. Se abiliti la verifica in Impostazioni → Preventivi, completa anche l’OTP.
API JSON pubblica
Prefisso /v1/public/quotes/{token} per lettura, PDF, accettazione, rifiuto e OTP start/confirm.
Quando sono configurati, anche PDF firmato e certificato. Non serve la chiave integrazioni. Il tenant si ricava dal token.
Eventi webhook collegati
Quando il cliente accetta o rifiuta, KREO emette gli eventi di dominio del preventivo (quote.accepted, quote.rejected, ecc.), come per le azioni interne.
Così Zapier o il tuo CRM possono reagire.
Per l’accettazione del preventivo non usare l’endpoint lead.
Posta, webmail e WhatsApp
Per collegare le caselle, firmare i messaggi e usare la webmail ogni giorno apri la Guida utente.
Qui trovi solo requisiti e confini.
Posta (Google, Microsoft, IMAP/SMTP manuale)
Serve il modulo di licenza Posta webmail. Si configura in Impostazioni → Posta e si usa in Comunicazioni → Posta.
Per OAuth la piattaforma KREO deve aver completato il consenso con Google o Microsoft.
Lo scope è per azienda o per utente, secondo l’impostazione del tenant.
Webmail Roundcube
È la tab Webmail in Comunicazioni → Posta. Se la webmail Roundcube è installata nel tuo ambiente, entri con SSO dalla sessione KREO.
Prima devi aver collegato una casella in Posta.
WhatsApp Business (Meta Cloud API)
Servono la licenza Posta webmail e la licenza WhatsApp. Si configura in Impostazioni → Posta → WhatsApp Business e si usa in Comunicazioni → WhatsApp.
Colleghi token Meta, phone number id e verify token del webhook. Meta manda i messaggi inbound a KREO, che verifica la firma hub.
AI sulla posta
È un modulo AI posta a parte e dipende da Assistente AI e Posta. Non espone webhook. Trovi i dettagli nella Guida e in Impostazioni → AI.
Ricette in dashboard
I connettori in Impostazioni non sono OAuth verso HubSpot o Slack App Store.
Precompilano nome, permessi e tipi di evento. Il meccanismo resta questo contratto.
Form sito web
Chiave lead:write + POST JSON dal form o dal backend della landing.
Landing & ads
Meta / Google / Typeform → passo HTTP di Zapier, Make o n8n → stesso POST.
Zapier / Make / n8n
Trigger “Webhook”: incolla l’URL Catch Hook in KREO. Lista eventi vuota = tutto.
Slack
Incoming Webhook Slack. Default: lead.created, quote.sent, quote.accepted. Slack non verifica HMAC: filtra in un passo intermedio se ti serve.
CRM / Sheets
Endpoint HTTPS del CRM, o Webhook → riga su foglio. Verifica la firma se il ricevente può.
ERP / gestionale
Stesso webhook su quote.accepted e erp.quote.export. Non è un connettore SAP/TeamSystem nativo.
Volutamente fuori da questa pagina
Token, segreti HMAC, credenziali tenant, chiavi di produzione.
Rotte autenticate a sessione (creazione chiavi, rotazione segreti, export ERP): si usano dalla dashboard, non da script pubblici.
Eventi AI interni, non consegnabili.
?legacy=1 sull’ingresso lead: crea un cliente invece di un lead. Non usarlo per integrazioni nuove.
Limiti noti
Rate limit API lead: per chiave, su una finestra di 60 secondi. Di default circa 60 scritture e 120 letture, contate separatamente. Se superi il limite ricevi 429 con Retry-After.
Webhook: solo HTTPS. Timeout di 10 secondi e fino a 6 retry. Il payload è firmato e per verificare l’HMAC usi il body grezzo.
MCP: usa la chiave del tenant e richiede un utente. Operazioni massive e invii passano da conferma_azione. Lo storico resta quello esposto in app.
Slack Incoming Webhook: lato Slack nessuno verifica la firma KREO. Se ti serve, metti un filtro intermedio.
CRM e Google Sheets: si collegano con webhook HTTPS o con Zapier/Make in mezzo, non con connettori OAuth nativi in KREO.
ERP: c’è l’evento erp.quote.export con webhook verso il tuo endpoint. Oggi KREO non ha connettori nativi SAP, TeamSystem o Zucchetti.
Import strutturato: in UI non c’è un upload CSV generico. L’import passa dall’assistente AI o dal tool MCP importa_da_file, con conferma.
Export CSV: lo fai dalla selezione negli elenchi in app. Questa pagina non documenta un export via API pubblica.
Notifiche push: richiedono sottoscrizione del browser da parte dell’utente quando la funzione è attiva sulla piattaforma.
App mobile: è una PWA installabile dal browser su /m, con sync offline limitato.
Attività CRM con scadenza: generano crm_task.created e crm_task.completed, utili per promemoria esterni via webhook.
Pronto a collegare il primo form?
Crea la chiave in dashboard, incolla lo snippet, tieni d’occhio il registro consegne.
Se stai valutando KREO, una demo mostra l’hub integrazioni sul tuo flusso reale.