Zenix Embed API

Embed the Zenix player on partner sites via a simple iframe. Auto-selects the best streaming source (VF/VO) with zero backend exposure.

Interactive Builder

Préparez votre code sans attendre. Lancez l’aperçu lorsque vous souhaitez tester le lecteur.

APERÇU À LA DEMANDE

Votre lecteur, prêt à tester.

Choisissez votre contenu, puis lancez la démonstration. Le code d’intégration est déjà disponible ci-dessous.


                

Sécurité & intégration

  • Ne pas utiliser l'attribut sandbox sur l'iframe, ou inclure au minimum allow-scripts allow-same-origin allow-popups.
  • Utilise uniquement l’iframe générée par Zenix : les lecteurs <video>, HLS ou MP4 maison ne sont pas pris en charge.
  • Le lecteur démarre automatiquement. La cadence Smartlink reste gérée à l’intérieur de l’iframe, sur les interactions réelles du lecteur.
  • Mode strict : définir EMBED_FRAME_ANCESTORS_MODE=whitelist et EMBED_ALLOWED_ORIGINS sur le serveur.
  • Les URLs de flux sont signées et liées à la session (expiration ~15 min).

Introduction

The Zenix Embed API lets you integrate a fully-hosted video player into any website using a single <iframe> tag. The player handles source selection, Smartlink cadence and playback — no server-side code required on your end. Raw stream extraction and native-player relays are not supported.

Confidential: This documentation page is not linked from the main https://fluxora.sbs site. It is provided exclusively to authorized partners.

Quick Start

Copy this snippet to embed a movie:

<iframe
  src="https://fluxora.sbs/embed/zenix?tmdb=550&type=movie&lang=vf"
  width="100%" height="500" frameborder="0"
  allowfullscreen allow="autoplay; fullscreen; encrypted-media">
</iframe>

For TV series, add season and episode:

<iframe
  src="https://fluxora.sbs/embed/zenix?tmdb=71712&type=tv&season=1&episode=1&lang=vf"
  width="100%" height="500" frameborder="0"
  allowfullscreen allow="autoplay; fullscreen; encrypted-media">
</iframe>
Important pour sites partenaires

N'utilisez pas defer_play ni parent_gate dans l'URL embed — réservés au site Zenix. Sur votre site, utilisez uniquement l'URL ci-dessus : le lecteur démarre automatiquement et affiche son propre contrôle si un navigateur mobile exige un geste. L'iframe doit avoir allow="autoplay; fullscreen; encrypted-media" sans attribut sandbox.

Parameters

ParameterTypeRequiredDescription
tmdbintegerYesTMDB content ID
typestringYesmovie or tv
seasonintegerTV onlySeason number (default: 1)
episodeintegerTV onlyEpisode number (default: 1)
langstringNovf (French) or vo (original). Auto-selects best source.

Availability API

Check whether content is available before embedding:

GET https://fluxora.sbs/api/embed-player/availability?tmdb=&type=&season=&episode=

Response

{
  "ok": true,
  "vf": true,
  "vo": false,
  "available": true,
  "meta": { "title": "Fight Club", "type": "movie" }
}
FieldTypeDescription
okbooleanRequest succeeded
vfboolean | nullFrench dub: true if confirmed on a source, false if absent, null if not verified. Includes confirmed S3 results.
voboolean | nullOriginal version availability; null means not verified.
availableboolean | nullAt least one source confirmed. Never treat null as false.
pendingbooleanVerification is incomplete. Do not hide the player solely because a source is unverified.
should_embedbooleanPresentation recommendation: true unless absence is confirmed. This does not claim that unknown content is available.
availability_statusstringconfirmed_available, confirmed_unavailable, unknown, or last_known_available (temporary cached evidence).
availability_cacheobjectShared metadata cache, with checked_at, age_seconds and stale. Positive evidence is fresh for 5 minutes; confirmed negatives for 2 minutes. Refresh runs asynchronously. Last-known positive evidence expires after 15 minutes; expired negatives become unknown. Episodes and languages remain separate; embedding permissions are evaluated on every request. A first-ever check returns HTTP 202 with null, never an invented false. On unknown, keep the reader visible (should_embed) and retry after 5 seconds.
sources.s3boolean | nullS3 evidence for the requested language and episode. Provider errors or cooldowns are unknown, not confirmed absence.
metaobjectContent metadata (title, type, etc.)
Ne masquez pas le lecteur sur une panne API

