Skip to content
Lingua: Italiano

API per sviluppatori

Limiti di richieste: tutti i limiti e header

Aggiornato il 1 novembre 2026 6 min di lettura

Quante richieste al minuto consente l’API di LinkHarbor, quanto può essere grande una richiesta, come leggere gli header e gestire bene un 429.

Per mantenere l’API veloce per tutti, LinkHarbor limita il numero di richieste al minuto. I limiti non dipendono dal tuo piano – non esiste una quota mensile di chiamate API. Questo articolo elenca tutti i limiti e mostra come il tuo codice può gestirli in modo pulito.

Come vengono contate le richieste

  • Ogni richiesta finisce esattamente in un bucket, per esempio user per le richieste autenticate o token per lo scambio del token
  • Il conteggio avviene per minuto intero (UTC); il contatore riparte da zero a ogni nuovo minuto
  • A seconda del bucket, l’API conta per workspace, per persona, per connessione o per indirizzo IP
  • Le richieste che falliscono già su token, scope o schema (401, 403 insufficient_scope, 400, 422 validation_failed dal controllo dello schema) non vengono contate; gli errori successivi come 403 feature_not_available sì

Tutti i limiti

Bucket (X-RateLimit-Bucket)LimiteContato perVale per
user600 al minutoWorkspace per i token delle chiavi API (tutte le chiavi e gli strumenti AI del workspace insieme); persona per gli accessi alla dashboardTutte le richieste autenticate a /v1 che non hanno un bucket proprio
token30 al minutoIndirizzo IPPOST /v1/token
public120 al minutoIndirizzo IPRichieste all’API senza autenticazione, come GET /v1/plans e GET /v1/pages/available
callback120 al minutoIndirizzo IPPOST /v1/callbacks/sale
internal120 al minutoIndirizzo IPURL di ingest dell’integrazione «Custom (API)» (POST /v1/ingest/{id})
mcp120 al minutoConnessione AI (token di accesso)Server MCP su /mcp
oauth300 al minutoIndirizzo IPAccesso OAuth e discovery per gli assistenti AI
auth30 al minutoIndirizzo IPLogin, registrazione, ripristino della password (dashboard e app)
refresh120 al minutoIndirizzo IPProlungamento di una sessione della dashboard
discover60 al minutoPersona, indirizzo IP se non hai effettuato l’accessoLa sezione Scopri dell’app
subs_read120 al minutoPersona, indirizzo IP se non hai effettuato l’accessoLettura delle pagine che segui (app)
subs_write20 al minutoPersona, indirizzo IP se non hai effettuato l’accessoModifica delle pagine che segui (app)

Un solo budget per workspace

Tutti i token delle chiavi API dello stesso workspace condividono le 600 richieste al minuto – indipendentemente da quante chiavi crei. Contano anche gli strumenti degli assistenti AI collegati, perché chiamano l’API internamente. Più chiavi quindi non alzano il limite. Se molto carico è distribuito su diversi programmi, pianifica tenendo conto del budget condiviso.

Gli header

X-RateLimit-Limit
Il limite al minuto del bucket, per esempio 600.
X-RateLimit-Remaining
Quante richieste restano nel minuto in corso.
X-RateLimit-Bucket
Il bucket in cui è finita la richiesta, per esempio user.
Retry-After
Solo con 429 rate_limited: secondi mancanti all’inizio del minuto successivo. Con api_key_locked, il tempo di attesa è in details.retry_after_sec.

Quando il limite è raggiunto

Una volta raggiunto il limite, l’API risponde con HTTP 429 e questo corpo. Il testo in message è nella lingua dell’account (vedi Formato degli errori API), qui in inglese. Basati sul codice rate_limited:

Risposta per 429
HTTP/1.1 429 Too Many Requests
Retry-After: 37
X-RateLimit-Limit: 600
X-RateLimit-Remaining: 0
X-RateLimit-Bucket: user

{ "error": "rate_limited", "message": "Too many requests. Please try again in a moment.", "retry_after_sec": 37 }
  1. Leggi Retry-After o retry_after_sec
  2. Attendi almeno quei secondi, più un po’ di casualità, così che non tutti i processi ripartano nello stesso momento
  3. Ripeti la richiesta al massimo qualche volta
  4. Se continui a ricevere 429, distribuisci il lavoro su un periodo più lungo
Node.js: token in cache e gestione del 429
const BASE = 'https://dock.at-harbor.com';
let cached = null; // { token, expiresAt }

async function getToken() {
  if (cached && Date.now() < cached.expiresAt - 60_000) return cached.token;
  const res = await fetch(BASE + '/v1/token', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      key_id: process.env.LH_KEY_ID,
      key_secret: process.env.LH_KEY_SECRET,
    }),
  });
  if (!res.ok) throw new Error('Token exchange failed: HTTP ' + res.status);
  const data = await res.json();
  cached = { token: data.token, expiresAt: Date.now() + data.expires_in * 1000 };
  return cached.token;
}

