Venditore Digitale — API

Versione 1.0 · sola lettura · una chiave per azienda

Queste API espongono in lettura i dati del Venditore Digitale della tua azienda: contatti, venditori, opportunità, azioni e le tabelle che servono a interpretarli. Servono ad alimentare automazioni esterne — CRM, flussi di ricontatto, cruscotti.

Indirizzo e versione

https://europe-west1-app-venditore-digitale.cloudfunctions.net/api/1.0

Tutte le rotte sono in GET. Un metodo diverso risponde 405 No method.

Autenticazione

Ogni chiamata richiede l’header authorization con la API key della tua azienda.

authorization: LA-TUA-API-KEY
La chiave va passata nuda. Niente Bearer, niente ApiKey, nessun prefisso: il valore viene confrontato tale e quale, spazi compresi.

La chiave identifica l’azienda: ogni risposta contiene soltanto i dati di quell’azienda, e non esiste modo di leggere quelli di un’altra. La trovi nel backoffice, in Aziende → la tua azienda → Api, oppure la chiedi a PowerApp.

Trattala come una password: chi ce l’ha legge l’intera anagrafica contatti. Tienila fuori dal codice sorgente e da qualunque pagina pubblica.

Formato della risposta

Tutte le rotte rispondono con lo stesso involucro:

{
  "success": true,
  "message": "",
  "code": 200,
  "meta": 500,
  "data": [ ... ]
}
camposignificato
successesito della chiamata
messagevuoto quando va bene, il motivo quando fallisce
coderipete lo status HTTP
metaquanti elementi ci sono in questa pagina
datai dati
meta non è il totale. È il numero di elementi restituiti dalla chiamata che hai appena fatto. Un conteggio complessivo non è esposto da nessuna rotta: se ti serve, lo ottieni solo scorrendo tutte le pagine.

Errori

Gli errori usano lo stesso involucro con success: false. Lo status HTTP coincide sempre con il campo code.

HTTPmessagecausa
405No methodmetodo diverso da GET
401No authorizationheader authorization assente o vuoto
400No company found. Wrong Api Keyla chiave non corrisponde a nessuna azienda
400No customerId · No projectIdmanca un parametro obbligatorio
400No customer found · No project foundl’id passato non esiste o non è della tua azienda
400Group not found · Temperature not foundvalore fuori dalla lista ammessa
500errore imprevisto; la risposta contiene anche "error": true

Paginazione

La paginazione è a cursore, non per numero di pagina.

parametrosignificato
sizequanti elementi per pagina. Default 500
lastDocumentl’id dell’ultimo elemento ricevuto: la pagina riparte da lì
# prima pagina
curl -H "authorization: LA-TUA-API-KEY" \
  ".../api/1.0/contacts?size=200"

# pagine successive: si passa l’id dell’ultimo elemento ricevuto
curl -H "authorization: LA-TUA-API-KEY" \
  ".../api/1.0/contacts?size=200&lastDocument=ID-ULTIMO-ELEMENTO"

Si continua finché data non torna vuoto.

size e lastDocument funzionano solo su quattro rotte: /contacts, /customers, /projects, /actions.
Su /origins e /sectors sono accettati ma ignorati: la risposta è sempre la lista completa. Su /groups, /states, /temperatures e /info non vengono nemmeno letti. Non scrivere cicli di paginazione su queste rotte.

GET/1.0/info

I dati anagrafici e di configurazione della tua azienda. Nessun parametro.

È anche la chiamata di prova: se risponde 200, la chiave è valida.

curl -H "authorization: LA-TUA-API-KEY" ".../api/1.0/info"

GET/1.0/customers

Gli utenti dell’azienda, cioè i venditori. Ordinati per data di inserimento decrescente, paginati.

È il punto di partenza: l’id di un customer serve a /projects e come filtro su /contacts.

parametrosignificato
sizeopz.elementi per pagina (default 500)
lastDocumentopz.cursore

GET/1.0/contacts

I contatti dell’azienda. È la rotta principale e l’unica con filtri veri. Nessun parametro è obbligatorio: la chiamata nuda funziona.

parametrosignificato
customerIdopz.solo i contatti di un venditore. Se l’id non è della tua azienda → 400 No customer found
groupopz.gruppo del contatto. Ammessi solo 0, 1, 2, 8 (vedi /groups); altri valori → 400 Group not found
temperatureopz.temperatura: 1, 2, 3 (vedi /temperatures)
winopz.true = solo le opportunità a punteggio pieno (100)
startDateopz.data minima, GG-MM-AAAA oppure GG-MM-AAAA HH:mm
endDateopz.data massima, stesso formato. La giornata indicata è inclusa per intero
byUpdateDateopz.su quale data agiscono i due filtri sopra: true (default) = ultima modifica, qualsiasi altro valore = data di creazione
originIdopz.id di una provenienza (vedi /origins)
sectorIdopz.id di un settore (vedi /sectors)
projectNameopz.nome dell’opportunità corrente. Cerca per inizio di parola, non per sottostringa
noGroupIdopz.esclude un gruppo. noGroupId=5 toglie i cancellati
size · lastDocumentopz.paginazione
win non si disattiva con false. Qualsiasi valore diverso da true — compresi false, 0, no — è un filtro attivo che restituisce le opportunità con punteggio diverso da 100. Per non filtrare, ometti il parametro.
Una data scritta male non dà errore. Se startDate o endDate non sono nel formato atteso, il filtro viene ignorato in silenzio e ricevi tutti i record. Controlla il numero di risultati, non solo lo status.
originId e sectorId non sono validati: un id inesistente non dà errore, restituisce zero contatti.

