
Stai ancora cercando una API key di HubSpot per collegare la tua integrazione API HubSpot? Smetti di cercarla. HubSpot ha eliminato le API key statiche il 30 novembre 2022, e l'attuale SDK Node (@hubspot/api-client, ora alla v14) non ne accetta più nemmeno una. La credenziale corretta per uno strumento interno a singolo account è un token di accesso di app privata, e questa guida costruisce una sincronizzazione reale tra HubSpot e uno strumento interno sia in Node sia in Python, dalla prima chiamata create contact fino a un webhook con firma verificata.
Risposta rapida: un'integrazione API HubSpot permette a uno strumento interno personalizzato di leggere e scrivere dati CRM tramite la REST API v3 di HubSpot. Per uno strumento interno a singolo account, autenticati con un token di accesso di app privata (HubSpot ha dismesso le API key nel 2022), poi sincronizza le modifiche in tempo reale con i webhook invece del polling.
Ecco cosa costruirai:
- Autenticazione con token di app privata più la tua prima chiamata
create contactin Node e Python - Un receiver webhook che valida
X-HubSpot-Signature-v3prima di fidarsi di un payload - Una sincronizzazione a prova di 429, in batch da 100, verso un record di ticketing interno o ERP
Come funziona l'integrazione API HubSpot per strumenti interni personalizzati?
Un'integrazione API HubSpot collega uno strumento interno personalizzato (un'app di ticketing, un ERP, una dashboard di fatturazione, un portale clienti) al CRM di HubSpot tramite la sua REST API v3. Il tuo strumento legge e scrive oggetti CRM (contatti, deal, aziende o oggetti personalizzati) via HTTPS con un token di accesso di app privata, e le modifiche in tempo reale rientrano tramite i webhook.
Pensa al CRM di HubSpot come a un database con cui parli via HTTP. Ogni record è un oggetto con un tipo e un ID. La integrazione crm api hubspot che stai costruendo svolge due compiti: invia dati verso HubSpot (crea un contatto quando si apre un ticket) e ne estrae dati (legge un deal quando la tua dashboard interna si aggiorna).
La sincronizzazione avviene in una di due direzioni. Una sincronizzazione unidirezionale copia le modifiche da HubSpot verso il tuo strumento, o dal tuo strumento verso HubSpot. Una sincronizzazione bidirezionale fa entrambe le cose e richiede una protezione contro i loop, che vedremo più avanti. E invece di chiedere a HubSpot "c'è qualcosa di nuovo?" ogni minuto (polling), registri un webhook così che HubSpot ti avvisi nell'istante in cui un record cambia.
Se preferisci possedere del tutto i tuoi dati piuttosto che integrare un CRM ospitato, l'auto-hosting di un CRM open source è un percorso diverso che vale la pena valutare prima di impegnarti. Ma se HubSpot è già la tua fonte di verità, l'API è il modo in cui tutto il resto ci comunica.
Per uno strumento interno a singolo account non ti servono OAuth né una scheda nel marketplace delle app. Un token di app privata e un webhook sono l'intera integrazione.
Autenticazione nel 2026: perché la API key di HubSpot non esiste più
Per l'autenticazione API HubSpot su uno strumento interno a singolo account, usa un token di accesso di app privata. È un bearer token statico che generi una volta sola nel tuo account HubSpot, con permessi limitati esattamente agli oggetti che il tuo strumento tocca. Non c'è alcun flusso di refresh né scadenza. OAuth esiste per app pubbliche multi-account, non per la dashboard che il tuo team operativo gestisce internamente.
Token di app privata vs la API key deprecata
Ecco l'insidia in cui inciampa metà degli sviluppatori che atterrano su questa SERP. HubSpot ha dismesso le API key il 30 novembre 2022, e ora non sono più supportate in alcun modo. L'autocompletamento suggerisce ancora "api key hubspot" perché l'abitudine non si è ancora aggiornata, ma non c'è nessuna chiave da recuperare. Punta invece su una app privata HubSpot: creala in Settings, assegna gli scope di cui ha bisogno e copia il token di accesso dalla scheda Auth. La panoramica sulle private app di HubSpot descrive la procedura.
| Metodo | Caso d'uso | Scade o richiede refresh? | Ideale per |
|---|---|---|---|
| API key | Rimossa | Dismessa nov. 2022 | Niente, è deprecata |
| Token di accesso di app privata | Strumento interno a singolo account | No, statico, nessun refresh | Il tuo strumento interno, l'opzione predefinita qui |
| OAuth 2.0 | App pubblica o multi-account | Sì, i token scadono dopo circa 6 ore e serve un refresh | App che pubblichi nei portali di altre aziende |
| Service Key (beta pubblica, feb. 2026) | Credenziale a livello di account, solo dati | Ambito account, secondo la documentazione | Job server solo dati, ancora in beta |
Due regole sul token stesso. Applica il principio del privilegio minimo: se il tuo strumento legge solo i deal e scrive solo i contatti, richiedi crm.objects.contacts.write e crm.objects.deals.read, niente di più. E tieni il token in una variabile d'ambiente o in un secret manager, inviato nell'header Authorization: Bearer, mai hard-coded e mai spedito al browser.
Il verdetto è semplice. Per uno strumento interno, usa un token di accesso di app privata. Passa a OAuth solo se in futuro questo diventerà un'app pubblica multi-account che altre aziende installano nei propri portali.
La tua prima chiamata API HubSpot: creare un contatto in Node e Python
La chiamata canonica di partenza è create contact, e gli SDK ufficiali la riducono a poche righe. Installa il client, inizializzalo con il tuo token di app privata preso dall'ambiente, poi crea un contatto e rileggi un deal. È lo stesso pattern che riutilizzerai per aziende, ticket e chiamate api per oggetti personalizzati hubspot, cambia solo il tipo di oggetto.
Ecco la versione Node con @hubspot/api-client (v14):
// npm i @hubspot/api-client (v14.x)
import { Client } from "@hubspot/api-client";
// Token di app privata da un secret manager o variabile d'ambiente, mai hard-coded
const hubspot = new Client({ accessToken: process.env.HUBSPOT_PRIVATE_APP_TOKEN });
// Crea un contatto
const { id } = await hubspot.crm.contacts.basicApi.create({
properties: {
email: "[email protected]",
firstname: "Ada",
lastname: "Lovelace",
lifecyclestage: "lead",
},
associations: [],
});
console.log("Created contact", id);
// Leggi un deal per ID
const deal = await hubspot.crm.deals.basicApi.getById(
"1234567890",
["dealname", "amount", "dealstage"],
);
console.log(deal.properties.dealname, deal.properties.amount);E la stessa cosa in Python con hubspot-api-client (v12):
# pip install hubspot-api-client (v12.x)
import os
from hubspot import HubSpot
from hubspot.crm.contacts import SimplePublicObjectInputForCreate
# Token di app privata dall'ambiente, non dal controllo versione
client = HubSpot(access_token=os.environ["HUBSPOT_PRIVATE_APP_TOKEN"])
# Crea un contatto
contact = client.crm.contacts.basic_api.create(
simple_public_object_input_for_create=SimplePublicObjectInputForCreate(
properties={
"email": "[email protected]",
"firstname": "Ada",
"lastname": "Lovelace",
"lifecyclestage": "lead",
}
)
)
print("Created contact", contact.id)
# Leggi un deal per ID
deal = client.crm.deals.basic_api.get_by_id(
deal_id="1234567890",
properties=["dealname", "amount", "dealstage"],
)
print(deal.properties["dealname"], deal.properties["amount"])Consiglio pratico: testa prima su una developer sandbox di HubSpot, mai in produzione. Una chiamata create malformata in produzione lascia record spazzatura reali che il tuo team commerciale dovrà ripulire. Il token, gli scope e il modello a oggetti si comportano in modo identico nella sandbox.
Come sincronizzare HubSpot con uno strumento interno in tempo reale?
Usa i webhook, non il polling. Registra una subscription webhook nella tua app privata per l'oggetto e l'evento che ti interessa (per esempio deal.propertyChange), puntala su un endpoint HTTPS che ospiti tu, e HubSpot ti invia un piccolo array JSON via POST nel momento esatto in cui avviene una modifica corrispondente. Fai polling solo quando non esiste una subscription per ciò che devi monitorare.
Il vantaggio è l'efficienza. Il polling chiede "c'è qualcosa di nuovo?" ogni minuto e brucia il tuo rate limit per farlo; un webhook ti avvisa semplicemente nell'istante in cui un deal cambia. Questa differenza conta su scala, e i webhook oggi sono uno standard, non un'eccezione: il 2025 State of the API Report di Postman, un sondaggio su oltre 5.700 sviluppatori, ha rilevato che circa metà dei team li usa.
Registra la subscription nella scheda Webhooks della tua app privata, imposta l'URL di destinazione e scegli gli eventi. HubSpot invia un array di oggetti evento, ciascuno con subscriptionType, objectId e cosa è cambiato. Ecco uno stub di receiver in Node con Express:
import express from "express";
const app = express();
// Cattura il raw body: ti servono i byte esatti per validare la firma nel prossimo passo
app.use(express.json({
verify: (req, _res, buf) => { req.rawBody = buf.toString("utf8"); },
}));
// HubSpot invia via POST un array di eventi a questo URL
app.post("/webhooks/hubspot", (req, res) => {
const events = req.body; // [{ subscriptionType: "deal.propertyChange", objectId: 1234, ... }]
for (const event of events) {
console.log("HubSpot event:", event.subscriptionType, event.objectId);
// NON fidarti ancora di questo payload. La prossima sezione lo valida prima che agiamo.
}
res.sendStatus(200);
});
app.listen(3000, () => console.log("Listening on :3000"));È qui che la costruzione passo passo diventa concreta. Immagina di sincronizzare un deal con il record ERP di un piccolo produttore: il webhook scatta, il tuo handler crea o aggiorna il ticket ERP corrispondente, e il tuo team operativo vede la modifica senza toccare HubSpot. È lo stesso approccio in tempo reale che usiamo per sincronizzare un agente vocale con un CRM, solo che qui il trigger è una modifica di proprietà invece di una telefonata. Un avvertimento: lo stub sopra si fida di qualunque cosa gli venga inviata via POST. Correggilo prima di andare in produzione.
Validare le firme dei webhook (v3) per non fidarti mai di un payload contraffatto
Valida ogni webhook in arrivo con la firma v3. HubSpot firma ogni richiesta con il tuo app secret e invia due header, X-HubSpot-Signature-v3 e X-HubSpot-Request-Timestamp. Rifiuta tutto ciò che ha più di 5 minuti, ricostruisci la stringa sorgente come method + full URL + raw body + timestamp, applicaci l'HMAC-SHA256 con l'app secret, codifica in base64 e confronta a tempo costante.
Se salti questo passaggio, chiunque indovini il tuo URL webhook può contraffare l'aggiornamento di un deal. La validazione non è opzionale. La documentazione sulla validazione delle richieste e il changelog delle firme v3 di HubSpot descrivono la ricetta esatta. Eccola come middleware Express pronto all'uso:
import crypto from "crypto";
const CLIENT_SECRET = process.env.HUBSPOT_APP_SECRET; // dalle impostazioni della tua app privata
const MAX_AGE_MS = 5 * 60 * 1000; // rifiuta tutto ciò che ha più di 5 minuti
export function validateHubSpotSignature(req, res, next) {
const signature = req.header("X-HubSpot-Signature-v3");
const timestamp = req.header("X-HubSpot-Request-Timestamp");
// 1. Rifiuta le richieste scadute (protezione dai replay)
if (!signature || !timestamp || Date.now() - Number(timestamp) > MAX_AGE_MS) {
return res.sendStatus(401);
}
// 2. Ricostruisci la stringa sorgente esatta: method + URL completo + raw body + timestamp
const uri = `https://${req.get("host")}${req.originalUrl}`;
const source = `${req.method}${uri}${req.rawBody}${timestamp}`;
// 3. HMAC-SHA256 con l'app secret, codificato in base64
const hash = crypto
.createHmac("sha256", CLIENT_SECRET)
.update(source, "utf8")
.digest("base64");
// 4. Confronto a tempo costante con l'header
const expected = Buffer.from(hash);
const received = Buffer.from(signature);
if (expected.length !== received.length ||
!crypto.timingSafeEqual(expected, received)) {
return res.sendStatus(401);
}
next();
}Lo stesso controllo come funzione Python, così entrambi gli stack sono coperti:
import base64
import hashlib
import hmac
import os
import time
CLIENT_SECRET = os.environ["HUBSPOT_APP_SECRET"].encode("utf-8")
MAX_AGE_MS = 5 * 60 * 1000 # 5 minuti
def is_valid_signature(method, uri, body, signature, timestamp):
# 1. Rifiuta le richieste scadute
if not signature or not timestamp:
return False
if int(time.time() * 1000) - int(timestamp) > MAX_AGE_MS:
return False
# 2. method + URL completo + raw body + timestamp
source = f"{method}{uri}{body}{timestamp}".encode("utf-8")
# 3. HMAC-SHA256, base64
digest = hmac.new(CLIENT_SECRET, source, hashlib.sha256).digest()
expected = base64.b64encode(digest).decode("utf-8")
# 4. Confronto a tempo costante
return hmac.compare_digest(expected, signature)L'insidia che costa un pomeriggio intero a molti: HubSpot firma l'URL di destinazione completo, schema, host e path insieme. Dietro un proxy, un load balancer o un tunnel ngrok, req.get("host") può restituire l'host interno invece di quello pubblico che HubSpot ha firmato. Se la validazione continua a fallire su un payload di cui sei certo che sia legittimo, logga l'URI esatto che hai ricostruito e confrontalo con il tuo URL webhook pubblico, carattere per carattere.
Rate limit, errori 429 e batch API: cosa abbiamo eseguito in produzione
Le app private hanno circa 10 richieste al secondo (100 ogni 10 secondi su Free/Starter, 190 ogni 10 secondi su Pro/Enterprise) con un tetto giornaliero tra 250.000 e 1.000.000. La trappola: CRM Search ha un limite separato di 4 richieste al secondo, e gli endpoint batch accettano un massimo di 100 record per richiesta. Le linee guida sull'utilizzo di HubSpot elencano i livelli.
| Livello | Per 10s | Al secondo | Tetto giornaliero | Note |
|---|---|---|---|---|
| Free / Starter (app privata) | 100 | ~10 | 250.000 | CRM Search ha un limite separato di 4 req/s |
| Pro / Enterprise (app privata) | 190 | ~19 | fino a 1.000.000 | Endpoint batch max 100 record per richiesta |
Ecco dove la teoria si è scontrata con una dashboard di staging tutta rossa. Durante un backfill questa primavera, abbiamo spinto circa 8.000 record esistenti in HubSpot da uno strumento di ticketing interno, arricchendo ciascuno con una lookup CRM Search. Usavamo @hubspot/api-client v14 sul lato Node e hubspot-api-client v12 per un worker Python di arricchimento. Le scritture bulk andavano bene. Le chiamate Search sono crollate in meno di un minuto, perché il nostro worker sparava Search a circa 15 richieste/s contro un tetto rigido di 4 richieste/s che non avevamo previsto separatamente.
Due modifiche hanno risolto il problema. Primo, un retry wrapper che legge gli header di risposta X-HubSpot-RateLimit-* e rallenta (backoff) su un 429:
// Incapsula qualunque chiamata HubSpot; riprova su 429 con backoff esponenziale
async function withRetry(fn, maxRetries = 5) {
let attempt = 0;
while (true) {
try {
return await fn();
} catch (err) {
const status = err.code ?? err.response?.status;
if (status !== 429 || attempt >= maxRetries) throw err;
// Rispetta la finestra di reset di HubSpot se l'header è presente
const headers = err.response?.headers ?? {};
const resetMs = Number(headers["x-hubspot-ratelimit-interval-milliseconds"]) || 0;
const backoff = Math.max(resetMs, 2 ** attempt * 500); // 0,5s, 1s, 2s, 4s...
console.warn(`429 hit, retry ${attempt + 1} in ${backoff}ms`);
await new Promise((r) => setTimeout(r, backoff));
attempt++;
}
}
}Secondo, abbiamo smesso di scrivere i record uno alla volta. Il batch endpoint accetta fino a 100 record per POST /crm/v3/objects/{objectType}/batch/create, quindi abbiamo suddiviso il backfill in 80 chiamate batch invece di 8.000 singole POST:
// Gli endpoint batch di HubSpot accettano al massimo 100 record per richiesta
function chunk(arr, size = 100) {
const out = [];
for (let i = 0; i < arr.length; i += size) out.push(arr.slice(i, i + size));
return out;
}
// POST /crm/v3/objects/contacts/batch/create, suddiviso in blocchi da 100
async function batchCreateContacts(records) {
for (const group of chunk(records, 100)) {
const inputs = group.map((r) => ({
properties: { email: r.email, firstname: r.firstName, lastname: r.lastName },
associations: [],
}));
await withRetry(() => hubspot.crm.contacts.batchApi.create({ inputs }));
console.log(`Wrote ${group.length} contacts`);
}
}Limitare il worker Search a 4 richieste/s e mettere in batch le scritture ha trasformato un'esecuzione che annegava nei retry in una che finiva senza intoppi. Se devi ricordare un solo numero di questa sezione, che sia 4: il tetto di CRM Search è il limite che morde in produzione, ed è quello che ogni articolo riepilogativo si dimentica di menzionare. Il vecchio tetto batch di "10 per i contatti", tra l'altro, non esiste più; oggi è 100 su tutti i tipi di oggetto.
Verso la bidirezionalità: scrivere le modifiche su HubSpot senza loop infiniti
Una sincronizzazione bidirezionale scrive le modifiche su HubSpot dal tuo strumento interno, oltre a leggerle. Il pericolo è un feedback loop: la tua scrittura di ritorno attiva proprio il webhook che ha fatto scattare il tuo handler, che scrive di nuovo, all'infinito. Evitalo con una chiave di idempotenza (salta le modifiche già applicate) e un flag di origine (ignora gli eventi in entrata causati dal tuo stesso strumento).
const processed = new Set(); // usa Redis o un vincolo univoco a livello di DB in produzione
async function writeBackToHubSpot(record) {
// Chiave di dedup: id oggetto + hash della modifica che stiamo per applicare
const key = `${record.id}:${record.updatedHash}`;
if (processed.has(key)) return; // questa esatta modifica è già stata sincronizzata
processed.add(key);
await withRetry(() =>
hubspot.crm.contacts.basicApi.update(record.id, {
// Etichetta l'origine così il webhook risultante viene ignorato dal nostro stesso receiver
// (verifica source: "internal-tool" prima di agire su un evento in entrata)
properties: { internal_status: record.status, last_sync_source: "internal-tool" },
})
);
}Il pattern è piccolo, ma saltarlo è il modo in cui una sincronizzazione raddoppia silenziosamente il tuo volume di scritture nel giro di una notte. Una volta che i dati sono puliti in entrambe le direzioni, i team spesso li instradano verso una pipeline AI SDR o un livello di reporting. Il tutorial sull'integrazione HubSpot di Nango è un riferimento solido, solo Node, se vuoi un secondo punto di vista sulla sincronizzazione bidirezionale, anche se dovrai portare tu stesso l'idea della prevenzione dei loop.
Conviene costruirla internamente o affidarsi a un partner per l'integrazione?
Costruiscila internamente quando la sincronizzazione è piccola, stabile e presidiata: un flusso unidirezionale, una manciata di oggetti e un ingegnere in grado di assorbire i breaking change di HubSpot, circa due volte l'anno. Affidati a un partner quando ti serve una sincronizzazione bidirezionale, la modellazione di oggetti personalizzati, o quando nessuno nel team può occuparsi della manutenzione continua. Il fattore decisivo raramente è la costruzione iniziale; è chi la sorveglierà tra un anno.
Ecco una checklist onesta. Costruiscila tu se: la direzione è unidirezionale, stai sincronizzando oggetti standard, hai uno sviluppatore in grado di ospitare un endpoint webhook, e qualcuno si accorgerà quando un payload inizia a fallire. Tutto ciò che hai letto sopra è il tuo progetto.
Affidati a un partner se: ti serve una sincronizzazione bidirezionale con prevenzione dei loop su più oggetti, stai modellando oggetti personalizzati con associazioni tipizzate, stai collegando più sistemi (HubSpot più un ERP più la fatturazione), oppure la persona che dovrebbe occuparsene ha già il tempo saturo. HubSpot usa un versionamento dell'API basato su date con breaking change solo circa due volte l'anno, il che sembra innocuo finché uno di questi non arriva proprio nella tua settimana più intensa e non c'è nessun responsabile. È quella coda di manutenzione, non il primo deploy, a far affondare silenziosamente le integrazioni interne. Se preferisci non doverlo gestire tu, è qui che entrano in gioco i nostri servizi di integrazione CRM personalizzata.
Punti chiave
- La API key di HubSpot non esiste più. Usa un token di accesso di app privata per uno strumento interno a singolo account; OAuth serve solo per le app pubbliche multi-account.
- Valida sempre
X-HubSpot-Signature-v3prima di fidarti di un payload webhook. Ricostruisci la stringa sorgente con l'URL di destinazione completo. - Rispetta il tetto di 4 richieste/s per CRM Search e metti in batch le scritture grandi in blocchi da 100 con un backoff sui 429.
- Preferisci i webhook al polling per la sincronizzazione in tempo reale, e un'integrazione HubSpot è solo un tassello di uno stack più ampio di strumenti IA per le aziende.
Sei bloccato sul lato manutenzione, o vuoi un secondo parere prima di andare in produzione? Prenota una consulenza gratuita per l'integrazione. Nessuna pressione in un senso o nell'altro; il codice qui sopra è comunque tuo da usare.
Informazioni sull'autore
Mert Batur Gurbuz è co-fondatore di Techsy.io, dove il team sviluppa agenti AI, sistemi di automazione e pipeline voice/SDR per clienti B2B. Studia alla University of Birmingham e scrive dello stack di strumenti LLM che il team Techsy usa davvero in produzione. Connettiti su LinkedIn.
Domande frequenti
Mi serve ancora una API key di HubSpot nel 2026?
No. HubSpot ha dismesso le API key statiche il 30 novembre 2022, e ora non sono più supportate in alcun modo. L'autocompletamento suggerisce ancora "api key hubspot" per abitudine, ma non c'è nulla da recuperare. Per uno strumento interno a singolo account, crea una app privata in Settings e usa il suo token di accesso al posto della chiave.
Qual è la differenza tra un token di app privata e OAuth per HubSpot?
Un token di accesso di app privata è una credenziale statica per un singolo account HubSpot, senza scadenza e senza flusso di refresh, ideale per uno strumento interno. OAuth 2.0 è pensato per app pubbliche multi-account che altre aziende installano nei propri portali; i suoi token scadono dopo circa sei ore e richiedono un ciclo di refresh.
Quali sono i rate limit dell'API di HubSpot nel 2026?
Le app private hanno circa 10 richieste al secondo (100 ogni 10 secondi su Free/Starter, 190 su Pro/Enterprise) con un tetto giornaliero da 250.000 a 1.000.000. L'API CRM Search ha un limite separato di 4 richieste al secondo, e gli endpoint batch accettano un massimo di 100 record per richiesta.
Come valido la firma di un webhook HubSpot?
Usa la ricetta v3: rifiuta le richieste in cui X-HubSpot-Request-Timestamp ha più di cinque minuti, poi costruisci una stringa sorgente composta da method più URL di destinazione completo più raw body più timestamp. Applicaci l'HMAC-SHA256 con il tuo app secret, codifica il risultato in base64 e confrontalo con X-HubSpot-Signature-v3 a tempo costante.
Quale SDK di HubSpot dovrei usare, Node o Python?
Entrambi sono ufficiali e mantenuti. Node usa @hubspot/api-client (v14) e Python usa hubspot-api-client (v12). Espongono lo stesso modello a oggetti CRM v3, quindi scegli quello che si adatta al tuo stack. Questa guida fornisce codice identico per autenticazione e validazione della firma in entrambi i linguaggi.
Come sincronizzo HubSpot con uno strumento interno personalizzato in tempo reale?
Registra una subscription webhook nella tua app privata per l'oggetto e l'evento che ti interessa, poi ospita un endpoint HTTPS a cui HubSpot invia una POST quando avviene una modifica corrispondente. Valida la firma, poi scrivi la modifica nel tuo strumento interno. Fai polling solo quando nessuna subscription webhook copre ciò di cui hai bisogno.
Cos'è una HubSpot Service Key e dovrei usarla?
Una Service Key è una credenziale a livello di account, solo per i dati, che HubSpot ha messo in beta pubblica a febbraio 2026. È pensata per job lato server che toccano solo i dati. Per uno strumento interno standard oggi, un token di accesso di app privata resta l'opzione predefinita più sicura e meglio documentata; considera le Service Key come beta finché non usciranno da questa fase.
Posso testare un'integrazione HubSpot senza toccare la produzione?
Sì. Crea una developer sandbox di HubSpot e puntaci il tuo token di app privata. Scope, modello a oggetti, webhook e rate limit si comportano come in produzione, quindi puoi creare contatti di test e far scattare webhook senza lasciare record spazzatura che il tuo team commerciale dovrà ripulire in seguito.
Quanti record può gestire alla volta la batch API di HubSpot?
Gli endpoint batch (POST /crm/v3/objects/{objectType}/batch/create e i suoi equivalenti update e upsert) accettano un massimo di 100 record per richiesta. Suddividi i payload più grandi in gruppi da 100. Il vecchio tetto di "10 record per i contatti" che alcuni tutorial citano ancora è stato rimosso; oggi è 100 per tutti i tipi di oggetto.
Dovrei costruirla internamente o affidarmi a un'agenzia?
Costruiscila internamente quando la sincronizzazione è unidirezionale, usa oggetti standard, e ha un responsabile in grado di assorbire i breaking change di HubSpot, due volte l'anno. Affidati a un partner per la sincronizzazione bidirezionale, la modellazione di oggetti personalizzati, o quando nessuno può occuparsi della manutenzione. Il primo deploy è facile; l'anno di manutenzione successivo è il vero costo.