API e embed de filmes, séries, canais e jogos ao vivo

API de streaming para plugar no seu site, app ou projeto: catálogo de filmes, séries, canais de TV e jogos ao vivo em endpoints REST que respondem JSON, e um player em iframe pronto para embedar — com legendas e troca automática de fonte quando uma falha. Escolha um endpoint no menu ao lado para ver parâmetros, exemplos e respostas de erro.

EMBED

<iframe>

O player do SuperFlixAPI é consumido por embed: você não baixa o vídeo nem pede um link direto — você aponta um <iframe> para uma URL nossa e nós resolvemos a fonte, as legendas e os fallbacks do outro lado. Cada tipo de conteúdo tem uma URL própria, sempre no mesmo formato.

Formato das URLs

O domínio é sempre o nosso (https://www.superflixapi.lat) — é ele que vai no src do iframe, não o do seu site. Repare que não é o mesmo domínio do site: é o nosso host de reprodução, dedicado a embed, justamente pra um bloqueio no domínio principal não derrubar os iframes de quem já usa. O que está entre chaves é você que preenche; cada linha traz um exemplo pronto ao lado.

  • https://www.superflixapi.lat/filme/{tmdb_id} — filmes. Ex: https://www.superflixapi.lat/filme/350
  • https://www.superflixapi.lat/serie/{tmdb_id}/{temporada}/{episodio} — episódios de série. Ex: https://www.superflixapi.lat/serie/1416/15/4
  • https://www.superflixapi.lat/canal/{nome} — canais de TV ao vivo. Ex: https://www.superflixapi.lat/canal/espn-brasil
  • https://www.superflixapi.lat/jogo/{nome} — jogos ao vivo. Ex: https://www.superflixapi.lat/jogo/corinthians-x-internacional
  • https://www.superflixapi.lat/evento/{slug} — eventos ao vivo. Ex: https://www.superflixapi.lat/evento/ufc-jonjones-vs-poatan

Exemplo mínimo (com fallback)

Cole o trecho inteiro — o <script> incluso é o que salva o iframe se o endereço for bloqueado por ordem legal. Ele sonda o endereço e, se não responder, tenta a mesma URL com barra no fim e depois o domínio alternativo. Sem esse script, um bloqueio derruba o embed até você trocar o src na mão.

<iframe data-sb-embed data-sb-alt='["https://www.superflixapi.lat/filme/350/"]' src="https://www.superflixapi.lat/filme/350" width="640" height="360" frameborder="0" allow="autoplay; encrypted-media; picture-in-picture" allowfullscreen></iframe>
<script>
(function(){
  var f=document.querySelectorAll("iframe[data-sb-embed]"); if(!f.length) return;
  var el=f[f.length-1], alts=JSON.parse(el.getAttribute("data-sb-alt")||"[]");
  (function tenta(i){ if(i>=alts.length) return;
    fetch(el.src,{method:"HEAD",mode:"cors",cache:"no-store"})
      .then(function(r){ if(r.ok) return; throw 0; })
      .catch(function(){ el.src=alts[i]; tenta(i+1); });
  })(0);
})();
</script>

Boas práticas

  • Sempre inclua allowfullscreen e o allow acima — sem eles o botão de tela cheia e o autoplay não funcionam.
  • Deixe o iframe responsivo com um wrapper de proporção 16:9 em vez de altura fixa em pixels.

Não bloqueie os anúncios do player

Não use o atributo sandbox no iframe, nem bloqueadores de anúncio, proxies ou qualquer outra forma de suprimir a publicidade do player. Se detectarmos isso, o conteúdo não será exibido. Se você quiser um player sem anúncios, veja a página de planos.

Quando dá erro

As rotas respondem 404 com uma mensagem em texto quando o conteúdo não existe ou ainda não tem fonte cadastrada.

Progresso de reprodução (postMessage)

O iframe é de outra origem, então seu site não consegue ler o <video> de dentro dele. Pra saber quanto já foi assistido, o player manda o progresso pra fora com postMessage — a cada ~15s enquanto toca, e na hora em play/pause/seeked/ended.

window.addEventListener('message', (event) => {
  // Obrigatório, não opcional: sem checar a origem, qualquer outro iframe
  // na sua página (ex: um anúncio) pode forjar 'superflixapi:progress' e
  // envenenar o que você guarda como progresso do usuário.
  if (event.origin !== 'https://superflixapi.lat') return;
  if (event.data?.type !== 'superflixapi:progress') return;

  const { currentTime, duration, state, tmdbId, season, episode } = event.data;
  const percent = (currentTime / duration) * 100;
  // state: 'playing' | 'paused' | 'ended' — use 'ended' pra marcar como
  // assistido e tirar o card de "continuar assistindo", em vez de inferir
  // isso por currentTime chegando perto de duration.
  // season/episode vêm só em episódio de série; em filme os dois são null.
});
  • Conferir event.origin é obrigatório, não uma boa prática opcional — é a única coisa que impede outro iframe da sua página (rede de anúncio, outro widget) de forjar uma mensagem com o mesmo type e envenenar o progresso que você guarda. Filtrar só por event.data?.type não basta.
  • tmdbId/season/episode identificam a que conteúdo o progresso pertence — necessário porque o player troca de fonte sozinho (autoplay do próximo episódio) sem o iframe recarregar, então o conteúdo pode mudar no meio da reprodução sem seu site saber pelo contexto da página.

A mensagem sai com targetOrigin: '*' porque o embed pode estar em qualquer domínio — isso não é o mesmo problema de segurança do event.origin acima: aqui é a origem de QUEM MANDA (nós, sempre https://superflixapi.lat) que importa conferir; o alvo aberto só significa que não escondemos pra quem escuta, e o conteúdo da mensagem não é sensível.

Posição inicial (?start=)

Se você guarda o progresso do seu lado (com o postMessage acima), pode abrir o vídeo de onde parou passando ?start= (segundos) na URL do embed — ex: https://www.superflixapi.lat/filme/350?start=1800 começa aos 30 minutos. Sem isso, o player sempre começa do zero pra visitante sem sessão nossa, mesmo que seu site já saiba a posição certa.

Escolher a fonte que carrega primeiro (?fonte=)

Passe o rótulo da fonte em minúsculas e com hífens: https://www.superflixapi.lat/canal/globo?fonte=painel-externo-p. Ela vai pra frente da fila e as outras continuam atrás como reserva; se o nome não existir naquele conteúdo, a ordem normal vale. Os rótulos disponíveis vêm no campo label de cada fonte em /api/v1/stream, que também aceita &fonte= e devolve a escolhida em sources[0]. Funciona em canal, jogo, evento, filme e série, em qualquer plano.

Mudar a posição sem recarregar (superflixapi:seek)

Pra mudar a posição durante a reprodução sem remontar a URL e recarregar o iframe inteiro, mande uma mensagem pro player:

iframeEl.contentWindow.postMessage(
  { type: 'superflixapi:seek', seconds: 1800 },
  'https://superflixapi.lat'
);

Use o domínio real do embed (nunca '*') como targetOrigin aqui — é você quem sabe pra onde está mandando, diferente do player, que não sabe onde você está embedado.

Play e pause (superflixapi:play / superflixapi:pause)

Mesmo canal, sem parâmetros:

iframeEl.contentWindow.postMessage({ type: 'superflixapi:pause' }, 'https://superflixapi.lat');
iframeEl.contentWindow.postMessage({ type: 'superflixapi:play' }, 'https://superflixapi.lat');

O navegador pode recusar o play se o visitante ainda não interagiu com a página — nesse caso o vídeo continua pausado. O pause sempre funciona. O estado novo volta pelo superflixapi:progress (state: 'playing'/'paused').

Limites de uso

  • Paginação: limit vai até 100 itens por página em todas as rotas JSON — valor acima disso é reduzido ao máximo, não recusado. Para varrer o catálogo, prefira o cursor after_id de /api/titles (cada página custa só o tamanho dela); page continua valendo, mas pular muitas páginas fica caro do nosso lado e é a primeira coisa a degradar num pico.
  • Rotas públicas: 120 requisições por minuto por IP em /api/titles, /api/recents e /api/season-episodes, com 429 ao estourar (o cabeçalho Retry-After diz quando voltar). Guarde o resultado do seu lado — o catálogo muda em horas, não em segundos, então uma consulta em loop a cada poucos segundos gasta o limite sem trazer nada novo.
  • Plano API: 60 requisições por minuto por chave, com 429 ao estourar. Veja API de link direto.