Referencia de la API REST
API HTTP de solo lectura para consultar eventos Nostr almacenados en GET /api/v1/... — endpoints, parámetros, paginación, reglas de visibilidad y errores.
URL base
La API se sirve bajo /api/v1 en el mismo puerto que el relé WebSocket:
http://<host>:<port>/api/v1/{identifier}
http://<host>:<port>/api/v1/{identifier}/{kind}Enrutamiento por host (server.api_host)
Cuando server.api_host (p. ej. api.example.com) está configurado, la API y el relé se separan por la cabecera Host: api.example.com recibe /api/v1, /health y /metrics; cualquier otro host recibe el relé WebSocket y NIP-11.
Sin api_host, la API se sirve en todos los hosts. Solo se admite GET — las solicitudes de actualización WebSocket a /api/v1 se rechazan con 403.
Endpoints
Rutas basadas en identificadores
| Ruta | Devuelve |
|---|---|
GET /api/v1/<npub1...> | Último evento de perfil kind-0 |
GET /api/v1/<note1> / <nevent1> | El evento único con este id |
GET /api/v1/<naddr1> | Eventos de la dirección (kind + autor + etiqueta d) |
GET /api/v1/<npub1...>/<kind> | Eventos por pubkey, filtrados por kind (acepta npub1... o nprofile1...; 400 en caso contrario) |
Los identificadores de autor aceptan npub1..., nprofile1... o una pubkey hexadecimal de 64 caracteres (insensible a mayúsculas) en cada endpoint.
Endpoints de consulta y agregación
GET /api/v1/query— consulta genérica con filtro sin identificador.GET /api/v1/count— recuento total para los mismos parámetros de filtro (semántica NIP-45).GET /api/v1/<npub1...>/kinds— recuentos de eventos por kind para un autor, los más usados primero.GET /api/v1/<npub1...>/<kind>/daily— recuentos por día para un mes; el mes debe ser 1–12, y cada día se informa con relleno de ceros hasta el último día (cada entrada y el total llevan una marcaapproximate).GET /api/v1/ids/<hex>— un evento único por su id hexadecimal de 64 caracteres (prefijos rechazados).GET /api/v1/<npub1...>/stats— resumen del autor (total, primera/última actividad, desglose por kind);first_seen/last_seen/los meses sonnullcuando no existen eventos visibles.GET /api/v1/<npub1...>/<kind>/hourly— recuentos por hora para un día; las 24 horas se informan con relleno de ceros (mismas marcasapproximateque daily).GET /api/v1/ids/<hex>/related— respuestas (#e) y citas (#q) que hacen referencia al evento; el id de la ruta se pasa a minúsculas antes de comparar, y un parámetro de consultaese combina con OR en el lado #e.GET /api/v1/<npub1...>/follows— la última lista de seguidos kind-3 del autor.GET /api/v1/relay/kinds— los kinds más comunes en el relé (muestra acotada, filtrada por visibilidad; marcasapproximateyfiltered).GET /api/v1/relay/top-authors— los autores más activos en el relé (muestra acotada, filtrada por visibilidad; marcasapproximateyfiltered).GET /api/v1/<npub1...>/relays— la última lista de relés NIP-65 del autor (kind 10002).GET /api/v1/<npub1...>/<kind>/monthly— recuentos por mes, con relleno de ceros en el rango since/until (por defecto: todo el período; limitado a 120 meses).
Parámetros de consulta
| Parámetro | Descripción |
|---|---|
limit | Máx. de resultados (por defecto 100, limitado por max_api_limit) |
offset | Número de resultados visibles a omitir (paginación) |
since | Solo eventos con created_at >= since |
until | Solo eventos con created_at <= until |
sort | asc/ascending para los más antiguos primero; por defecto, los más recientes primero |
search | Búsqueda de texto completo NIP-50 (coincidencia de palabras completas) |
e / p / t / d | Filtrar por etiquetas #e / #p / #t / #d |
no_p / no_e / no_t / no_d | Excluir eventos con esa etiqueta — se aplica antes de la paginación, por lo que los eventos excluidos nunca consumen huecos de limit ni pasos de offset |
Formato de respuesta
Las respuestas exitosas devuelven 200 OK con el siguiente cuerpo 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
}| Campo | Descripción |
|---|---|
events | Los eventos de esta página (los más recientes primero por defecto) |
count | El número de eventos en esta página |
more | true cuando existen más páginas (usa offset para obtenerlas) |
Paginación
La paginación se hace con offset y la marca more, calculados sobre la secuencia visible — los eventos ocultos nunca omiten ni duplican una página:
curl "http://127.0.0.1:8080/api/v1/npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkws3w8ktc/1?limit=50&offset=0" # página 1
curl "http://127.0.0.1:8080/api/v1/npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkws3w8ktc/1?limit=50&offset=50" # página 2 (cuando more era true)Reglas de visibilidad
La API no está autenticada, por lo que oculta los mismos eventos que una conexión WebSocket anónima:
- Eventos protegidos NIP-70 (con etiqueta
-) - Gift wraps NIP-59 (kind 1059)
- Contenido de grupo privado/oculto NIP-29 (visible solo para miembros)
Errores y códigos de estado
| Código | Significado |
|---|---|
| 200 | Éxito |
| 400 | Identificador o parámetro de consulta inválido |
| 403 | Intento de actualización WebSocket a /api/v1 |
| 404 | Ruta desconocida, o Host incorrecto para la API (api_host configurado) |
| 503 | Límite de concurrencia de la API alcanzado — reintente en breve |
Ejemplos
Obtener las notas de un usuario (las más recientes primero):
curl "http://127.0.0.1:8080/api/v1/npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkws3w8ktc/1"Paginar y ordenar:
curl "http://127.0.0.1:8080/api/v1/npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkws3w8ktc/1?limit=10&offset=10&sort=asc"Obtener un evento único por id (tanto note1... como nevent1... funcionan):
curl "http://127.0.0.1:8080/api/v1/note1..."
curl "http://127.0.0.1:8080/api/v1/nevent1..."Obtener un evento direccionable (naddr1...):
curl "http://127.0.0.1:8080/api/v1/naddr1..."Buscar:
curl "http://127.0.0.1:8080/api/v1/npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkws3w8ktc/1?search=rust"Filtro por etiqueta:
curl "http://127.0.0.1:8080/api/v1/npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkws3w8ktc/7?e=<event-id>&limit=100"