Búsqueda web (Keenable)
Buscar en internet y leer páginas directamente desde su código, con la misma clave que usa para los modelos. Funciona de dos maneras: como un modelo corriente a través de /v1/chat/completions o mediante endpoints propios que devuelven JSON puro.
Cuánto cuesta
0,005 $ por petición, es decir 5 $ por cada 1000 peticiones.
El precio es por llamada: una llamada es una petición, sin importar cuántos resultados lleguen. Encontrar 50 fuentes cuesta lo mismo que encontrar una.
Las peticiones fallidas no se cobran: ni un fallo de la búsqueda ni unos parámetros incorrectos.
| qué | cuenta como |
|---|---|
| búsqueda con 1 resultado | 1 petición |
| búsqueda con 50 resultados | 1 petición |
| leer una página | 1 petición |
| cualquier error | 0 |
Vía 1 — como modelo
Funciona en Cursor, Claude Code, OpenCode y cualquier cliente de OpenAI sin tocar nada: basta con elegir el modelo.
Modelos:
| modelo | qué hace |
|---|---|
keenable/search | busca en internet y devuelve una lista de fuentes con extractos |
keenable/read | lee una página y devuelve su texto en markdown |
Búsqueda
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": "precio del bitcoin hoy"}]
}'Recibirá un mensaje de asistente normal con la lista de fuentes: título, fecha de publicación, dirección completa y un extracto de cada una.
Leer una página
La primera palabra del mensaje es la dirección. Después puede añadir qué le interesa exactamente de esa 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://es.wikipedia.org/wiki/Tokio número de habitantes"}]
}'Sin la indicación recibirá la página entera en markdown. Con ella, solo lo que ha pedido: es más rápido y bastante más barato en tokens de su lado cuando el resultado alimenta a un modelo.
Para qué sirve la indicación
Un artículo de Wikipedia son decenas de miles de caracteres. Si solo necesita una cifra, la indicación le ahorra tiempo y los tokens del paso siguiente.
Python
from openai import OpenAI
client = OpenAI(
api_key="su-clave",
base_url="https://nordrouter.com/v1",
)
found = client.chat.completions.create(
model="keenable/search",
messages=[{"role": "user", "content": "noticias de IA de esta semana"}],
)
print(found.choices[0].message.content)Vía 2 — endpoints propios
Si necesita resultados con campos, fechas y filtros en vez de texto corrido, use el JSON.
POST /v1/search
curl https://nordrouter.com/v1/search \
-H "Authorization: Bearer $NORDROUTER_KEY" \
-H "Content-Type: application/json" \
-d '{
"query": "noticias sobre redes neuronales",
"max_results": 5,
"published_after": "7d"
}'Parámetros:
| parámetro | tipo | por defecto | qué hace |
|---|---|---|---|
query | cadena | obligatorio | qué buscar |
site | cadena | — | buscar solo en este dominio, por ejemplo xataka.com |
max_results | número | 10 | cuántos resultados, de 1 a 50 |
snippet_max_chars | número | — | longitud del extracto, de 180 a 10 000 caracteres |
published_after | cadena | — | material publicado después de ese momento |
published_before | cadena | — | publicado antes |
acquired_after | cadena | — | incorporado al índice después |
acquired_before | cadena | — | incorporado al índice antes |
query_time | cadena | — | buscar en el índice tal como estaba en ese momento |
Las fechas se admiten de tres formas: 2026-08-01, una marca de tiempo ISO 8601 completa o en forma relativa: 30min, 12h, 7d, 3mo, 1y.
Publicación e índice no son lo mismo
published_* filtra por la fecha del propio material; acquired_*, por la fecha en que la página entró en el índice. La diferencia importa: una página puede reescribirse sin tocar su fecha de publicación. Si quiere «qué ha aparecido en la red en las últimas 24 horas», use acquired_after.
Respuesta:
{
"query": "noticias sobre redes neuronales",
"count": 5,
"results": [
{
"title": "Titular del artículo",
"url": "https://example.com/article",
"description": "Descripción breve",
"snippet": "Un extracto del texto de la 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=extrae la tabla de precios"Parámetros:
| parámetro | tipo | por defecto | qué hace |
|---|---|---|---|
url | cadena | obligatorio | dirección de la página |
max_chars | número | 50 000 | cuántos caracteres devolver |
prompt | cadena | — | qué extraer exactamente, hasta 2000 caracteres |
live | true / false | false | tomarla directamente del sitio en vez del índice |
Respuesta:
{
"url": "https://example.com/article",
"title": "Titular",
"description": "Descripción",
"author": "Autor",
"content": "# Texto de la página en markdown…",
"published_at": 1787777084
}Cuándo hace falta live
Del índice la página llega más rápido, pero el índice no lo contiene todo. Si la página es reciente o está cerrada a los rastreadores, ponga live=true y se leerá directamente del sitio. Cuesta lo mismo.
Límites
| ritmo | 2 peticiones por segundo por clave |
| longitud del extracto | de 180 a 10 000 caracteres |
| resultados por llamada | hasta 50 |
| longitud de la indicación de lectura | hasta 2000 caracteres |
Superar el ritmo devuelve 429 con la cabecera Retry-After: repita al cabo de un segundo.
Errores
| código | qué significa | qué hacer |
|---|---|---|
400 | falta query o url, o la dirección no lleva http:// | corrija la petición |
401 | clave no aceptada | revise Authorization |
402 | saldo agotado | recargue en el panel |
429 | demasiado seguido | repita al cabo de un segundo |
502 | la búsqueda no respondió | repita; no se ha cobrado nada |
503 | búsqueda temporalmente no disponible | ya nos estamos ocupando; no se ha cobrado nada |
Preguntas frecuentes
¿Se cobra un resultado vacío? Sí, si la búsqueda se ejecutó y respondió honestamente «no se ha encontrado nada»: el trabajo se hizo. Solo los errores salen gratis.
¿Se puede usar streaming? No, y no hace falta: los resultados llegan de una vez en una fracción de segundo.
¿Se cuentan los tokens? El precio es por llamada, los tokens no influyen. Aun así se muestran en la respuesta del modelo para que las bibliotecas cliente no la tomen por vacía.
¿En qué se diferencia de los modelos search/…? Aquellos primero buscan y luego responden con un modelo de lenguaje: usted paga dos trabajos. Aquí obtiene los resultados en bruto y decide usted mismo qué hacer con ellos.