Documentazione API
API REST e webhook di Coonvert · versione v1
Cosa si può fare
Con l'API colleghi Coonvert al tuo CRM. Puoi:
- leggere i lead, anche solo quelli cambiati dall'ultima volta;
- creare lead raccolti altrove (campagne, telefono, altri siti);
- aggiornare stato, valore e campi personalizzati di un lead quando il commerciale lo lavora;
- ricevere i nuovi lead e le modifiche in tempo reale con i webhook.
API e webhook sono inclusi nel piano Agency. Ogni token vale per un solo account: se gestisci più clienti, crea un token dentro ogni cliente.
Primo passo: il token
- Entra nel pannello e apri l'account (o il cliente) da collegare.
- Vai su Account → API e crea un token. Copialo subito: non sarà più mostrato.
- Prova il token:
curl https://coonvert.com/api/v1/user \
-H "Authorization: Bearer $COONVERT_TOKEN" \
-H "Accept: application/json"Risposta
{
"id": 57,
"name": "Mario Rossi",
"email": "mario.rossi@example.com",
"role": "owner"
}Il token agisce con i permessi del suo utente. Per leggere e modificare i lead l'utente deve poter vedere i dati dei lead nell'account del token.
Autenticazione e indirizzo
Tutte le chiamate partono da questo indirizzo:
https://coonvert.com/api/v1Manda il token in ogni richiesta, con queste intestazioni:
Authorization: Bearer <token>
Accept: application/json
Content-Type: application/jsonCorpi e risposte sono in JSON (UTF-8). Le date sono in formato ISO 8601 e in UTC, ad esempio 2026-10-27T16:40:00+00:00. Un token mancante o revocato risponde 401.
Il lead
L'API restituisce il lead sempre in questa forma, uguale a quella dei webhook.
{
"id": 4821,
"name": "Mario Rossi",
"email": "mario.rossi@example.com",
"phone": "+393331234567",
"page": "Consulenza gratuita",
"page_id": 312,
"form_id": null,
"status": "convertito",
"valore": 1250.5,
"convertito_at": "2026-10-27T16:40:00+00:00",
"source": "form",
"source_detail": null,
"data": {
"messaggio": "Vorrei un preventivo per il mio ristorante"
},
"utm": {
"source": "facebook",
"medium": "cpc",
"campaign": "autunno-2026",
"term": null,
"content": null
},
"gruppi": [
"Caldi"
],
"campi": {
"budget": 5000,
"settore": "Ristorazione"
},
"created_at": "2026-10-25T09:12:30+00:00",
"updated_at": "2026-10-27T16:40:00+00:00",
"utm_source": "facebook",
"utm_campaign": "autunno-2026"
}| Campo | Tipo | Significato |
|---|---|---|
id | numero | Identificativo del lead. Usalo come chiave nel CRM. |
name, email, phone | testo o null | Dati del contatto. C'è sempre almeno l'email o il telefono. |
page | testo o null | Titolo della pagina da cui è arrivato. |
page_id | numero o null | Id della pagina (vedi GET /pages). |
form_id | numero o null | Id del form esterno da cui è arrivato. |
status | testo | Stato di lavorazione, vedi sotto. |
valore | numero o null | Valore in euro della vendita (es. 1250.5). Esiste solo per i lead convertiti. |
convertito_at | data o null | Quando è diventato convertito l'ultima volta. |
source | testo | Provenienza: form, meta, api, pagamento, manuale, form_esterno, email, webhook, importazione. I lead creati con l'API hanno sempre api. |
source_detail | testo o null | Provenienza leggibile, es. «Google Ads – campagna primavera». |
data | oggetto o null | Gli altri campi inviati col form (o custom nel POST). |
utm | oggetto | source, medium, campaign, term, content (ognuno testo o null). |
gruppi | lista di testi | Nomi dei gruppi del lead, in ordine alfabetico. Vuota se non ne ha. |
campi | oggetto | Campi personalizzati, per chiave. Solo i campi che esistono oggi nell'account. |
created_at, updated_at | data | Creazione e ultima modifica. updated_at cambia anche quando cambiano gruppi o richiamo. |
utm_source, utm_campaign | testo o null | Deprecati: restano per compatibilità, usa utm. Non ci sono nei webhook. |
Stati possibili
| Valore | Nel pannello |
|---|---|
nuovo | Nuovo |
contattato | Contattato |
qualificato | Qualificato |
convertito | Convertito (chiude il lead) |
perso | Perso (chiude il lead) |
falso_duplicato | Falso/Duplicato (chiude il lead) |
Uno stato che chiude il lead toglie il richiamo in programma. Diventando convertito si aggiorna convertito_at.
Campi personalizzati e gruppi
I campi personalizzati si creano nel pannello in Lead & Analisi → Campi personalizzati. Ogni campo ha una chiave (es. budget) e un tipo. Nei corpi JSON il valore segue il tipo:
| Tipo | Valore |
|---|---|
| Testo | testo, massimo 255 caratteri |
| Testo lungo | testo, massimo 5000 caratteri |
| Numero | numero |
| Data | testo AAAA-MM-GG, es. 2026-11-15 |
| Scelta | una delle opzioni del campo, scritta uguale |
| Sì/No | true o false |
Un valore vuoto (null o "") toglie il campo dal lead. Una chiave che non esiste risponde 422 con l'elenco delle chiavi valide. I gruppi si leggono soltanto: si assegnano dal pannello.
Endpoint
I percorsi qui sotto si aggiungono all'indirizzo https://coonvert.com/api/v1.
GET/leads
Elenco dei lead, a pagine. Senza filtri parte dal più recente.
| Parametro | Significato |
|---|---|
updated_since | Solo i lead con updated_at uguale o successivo a questa data (ISO 8601). Ordina dal meno recente: è il filtro per la sincronizzazione. |
created_since | Solo i lead creati da questa data in poi (ISO 8601). |
status | Uno degli stati. |
page_id, form_id | Solo i lead di quella pagina o di quel form. |
per_page | Lead per pagina, da 1 a 100. Predefinito 50. |
page | Numero della pagina, da 1. |
Ordine: con updated_since per updated_at crescente, poi id crescente; senza, per data di creazione decrescente, poi id decrescente. Un parametro non valido risponde 422.
curl -G https://coonvert.com/api/v1/leads \
-H "Authorization: Bearer $COONVERT_TOKEN" \
-H "Accept: application/json" \
--data-urlencode "status=convertito" \
--data-urlencode "per_page=100"Risposta
{
"data": [
{
"id": 4821,
"name": "Mario Rossi",
"email": "mario.rossi@example.com",
"phone": "+393331234567",
"page": "Consulenza gratuita",
"page_id": 312,
"form_id": null,
"status": "convertito",
"valore": 1250.5,
"convertito_at": "2026-10-27T16:40:00+00:00",
"source": "form",
"source_detail": null,
"data": {
"messaggio": "Vorrei un preventivo per il mio ristorante"
},
"utm": {
"source": "facebook",
"medium": "cpc",
"campaign": "autunno-2026",
"term": null,
"content": null
},
"gruppi": [
"Caldi"
],
"campi": {
"budget": 5000,
"settore": "Ristorazione"
},
"created_at": "2026-10-25T09:12:30+00:00",
"updated_at": "2026-10-27T16:40:00+00:00",
"utm_source": "facebook",
"utm_campaign": "autunno-2026"
}
],
"links": {
"first": "https://coonvert.com/api/v1/leads?per_page=100&status=convertito&page=1",
"last": "https://coonvert.com/api/v1/leads?per_page=100&status=convertito&page=3",
"prev": null,
"next": "https://coonvert.com/api/v1/leads?per_page=100&status=convertito&page=2"
},
"meta": {
"current_page": 1,
"from": 1,
"last_page": 3,
"links": [
{
"url": null,
"label": "« Previous",
"page": null,
"active": false
},
{
"url": "https://coonvert.com/api/v1/leads?per_page=100&status=convertito&page=1",
"label": "1",
"page": 1,
"active": true
},
{
"url": "https://coonvert.com/api/v1/leads?per_page=100&status=convertito&page=2",
"label": "Next »",
"page": 2,
"active": false
}
],
"path": "https://coonvert.com/api/v1/leads",
"per_page": 100,
"to": 1,
"total": 201
}
}links.next è null sull'ultima pagina. meta.total è il numero totale dei lead che corrispondono ai filtri.
Errori possibili: 401, 403, 422, 429.
Sincronizzazione incrementale
Per tenere il CRM allineato senza rileggere tutto:
- Salva l'
updated_atdell'ultimo lead che hai letto (la prima volta usa una data lontana, es.2020-01-01T00:00:00Z). - Chiedi
GET /leads?updated_since=<quel valore>&per_page=100. - Per ogni lead: se nel CRM c'è già lo stesso
idaggiornalo, altrimenti crealo. Deduplica sempre perid: il filtro include il valore indicato, quindi l'ultimo lead della volta prima torna anche questa volta. - Salva l'
updated_atdell'ultimo lead ricevuto e richiedi di nuovo la prima pagina da lì. Ripeti finché ricevi meno di 100 lead. - Solo se tutti i 100 lead hanno lo stesso
updated_at(es. dopo una modifica di massa) passa apage=2,page=3… con lo stesso valore, finché l'updated_atcambia.
Ripartire ogni volta dalla prima pagina evita di saltare lead che cambiano mentre stai leggendo. Nella query string il + del fuso va codificato (%2B): con cURL usa --data-urlencode.
curl -G https://coonvert.com/api/v1/leads \
-H "Authorization: Bearer $COONVERT_TOKEN" \
-H "Accept: application/json" \
--data-urlencode "updated_since=2026-10-27T16:40:00+00:00" \
--data-urlencode "per_page=100"Esempio in JavaScript (Node 18+)
async function sincronizza(cursore, salvaLead, salvaCursore) {
let pagina = 1;
for (;;) {
const url = new URL('https://coonvert.com/api/v1/leads');
url.search = new URLSearchParams({ updated_since: cursore, per_page: '100', page: String(pagina) });
const risposta = await fetch(url, {
headers: { Authorization: `Bearer ${process.env.COONVERT_TOKEN}`, Accept: 'application/json' },
});
if (!risposta.ok) throw new Error(`Coonvert ha risposto ${risposta.status}`);
const { data } = await risposta.json();
for (const lead of data) await salvaLead(lead); // crea o aggiorna per lead.id
if (data.length === 0) return cursore;
const ultimo = data[data.length - 1].updated_at;
if (data.length < 100) { await salvaCursore(ultimo); return ultimo; } // finito
if (ultimo === cursore) { pagina++; continue; } // tutta la pagina con lo stesso istante
cursore = ultimo;
pagina = 1;
await salvaCursore(cursore);
}
}L'API non segnala i lead eliminati. Se ti servono gli aggiornamenti in tempo reale usa i webhook e tieni la sincronizzazione come controllo periodico.
GET/leads/{id}
Un lead solo.
curl https://coonvert.com/api/v1/leads/4821 \
-H "Authorization: Bearer $COONVERT_TOKEN" \
-H "Accept: application/json"Risposta
{
"data": {
"id": 4821,
"name": "Mario Rossi",
"email": "mario.rossi@example.com",
"phone": "+393331234567",
"page": "Consulenza gratuita",
"page_id": 312,
"form_id": null,
"status": "convertito",
"valore": 1250.5,
"convertito_at": "2026-10-27T16:40:00+00:00",
"source": "form",
"source_detail": null,
"data": {
"messaggio": "Vorrei un preventivo per il mio ristorante"
},
"utm": {
"source": "facebook",
"medium": "cpc",
"campaign": "autunno-2026",
"term": null,
"content": null
},
"gruppi": [
"Caldi"
],
"campi": {
"budget": 5000,
"settore": "Ristorazione"
},
"created_at": "2026-10-25T09:12:30+00:00",
"updated_at": "2026-10-27T16:40:00+00:00",
"utm_source": "facebook",
"utm_campaign": "autunno-2026"
}
}Errori possibili: 401, 403, 404 (inesistente o di un altro account), 429.
POST/leads
Crea un lead. Serve almeno email o phone. La provenienza (source) è sempre api.
| Campo | Significato |
|---|---|
name | Nome, massimo 255 caratteri. |
email | Email valida. Obbligatoria se manca il telefono. |
phone | Telefono, massimo 50 caratteri. Obbligatorio se manca l'email. |
page_id | Facoltativo. Una pagina pubblicata dell'account. |
form_id | Facoltativo. Un form esterno dell'account. Non insieme a page_id. |
source_detail | Facoltativo. Provenienza leggibile, massimo 255 caratteri. |
campi | Facoltativo. Campi personalizzati, come nel PATCH. |
custom | Facoltativo. Oggetto libero, finisce in data. |
utm_source, utm_medium, utm_campaign, utm_term, utm_content | Facoltativi, massimo 255 caratteri. |
Ci sono tre modi:
- Senza pagina né form: un lead dell'account. Lo ricevono i destinatari generali dei nuovi lead; nessuna risposta automatica.
- Con
page_id: come se arrivasse dal form della pagina, con la sua risposta automatica. - Con
form_id: come se arrivasse da quel form esterno: destinatari, risposta automatica e automazioni del form. L'id del form si legge nell'indirizzo della sua scheda in Lead & Analisi → Form.
In tutti e tre i casi il lead entra nelle automazioni con sorgente «API» e manda il webhook lead.created.
Senza pagina né form
curl -X POST https://coonvert.com/api/v1/leads \
-H "Authorization: Bearer $COONVERT_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: crm-contatto-98765" \
-d '{
"name": "Mario Rossi",
"email": "mario.rossi@example.com",
"phone": "+393331234567",
"source_detail": "Google Ads – campagna primavera",
"utm_source": "google",
"utm_campaign": "primavera",
"campi": { "budget": 5000 }
}'Con una pagina
curl -X POST https://coonvert.com/api/v1/leads \
-H "Authorization: Bearer $COONVERT_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{ "page_id": 312, "name": "Mario Rossi", "email": "mario.rossi@example.com" }'Con un form esterno
curl -X POST https://coonvert.com/api/v1/leads \
-H "Authorization: Bearer $COONVERT_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{ "form_id": 18, "name": "Mario Rossi", "phone": "+393331234567" }'Risposta (201)
{
"data": {
"id": 4821,
"name": "Mario Rossi",
"email": "mario.rossi@example.com",
"phone": "+393331234567",
"page": null,
"page_id": null,
"form_id": null,
"status": "nuovo",
"valore": null,
"convertito_at": null,
"source": "api",
"source_detail": "Google Ads – campagna primavera",
"data": null,
"utm": {
"source": "google",
"medium": null,
"campaign": "primavera",
"term": null,
"content": null
},
"gruppi": [],
"campi": {
"budget": 5000
},
"created_at": "2026-10-28T09:30:00+00:00",
"updated_at": "2026-10-28T09:30:00+00:00",
"utm_source": "google",
"utm_campaign": "primavera"
}
}Errori possibili: 401, 402 (limite dei lead del piano raggiunto), 403, 404 (pagina non pubblicata, form inesistente o di un altro account, oppure pagine dell'account sospese), 409, 422, 429. Per non creare doppioni nei tentativi vedi l'idempotenza.
PATCH/leads/{id}
Aggiorna un lead dal CRM. Tutti i campi sono facoltativi, ma ne serve almeno uno:
status: uno degli stati;valore: euro come numero JSON (es.1250.50, massimo999999999.99), oppurenullper toglierlo. Solo su un lead che è giàconvertitoo lo diventa nella stessa richiesta;campi: oggetto{chiave: valore}. Si uniscono a quelli che il lead ha già; un valore vuoto toglie il campo.
Nome, email e telefono non si modificano via API. L'effetto è lo stesso di una modifica dal pannello: la cronologia del lead registra il cambio di stato «via API», uno stato chiuso toglie il richiamo, le automazioni che si fermano su quello stato fanno uscire il lead e parte il webhook lead.updated. Se non cambia niente non succede niente: puoi ripetere la stessa richiesta senza effetti doppi.
curl -X PATCH https://coonvert.com/api/v1/leads/4821 \
-H "Authorization: Bearer $COONVERT_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{ "status": "convertito", "valore": 1250.50, "campi": { "settore": "Ristorazione" } }'Risposta
{
"data": {
"id": 4821,
"name": "Mario Rossi",
"email": "mario.rossi@example.com",
"phone": "+393331234567",
"page": "Consulenza gratuita",
"page_id": 312,
"form_id": null,
"status": "convertito",
"valore": 1250.5,
"convertito_at": "2026-10-27T16:40:00+00:00",
"source": "form",
"source_detail": null,
"data": {
"messaggio": "Vorrei un preventivo per il mio ristorante"
},
"utm": {
"source": "facebook",
"medium": "cpc",
"campaign": "autunno-2026",
"term": null,
"content": null
},
"gruppi": [
"Caldi"
],
"campi": {
"budget": 5000,
"settore": "Ristorazione"
},
"created_at": "2026-10-25T09:12:30+00:00",
"updated_at": "2026-10-27T16:40:00+00:00",
"utm_source": "facebook",
"utm_campaign": "autunno-2026"
}
}Valore su un lead non convertito (422)
{
"message": "Il valore si imposta solo su un lead convertito.",
"errors": {
"valore": [
"Il valore si imposta solo su un lead convertito."
]
}
}Errori possibili: 401, 403 (ruolo senza permesso di modifica, o account in sola lettura), 404, 422, 429.
GET/pages
Le pagine dell'account, dalla più recente, a pagine come /leads (per_page da 1 a 100, predefinito 50; page). Serve a trovare il page_id.
curl -G https://coonvert.com/api/v1/pages \
-H "Authorization: Bearer $COONVERT_TOKEN" \
-H "Accept: application/json" \
--data-urlencode "per_page=100"Risposta
{
"data": [
{
"id": 312,
"title": "Consulenza gratuita",
"slug": "consulenza-gratuita",
"status": "pubblicata",
"published_at": "2026-10-01T08:00:00+00:00",
"created_at": "2026-09-28T14:05:10+00:00"
}
],
"links": {
"first": "https://coonvert.com/api/v1/pages?per_page=100&page=1",
"last": "https://coonvert.com/api/v1/pages?per_page=100&page=3",
"prev": null,
"next": "https://coonvert.com/api/v1/pages?per_page=100&page=2"
},
"meta": {
"current_page": 1,
"from": 1,
"last_page": 3,
"links": [
{
"url": null,
"label": "« Previous",
"page": null,
"active": false
},
{
"url": "https://coonvert.com/api/v1/pages?per_page=100&page=1",
"label": "1",
"page": 1,
"active": true
},
{
"url": "https://coonvert.com/api/v1/pages?per_page=100&page=2",
"label": "Next »",
"page": 2,
"active": false
}
],
"path": "https://coonvert.com/api/v1/pages",
"per_page": 100,
"to": 1,
"total": 201
}
}status è bozza o pubblicata. Errori possibili: 401, 403, 422, 429.
GET/pages/{id}
curl https://coonvert.com/api/v1/pages/312 \
-H "Authorization: Bearer $COONVERT_TOKEN" \
-H "Accept: application/json"Risposta
{
"data": {
"id": 312,
"title": "Consulenza gratuita",
"slug": "consulenza-gratuita",
"status": "pubblicata",
"published_at": "2026-10-01T08:00:00+00:00",
"created_at": "2026-09-28T14:05:10+00:00"
}
}Errori possibili: 401, 403, 404, 429.
GET/user
L'utente del token: utile per controllare che il token funzioni (vedi Primo passo). Risponde id, name, email, role, senza data attorno.
Webhook
Con i webhook Coonvert chiama il tuo indirizzo quando succede qualcosa. Si configurano in Account → Webhook: indirizzo HTTPS pubblico, eventi da ricevere e un secret per la firma.
| Evento | Quando | Corpo |
|---|---|---|
lead.created | Arriva un lead nuovo, da qualunque fonte (anche dall'API). | Il lead. |
lead.updated | Cambiano stato, nome, email, telefono, valore o campi personalizzati; cambiano anche le note, che l'evento segnala ma non fanno parte del lead nel corpo. Gruppi e richiami no. | Il lead più origine. |
page.published | Una pagina viene pubblicata. | id, title, slug, status, published_at. |
La richiesta è un POST con il JSON nel corpo, senza involucro: il corpo è direttamente il lead (o la pagina). Il lead ha la stessa forma dell'API, senza i campi deprecati utm_source e utm_campaign. Intestazioni:
Content-Type: application/json
X-Coonvert-Event: lead.updated
X-Coonvert-Signature: sha256=<HMAC-SHA256 del corpo con il secret, in esadecimale>Corpo di lead.updated
{
"id": 4821,
"name": "Mario Rossi",
"email": "mario.rossi@example.com",
"phone": "+393331234567",
"page": "Consulenza gratuita",
"page_id": 312,
"form_id": null,
"status": "convertito",
"valore": 1250.5,
"convertito_at": "2026-10-27T16:40:00+00:00",
"source": "form",
"source_detail": null,
"data": {
"messaggio": "Vorrei un preventivo per il mio ristorante"
},
"utm": {
"source": "facebook",
"medium": "cpc",
"campaign": "autunno-2026",
"term": null,
"content": null
},
"gruppi": [
"Caldi"
],
"campi": {
"budget": 5000,
"settore": "Ristorazione"
},
"created_at": "2026-10-25T09:12:30+00:00",
"updated_at": "2026-10-27T16:40:00+00:00",
"origine": "coonvert"
}Il pulsante «Test» del pannello manda invece {"test": true, "message": "Evento di test da Coonvert"}.
Verificare la firma
Calcola l'HMAC-SHA256 del corpo così come è arrivato (prima di decodificare il JSON) e confrontalo con l'intestazione in tempo costante.
PHP
<?php
$secret = getenv('COONVERT_WEBHOOK_SECRET');
$corpo = file_get_contents('php://input');
$firma = $_SERVER['HTTP_X_COONVERT_SIGNATURE'] ?? '';
$attesa = 'sha256=' . hash_hmac('sha256', $corpo, $secret);
if (! hash_equals($attesa, $firma)) {
http_response_code(401);
exit;
}
$evento = $_SERVER['HTTP_X_COONVERT_EVENT'] ?? '';
$lead = json_decode($corpo, true);
// ... salva il lead, poi rispondi 2xx
http_response_code(200);Node (Express)
const crypto = require('crypto');
const express = require('express');
const app = express();
app.post('/coonvert', express.raw({ type: 'application/json' }), (req, res) => {
const attesa = Buffer.from(
'sha256=' + crypto.createHmac('sha256', process.env.COONVERT_WEBHOOK_SECRET).update(req.body).digest('hex')
);
const firma = Buffer.from(req.get('X-Coonvert-Signature') || '');
if (firma.length !== attesa.length || !crypto.timingSafeEqual(firma, attesa)) {
return res.sendStatus(401);
}
const evento = req.get('X-Coonvert-Event');
const lead = JSON.parse(req.body.toString('utf8'));
// ... salva il lead
res.sendStatus(200);
});Tentativi
Una consegna riesce se il tuo indirizzo risponde con un codice 2xx entro 10 secondi. Altrimenti Coonvert riprova: al massimo 3 tentativi in tutto, il secondo dopo circa 10 secondi e il terzo dopo circa 1 minuto. Le consegne fallite restano in Account → Webhook con il motivo e si possono rispedire. Rispondi subito e fai il lavoro lungo dopo; lo stesso evento può arrivare più di una volta, quindi riconoscilo per id e updated_at.
Il campo origine: niente eco
Se il tuo CRM aggiorna un lead con il PATCH, Coonvert manda anche a te il lead.updated di quella modifica. Per non riapplicarla (e rimandarla, in un giro senza fine) guarda origine:
"api": la modifica è arrivata dall'API, quindi probabilmente da te. Puoi ignorarla."coonvert": la modifica è nata in Coonvert (pannello, automazioni). Applicala al CRM.
origine c'è solo in lead.updated. Se più sistemi usano l'API sullo stesso account, confronta anche i valori con quelli che hai già prima di scartare l'evento.
Limiti, errori, idempotenza
Limite di richieste
Ogni token può fare 120 richieste al minuto. Ogni risposta indica il limite e quante richieste restano:
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 119Oltre il limite la risposta è 429 con l'intestazione Retry-After (secondi da aspettare). Aspetta quel tempo e riprova.
Errori
Gli errori sono sempre JSON con un message in italiano. Gli errori di validazione (422) hanno anche errors, con i messaggi per campo:
{
"message": "Indica una pagina oppure un form, non entrambi.",
"errors": {
"page_id": [
"Indica una pagina oppure un form, non entrambi."
]
}
}| Codice | Quando | Messaggio |
|---|---|---|
401 | Token mancante, sbagliato o revocato. | Token mancante o non valido. |
402 | POST /leads oltre il limite dei lead del piano. | Limite lead del piano raggiunto. |
403 | Il piano non include l'API. | Questa funzione non è inclusa nel tuo piano. |
| L'utente del token non ha più accesso all'account. | Il token non ha più accesso a questo account. | |
| Il ruolo dell'utente non mostra i dati dei lead. | Il tuo ruolo non permette di vedere i dati dei lead. | |
PATCH con un ruolo che non modifica i lead. | Il tuo ruolo non permette di modificare i lead. | |
PATCH su un cliente in attesa di decisione. | Questo account è in sola lettura. | |
404 | Risorsa inesistente o di un altro account; nel POST anche pagina non pubblicata o pagine dell'account sospese. | Risorsa non trovata. |
405 | Metodo non previsto per quell'indirizzo (ad esempio DELETE su un lead). L'intestazione Allow elenca i metodi ammessi. | Metodo non supportato. |
409 | Due POST insieme con la stessa Idempotency-Key. | Richiesta concorrente in corso con la stessa Idempotency-Key, riprova. |
422 | Dati non validi (il messaggio dipende dal campo). | es. Lo stato indicato non esiste. |
valore su un lead non convertito. | Il valore si imposta solo su un lead convertito. | |
page_id e form_id insieme. | Indica una pagina oppure un form, non entrambi. | |
429 | Troppe richieste. | Troppe richieste: riprova tra N secondi. |
Idempotenza
Un POST /leads ripetuto (timeout, rete che cade) può creare due lead uguali. Per evitarlo manda l'intestazione Idempotency-Key con un valore unico per ogni lead, ad esempio l'id del contatto nel tuo CRM (massimo 255 caratteri).
Per 24 ore la stessa chiave restituisce il lead già creato invece di crearne un altro. Se la prima richiesta è fallita (es. 402) non resta nulla: puoi riprovare con la stessa chiave. Il PATCH non ne ha bisogno: ripetuto, non cambia niente.
Novità e compatibilità
Da ottobre 2026:
GET /pagesè a pagine eGET /leadsrisponde condata,linksemeta: il totale è inmeta.totale non più in cima alla risposta. Chi legge solodatadella prima pagina non deve cambiare niente.- Il lead ha la forma completa dei webhook.
utm_sourceeutm_campaignrestano ma sono deprecati: usautm. - Nuovi: i filtri di
GET /leads,PATCH /leads/{id},POST /leadssenza pagina o con un form, il limite di 120 richieste al minuto eorigineinlead.updated.