async function lh(method, path, body, attempt = 0) {
  const headers = { Authorization: 'Bearer ' + (await getToken()) };
  if (body !== undefined) headers['Content-Type'] = 'application/json';

  const res = await fetch(BASE + path, {
    method,
    headers,
    body: body === undefined ? undefined : JSON.stringify(body),
  });

  if (res.status === 429 && attempt < 3) {
    const wait = Number(res.headers.get('Retry-After') ?? 5);
    await new Promise((r) => setTimeout(r, (wait + Math.random() * 2) * 1000));
    return lh(method, path, body, attempt + 1);
  }
  if (res.status === 401 && attempt === 0) {
    cached = null; // token scaduto – riprova una volta con un nuovo token
    return lh(method, path, body, attempt + 1);
  }
  const data = await res.json().catch(() => null);
  if (!res.ok) throw new Error((data && data.error) + ' (HTTP ' + res.status + ')');
  return data;
}

// Esempio: const { items } = await lh('GET', '/v1/pages');

Consigli per grandi quantità di dati

  • Tieni il token in cache e rinnovalo solo poco prima che scada dopo 15 minuti
  • Tieni d’occhio X-RateLimit-Remaining e rallenta quando il valore si abbassa
  • Invia le richieste una dopo l’altra invece che su decine di connessioni parallele
  • Carica gli elenchi una volta e filtrali in locale invece di interrogare ogni pagina singolarmente
  • Distribuisci le sincronizzazioni grandi su più minuti
  • Ripeti gli errori 5xx con pause crescenti, ma non gli errori 4xx

Altri limiti

CosaLimiteRisposta
Accessi fallitiBlocco dopo 5, 10 e 20 tentativi falliti per indirizzo e-mail e IP: 60 secondi, 5 minuti, 30 minuti429 account_locked
Invii dei moduli10 all’ora per indirizzo IP, su tutti i moduli429 form_rate_limited

I tentativi falliti nello scambio del token bloccano temporaneamente chiave e IP, vedi Chiavi API e token di accesso. Le notifiche push le invii solo dalla dashboard; i loro limiti sono spiegati in Follower e notifiche push.

I limiti di contenuto del tuo piano – pagine, link, blocchi, link brevi e così via – non sono limiti di richieste ma tetti fissi. Sono elencati in Piani a confronto.

Dimensione della richiesta

Ogni corpo viene misurato prima che l’API lo legga. Quanto può essere grande dipende dall’endpoint:

EndpointCorpo massimo
Login, registrazione e le altre chiamate non autenticate sotto /v1/auth, POST /v1/token, POST /v1/oauth/exchange, gli endpoint OAuth per gli assistenti AI sotto /oauth e il relativo consenso, POST /v1/ingest/{id}, il checkout del blocco Sostieni, le chiamate di iscrizione dell’app (pagine seguite, collezioni, dispositivi push), il cambio di workspace, POST /v1/auth/logout-all, l’eliminazione di un account, la configurazione dell’autenticazione a due fattori, l’accettazione di un invito, l’attivazione del programma «Consiglia e guadagna» e il passaggio di ritorno quando colleghi un’integrazione64 KB
Tutti gli altri endpoint JSON, compreso l’invio di un modulo su una pagina1 MB
POST /v1/webhooks/{id}/verify-signature e il server MCP su /mcp2 MB
Caricamento di file (POST /v1/assets e POST /v1/pages/{id}/uploads, multipart/form-data)11 MB per l’intera richiesta, il file stesso al massimo 10 MB

Se il corpo è più grande, l’API risponde con 413 request_too_large; details.max_bytes e details.max_kb indicano il limite. Un file troppo grande in un caricamento porta a 413 payload_too_large. Gli endpoint senza corpo, come le chiamate DELETE, non accettano alcun corpo oppure solo {}.

Risposta per 413
HTTP/1.1 413 Payload Too Large

{ "error": "request_too_large", "message": "…", "details": { "max_bytes": 65536, "max_kb": 64 }, "request_id": "…" }

Ci sono limiti anche all’interno del corpo: ogni testo ha una lunghezza massima, ogni elenco un numero massimo di voci, e i campi sconosciuti vengono rifiutati. I valori sono elencati per endpoint nel riferimento dell’API. Una violazione porta a 422 validation_failed, e details indica campo, regola e limite. Percorso e query string di una richiesta possono essere lunghi insieme al massimo 16 KB.

Non hai trovato nulla?

Dicci di cosa hai bisogno e il nostro team di assistenza ti aiuterà personalmente.

Contatta l’assistenza