Risposta rapida
Quali errori può restituire l'API LLMWebSearch e vengono addebitati?
LLMWebSearch ha sei errori HTTP: 400 invalid_parameter, 401 invalid_api_key, 402 insufficient_credits, 429 rate_limited, 502 search_failed e 504 search_timeout. Nessuno viene addebitato. Le pagine che non si riescono a leggere mostrano invece un content_status dentro un 200. Una ricerca funzionante costa 1 credito, a partire da 1,20 USD/1K ricerche a ottobre 2026. Senza KYC; paghi in criptovalute.
Quali errori HTTP esistono?
Il body è sempre {"error": {"code": "…", "message": "…"}}. Nessun errore usa un credito.
| HTTP | code | Causa | Riprovare? |
|---|---|---|---|
| 400 | invalid_parameter | Manca un parametro obbligatorio o un valore è fuori intervallo | No: correggi la richiesta |
| 401 | invalid_api_key | La chiave manca, è errata o revocata | No: controlla la chiave |
| 402 | insufficient_credits | Il saldo non può pagare questa chiamata | No: acquista un pack |
| 429 | rate_limited | Più chiamate al minuto di quelle consentite all'account | Sì, dopo una pausa |
| 502 | search_failed | La ricerca non è stata completata | Sì, con backoff |
| 504 | search_timeout | Nessun risultato di ricerca entro 30 secondi | Sì, con backoff |
In cosa è diverso lo stato di una pagina da un errore?
Lo stato di una pagina descrive un singolo risultato, non la chiamata. La ricerca è stata eseguita, i risultati ci sono e credits_used è impostato come al solito. Manca solo il contenuto di quella singola pagina, e content_status ne indica il motivo: blocked_by_robots, blocked_by_site_policy, target_refused, fetch_failed, fetch_timeout o unsupported_content.
Non trattarli come errori per cui ripetere l'intera ricerca. Usa gli altri risultati, lo snippet della pagina mancante o una fonte diversa. La pagina del formato della risposta spiega ogni stato in una tabella.
Perché non riprovi mai quando un sito rifiuta?
Perché un rifiuto è la risposta del sito, e la rispettiamo. Il nostro reader rispetta robots.txt: si presenta come LLMWebSearch, segue le regole che un sito scrive per lui o per tutti i robot, e lascia fuori il contenuto di qualsiasi pagina che non gli è permesso leggere. Un sito che imposta Content-Signal: ai-input=no nel suo robots.txt tiene le sue pagine fuori dal contenuto dei tuoi risultati. Quando un sito respinge il nostro reader con un 403, un 429 o una pagina di challenge, lo segnaliamo come target_refused con lo stato del sito in target_status.
Quando un sito respinge il nostro reader, il risultato torna senza contenuto e con lo status del sito: non risolviamo mai CAPTCHA, non accediamo agli account e non aggiriamo un blocco o un paywall. Non riproviamo nemmeno con un'altra identità o un browser camuffato. Il tuo agente non deve fare loop su una pagina così: il risultato non cambierà, e il sito ha detto no.
Quando deve riprovare il mio codice?
Solo su 429, 502 e 504. Aspetta, poi riprova, raddoppiando l'attesa ogni volta e aggiungendo un po' di casualità così i worker paralleli non riprovano in sincrono. Da tre a cinque tentativi bastano; dopo, segnala l'errore.
Non riprovare mai 400, 401 o 402: la stessa richiesta dà la stessa risposta finché non cambi qualcosa. Per le pagine, fetch_failed e fetch_timeout potrebbero funzionare più tardi, con una nuova ricerca o una chiamata /extract. target_refused, blocked_by_robots e blocked_by_site_policy sono definitivi.
import os
import random
import time
import requests
API = "https://llmwebsearch.com/api/v1/search"
HEADERS = {"Authorization": "Bearer " + os.environ["LLMWEBSEARCH_API_KEY"]}
RETRY_ON = {429, 502, 504}
def search(body, attempts=5):
delay = 1.0
for attempt in range(1, attempts + 1):
resp = requests.post(API, headers=HEADERS, json=body, timeout=60)
if resp.status_code == 200:
return resp.json()
err = resp.json().get("error", {})
if resp.status_code not in RETRY_ON or attempt == attempts:
raise RuntimeError(f"{resp.status_code} {err.get('code')}: {err.get('message')}")
time.sleep(delay + random.uniform(0, delay / 2))
delay = min(delay * 2, 30)
data = search({"q": "how to rotate api keys without downtime"})
unread = [r["url"] for r in data["results"] if r["content_status"] not in ("ok", "not_requested")]
print("credits:", data["credits_used"], "| pages not read:", unread)
Cosa devo fare su 402 insufficient_credits?
Fermati e ricarica. La chiamata non è stata eseguita e non è costata nulla. Per evitare di fermarti a metà di un lavoro lungo, controlla prima il saldo con GET https://llmwebsearch.com/api/v1/credits, che è gratuito, e confrontalo con il numero di ricerche che prevedi. Ricorda che una ricerca con read maggiore di 3 richiede 2 crediti.
I crediti vengono dai pack acquistati con il tuo saldo in criptovalute. I crediti di ricerca non hanno data di scadenza: quello che non usi questo mese è ancora lì l'anno prossimo.
Come faccio a restare sotto il rate limit?
Limita quante chiamate girano contemporaneamente nel tuo codice. Ogni account ha un limite di chiamate al minuto, mostrato nella dashboard; chiedi al supporto e può essere alzato. Un piccolo pool di worker paralleli, da quattro a otto per la maggior parte degli agenti, mantiene un ritmo costante senza picchi. Le pagine Python e Node.js mostrano ciascuna un pool di questo tipo.
Quando ricevi un 429, metti in pausa prima del tentativo successivo invece di lanciarlo subito. Riprovare immediatamente aggiunge solo altre chiamate rifiutate.
Errori: domande frequenti
Una ricerca con tutte le pagine rifiutate costa comunque un credito?
Sì, se la ricerca in sé ha funzionato: ricevi comunque i risultati classificati e gli snippet. Il prezzo di una ricerca non dipende da quante delle sue pagine è stato possibile leggere.
Un 401 è causato da una chiave revocata?
Può esserlo. Una chiave revocata, un errore di battitura, un prefisso Bearer mancante o un header che non ci è mai arrivato danno tutti 401 invalid_api_key. Crea una chiave API per agente, app o teammate e revoca qualsiasi di esse dalla dashboard senza toccare le altre.
Perché una pagina ha restituito fetch_timeout?
Le pagine vengono lette in parallelo, e una pagina che impiega più di 15 secondi viene restituita senza contenuto per non bloccare l'intera risposta. I siti lenti a volte rispondono a un tentativo successivo.
Posso vedere le mie chiamate fallite?
Sì. La cronologia della dashboard elenca le tue chiamate per 30 giorni, comprese quelle fallite, con stato e crediti. Le chiamate fallite mostrano 0 crediti.