API de Revenda - IPTV

Venda testes, acessos e paineis do BR ULTRA IPTV pelo seu proprio sistema.

Esta API roda no PC, nao na nuvem.

O painel Sigma responde 404 para IP de datacenter e so atende o IP residencial. Por isso ela escuta em 127.0.0.1 por padrao. Se o PC estiver desligado, a API nao responde — isso e esperado.

Autenticacao

Authorization: Bearer sk_live_SUA_CHAVE

Tambem aceita X-API-Key. A chave sai do bot no Telegram, no privado, com /apikey. Ela aparece uma vez so — guardamos apenas o hash.

A chave nao e aceita na querystring de proposito: querystring vaza em log, historico e header Referer.

Producao e teste

PrefixoO que faz
sk_test_Simula tudo. Nao cobra, nao cria nada no painel, nao gasta credito. A resposta traz "simulado": true.
sk_live_Vale de verdade: debita o saldo e cria no painel.

Idempotencia

Todo endpoint que gasta dinheiro exige:

Idempotency-Key: pedido-10432

8 a 80 caracteres, aceitando A-Z a-z 0-9 _ -. Use o numero do pedido do seu sistema — um valor novo por venda.

Se a conexao cair e voce repetir com a mesma chave, devolvemos a venda que ja existe em vez de cobrar de novo (resposta com "repetida": true). E isso que impede cobranca dupla no timeout.

Valores

Dinheiro em reais, numero com 2 casas: 29.90. (Diferente da API de VPN, que usa centavos.)

Limites

TipoLimite
Consultas (GET)120 por minuto, por chave
Operacoes (POST)20 por minuto, por chave
Teste gratiso mesmo teto por dia que vale no bot

Erros

{ "ok": false, "erro": "saldo_insuficiente",
  "mensagem": "Saldo insuficiente pra essa compra.",
  "saldo": 5.00, "preco": 29.90 }
HTTPerroSignifica
401chave_ausente / chave_invalidachave faltando, errada ou revogada
402saldo_insuficienteadicione saldo no bot
403conta_suspensaconta banida
404servico_indisponivelnao existe ou esta inativo
429limite_de_usodevagar; veja Retry-After
503sem_credito_no_painelo painel esta sem credito - nada foi cobrado
502painel_recusouo painel recusou; saldo devolvido
202em_verificacaoresultado ambiguo; o suporte confere - NAO repita a cobranca

Endpoints

GET/v1/ping

{ "ok": true, "versao": "1.0", "modo": "producao",
  "revendedor": { "id_telegram": "123", "saldo": 150.00 } }

GET/v1/saldo - /v1/creditos

/v1/creditos mostra os creditos que sobram no painel Sigma (o estoque real).

GET/v1/servicos

Catalogo de acessos pagos. So aparece o que esta ativo e tem integracao com o painel.

{ "ok": true, "servicos": [
  { "id": "supreme_mensal", "nome": "SUPREME - Mensal", "preco": 25.00,
    "duracao": "30 dias", "categoria": "mensal", "conexoes": 1 } ] }

GET/v1/testes

Catalogo dos testes disponiveis (mesma forma, preco 0).

GET/v1/planos-painel

{ "ok": true, "planos": [
  { "id": 1, "creditos": 5, "preco": 12.90, "nome": "PAINEL 5 CREDITOS" } ] }

POST/v1/testes

Corpo: { "servico_id": "supreme_teste" }. Nao gasta saldo, mas conta no teto diario.

POST/v1/acessos

Header Idempotency-Key obrigatorio. Corpo: { "servico_id": "supreme_mensal" }

Nao existe campo de preco no corpo. O valor sai do catalogo — mandar preco no JSON nao faz nada.
{ "ok": true, "cobrado": 25.00, "saldo": 125.00,
  "acesso": { "usuario": "123456789", "senha": "987654321",
    "plano": "SUPREME - Mensal", "vencimento": "2026-09-06",
    "conexoes": 1, "dns": "http://...", "m3u": "http://...",
    "id_no_painel": "abc123" } }

POST/v1/paineis

Header Idempotency-Key obrigatorio. Corpo: { "plano_id": 1 }

GET/v1/compras

Suas ultimas compras. ?limite=50 (1 a 200).

Exemplos

curl

curl -X POST http://127.0.0.1:8090/v1/acessos \
  -H "Authorization: Bearer sk_live_SUA_CHAVE" \
  -H "Idempotency-Key: pedido-10432" \
  -H "Content-Type: application/json" \
  -d '{"servico_id":"supreme_mensal"}'

Python

import os, requests

r = requests.post(
    "http://127.0.0.1:8090/v1/acessos",
    headers={
        "Authorization": f"Bearer {os.environ['BR_ULTRA_IPTV_KEY']}",
        "Idempotency-Key": f"pedido-{pedido_id}",
    },
    json={"servico_id": "supreme_mensal"},
    timeout=90,
)
d = r.json()
if not d.get("ok"):
    raise RuntimeError(f"{d['erro']}: {d['mensagem']}")
print(d["acesso"]["usuario"], d["acesso"]["senha"])
Timeout do jeito certo

Criar acesso fala com o painel e pode passar de 30s. Use timeout de 90s. Se estourar, repita com a mesma Idempotency-Key — ou voce recebe a venda que ja saiu, ou ela acontece agora. Nunca cobra duas vezes.

A unica excecao e o 202 em_verificacao: ali o painel pode ter criado sem confirmar. Nao repita — fale com o suporte.