API Reference / Lead

Lead

I lead sono i contatti non ancora qualificati in cima all'imbuto. Oltre alla CRUD completa, hanno l'operazione distintiva di conversione: da un lead nascono account, contatto ed eventuale trattativa in un colpo solo.

Prima di iniziare

Envelope, errori, paginazione e advanced_filters sono comuni: vedi Introduzione alle API. Ogni richiesta richiede Authorization: Bearer <accessToken>.

01L'oggetto Lead

Ogni lead restituito dall'API ha questa forma. Le date sono stringhe ISO 8601 in UTC; i campi non leggibili dal tuo ruolo vengono omessi dalla risposta.

AttributoTipoDescrizione
idintegerIdentificativo univoco del lead.
sourcestring | nullProvenienza del lead (es. fiera, sito).
statusstringStato del lead (default new).
first_namestringNome.
last_namestring | nullCognome.
emailstring | nullEmail del lead.
phonestring | nullTelefono.
company_namestring | nullAzienda del lead.
job_titlestring | nullRuolo/mansione.
estimated_valuenumberValore stimato (default 0).
owner_user_idinteger | nullUtente proprietario del record.
assigned_user_idinteger | nullUtente assegnatario.
created_byinteger | nullUtente che ha creato il record.
updated_byinteger | nullUltimo utente che l'ha modificato.
is_deletedbooleantrue se in cestino (soft delete).
created_atstringData/ora di creazione (ISO 8601).
updated_atstringData/ora ultima modifica (ISO 8601).
json · l'oggetto Lead
{
  "id": 57,
  "source": "Fiera MECSPE",
  "status": "new",
  "first_name": "Marco",
  "last_name": "Rossi",
  "email": "m.rossi@brembotech.it",
  "phone": "+39 035 998877",
  "company_name": "Brembo Tech S.r.l.",
  "job_title": "Direttore tecnico",
  "estimated_value": 24000,
  "owner_user_id": 7,
  "assigned_user_id": 7,
  "created_by": 7,
  "updated_by": 7,
  "is_deleted": false,
  "created_at": "2026-07-07T15:24:00.000Z",
  "updated_at": "2026-07-07T15:24:00.000Z"
}

02Endpoint

MetodoPathAzioneCosa fa
GET/api/leadsreadElenco paginato e filtrabile.
GET/api/leads/:idreadUn singolo lead.
GET/api/leads/:id/historyreadStorico modifiche del record.
GET/api/leads/lookupreadOpzioni per i campi lookup (id + etichetta).
POST/api/leadscreateCrea un lead.
PATCH/api/leads/:idupdateModifica parziale.
POST/api/leads/:id/convertupdateConverte il lead in account + contatto (+ trattativa).
PATCH/api/leads/bulkupdateAggiornamento massivo.
DELETE/api/leads/:iddeleteSoft delete.
POST/api/leads/:id/restoreupdateRipristina un record eliminato.
GET/api/leads/export.csv · .xlsxexportEsporta l'elenco filtrato.
POST/api/leads/import/preview · /executecreateImport CSV.

03Elencare i lead

GET /api/leads bearer richiesto

Restituisce i lead visibili all'utente (secondo lo scope del ruolo), paginati.

Parametri query
ParametroTipoDescrizione
limitintegeropzionaleRighe per pagina. Default 50, max 200.
offsetintegeropzionaleRighe da saltare (default 0).
sort_bystringopzionaleColonna di ordinamento (es. status, estimated_value, created_at).
sort_dirstringopzionaleasc o desc.
advanced_filtersstring (JSON)opzionaleArray di condizioni: vedi Filtri avanzati.
Richiesta
curl "https://crm.tuodominio.it/api/leads?limit=2&sort_by=created_at&sort_dir=desc" \
  -H "Authorization: Bearer <accessToken>"
const res = await fetch("https://crm.tuodominio.it/api/leads?limit=2&sort_by=created_at&sort_dir=desc", {
  headers: { Authorization: `Bearer ${accessToken}` },
});
const { data } = await res.json();
Risposta · 200
json
{
  "success": true,
  "data": {
    "items": [ { "id": 57, "first_name": "Marco", "status": "new",  }, { "id": 56,  } ],
    "pagination": { "limit": 2, "offset": 0, "count": 2, "sortBy": "created_at", "sortDir": "desc" }
  }
}

04Recuperare un lead

GET /api/leads/:id bearer richiesto
Parametri path
ParametroTipoDescrizione
idintegerId del lead.
Esiti
StatoCorpo
200{ success: true, data: { …lead } }
404NOT_FOUND: inesistente o fuori dal tuo scope.

05Creare un lead

