Skip to main content
A integração com o Bluube consiste em fazer uma chamada HTTP ao endpoint de validação quando seu software inicializa. Se a licença for inválida ou expirada, você bloqueia o acesso — se for válida, o software funciona normalmente. O Bluube funciona com qualquer biblioteca HTTP. Não é necessário instalar um SDK dedicado.
Nunca inclua seu api_key diretamente no código-fonte. Se o executável for descompilado, a chave ficará exposta e qualquer pessoa poderá manipular as licenças da sua aplicação. Use variáveis de ambiente ou um arquivo de configuração externo que não seja distribuído junto com o software.

Autenticação

Todas as requisições à API do Bluube exigem o cabeçalho Authorization com o api_key da sua aplicação no formato Bearer:
Authorization: Bearer blv1_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Validar uma licença na inicialização

O endpoint de validação recebe a chave de licença do usuário e retorna se ela é válida, expirada ou inválida.
POST https://api.bluube.com/v1/validate
Payload:
{
  "key": "A1B2-C3D4-E5F6-G7H8",
  "app_id": "app_01j9k2m3n4p5q6r7s8t9",
  "device_id": "identificador-unico-do-dispositivo"
}
O campo device_id é usado para controle de ativações por dispositivo. Pode ser um hash do identificador único da máquina.

Respostas possíveis

Status HTTPvalidstatusSignificado
200trueactiveLicença ativa e dentro do prazo.
200falseexpiredLicença expirada.
200falsenot_foundChave não encontrada.
200falsesuspendedLicença suspensa pelo administrador.
429Limite de requisições atingido. Aplique retry com backoff.

Exemplos de integração

Os exemplos abaixo implementam a validação completa: chamada à API, tratamento dos possíveis resultados e bloqueio do acesso quando necessário.
import os
import hashlib
import time
import requests

BLUUBE_APP_ID = os.environ["BLUUBE_APP_ID"]
BLUUBE_API_KEY = os.environ["BLUUBE_API_KEY"]
BLUUBE_API_URL = "https://api.bluube.com/v1/validate"


def get_device_id() -> str:
    """Gera um identificador único e anônimo para o dispositivo."""
    import platform
    raw = platform.node() + platform.machine() + platform.processor()
    return hashlib.sha256(raw.encode()).hexdigest()


def validate_license(license_key: str, retries: int = 3) -> dict:
    """Valida a licença com retry automático em caso de erro temporário."""
    payload = {
        "key": license_key,
        "app_id": BLUUBE_APP_ID,
        "device_id": get_device_id(),
    }
    headers = {
        "Authorization": f"Bearer {BLUUBE_API_KEY}",
        "Content-Type": "application/json",
    }

    for attempt in range(retries):
        try:
            response = requests.post(BLUUBE_API_URL, json=payload, headers=headers, timeout=10)
            response.raise_for_status()
            return response.json()
        except requests.exceptions.Timeout:
            if attempt < retries - 1:
                time.sleep(2 ** attempt)  # backoff exponencial
            else:
                raise
        except requests.exceptions.HTTPError as e:
            if e.response.status_code == 429:
                time.sleep(2 ** attempt)
            else:
                raise


def check_license_at_startup(license_key: str) -> None:
    """Bloqueia a execução se a licença não for válida."""
    result = validate_license(license_key)

    if result.get("valid"):
        print("Licença válida. Iniciando aplicação...")
    else:
        status = result.get("status")
        if status == "expired":
            print("Sua licença expirou. Renove em app.bluube.com.")
        elif status == "suspended":
            print("Sua licença está suspensa. Entre em contato com o suporte.")
        else:
            print("Licença inválida ou não encontrada.")
        exit(1)


# Ponto de entrada
if __name__ == "__main__":
    user_license_key = input("Digite sua chave de licença: ")
    check_license_at_startup(user_license_key)
    # ... restante da inicialização do app

Cache da validação

Não chame a API de validação a cada ação do usuário. Armazene o resultado em memória com um TTL de 1 a 4 horas. Isso reduz a latência percebida, diminui o consumo de cota de requisições e mantém o software funcional em caso de indisponibilidade temporária da rede. Invalide o cache e revalide imediatamente se o usuário informar que renovou a licença.
Exemplo de cache simples em memória:
import time

_license_cache: dict = {}
CACHE_TTL_SECONDS = 3600  # 1 hora


def validate_license_cached(license_key: str) -> dict:
    cached = _license_cache.get(license_key)
    if cached and time.time() < cached["expires_at"]:
        return cached["data"]

    data = validate_license(license_key)
    _license_cache[license_key] = {
        "data": data,
        "expires_at": time.time() + CACHE_TTL_SECONDS,
    }
    return data

Tratamento de erros de rede

Se a API do Bluube estiver inacessível no momento da validação, você tem duas opções:
  • Modo permissivo: permitir o uso por um período de graça (ex.: 24 horas) e revalidar quando a conectividade for restaurada. Adequado para software que pode funcionar offline.
  • Modo restritivo: bloquear o acesso imediatamente. Adequado para software com requisitos de segurança mais rígidos.
Os exemplos acima implementam retry automático com backoff exponencial para erros temporários (429 e timeouts). Adapte a lógica de fallback conforme a política de licenciamento do seu produto.

Próximos passos

Com a validação integrada, considere também implementar a ativação por dispositivo para controlar o max_activations. Consulte Gerenciar Licenças para entender como o campo activations_count se comporta ao longo do ciclo de vida de uma licença.