Référence de l’API REST

API HTTP en lecture seule pour interroger les événements Nostr stockés via GET /api/v1/... — points de terminaison, paramètres, pagination, règles de visibilité et erreurs.

URL de base

L’API est servie sous /api/v1 sur le même port que le relais WebSocket :

text
http://<host>:<port>/api/v1/{identifier}
http://<host>:<port>/api/v1/{identifier}/{kind}

Routage par hôte (server.api_host)

Lorsque server.api_host (p. ex. api.example.com) est configuré, l’API et le relais sont séparés par l’en-tête Host : api.example.com reçoit /api/v1, /health et /metrics ; tout autre hôte reçoit le relais WebSocket et NIP-11. Sans api_host, l’API est servie sur tous les hôtes. Seul GET est pris en charge — les demandes de mise à niveau WebSocket vers /api/v1 sont refusées avec 403.

Points de terminaison

Chemins basés sur un identifiant

CheminRetourne
GET /api/v1/<npub1...>Dernier événement de profil (kind 0)
GET /api/v1/<note1> / <nevent1>L’événement unique portant cet identifiant
GET /api/v1/<naddr1>Événements de l’adresse (kind + auteur + tag d)
GET /api/v1/<npub1...>/<kind>Événements par pubkey, filtrés par kind (accepte npub1... ou nprofile1... ; 400 sinon)

Les identifiants d’auteur acceptent npub1..., nprofile1... ou une pubkey hexadécimale de 64 caractères (insensible à la casse) sur chaque point de terminaison.

Points de terminaison de requête et d’agrégation

  • GET /api/v1/query — requête générique avec filtre sans identifiant.
  • GET /api/v1/count — nombre total pour les mêmes paramètres de filtre (sémantique NIP-45).
  • GET /api/v1/<npub1...>/kinds — nombres d’événements par kind pour un auteur, les plus utilisés d’abord.
  • GET /api/v1/<npub1...>/<kind>/daily — nombres par jour pour un mois ; le mois doit être entre 1 et 12, et chaque jour est rapporté avec remplissage par zéro jusqu’au dernier jour (chaque entrée et le total portent un drapeau approximate).
  • GET /api/v1/ids/<hex> — un événement unique par son id hexadécimal de 64 caractères (préfixes rejetés).
  • GET /api/v1/<npub1...>/stats — résumé de l’auteur (total, première/dernière activité, répartition par kind) ; first_seen/last_seen/les mois valent null lorsqu’il n’existe aucun événement visible.
  • GET /api/v1/<npub1...>/<kind>/hourly — nombres par heure pour un jour ; les 24 heures sont rapportées avec remplissage par zéro (mêmes drapeaux approximate que daily).
  • GET /api/v1/ids/<hex>/related — réponses (#e) et citations (#q) référençant l’événement ; l’id du chemin est mis en minuscules avant comparaison, et un paramètre de requête e est combiné par OR avec le côté #e.
  • GET /api/v1/<npub1...>/follows — la dernière liste de suivis kind-3 de l’auteur.
  • GET /api/v1/relay/kinds — les kinds les plus courants sur le relais (échantillon borné, filtré par visibilité ; drapeaux approximate et filtered).
  • GET /api/v1/relay/top-authors — les auteurs les plus actifs sur le relais (échantillon borné, filtré par visibilité ; drapeaux approximate et filtered).
  • GET /api/v1/<npub1...>/relays — la dernière liste de relais NIP-65 de l’auteur (kind 10002).
  • GET /api/v1/<npub1...>/<kind>/monthly — nombres par mois, avec remplissage par zéro sur la plage since/until (défaut : toute la période ; plafonné à 120 mois).

Paramètres de requête

ParamètreDescription
limitRésultats max (défaut 100, plafonné par max_api_limit)
offsetNombre de résultats visibles à ignorer (pagination)
sinceUniquement les événements avec created_at >= since
untilUniquement les événements avec created_at <= until
sortasc/ascending pour les plus anciens d’abord ; défaut : les plus récents d’abord
searchRecherche plein texte NIP-50 (correspondance de mots entiers)
e / p / t / dFiltrer par tags #e / #p / #t / #d
no_p / no_e / no_t / no_dExclure les événements portant ce tag — appliqué avant la pagination, donc les événements exclus ne consomment jamais de places limit ni d’étapes offset

Format de réponse

Les réponses réussies retournent 200 OK avec le corps JSON suivant :

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
}
ChampDescription
eventsLes événements de cette page (les plus récents d’abord par défaut)
countLe nombre d’événements dans cette page
moretrue quand d’autres pages existent (utilisez offset pour les récupérer)

Pagination

La pagination se fait avec offset et le drapeau more, calculés sur la séquence visible — les événements masqués ne sautent ni ne dupliquent jamais une page :

sh
curl "http://127.0.0.1:8080/api/v1/npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkws3w8ktc/1?limit=50&offset=0"     # page 1
curl "http://127.0.0.1:8080/api/v1/npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkws3w8ktc/1?limit=50&offset=50"    # page 2 (quand more était vrai)
Particularités des points de terminaison
Les points de terminaison singleton (profil, /ids/{hex}, follows, relays) acceptent tout de même offset — ?offset=1 ignore l’unique événement et retourne []. Les paramètres de requête authors/kinds ne filtrent que le point de terminaison générique /query : sur les points de terminaison kind ils sont silencieusement ignorés (tous deux pré-remplis), tandis que sur les points de terminaison id ils sont combinés par AND. La répartition par kind de stats est ordonnée par kind, contrairement à /kinds (d’abord par nombre).

Règles de visibilité

L’API n’est pas authentifiée, elle retient donc les mêmes événements qu’une connexion WebSocket anonyme :

  • Événements protégés NIP-70 (portant un tag -)
  • Gift wraps NIP-59 (kind 1059)
  • Contenu de groupe privé/masqué NIP-29 (visible uniquement par les membres)

Erreurs et codes de statut

CodeSignification
200Succès
400Identifiant ou paramètre de requête invalide
403Tentative de mise à niveau WebSocket vers /api/v1
404Chemin inconnu, ou mauvais Host pour l’API (api_host configuré)
503Limite de concurrence de l’API atteinte — réessayez sous peu

Exemples

Récupérer les notes d’un utilisateur (les plus récentes d’abord) :

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

Paginer et trier :

sh
curl "http://127.0.0.1:8080/api/v1/npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkws3w8ktc/1?limit=10&offset=10&sort=asc"

Récupérer un événement unique par id (note1... ou nevent1... fonctionnent tous deux) :

sh
curl "http://127.0.0.1:8080/api/v1/note1..."
curl "http://127.0.0.1:8080/api/v1/nevent1..."

Récupérer un événement adressable (naddr1...) :

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

Recherche :

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

Filtre par tag :

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