POST /api/leads bearer richiesto
Parametri body
CampoTipoNote
first_namestringrichiestoNome. 1–120 caratteri.
last_namestringopzionaleCognome. Max 120.
emailstringopzionaleEmail, validata.
phonestringopzionaleMax 40 caratteri.
company_namestringopzionaleAzienda del lead. Max 255.
job_titlestringopzionaleRuolo/mansione. Max 120.
sourcestringopzionaleProvenienza (es. fiera, sito). Max 80.
statusstringopzionaleStato del lead. Max 40.
estimated_valuenumberopzionaleValore stimato (≥ 0).
owner_user_idintegeropzionaleProprietario. Assegnabile solo a sé o a un sottoposto nella gerarchia dei ruoli (admin: chiunque). Vedi Utenti e team.
assigned_user_idintegeropzionaleUtente assegnatario.
Richiesta
curl -X POST https://crm.tuodominio.it/api/leads \
  -H "Authorization: Bearer <accessToken>" \
  -H "Content-Type: application/json" \
  -d '{ "first_name": "Marco", "last_name": "Rossi", "company_name": "Brembo Tech S.r.l.", "source": "Fiera MECSPE", "estimated_value": 24000 }'
const res = await fetch("https://crm.tuodominio.it/api/leads", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${accessToken}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ first_name: "Marco", last_name: "Rossi", company_name: "Brembo Tech S.r.l.", source: "Fiera MECSPE", estimated_value: 24000 }),
});
const { data } = await res.json();
Risposta · 201
json
{ "success": true, "data": { "id": 57, "first_name": "Marco", "status": "new", "is_deleted": false,  } }
Esiti
StatoCodiceQuando
201·Lead creato; nel corpo l'oggetto completo.
422VALIDATION_ERRORfirst_name mancante, campo fuori misura o valore picklist non valido.
403FORBIDDENCampo non scrivibile dal ruolo (nei details l'elenco dei campi negati).

06Aggiornare un lead

PATCH/api/leads/:idbearer richiesto

Modifica parziale: invia solo i campi da cambiare (gli stessi del body di creazione, tutti opzionali). Risponde 200 con l'oggetto aggiornato, 404 se fuori scope, 422 in validazione.

curl
curl -X PATCH https://crm.tuodominio.it/api/leads/57 \
  -H "Authorization: Bearer <accessToken>" \
  -H "Content-Type: application/json" \
  -d '{ "status": "qualified" }'

07Convertire un lead

POST /api/leads/:id/convert bearer richiesto

Trasforma il lead in un account e un contatto, e facoltativamente crea una trattativa. Puoi agganciarlo a un account esistente oppure lasciarne creare uno nuovo dai dati del lead, con la possibilità di sovrascrivere singoli campi.

Body · tutti i campi sono opzionali
CampoTipoDescrizione
existing_account_idintegerAggancia a un account già esistente invece di crearne uno nuovo.
create_dealbooleanSe true, crea anche una trattativa.
accountobjectOverride dei campi del nuovo account: name, email, phone, website, industry, status, owner_user_id, assigned_user_id.
contactobjectOverride dei campi del contatto creato: first_name, last_name, email, phone, job_title, owner_user_id, assigned_user_id.
dealobjectCampi della trattativa (usati con create_deal): name, stage, status, amount, close_date, owner_user_id, assigned_user_id.
Attenzione

Non passare insieme existing_account_id e gli override di account: o agganci un account esistente, o ne crei uno nuovo. Le due cose insieme danno 422.

Richiesta
curl -X POST https://crm.tuodominio.it/api/leads/57/convert \
  -H "Authorization: Bearer <accessToken>" \
  -H "Content-Type: application/json" \
  -d '{ "create_deal": true, "deal": { "name": "Fornitura 2026", "amount": 24000 } }'
const res = await fetch("https://crm.tuodominio.it/api/leads/57/convert", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${accessToken}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ create_deal: true, deal: { name: "Fornitura 2026", amount: 24000 } }),
});
const { data } = await res.json();
Risposta · 200
json
{
  "success": true,
  "data": {
    "account": { "id": 128, "name": "Brembo Tech S.r.l.",  },
    "contact": { "id": 341, "first_name": "Marco",  },
    "deal":    { "id": 88,  "name": "Fornitura 2026",  }   // null se create_deal non era true
  }
}
Esiti
StatoCodiceQuando
200·Lead convertito; nel corpo account, contact ed eventuale deal.
422VALIDATION_ERRORexisting_account_id passato insieme agli override di account, o campo non valido.
404NOT_FOUNDLead inesistente o fuori dal tuo scope.

08Eliminare e ripristinare

DELETE/api/leads/:idbearer richiesto

Soft delete: il record viene marcato eliminato (is_deleted: true), non cancellato. Risponde 200 { deleted: true, id }.

POST/api/leads/:id/restorebearer richiesto

Ripristina un lead eliminato (richiede il permesso update). Risponde 200 con l'oggetto ripristinato.

09Aggiornamento massivo

PATCH/api/leads/bulkbearer richiesto

Applica gli stessi valori a una lista di record. Gli id fuori dal tuo scope vengono saltati; la risposta riporta quanti record sono stati effettivamente aggiornati.

Body
json
{ "ids": [57, 56, 55], "changes": { "status": "qualified" } }
Risposta · 200
json
{ "success": true, "data": { "requested": 3, "updated": 2 } }

10Import ed export