Справочник по REST API
HTTP API только для чтения для запроса сохранённых Nostr-событий через GET /api/v1/... — конечные точки, параметры, пагинация, правила видимости и ошибки.
Базовый URL
API обслуживается по пути /api/v1 на том же порту, что и WebSocket-релей:
http://<host>:<port>/api/v1/{identifier}
http://<host>:<port>/api/v1/{identifier}/{kind}Маршрутизация по хосту (server.api_host)
Когда настроен server.api_host (например, api.example.com), API и релей разделяются по заголовку Host: api.example.com получает /api/v1, /health и /metrics; любой другой хост получает WebSocket-релей и NIP-11.
Без api_host API обслуживается на всех хостах. Поддерживается только GET — запросы на обновление WebSocket к /api/v1 отклоняются с кодом 403.
Конечные точки
Пути на основе идентификаторов
| Путь | Возвращает |
|---|---|
GET /api/v1/<npub1...> | Последнее событие профиля kind-0 |
GET /api/v1/<note1> / <nevent1> | Единственное событие с этим id |
GET /api/v1/<naddr1> | События адреса (kind + автор + d-тег) |
GET /api/v1/<npub1...>/<kind> | События по pubkey с фильтром по kind (принимает npub1... или nprofile1...; иначе 400) |
В качестве идентификаторов авторов принимаются npub1..., nprofile1... или 64-hex pubkey (без учёта регистра) на каждой конечной точке.
Конечные точки запросов и агрегации
GET /api/v1/query— общий запрос с фильтром без идентификатора.GET /api/v1/count— общее количество для тех же параметров фильтра (семантика NIP-45).GET /api/v1/<npub1...>/kinds— количество событий автора по kind, сначала наиболее используемые.GET /api/v1/<npub1...>/<kind>/daily— количество по дням за один месяц; месяц должен быть 1–12, и каждый день отчитывается с заполнением нулями до последнего дня (каждая запись и итог несут флагapproximate).GET /api/v1/ids/<hex>— единственное событие по его 64-hex id (префиксы отклоняются).GET /api/v1/<npub1...>/stats— сводка автора (всего, первая/последняя активность, разбивка по kind);first_seen/last_seen/месяцы равныnull, когда видимых событий нет.GET /api/v1/<npub1...>/<kind>/hourly— количество по часам за один день; все 24 часа отчитываются с заполнением нулями (те же флагиapproximate, что и для daily).GET /api/v1/ids/<hex>/related— ответы (#e) и цитаты (#q), ссылающиеся на событие; id в пути приводится к нижнему регистру перед сопоставлением, а параметр запросаeдобавляется через OR к стороне #e.GET /api/v1/<npub1...>/follows— последний список подписок автора kind-3.GET /api/v1/relay/kinds— самые распространённые kind на релее (ограниченная, отфильтрованная по видимости выборка; флагиapproximateиfiltered).GET /api/v1/relay/top-authors— самые активные авторы на релее (ограниченная, отфильтрованная по видимости выборка; флагиapproximateиfiltered).GET /api/v1/<npub1...>/relays— последний список релеев автора NIP-65 (kind 10002).GET /api/v1/<npub1...>/<kind>/monthly— количество по месяцам с заполнением нулями за диапазон since/until (по умолчанию: весь период; максимум 120 месяцев).
Параметры запроса
| Параметр | Описание |
|---|---|
limit | Максимум результатов (по умолчанию 100, ограничено max_api_limit) |
offset | Количество видимых результатов для пропуска (пагинация) |
since | Только события с created_at >= since |
until | Только события с created_at <= until |
sort | asc/ascending для порядка от старых к новым; по умолчанию — от новых к старым |
search | Полнотекстовый поиск NIP-50 (совпадение целых слов) |
e / p / t / d | Фильтр по тегам #e / #p / #t / #d |
no_p / no_e / no_t / no_d | Исключить события с этим тегом — применяется до пагинации, поэтому исключённые события никогда не занимают слоты limit или шаги offset |
Формат ответа
Успешные ответы возвращают 200 OK со следующим телом JSON:
{
"events": [
{
"id": "32-byte hex event id",
"pubkey": "32-byte hex pubkey",
"created_at": 1700000000,
"kind": 1,
"tags": [["t", "example"]],
"content": "hello",
"sig": "64-byte hex signature"
}
],
"count": 1,
"more": false
}| Поле | Описание |
|---|---|
events | События этой страницы (по умолчанию от новых к старым) |
count | Количество событий на этой странице |
more | true, когда есть следующие страницы (используйте offset для их получения) |
Пагинация
Пагинация выполняется с помощью offset и флага more, вычисленных по видимой последовательности — скрытые события никогда не пропускают и не дублируют страницу:
curl "http://127.0.0.1:8080/api/v1/npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkws3w8ktc/1?limit=50&offset=0" # страница 1
curl "http://127.0.0.1:8080/api/v1/npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkws3w8ktc/1?limit=50&offset=50" # страница 2 (когда more было true)Правила видимости
API не требует аутентификации, поэтому оно скрывает те же события, что и анонимное WebSocket-подключение:
- Защищённые события NIP-70 (с тегом
-) - Gift wrap NIP-59 (kind 1059)
- Приватный/скрытый контент групп NIP-29 (виден только участникам)
Ошибки и коды состояния
| Код | Значение |
|---|---|
| 200 | Успех |
| 400 | Недопустимый идентификатор или параметр запроса |
| 403 | Попытка обновления WebSocket к /api/v1 |
| 404 | Неизвестный путь или неверный Host для API (настроен api_host) |
| 503 | Достигнут лимит параллельности API — повторите попытку позже |
Примеры
Получить заметки пользователя (сначала новые):
curl "http://127.0.0.1:8080/api/v1/npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkws3w8ktc/1"Пагинация и сортировка:
curl "http://127.0.0.1:8080/api/v1/npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkws3w8ktc/1?limit=10&offset=10&sort=asc"Получить единственное событие по id (работают и note1..., и nevent1...):
curl "http://127.0.0.1:8080/api/v1/note1..."
curl "http://127.0.0.1:8080/api/v1/nevent1..."Получить адресуемое событие (naddr1...):
curl "http://127.0.0.1:8080/api/v1/naddr1..."Поиск:
curl "http://127.0.0.1:8080/api/v1/npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkws3w8ktc/1?search=rust"Фильтр по тегу:
curl "http://127.0.0.1:8080/api/v1/npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkws3w8ktc/7?e=<event-id>&limit=100"