HTTP 202 ou null signifie « non vérifié », jamais « absent ». Ne testez pas if (data.available). Pour la langue demandée, masquez uniquement lorsque son champ vaut strictement false ; sur erreur réseau, conservez le lecteur.

let showReader = true;
try {
  const response = await fetch(availabilityUrl);
  if (response.ok) {
    const data = await response.json();
    // requestedLanguage vaut "vf" ou "vo".
    showReader = data.available !== false && data[requestedLanguage] !== false;
  }
} catch (_) { /* On garde le lecteur : pas de fausse absence. */ }
reader.hidden = !showReader;

Les sites déjà intégrés doivent adopter cette condition : le serveur Fluxora ne peut pas corriger à distance leur propre JavaScript. Les permissions d’accès au lecteur restent inchangées.

Sorties & calendrier

JSON public, sans clé, avec cache partagé et accès navigateur (CORS). Aucun appel à une source n’est effectué pendant votre requête. Dates ISO, fuseau UTC ; pagination avec page et limit (100 au maximum).

Dernières sorties référencées

GET https://fluxora.sbs/api/releases?from=2026-10-01&to=2026-10-31&type=movie&source=s3&limit=30

Par défaut : les 30 derniers jours, triés par release_date décroissante. Filtres : type=movie|tv|anime, source=s1|s2|s3. Sans filtre, toutes les sources. Intervalle maximal : 366 jours. Les dates inconnues sont exclues, jamais inventées. Pour une série, cette date est celle du titre, pas de chaque épisode.

Derniers ajouts S3 (films et épisodes)

GET https://fluxora.sbs/api/releases?date_field=added&source=s3&limit=50

added_at est la date d’ajout communiquée par S3, distincte de la sortie du film. Ce flux conserve les nouveautés reçues depuis son activation pendant 30 jours, sans reconstituer l’historique manquant. Il ne contient pas les ajouts S1/S2.

Calendrier des épisodes annoncés

GET https://fluxora.sbs/api/calendar

Diffusions annoncées par S3 pour les 7 prochains jours, avec season, episode, episode_title et date. meta.coverage précise l’intervalle en cache ; un intervalle extérieur renvoie 422. Une annonce ne confirme jamais la disponibilité de lecture.

Format commun

{ "ok": true, "items": [], "total": 0, "page": 1, "pages": 1, "per_page": 30,
  "meta": { "date_field": "release", "timezone": "UTC", "catalogue_partial": true } }

Chaque entrée fournit son identifiant tmdb, son type, son titre, ses sources, sa date et date_type. available: null signifie que cette route ne teste pas la lecture : utilisez Availability API pour cela. La présence d’un épisode n’atteste pas toute la série. meta.stale indique un flux S3 âgé de plus d’une heure. S3 est synchronisé toutes les 30 minutes par pages limitées ; les plafonds du catalogue officiel restent applicables, l’index n’est pas exhaustif.

Annonces Discord → votre site

Récupérez les nouveautés qui alimentent déjà nos annonces Discord S1, S2 et S3 : film, série, saison ou épisode. Cette API publique, sans clé, lit un index local. Elle ne redétecte pas les contenus et n’appelle ni Discord ni les sources pendant votre requête.

Première lecture : dernières annonces

GET https://fluxora.sbs/api/announcements?limit=20

Sans after, vous recevez les 20 dernières annonces, dans l’ordre de leur identifiant. Enregistrez next_cursor, puis passez-le dans les appels suivants pour ne recevoir que les nouveaux événements.

