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:

text
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

RutaDevuelve
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 marca approximate).
  • 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 son null cuando 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 marcas approximate que 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 consulta e se 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; marcas approximate y filtered).
  • GET /api/v1/relay/top-authors — los autores más activos en el relé (muestra acotada, filtrada por visibilidad; marcas approximate y filtered).
  • 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ámetroDescripción
limitMáx. de resultados (por defecto 100, limitado por max_api_limit)
offsetNúmero de resultados visibles a omitir (paginación)
sinceSolo eventos con created_at >= since
untilSolo eventos con created_at <= until
sortasc/ascending para los más antiguos primero; por defecto, los más recientes primero
searchBúsqueda de texto completo NIP-50 (coincidencia de palabras completas)
e / p / t / dFiltrar por etiquetas #e / #p / #t / #d
no_p / no_e / no_t / no_dExcluir 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:

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
}
CampoDescripción
eventsLos eventos de esta página (los más recientes primero por defecto)
countEl número de eventos en esta página
moretrue 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:

sh
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)
Peculiaridades de los endpoints
Los endpoints singleton (perfil, /ids/{hex}, follows, relays) siguen aceptando offset — ?offset=1 omite el único evento y devuelve []. Los parámetros de consulta authors/kinds solo filtran el endpoint genérico /query: en endpoints kind se ignoran silenciosamente (ambos están prerrellenados), mientras que en endpoints id se combinan con AND. El desglose por kind de stats está ordenado por kind, a diferencia de /kinds (primero por recuento).

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ódigoSignificado
200Éxito
400Identificador o parámetro de consulta inválido
403Intento de actualización WebSocket a /api/v1
404Ruta desconocida, o Host incorrecto para la API (api_host configurado)
503Límite de concurrencia de la API alcanzado — reintente en breve

Ejemplos

Obtener las notas de un usuario (las más recientes primero):

sh
curl "http://127.0.0.1:8080/api/v1/npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkws3w8ktc/1"

Paginar y ordenar:

sh
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):

sh
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...):

sh
curl "http://127.0.0.1:8080/api/v1/naddr1..."

Buscar:

sh
curl "http://127.0.0.1:8080/api/v1/npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkws3w8ktc/1?search=rust"

Filtro por etiqueta:

sh
curl "http://127.0.0.1:8080/api/v1/npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkws3w8ktc/7?e=<event-id>&limit=100"