Aller au contenu

API Peer

L'API Peer permet à des instances Stream Fusion distantes de partager leurs torrents privés de manière sécurisée. L'instance source exporte depuis PostgreSQL (base privée), l'instance cible insère dans Meilisearch (base publique). Pour l'intégration depuis une application tierce, voir Intégration externe.

Authentification HMAC-SHA256

Tous les endpoints nécessitent 3 headers : X-Peer-Key-Id, X-Peer-Timestamp, X-Peer-Signature. Voir Sécurité.


Endpoints

Vérification de cache Debrid

POST /api/peer/debrid/check

Vérifie la disponibilité de hashes sur un service debrid.

Requête (PeerDebridCheckRequest) :

Champ Type Contrainte Description
hashes list[string] 1-200 items Info-hashes à vérifier
service string realdebrid / alldebrid / torbox Service cible
{
  "hashes": ["abc123...", "def456..."],
  "service": "alldebrid"
}

Réponse (PeerDebridCheckResponse) :

Champ Type Description
payload string Charge utile chiffrée Fernet contenant {"service": str, "debrid_cache": {hash: dict}}

Recherche d'items par hashes

POST /api/peer/private/items

Récupère les items torrent correspondants aux hashes fournis.

Requête (PeerPrivateItemsRequest) :

Champ Type Contrainte Description
hashes list[string] 1-200 items Info-hashes à rechercher

Réponse (PeerPrivateItemsResponse) :

Champ Type Description
payload string Charge utile chiffrée Fernet contenant {"torrent_items": {hash: TorrentItemOut}}

TorrentItemOut (modèle interne dans le payload chiffré) :

Champ Type Description
info_hash string Hash du torrent
raw_title string Titre brut
size integer Taille en octets
languages list[string] Langues détectées
seeders integer Nombre de seeders
indexer string ou null Indexeur source
type string ou null Type (movie/series)
imdb_id string ou null ID IMDB
tmdb_id integer ou null ID TMDB
created_at integer Timestamp Unix

Recherche privée (PostgreSQL)

POST /api/peer/private/search

Recherche dans la base privée PostgreSQL. Exactement un champ de recherche requis.

Requête (PeerPrivateSearchRequest) :

Champ Type Contrainte Description
query string ou null ILIKE full-text Recherche par titre
tmdb_id integer ou null Exact Recherche par ID TMDB
imdb_id string ou null Exact Recherche par ID IMDB
info_hash string ou null Exact Recherche par hash unique
limit integer 1-200 (défaut: 20) Résultats max
offset integer ≥ 0 (défaut: 0) Pagination

Validation

Le modèle exige exactement un des champs query, tmdb_id, imdb_id ou info_hash.

{ "query": "matrix", "limit": 20, "offset": 0 }
{ "tmdb_id": 155, "limit": 20, "offset": 0 }
{ "imdb_id": "tt0111161", "limit": 20, "offset": 0 }
{ "info_hash": "abc123def456...", "limit": 1, "offset": 0 }

Réponse (PeerPrivateSearchResponse) :

Champ Type Description
payload string Charge chiffrée contenant {"items": [TorrentItemOut], "total": int}

Export paginé (sync)

POST /api/peer/private/export

Export incrémental pour la synchronisation entre instances.

Requête (PeerPrivateExportRequest) :

Champ Type Contrainte Description
since integer ou null Timestamp Unix Filtrer created_at > since
cursor string ou null - Dernier hash reçu (keyset pagination)
limit integer 1-2000 (défaut: 500) Résultats max
{
  "since": 1704067200,
  "cursor": null,
  "limit": 500
}

Réponse (PeerPrivateExportResponse) :

Champ Type Description
payload string Charge chiffrée contenant {"items": [PeerExportItemOut], "next_cursor": str|null, "count": int}

PeerExportItemOut (sous-ensemble sûr, sans indexer/link/trackers) :

Champ Type Description
info_hash string Hash du torrent
raw_title string Titre brut
size integer Taille en octets
type string ou null Type (movie/series)
imdb_id string ou null ID IMDB
tmdb_id integer ou null ID TMDB
parsed_data dict ou null Données parsées
created_at integer Timestamp Unix

Recherche publique (Meilisearch)

POST /api/peer/public/search

Recherche full-text dans les torrents publics (Meilisearch). Au moins un de query ou imdb_id requis.

Requête (PeerPublicSearchRequest) :

Champ Type Contrainte Description
query string ou null - Recherche full-text
imdb_id string ou null - Recherche par ID IMDB
limit integer 1-200 (défaut: 20) Résultats max
offset integer ≥ 0 (défaut: 0) Pagination
{
  "query": "matrix 1080p",
  "limit": 20,
  "offset": 0
}

Réponse (PeerPublicSearchResponse) :

Champ Type Description
payload string Charge chiffrée contenant {"hits": [MeiliTorrentOut], "total_hits": int}

MeiliTorrentOut (document Meilisearch) :

Champ Type Description
hash string Hash du torrent
raw_title string Titre brut
type string ou null Type
size integer ou null Taille en octets
year integer ou null Année
resolution string ou null Résolution
languages list[string] ou null Langues
imdb_id string ou null ID IMDB
tmdb_id integer ou null ID TMDB
hash_source string ou null Source (DMM, Peer, etc.)
quality string ou null Qualité vidéo
codec string ou null Codec
audio string ou null Format audio
hdr list[string] ou null Types HDR

Lookup IMDB (DuckDB)

POST /api/peer/imdb/lookup

Recherche dans la base IMDB locale. Au moins un de imdb_id ou query requis.

Requête (PeerImdbRequest) :

Champ Type Contrainte Description
imdb_id string ou null Exact ID IMDB (ex: tt0111161)
query string ou null - Recherche par titre
limit integer 1-50 (défaut: 10) Résultats max
{
  "imdb_id": "tt0111161",
  "limit": 10
}

Réponse (PeerImdbResponse) :

Champ Type Description
payload string Charge chiffrée contenant {"results": [ImdbTitleOut]}

ImdbTitleOut :

Champ Type Description
imdb_id string ID IMDB
title_type string ou null Type (movie, series, etc.)
primary_title string Titre principal
original_title string ou null Titre original
start_year integer ou null Année de début
average_rating float ou null Note moyenne
num_votes integer ou null Nombre de votes
tmdb_id integer ou null ID TMDB correspondant

Sécurité et Rate limiting

Rate limiting par clé

Paramètre Défaut Description
rate_limit 60 Max requêtes par fenêtre
rate_window 60 Durée de la fenêtre (s)

Codes d'erreur

Code Description
200 Succès (payload Fernet chiffré)
400 Requête invalide
401 Auth HMAC manquante/invalide
403 Clé inactive/expirée
429 Rate limiting dépassé
500 Erreur interne