GET https://fluxora.sbs/api/announcements?after=123&limit=100
GET https://fluxora.sbs/api/announcements?after=123&source=s3&type=tv&lang=vf
ParamètreValeursUtilisation
afterIdentifiant entier ≥ 0Exclusif : événements après ce curseur. 0 relit tout l’historique conservé.
limit1 à 100 ; défaut 20Nombre maximal d’événements par réponse.
sourceall, s1, s2, s3Source annoncée ; défaut all.
typeall, movie, tvtv regroupe séries et épisodes.
langall, vf, voLangue explicitement annoncée. Les langues inconnues ne correspondent pas à VF ou VO.

Réponse JSON

Exemple de structure ; les valeurs ci-dessous sont illustratives.

{
  "ok": true,
  "items": [{
    "id": 124,
    "content_key": "identifiant-stable-du-contenu",
    "event_type": "episode_added",
    "source": "s3", "type": "tv", "tmdb": 1399,
    "title": "Titre de la série", "season": 1, "episode": 2,
    "episode_end": null, "languages": ["vf"], "poster": null,
    "announced_at": "2026-10-25T17:00:00Z",
    "embed_url": "https://fluxora.sbs/embed/zenix?tmdb=1399&type=tv&lang=vf&season=1&episode=2",
    "availability": { "playback_confirmed": null },
    "message": {
      "title": "Nouvel épisode", "description": "Texte de l’annonce Discord",
      "fields": [], "url": "https://fluxora.sbs/embed/zenix?tmdb=1399&type=tv&season=1&episode=2",
      "thumbnail": null, "image": null, "timestamp": "2026-10-25T17:00:00Z"
    }
  }],
  "next_cursor": 124, "has_more": false,
  "meta": { "initial_snapshot": false, "latest_id": 124, "poll_after_seconds": 60, "timezone": "UTC", "coverage": "existing_webhook_announcements" }
}

message reprend les textes, champs et images publics de l’annonce ; aucun webhook, jeton ni identifiant de salon privé n’est exposé. Le lien embed_url ouvre le lecteur Fluxora. Les textes peuvent contenir du Markdown : utilisez textContent, jamais une injection HTML directe.

Pour ouvrir votre propre fiche film ou série, construisez votre URL avec tmdb, type, season et episode. embed_url est un lien public sans PK : gardez votre PK habituelle lorsque vous intégrez le lecteur sur votre site.

event_type vaut movie_added, series_added, season_added ou episode_added. episode_end est renseigné pour une plage annoncée. languages: [] signifie « non précisé ». announced_at est la date de l’annonce en UTC, pas la date de sortie du film. Un événement peut être indexé après son annonce ; le curseur suit toujours l’ordre des identifiants.

Notifications sur votre site : exemple JavaScript

<ul id="fluxora-news"></ul>
<script>
const cursorKey = 'fluxora-announcements-all-v1';
let cursor = localStorage.getItem(cursorKey);
const seen = new Set();

async function pollFluxora() {
  try {
    let more;
    do {
      const url = new URL('https://fluxora.sbs/api/announcements');
      url.searchParams.set('limit', '100');
      if (cursor !== null) url.searchParams.set('after', cursor);
      const response = await fetch(url, { signal: AbortSignal.timeout(10000) });
      if (!response.ok) throw new Error('Flux temporairement indisponible');
      const data = await response.json();
      for (const event of data.items) {
        if (seen.has(event.id)) continue;
        const li = document.createElement('li');
        const a = document.createElement('a');
        a.href = event.embed_url;
        a.textContent = event.message.title || event.title;
        li.append(a);
        document.getElementById('fluxora-news').prepend(li);
        seen.add(event.id);
      }
      // Enregistrer seulement après avoir traité les événements.
      cursor = String(data.next_cursor);
      localStorage.setItem(cursorKey, cursor);
      more = data.has_more;
    } while (more);
  } catch (error) {
    console.warn(error.message); // Curseur conservé : reprise au prochain passage.
  } finally {
    setTimeout(pollFluxora, 60000);
  }
}
pollFluxora();
</script>

