Веб-поиск (Keenable)
Поиск по интернету и чтение страниц прямо из вашего кода — тем же ключом, что и модели. Работает двумя способами: как обычная модель через /v1/chat/completions и как отдельные ручки с чистым JSON.
Сколько стоит
$0.005 за запрос — то есть $5 за 1000 запросов.
Цена повызовная: один вызов = один запрос, сколько бы результатов ни вернулось. Найти 50 источников стоит столько же, сколько найти один.
За неудачный запрос деньги не списываются — ни за отказ поиска, ни за неверные параметры.
| что | считается как |
|---|---|
| поиск, вернувший 1 результат | 1 запрос |
| поиск, вернувший 50 результатов | 1 запрос |
| чтение страницы | 1 запрос |
| ошибка любого рода | 0 |
Способ 1 — как модель
Работает в Cursor, Claude Code, OpenCode и любом клиенте OpenAI без единой правки: просто выберите модель.
Модели:
| модель | что делает |
|---|---|
keenable/search | ищет в интернете, возвращает список источников с выдержками |
keenable/read | читает страницу и возвращает её текстом в markdown |
Поиск
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": "курс биткоина сегодня"}]
}'В ответ придёт обычное сообщение ассистента со списком источников: заголовок, дата публикации, полный адрес и выдержка по каждому.
Чтение страницы
Первым словом сообщения — адрес. Дальше можно добавить, что именно вас интересует на этой странице.
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://ru.wikipedia.org/wiki/Токио численность населения"}]
}'Без уточнения вернётся вся страница в markdown. С уточнением — только то, что вы попросили: это быстрее и заметно дешевле по токенам на вашей стороне, когда результат уходит в модель.
Зачем уточнение
Страница Википедии — это десятки тысяч знаков. Если вам нужна одна цифра, уточнение сэкономит и время, и токены следующего шага.
Python
from openai import OpenAI
client = OpenAI(
api_key="ваш-ключ",
base_url="https://nordrouter.com/v1",
)
found = client.chat.completions.create(
model="keenable/search",
messages=[{"role": "user", "content": "новости про ИИ за неделю"}],
)
print(found.choices[0].message.content)Способ 2 — свои ручки
Если нужна выдача с полями, датами и фильтрами, а не текстом — берите JSON.
POST /v1/search
curl https://nordrouter.com/v1/search \
-H "Authorization: Bearer $NORDROUTER_KEY" \
-H "Content-Type: application/json" \
-d '{
"query": "нейросети новости",
"max_results": 5,
"published_after": "7d"
}'Параметры:
| параметр | тип | по умолчанию | что делает |
|---|---|---|---|
query | строка | обязателен | что искать |
site | строка | — | искать только на этом домене, например habr.com |
max_results | число | 10 | сколько результатов, от 1 до 50 |
snippet_max_chars | число | — | длина выдержки, от 180 до 10 000 знаков |
published_after | строка | — | материалы, опубликованные позже этого момента |
published_before | строка | — | опубликованные раньше |
acquired_after | строка | — | попавшие в индекс позже |
acquired_before | строка | — | попавшие в индекс раньше |
query_time | строка | — | искать по индексу, каким он был на этот момент |
Даты принимаются в трёх видах: 2026-08-01, полная метка времени ISO 8601 или относительно — 30min, 12h, 7d, 3mo, 1y.
Публикация и индекс — не одно и то же
published_* фильтрует по дате самого материала, acquired_* — по дате, когда страница попала в индекс. Разница важна: страницу могли переписать, не трогая дату публикации. Если вам нужно «что появилось в сети за сутки», берите acquired_after.
Ответ:
{
"query": "нейросети новости",
"count": 5,
"results": [
{
"title": "Заголовок статьи",
"url": "https://example.com/article",
"description": "Краткое описание",
"snippet": "Выдержка из текста страницы…",
"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=достань таблицу цен"Параметры:
| параметр | тип | по умолчанию | что делает |
|---|---|---|---|
url | строка | обязателен | адрес страницы |
max_chars | число | 50 000 | сколько знаков вернуть |
prompt | строка | — | что именно достать со страницы, до 2000 знаков |
live | true / false | false | брать со страницы напрямую, а не из индекса |
Ответ:
{
"url": "https://example.com/article",
"title": "Заголовок",
"description": "Описание",
"author": "Автор",
"content": "# Текст страницы в markdown…",
"published_at": 1787777084
}Когда нужен live
Из индекса страница отдаётся быстрее, но в индексе есть не всё. Если страница свежая или закрытая от обхода, ставьте live=true — тогда она читается напрямую с сайта. Стоит столько же.
Ограничения
| скорость | 2 запроса в секунду на ключ |
| размер выдержки | от 180 до 10 000 знаков |
| результатов за раз | до 50 |
| длина уточнения при чтении | до 2000 знаков |
Превышение скорости вернёт 429 с заголовком Retry-After — повторите через секунду.
Ошибки
| код | что значит | что делать |
|---|---|---|
400 | не хватает query или url, либо адрес без http:// | поправьте запрос |
401 | ключ не принят | проверьте Authorization |
402 | закончился баланс | пополните в личном кабинете |
429 | слишком часто | повторите через секунду |
502 | поиск не ответил | повторите; деньги не списаны |
503 | поиск временно недоступен | мы уже занимаемся; деньги не списаны |
Частые вопросы
Списывается ли за пустую выдачу? Да, если поиск отработал и честно ответил «ничего не нашлось» — работа была выполнена. Не списывается только за ошибки.
Можно ли стримить? Нет и не нужно: выдача приходит одним куском за доли секунды.
Считаются ли токены? Цена повызовная, токены на неё не влияют. В ответе модели они показываются, чтобы клиентские библиотеки не считали ответ пустым.
Чем это отличается от моделей search/…? Те модели сначала ищут, потом отвечают найденным языковой моделью — вы платите за две работы. Здесь вы получаете сырую выдачу и решаете сами, что с ней делать.