DESENVOLVEDORES · CONTRATO 1.1.0
Integre sua revenda ao Juba Player
Consulte saldo, acompanhe licenças e ative aparelhos pelo seu sistema. API para servidores de revendedores aprovados, com autenticação por chave.
Primeiros passos
- Cadastre sua revenda e aguarde aprovação.
- Em Conta e integração, gere sua chave de API. Copie e guarde: ela aparece uma única vez.
- Guarde a chave como
JUBA_API_KEYno backend. Valide acesso comGET /partner/me, sem gastar saldo. - Abra o app na TV para registrar o aparelho. Com créditos disponíveis, envie o ID fornecido pelo cliente para ativação.
Base: https://jubaplayer.com/api/v1
x-api-key: SUA_CHAVE
Content-Type: application/jsonAtivar consome saldo real. Não há sandbox público ou dry-run nesta API. Combine conta, aparelho e créditos de teste com o administrador.
Segurança e limites
Use HTTPS e mantenha a chave apenas no servidor. Nunca a exponha em navegador, app distribuído, URL, Git ou conversa com IA. Uma nova chave revoga a anterior; suspensão da conta bloqueia a integração. Não use JWT do painel.
| Limite | Janela | Escopo |
|---|---|---|
| 60 leituras | 1 minuto | Por conta, somando todos os GETs |
| 10 ativações/tentativas | 1 minuto | Por conta, incluindo retries |
| 120 requisições | 1 minuto | Por IP/instância, somando todas as rotas |
| 20 escritas de gestão | 1 minuto | Por conta, API e painel |
| 8192 bytes | Por corpo JSON | Gestão de playlists |
| 4096 bytes | Por corpo JSON | POST de ativação |
Contadores por conta persistem entre deploys e são compartilhados entre instâncias. O limite por IP usa memória local e pode afetar servidores atrás do mesmo NAT. Em HTTP 429, aguarde Retry-After segundos. Cacheie consultas e use espera crescente com aleatoriedade em retries.
Cabeçalhos: x-ratelimit-limit, x-ratelimit-remaining e x-ratelimit-reset (segundos, não timestamp). Cada requisição recebe x-request-id para suporte. Não tente contornar limites alternando IPs ou chaves.
Evitar débitos duplicados
Crie e salve um UUID por pedido antes de chamar a API. Envie-o como Idempotency-Key. Se houver timeout ou erro de rede, repita com a mesma chave e o mesmo aparelho.
- Um sucesso repetido retorna a resposta original sem novo débito. Saldo e vencimento nessa resposta são os do momento original; consulte os GETs para o estado atual.
- Nova renovação = nova chave de idempotência. Não gere outra chave a cada tentativa do mesmo pedido.
- A mesma chave para outro aparelho retorna 409. Falhas não reservam a chave.
- O registro permanece enquanto a conta existir e sobrevive à rotação da chave de API. Autenticação e limites continuam valendo em repetições.
- Sem esse cabeçalho, cada POST válido consome outro crédito, por compatibilidade com integrações anteriores.
Gestão autorizada de playlists
Ativação e gestão são independentes. Envie um convite ao cliente: ele entra no portal com ID e chave e aprova. O administrador global também pode vincular, transferir ou revogar com motivo e auditoria, sem aprovação prévia. Há um gestor por aparelho; o cliente pode revogar no portal.
Sua revenda só altera listas adicionadas durante o vínculo atual. Transferir preserva listas e licença, mas não transfere acesso às listas antigas. URLs e credenciais não são exibidas. Listas locais da TV ficam fora deste recurso. POST de playlist não é idempotente: após timeout, consulte antes de repetir. Veja exemplos M3U, Xtream e código de provedor no guia Markdown.
Chamadas e respostas
GET /partner/me
Consultar conta e saldo
Retorna nome e créditos disponíveis da conta autenticada. Não altera saldo.
curl --fail-with-body -X GET 'https://jubaplayer.com/api/v1/partner/me' -H "x-api-key: $JUBA_API_KEY"Resposta 200 · dados fictícios
{
"name": "Revenda Exemplo",
"credits": 30
}GET /partner/devices/{deviceId}
Consultar licença de aparelho vinculado
Somente aparelhos com pelo menos uma ativação deste revendedor (API ou painel). Aparelhos inexistentes e sem vínculo retornam o mesmo 404. A resposta não contém listas, senhas ou chave do aparelho.
deviceId · path · obrigatório: Seis pares hexadecimais separados por dois-pontos.
curl --fail-with-body -X GET 'https://jubaplayer.com/api/v1/partner/devices/aa:bb:cc:dd:ee:ff' -H "x-api-key: $JUBA_API_KEY"Resposta 200 · dados fictícios
{
"deviceId": "aa:bb:cc:dd:ee:ff",
"license": {
"status": "active",
"plan": "annual",
"registeredAt": "2026-11-11T12:00:00.000Z",
"expiresAt": "2027-11-11T12:00:00.000Z"
}
}POST /partner/activate
Ativar ou renovar um aparelho
Consome 1 crédito e acrescenta 365 dias na configuração atual. Se a licença ainda for válida, soma ao vencimento; se expirada, começa agora. O aparelho precisa existir (abrir o app e sincronizar antes). Use Idempotency-Key em toda ativação. A operação real debita saldo; não há modo de simulação neste endpoint.
Idempotency-Key · header · opcional: Fortemente recomendado. 8–128 caracteres: letras ASCII, números, ponto, sublinhado, dois-pontos ou hífen. Use um UUID por pedido e persista antes de enviar. Mesmo revendedor + mesma chave + mesmo aparelho retorna a resposta original sem novo débito, inclusive após rotação da API key. Mesma chave com outro aparelho retorna 409. Registro de sucesso conservado enquanto a conta existir; respostas de falha não reservam a chave. Sem cabeçalho, cada POST é uma nova ativação (compatibilidade).
curl --fail-with-body -X POST 'https://jubaplayer.com/api/v1/partner/activate' -H "x-api-key: $JUBA_API_KEY" -H 'Idempotency-Key: a4939de8-394c-4fa5-aa09-21f78433b6db' -H 'Content-Type: application/json' --data '{"deviceId":"aa:bb:cc:dd:ee:ff"}'Resposta 200 · dados fictícios
{
"deviceId": "aa:bb:cc:dd:ee:ff",
"license": {
"status": "active",
"plan": "annual",
"registeredAt": "2026-11-11T12:00:00.000Z",
"expiresAt": "2027-11-11T12:00:00.000Z"
},
"creditsLeft": 29
}POST /partner/management-invitations
Solicitar autorização de gestão
Cria link de uso único válido por 30 minutos. Entregue approvalUrl ao cliente, que deve autenticar o próprio aparelho e aprovar explicitamente. Nunca solicite sua chave de seis dígitos. Reemitir expira o convite anterior da mesma conta/aparelho. Não concede acesso por si só. Limite de escrita: 20/min por conta.
curl --fail-with-body -X POST 'https://jubaplayer.com/api/v1/partner/management-invitations' -H "x-api-key: $JUBA_API_KEY" -H 'Content-Type: application/json' --data '{"deviceId":"aa:bb:cc:dd:ee:ff"}'Resposta 201 · dados fictícios
{
"id": "d6f7d632-522c-445a-9664-2cf7adef2f62",
"expiresAt": "2026-11-11T12:00:00.000Z",
"approvalUrl": "https://jubaplayer.com/entrar#gestao=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
}GET /partner/managed-devices
Listar aparelhos sob gestão
Somente vínculos atuais; gestão não implica histórico de ativação. Página de 50 itens, ordenada por vínculo mais recente.
page · query · opcional: Página, começando em 1.
curl --fail-with-body -X GET 'https://jubaplayer.com/api/v1/partner/managed-devices' -H "x-api-key: $JUBA_API_KEY"Resposta 200 · dados fictícios
{
"total": 1,
"pageSize": 50,
"items": [
{
"deviceId": "aa:bb:cc:dd:ee:ff",
"managementId": "d6f7d632-522c-445a-9664-2cf7adef2f62",
"grantedAt": "2026-11-11T12:00:00.000Z",
"grantedBy": "admin"
}
]
}GET /partner/devices/{deviceId}/playlists
Listar metadados das próprias listas
Exige vínculo atual. Retorna somente listas criadas durante este vínculo, sem URLs ou credenciais. Listas do cliente, do admin e de outros vínculos não aparecem. Limite de leitura: 60/min por conta.
deviceId · path · obrigatório: ID do aparelho autorizado.
curl --fail-with-body -X GET 'https://jubaplayer.com/api/v1/partner/devices/aa:bb:cc:dd:ee:ff/playlists' -H "x-api-key: $JUBA_API_KEY"Resposta 200 · dados fictícios
[
{
"id": "d6f7d632-522c-445a-9664-2cf7adef2f62",
"name": "Minha lista",
"type": "m3u",
"createdAt": "2026-11-11T12:00:00.000Z",
"managementId": "d6f7d632-522c-445a-9664-2cf7adef2f62"
}
]POST /partner/devices/{deviceId}/playlists
Adicionar lista remota
Exige vínculo atual. Só listas criadas pela revenda durante este vínculo podem ser alteradas. Revogação/transferência preserva listas, mas corta acesso; nova autorização não recupera acesso a listas de vínculos antigos. Máximo de 20 listas remotas por aparelho (inclui todas as origens). Corpo completo M3U, Xtream ou código de provedor ativo. URLs e credenciais são somente de escrita. Limite de escrita: 20/min por conta, compartilhado com convites e painel. POST não implementa Idempotency-Key: após timeout consulte as listas antes de repetir, pois pode duplicar. Salve o id retornado.
deviceId · path · obrigatório: ID do aparelho autorizado.
curl --fail-with-body -X POST 'https://jubaplayer.com/api/v1/partner/devices/aa:bb:cc:dd:ee:ff/playlists' -H "x-api-key: $JUBA_API_KEY" -H 'Content-Type: application/json' --data '{"type":"m3u","name":"Minha lista","url":"https://example.com/lista.m3u"}'Resposta 201 · dados fictícios
{
"id": "d6f7d632-522c-445a-9664-2cf7adef2f62"
}PUT /partner/devices/{deviceId}/playlists/{id}
Substituir dados da própria lista
Exige vínculo atual. Só listas criadas pela revenda durante este vínculo podem ser alteradas. Revogação/transferência preserva listas, mas corta acesso; nova autorização não recupera acesso a listas de vínculos antigos. Máximo de 20 listas remotas por aparelho (inclui todas as origens). Corpo completo M3U, Xtream ou código de provedor ativo. URLs e credenciais são somente de escrita. Limite de escrita: 20/min por conta, compartilhado com convites e painel. Envie todos os campos; preserva o ID. Repetir PUT com o mesmo conteúdo mantém o estado.
deviceId · path · obrigatório: ID do aparelho autorizado.
id · path · obrigatório: UUID da lista retornado na criação.
curl --fail-with-body -X PUT 'https://jubaplayer.com/api/v1/partner/devices/aa:bb:cc:dd:ee:ff/playlists/d6f7d632-522c-445a-9664-2cf7adef2f62' -H "x-api-key: $JUBA_API_KEY" -H 'Content-Type: application/json' --data '{"type":"m3u","name":"Minha lista","url":"https://example.com/lista.m3u"}'Resposta 200 · dados fictícios
{
"id": "d6f7d632-522c-445a-9664-2cf7adef2f62"
}DELETE /partner/devices/{deviceId}/playlists/{id}
Remover a própria lista
Exige vínculo atual e lista criada nele. Sem corpo JSON. Retorna 204; repetir após sucesso retorna 404. Não remove listas locais da TV.
deviceId · path · obrigatório: ID do aparelho autorizado.
id · path · obrigatório: UUID da lista retornado na criação.
curl --fail-with-body -X DELETE 'https://jubaplayer.com/api/v1/partner/devices/aa:bb:cc:dd:ee:ff/playlists/d6f7d632-522c-445a-9664-2cf7adef2f62' -H "x-api-key: $JUBA_API_KEY"Resposta 204 · dados fictícios
Sem corpo.O guia completo também inclui exemplo JavaScript para Node.js, parâmetros e regras de renovação.
Erros e suporte
O corpo de erro contém error; validações podem incluir details. Para suporte, informe horário, rota, status HTTP e x-request-id. Nunca envie chave ou senha.
| HTTP | Código | Como agir |
|---|---|---|
| 400 | validation | Formato inválido de ID, JSON ou Idempotency-Key. Corrija a entrada antes de repetir. |
| 401 | invalid_api_key | Chave ausente, inválida, revogada ou conta suspensa/pendente. Confira a conta e a chave. |
| 402 | no_credits | Saldo insuficiente. Compre créditos no painel antes de tentar novamente. |
| 404 | device_not_found | Aparelho/lista não encontrado ou fora do escopo permitido. Consulta de licença exige ativação anterior pela própria conta. |
| 409 | idempotency_conflict | A mesma Idempotency-Key já foi concluída para outro aparelho. Não reutilize uma chave para operações diferentes. |
| 413 | FST_ERR_CTP_BODY_TOO_LARGE | JSON excede 4096 bytes em ativação ou 8192 bytes em gestão. |
| 415 | FST_ERR_CTP_INVALID_MEDIA_TYPE | Envie Content-Type: application/json. |
| 429 | rate_limited | Limite excedido. Aguarde os segundos do cabeçalho Retry-After antes de repetir. |
| 500 | internal | Erro interno. Em ativações, repita somente com a MESMA Idempotency-Key. Sem ela, confirme com suporte antes de repetir. |
| 403 | management_required | Gestão não autorizada, revogada ou conta indisponível. Solicite novo consentimento ou intervenção administrativa. |
Provedores e escopo
Provedores usam o painel web para código, DNS e plano. Ainda não há API pública por chave para provedores, compra de créditos, vouchers ou administração. As rotas internas dos painéis e do app não fazem parte deste contrato.
A API não fornece listas/canais e não transporta mídia. Datas são ISO 8601 UTC. Aceite campos adicionais em respostas e novos valores de plano. Contrato e exemplos estão disponíveis em OpenAPI e Markdown nos links acima.