Busca na web (Keenable)
Pesquisar na internet e ler páginas direto do seu código, com a mesma chave que você usa para os modelos. Funciona de dois jeitos: como um modelo comum via /v1/chat/completions ou por endpoints próprios que devolvem JSON puro.
Quanto custa
US$ 0,005 por requisição — ou seja, US$ 5 por 1000 requisições.
O preço é por chamada: uma chamada é uma requisição, não importa quantos resultados voltem. Encontrar 50 fontes custa o mesmo que encontrar uma.
Requisições que falham não são cobradas — nem uma falha da busca, nem parâmetros errados.
| o que | conta como |
|---|---|
| busca com 1 resultado | 1 requisição |
| busca com 50 resultados | 1 requisição |
| leitura de uma página | 1 requisição |
| erro de qualquer tipo | 0 |
Caminho 1 — como modelo
Funciona no Cursor, Claude Code, OpenCode e em qualquer cliente OpenAI sem mexer em nada: basta escolher o modelo.
Modelos:
| modelo | o que faz |
|---|---|
keenable/search | pesquisa na web e devolve uma lista de fontes com trechos |
keenable/read | lê uma página e devolve o texto dela em markdown |
Busca
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": "cotação do bitcoin hoje"}]
}'Você recebe uma mensagem de assistente comum com a lista de fontes: título, data de publicação, endereço completo e um trecho de cada uma.
Ler uma página
A primeira palavra da mensagem é o endereço. Depois dele você pode acrescentar o que exatamente interessa naquela página.
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://pt.wikipedia.org/wiki/Tóquio número de habitantes"}]
}'Sem a indicação você recebe a página inteira em markdown. Com ela, apenas o que pediu: é mais rápido e bem mais barato em tokens do seu lado quando o resultado segue para um modelo.
Para que serve a indicação
Um verbete da Wikipédia tem dezenas de milhares de caracteres. Se você precisa de um único número, a indicação economiza tempo e os tokens do passo seguinte.
Python
from openai import OpenAI
client = OpenAI(
api_key="sua-chave",
base_url="https://nordrouter.com/v1",
)
found = client.chat.completions.create(
model="keenable/search",
messages=[{"role": "user", "content": "notícias de IA desta semana"}],
)
print(found.choices[0].message.content)Caminho 2 — endpoints próprios
Se você precisa de resultados com campos, datas e filtros em vez de texto corrido, use o JSON.
POST /v1/search
curl https://nordrouter.com/v1/search \
-H "Authorization: Bearer $NORDROUTER_KEY" \
-H "Content-Type: application/json" \
-d '{
"query": "notícias sobre redes neurais",
"max_results": 5,
"published_after": "7d"
}'Parâmetros:
| parâmetro | tipo | padrão | o que faz |
|---|---|---|---|
query | texto | obrigatório | o que buscar |
site | texto | — | buscar apenas neste domínio, por exemplo uol.com.br |
max_results | número | 10 | quantos resultados, de 1 a 50 |
snippet_max_chars | número | — | tamanho do trecho, de 180 a 10 000 caracteres |
published_after | texto | — | material publicado depois deste momento |
published_before | texto | — | publicado antes |
acquired_after | texto | — | entrou no índice depois |
acquired_before | texto | — | entrou no índice antes |
query_time | texto | — | buscar no índice como ele estava naquele momento |
As datas são aceitas de três formas: 2026-08-01, um carimbo de tempo ISO 8601 completo, ou de forma relativa: 30min, 12h, 7d, 3mo, 1y.
Publicação e índice não são a mesma coisa
published_* filtra pela data do próprio material; acquired_*, pela data em que a página entrou no índice. A diferença importa: uma página pode ser reescrita sem que a data de publicação mude. Se você quer «o que apareceu na rede nas últimas 24 horas», use acquired_after.
Resposta:
{
"query": "notícias sobre redes neurais",
"count": 5,
"results": [
{
"title": "Título do artigo",
"url": "https://example.com/article",
"description": "Descrição breve",
"snippet": "Um trecho do texto da página…",
"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=extraia a tabela de preços"Parâmetros:
| parâmetro | tipo | padrão | o que faz |
|---|---|---|---|
url | texto | obrigatório | endereço da página |
max_chars | número | 50 000 | quantos caracteres devolver |
prompt | texto | — | o que exatamente extrair, até 2000 caracteres |
live | true / false | false | pegar direto do site em vez do índice |
Resposta:
{
"url": "https://example.com/article",
"title": "Título",
"description": "Descrição",
"author": "Autor",
"content": "# Texto da página em markdown…",
"published_at": 1787777084
}Quando o live é necessário
Do índice a página chega mais rápido, mas o índice não tem tudo. Se a página for recente ou estiver fechada a rastreadores, coloque live=true — assim ela é lida direto do site. O preço é o mesmo.
Limites
| ritmo | 2 requisições por segundo por chave |
| tamanho do trecho | de 180 a 10 000 caracteres |
| resultados por chamada | até 50 |
| tamanho da indicação de leitura | até 2000 caracteres |
Ultrapassar o ritmo devolve 429 com o cabeçalho Retry-After — repita depois de um segundo.
Erros
| código | o que significa | o que fazer |
|---|---|---|
400 | falta query ou url, ou o endereço está sem http:// | corrija a requisição |
401 | chave não aceita | confira o Authorization |
402 | saldo esgotado | recarregue no painel |
429 | frequente demais | repita depois de um segundo |
502 | a busca não respondeu | repita; nada foi cobrado |
503 | busca temporariamente indisponível | já estamos cuidando; nada foi cobrado |
Perguntas frequentes
Resultado vazio é cobrado? Sim, se a busca rodou e respondeu honestamente «nada encontrado» — o trabalho foi feito. Só os erros saem de graça.
Dá para usar streaming? Não, e não é preciso: os resultados chegam de uma vez, em uma fração de segundo.
Os tokens são contados? O preço é por chamada, os tokens não influenciam. Ainda assim eles aparecem na resposta do modelo para que as bibliotecas cliente não a tomem por vazia.
Qual a diferença para os modelos search/…? Aqueles primeiro buscam e depois respondem com um modelo de linguagem — você paga dois trabalhos. Aqui você recebe os resultados crus e decide sozinho o que fazer com eles.