Ricerca web (Keenable)
Cercare in rete e leggere pagine direttamente dal vostro codice, con la stessa chiave che usate per i modelli. Due modi per chiamarla: come un modello qualsiasi tramite /v1/chat/completions, oppure con endpoint dedicati che restituiscono JSON puro.
Quanto costa
0,005 $ a richiesta, cioè 5 $ ogni 1000 richieste.
Il prezzo è a chiamata: una chiamata è una richiesta, indipendentemente da quanti risultati tornino. Trovare 50 fonti costa quanto trovarne una.
Le richieste fallite non vengono addebitate: né un guasto della ricerca né parametri sbagliati.
| cosa | conta come |
|---|---|
| ricerca con 1 risultato | 1 richiesta |
| ricerca con 50 risultati | 1 richiesta |
| lettura di una pagina | 1 richiesta |
| errore di qualunque tipo | 0 |
Via 1 — come modello
Funziona in Cursor, Claude Code, OpenCode e in qualsiasi client OpenAI senza toccare nulla: basta scegliere il modello.
Modelli:
| modello | che cosa fa |
|---|---|
keenable/search | cerca in rete e restituisce un elenco di fonti con estratti |
keenable/read | legge una pagina e ne restituisce il testo in markdown |
Ricerca
curl https://nordrouter.com/v1/chat/completions \
-H "Authorization: Bearer $NORDROUTER_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "keenable/search",
"messages": [{"role": "user", "content": "quotazione del bitcoin oggi"}]
}'Riceverete un normale messaggio dell'assistente con l'elenco delle fonti: titolo, data di pubblicazione, indirizzo completo e un estratto per ciascuna.
Leggere una pagina
La prima parola del messaggio è l'indirizzo. Dopo potete aggiungere che cosa vi interessa esattamente di quella pagina.
curl https://nordrouter.com/v1/chat/completions \
-H "Authorization: Bearer $NORDROUTER_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "keenable/read",
"messages": [{"role": "user", "content": "https://it.wikipedia.org/wiki/Tokyo numero di abitanti"}]
}'Senza indicazione ricevete l'intera pagina in markdown. Con l'indicazione solo ciò che avete chiesto: è più veloce e sensibilmente più economico in token dalla vostra parte, quando il risultato passa a un modello.
A che serve l'indicazione
Una voce di Wikipedia sono decine di migliaia di caratteri. Se vi serve un solo numero, l'indicazione vi fa risparmiare tempo e i token del passo successivo.
Python
from openai import OpenAI
client = OpenAI(
api_key="la-vostra-chiave",
base_url="https://nordrouter.com/v1",
)
found = client.chat.completions.create(
model="keenable/search",
messages=[{"role": "user", "content": "notizie sull IA di questa settimana"}],
)
print(found.choices[0].message.content)Via 2 — endpoint dedicati
Se vi servono risultati con campi, date e filtri invece che testo discorsivo, prendete il JSON.
POST /v1/search
curl https://nordrouter.com/v1/search \
-H "Authorization: Bearer $NORDROUTER_KEY" \
-H "Content-Type: application/json" \
-d '{
"query": "notizie sulle reti neurali",
"max_results": 5,
"published_after": "7d"
}'Parametri:
| parametro | tipo | predefinito | che cosa fa |
|---|---|---|---|
query | stringa | obbligatorio | che cosa cercare |
site | stringa | — | cercare solo su questo dominio, per esempio repubblica.it |
max_results | numero | 10 | quanti risultati, da 1 a 50 |
snippet_max_chars | numero | — | lunghezza dell'estratto, da 180 a 10 000 caratteri |
published_after | stringa | — | materiale pubblicato dopo questo momento |
published_before | stringa | — | pubblicato prima |
acquired_after | stringa | — | entrato nell'indice dopo |
acquired_before | stringa | — | entrato nell'indice prima |
query_time | stringa | — | cercare nell'indice com'era in quel momento |
Le date sono accettate in tre forme: 2026-08-01, un timestamp ISO 8601 completo, oppure in forma relativa: 30min, 12h, 7d, 3mo, 1y.
Pubblicazione e indice non sono la stessa cosa
published_* filtra per la data del materiale stesso, acquired_* per la data in cui la pagina è entrata nell'indice. La differenza conta: una pagina può essere riscritta senza toccarne la data di pubblicazione. Se cercate «che cosa è comparso in rete nelle ultime 24 ore», usate acquired_after.
Risposta:
{
"query": "notizie sulle reti neurali",
"count": 5,
"results": [
{
"title": "Titolo dell articolo",
"url": "https://example.com/article",
"description": "Breve descrizione",
"snippet": "Un estratto dal testo della pagina…",
"published_at": "2026-08-25T10:30:00Z",
"acquired_at": "2026-08-25T11:02:00Z"
}
]
}GET /v1/fetch
curl -G https://nordrouter.com/v1/fetch \
-H "Authorization: Bearer $NORDROUTER_KEY" \
--data-urlencode "url=https://example.com/article" \
--data-urlencode "prompt=estrai la tabella dei prezzi"Parametri:
| parametro | tipo | predefinito | che cosa fa |
|---|---|---|---|
url | stringa | obbligatorio | indirizzo della pagina |
max_chars | numero | 50 000 | quanti caratteri restituire |
prompt | stringa | — | che cosa estrarre esattamente, fino a 2000 caratteri |
live | true / false | false | prenderla direttamente dal sito anziché dall'indice |
Risposta:
{
"url": "https://example.com/article",
"title": "Titolo",
"description": "Descrizione",
"author": "Autore",
"content": "# Testo della pagina in markdown…",
"published_at": 1787777084
}Quando serve live
Dall'indice la pagina arriva più in fretta, ma l'indice non contiene tutto. Se la pagina è recente o chiusa ai crawler, mettete live=true: verrà letta direttamente dal sito. Il prezzo è lo stesso.
Limiti
| ritmo | 2 richieste al secondo per chiave |
| lunghezza dell'estratto | da 180 a 10 000 caratteri |
| risultati per chiamata | fino a 50 |
| lunghezza dell'indicazione di lettura | fino a 2000 caratteri |
Superare il ritmo restituisce 429 con l'intestazione Retry-After: riprovate dopo un secondo.
Errori
| codice | che cosa significa | che cosa fare |
|---|---|---|
400 | manca query o url, oppure l'indirizzo è senza http:// | correggete la richiesta |
401 | chiave non accettata | controllate Authorization |
402 | credito esaurito | ricaricate dall'area personale |
429 | troppo spesso | riprovate dopo un secondo |
502 | la ricerca non ha risposto | riprovate; non è stato addebitato nulla |
503 | ricerca temporaneamente non disponibile | ce ne stiamo già occupando; non è stato addebitato nulla |
Domande frequenti
Un risultato vuoto viene addebitato? Sì, se la ricerca è stata eseguita e ha risposto onestamente «non trovato nulla»: il lavoro è stato fatto. Sono gratuiti solo gli errori.
Si può fare streaming? No, e non serve: i risultati arrivano in un blocco solo, in una frazione di secondo.
I token vengono contati? Il prezzo è a chiamata, i token non lo influenzano. Compaiono comunque nella risposta del modello perché le librerie client non la considerino vuota.
In che cosa differisce dai modelli search/…? Quelli prima cercano e poi rispondono con un modello linguistico: pagate due lavori. Qui ricevete i risultati grezzi e decidete voi che farne.