Pagination, fiabilité et disponibilité

Interrogez le flux toutes les 60 secondes. Si has_more vaut true, poursuivez avec next_cursor jusqu’à avoir tout traité. Le curseur peut avancer même si le filtre ne renvoie aucun événement. Gardez un curseur distinct par combinaison de filtres, et dédupliquez avec id. Pour ne prévenir qu’une seule fois du même contenu malgré plusieurs annonces de sources, utilisez aussi content_key.

Le flux provient des circuits d’annonces existants : il ne couvre pas tout le catalogue ni toutes les modifications. L’historique commence à son activation, avec une reprise limitée d’annonces antérieures. Une panne Discord n’interrompt pas l’API ; les événements du circuit existant sont indexés séparément, normalement sous une minute, sans garantie de délai absolu.

playback_confirmed décrit uniquement la vérification effectuée au moment de l’annonce : true confirmé, false non confirmé, null non vérifié. Ce n’est pas l’état de lecture actuel. Pour celui-ci, utilisez Availability API. Une annonce de série ou de saison ne prouve pas tous ses épisodes.

HTTP 200 : réponse valide, y compris une liste vide ; 204 : précontrôle OPTIONS ; 405 : méthode interdite ; 422 : paramètre invalide ; 429 : ralentir selon Retry-After ; 503 : index temporairement indisponible, conserver le curseur et réessayer. GET, HEAD et OPTIONS sont autorisés. CORS public, cache de 15 secondes ; aucun cookie ni clé à envoyer.

Embed URL

Base pattern:

https://fluxora.sbs/embed/zenix?tmdb=ID&type=movie|tv&season=1&episode=1&lang=vf|vo

Integration Examples

HTML

<!-- Movie -->
<iframe
  src="https://fluxora.sbs/embed/zenix?tmdb=550&type=movie&lang=vf"
  width="100%" height="500" frameborder="0"
  allowfullscreen allow="autoplay; fullscreen; encrypted-media">
</iframe>

<!-- TV Series -->
<iframe
  src="https://fluxora.sbs/embed/zenix?tmdb=71712&type=tv&season=1&episode=1&lang=vf"
  width="100%" height="500" frameborder="0"
  allowfullscreen allow="autoplay; fullscreen; encrypted-media">
</iframe>

React

function ZenixPlayer({ tmdb, type = 'movie', season = 1, episode = 1, lang = 'vf' }) {
  const params = new URLSearchParams({ tmdb, type, lang });
  if (type === 'tv') { params.set('season', season); params.set('episode', episode); }
  const src = `https://fluxora.sbs/embed/zenix?${params}`;

  return (
    <iframe
      src={src}
      width="100%" height="500"
      frameBorder="0"
      allowFullScreen
      allow="autoplay; fullscreen; encrypted-media"
      title="Zenix Player"
    />
  );
}

WordPress

// functions.php — shortcode [zenix tmdb="550" type="movie" lang="vf"]
function zenix_embed_shortcode($atts) {
    $a = shortcode_atts([
        'tmdb' => '', 'type' => 'movie',
        'season' => '1', 'episode' => '1', 'lang' => 'vf'
    ], $atts);
    if (!$a['tmdb']) return '';
    $url = 'https://fluxora.sbs/embed/zenix?' . http_build_query(array_filter([
        'tmdb' => $a['tmdb'], 'type' => $a['type'],
        'season' => $a['type'] === 'tv' ? $a['season'] : null,
        'episode' => $a['type'] === 'tv' ? $a['episode'] : null,
        'lang' => $a['lang']
    ]));
    return '<iframe src="' . esc_url($url) . '" width="100%" height="500" '
         . 'frameborder="0" allowfullscreen '
         . 'allow="autoplay; fullscreen; encrypted-media"></iframe>';
}
add_shortcode('zenix', 'zenix_embed_shortcode');

Usage: [zenix tmdb="550" type="movie" lang="vf"]