Campi principali di un contatto

camposignificato
ididentificativo, e valore da usare come lastDocument
name · surname · companyNamenome, cognome, azienda
email · phone · cityrecapiti
stateId0 = Contatto, 1 = Cliente (vedi /states)
groupAttivi / Persi / Inattivi / Vinti
scorepunteggio dell’opportunità corrente
currentProject · currentProjectIdl’opportunità in corso
customerIdil venditore a cui è assegnato
sector · sectorTagId · originTagIdsettore e provenienza
insertDate · updateDatecreazione e ultima modifica
commentnote libere

GET/1.0/projects

Le opportunità correnti dei contatti assegnati a un venditore.

parametrosignificato
customerIdOBBLIGATORIOid del venditore, da /customers
size · lastDocumentopz.paginazione
Senza customerId risponde 400 No customerId. È la causa più comune di errore su questa rotta: non è la chiave a essere sbagliata.
curl -H "authorization: LA-TUA-API-KEY" \
  ".../api/1.0/projects?customerId=ID-VENDITORE"
Qui lastDocument è l’id di un contatto, non di un’opportunità: la lista scorre i contatti del venditore.

GET/1.0/actions

Le azioni registrate su un’opportunità: email, messaggi, telefonate, social, eventi, incontri. Ordinate dalla più recente.

parametrosignificato
projectIdOBBLIGATORIOid dell’opportunità, da /projects
size · lastDocumentopz.paginazione
Senza projectId risponde 400 No projectId.

GET/1.0/groups

I gruppi del contatto. Lista fissa, uguale per tutte le aziende. Nessun parametro.

idetichetta
0Attivi
1Persi
2Inattivi
8Vinti

Sono anche gli unici valori accettati dal filtro group di /contacts.

GET/1.0/states

Lo stato del contatto. Lista fissa, nessun parametro.

idetichetta
0Contatto
1Cliente

GET/1.0/temperatures

La temperatura, calcolata sul punteggio dell’opportunità corrente. Lista fissa, nessun parametro.

idetichettapunteggio
1Freddifino a 33
2Tiepidida 34 a 66
3Caldioltre 66
La temperatura 0 non esiste. Passare ?temperature=0 a /contacts400 Temperature not found. Per «tutte», ometti il parametro.

GET/1.0/origins

Le provenienze censite dalla tua azienda (passaparola, sito web, fiera…): sono i valori del campo originTagId dei contatti e gli id validi per il filtro originId.

Lista sempre completa, non paginata.

GET/1.0/sectors

I settori censiti dalla tua azienda: gli id validi per il filtro sectorId.

Lista sempre completa, non paginata.

Qui il nome del settore sta nel campo sector, non in name come nelle altre liste.

La catena delle chiamate

Tre rotte si concatenano: l’id di una serve alla successiva.

/1.0/customers                 →  id del venditore
        ↓
/1.0/projects?customerId=...   →  id dell’opportunità
        ↓
/1.0/actions?projectId=...     →  le azioni

Se salti un passaggio ottieni un 400 che dice quale parametro manca.

Ricette

I contatti che non hanno ancora comprato

Sono quelli nel gruppo Attivi con stato Contatto:

curl -H "authorization: LA-TUA-API-KEY" \
  ".../api/1.0/contacts?group=0&size=200"

Nella risposta tieni quelli con stateId = 0: chi ha stateId = 1 è già diventato cliente.

Chi si è mosso in un periodo

curl -H "authorization: LA-TUA-API-KEY" \
  ".../api/1.0/contacts?startDate=01-08-2026&endDate=31-08-2026"

Il filtro agisce sull’ultima modifica. Per i contatti creati nel periodo aggiungi &byUpdateDate=false.

Scaricare tutto, a pagine

ID=""
while :; do
  URL=".../api/1.0/contacts?size=500"
  [ -n "$ID" ] && URL="$URL&lastDocument=$ID"
  R=$(curl -s -H "authorization: LA-TUA-API-KEY" "$URL")
  N=$(echo "$R" | jq '.data | length')
  [ "$N" = "0" ] && break
  echo "$R" | jq -c '.data[]'
  ID=$(echo "$R" | jq -r '.data[-1].id')
done

Prima di segmentare per settore

Normalizza le maiuscole. Nel campo sector possono convivere grafie diverse dello stesso settore (per esempio Kit e kit): se raggruppi sul valore grezzo, lo stesso settore si spacca in due.