Tuya · Guia técnico

Como integrar a API Tuya Cloud: guia passo a passo

Do projeto de nuvem ao primeiro comando enviado a um dispositivo. Este guia cobre a sequência completa — credenciais, data center, vínculo de conta, token, assinatura HMAC-SHA256, leitura de estado e envio de comandos — e os erros que travam praticamente toda integração de primeira viagem.

Por NasteSoft Leitura de 12 min

A API Tuya Cloud — oficialmente a Tuya OpenAPI — é o caminho servidor a servidor para ler, comandar e automatizar dispositivos da plataforma Tuya a partir do seu próprio software. Ela é bem documentada, mas a documentação é enorme e organizada por referência, não por percurso. Quem chega pela primeira vez costuma perder dias em três ou quatro detalhes que não aparecem em destaque.

Este guia é o percurso. A ordem importa: pular uma etapa faz a seguinte falhar com uma mensagem que não explica o motivo real.

Antes de começar

A Tuya evolui os endpoints e reorganiza os planos com frequência. Os caminhos e nomes aqui refletem o comportamento estável da plataforma, mas confirme sempre contra o console e a documentação oficial da sua conta antes de fixar algo em produção.

1. O que você precisa antes de escrever código

A integração pela API Cloud não pareia dispositivos. Ela enxerga dispositivos que já foram instalados e vinculados a uma conta. Então você precisa de três coisas prontas:

  • Os dispositivos já pareados em um aplicativo Tuya Smart ou Smart Life.
  • Uma conta no Tuya IoT Development Platform (o console de desenvolvedor, distinto da conta do aplicativo).
  • Saber em qual data center a conta do aplicativo vive — o detalhe que mais causa confusão.

Se o seu caso exige que o usuário final instale os dispositivos pelo seu app, a API Cloud sozinha não resolve — você vai precisar do App SDK. Comparamos os dois caminhos em detalhe aqui.

2. Criar o projeto de nuvem e pegar as credenciais

No console de desenvolvedor, crie um projeto do tipo de desenvolvimento em nuvem. Na criação você escolhe o setor de atuação e, principalmente, a região de disponibilidade. Ao terminar, o projeto expõe duas credenciais na aba de visão geral:

  • Access ID — também chamado de client_id.
  • Access Secret — o segredo usado para assinar cada requisição. Nunca vai para o front-end.

Assinar os produtos de API

Este é o primeiro tropeço clássico. Ter o projeto não dá acesso a nada: cada família de endpoints é um produto que precisa ser assinado e depois autorizado para aquele projeto específico. Os essenciais para começar costumam ser os de gestão de dispositivo e de estado, além do serviço de autorização.

A Tuya oferece um período de avaliação gratuito, em geral prorrogável uma vez. Se você assinar o produto mas esquecer de autorizá-lo no projeto, as chamadas voltam com erro de permissão — e a mensagem não diz que o problema é esse.

3. Escolher o data center certo

A Tuya opera regiões independentes, e a conta do usuário do aplicativo pertence a uma delas, definida quando a conta foi criada, com base no país informado. Se o seu código apontar para a região errada, a autenticação até funciona — e a lista de dispositivos volta vazia, sem nenhuma indicação do motivo.

RegiãoEndpoint base
América — Oeste (padrão para o Brasil na maioria dos casos)https://openapi.tuyaus.com
Europa — Centralhttps://openapi.tuyaeu.com
Chinahttps://openapi.tuyacn.com
Índiahttps://openapi.tuyain.com

Contas brasileiras normalmente caem na região das Américas. Mas "normalmente" não é garantia: se a conta foi criada com outro país selecionado, ela ficou em outro data center e não há como movê-la. Na dúvida, teste as duas mais prováveis — a que devolver dispositivos é a certa.

4. Vincular a conta do aplicativo ao projeto

Com o projeto criado, os dispositivos ainda não aparecem. É preciso vincular a conta do app onde eles estão cadastrados. No console isso fica na área de dispositivos do projeto, na opção de associação por conta de aplicativo: o console mostra um QR Code que você lê com o próprio aplicativo Tuya Smart ou Smart Life, autenticado com a conta dona dos dispositivos.

Atenção operacional

Esse vínculo é frágil por natureza. Se alguém desvincular a conta, trocar a senha de forma que invalide a sessão ou remover a associação no console, todos os dispositivos somem de uma vez da sua integração. O sintoma no seu sistema é uma lista vazia — não um erro.

Trate lista vazia como estado anômalo e alerte. Em projetos de produção, isso poupa horas de investigação no dia em que acontecer.

5. A assinatura HMAC-SHA256

Toda chamada à OpenAPI é assinada. É aqui que a maioria das integrações trava, porque a assinatura do pedido de token é ligeiramente diferente da assinatura das demais chamadas — e a diferença é fácil de não perceber.

A montagem tem duas partes. Primeiro, a string canônica da requisição:

stringToSign =
    MÉTODO           + "\n" +   // GET, POST…
    SHA256(corpo)    + "\n" +   // hex minúsculo; corpo vazio também tem hash
    cabeçalhosAssinados + "\n" + // normalmente vazio
    caminho + query             // query com parâmetros ordenados alfabeticamente

Depois, a string que efetivamente vai para o HMAC:

# Requisição de TOKEN — sem access_token
str = client_id + t + nonce + stringToSign

# Demais requisições — COM access_token
str = client_id + access_token + t + nonce + stringToSign

sign = HMAC_SHA256(str, access_secret) em hexadecimal MAIÚSCULO

O t é o instante atual em milissegundos — não em segundos. O nonce é opcional; se você não usar, ele entra como string vazia na concatenação, e não como a palavra "null". O hash do corpo vazio não é vazio: é o SHA-256 da string vazia.

Implementação de referência em Python

import hashlib, hmac, time, json, requests

BASE   = "https://openapi.tuyaus.com"
CLIENT = "seu_access_id"
SECRET = "seu_access_secret"

EMPTY_BODY_HASH = hashlib.sha256(b"").hexdigest()

def _sign(method, path, body="", token=""):
    t = str(int(time.time() * 1000))
    content_hash = hashlib.sha256(body.encode()).hexdigest() if body else EMPTY_BODY_HASH
    string_to_sign = f"{method}\n{content_hash}\n\n{path}"
    payload = CLIENT + token + t + string_to_sign
    sign = hmac.new(
        SECRET.encode(), payload.encode(), hashlib.sha256
    ).hexdigest().upper()
    headers = {
        "client_id": CLIENT,
        "sign": sign,
        "t": t,
        "sign_method": "HMAC-SHA256",
    }
    if token:
        headers["access_token"] = token
    if body:
        headers["Content-Type"] = "application/json"
    return headers

def get_token():
    path = "/v1.0/token?grant_type=1"
    r = requests.get(BASE + path, headers=_sign("GET", path))
    data = r.json()
    if not data.get("success"):
        raise RuntimeError(data)
    return data["result"]["access_token"]

def api_get(path, token):
    r = requests.get(BASE + path, headers=_sign("GET", path, token=token))
    return r.json()

def api_post(path, token, payload):
    body = json.dumps(payload, separators=(",", ":"))
    r = requests.post(
        BASE + path, headers=_sign("POST", path, body=body, token=token), data=body
    )
    return r.json()
Detalhe que quebra a assinatura

O corpo usado para calcular o hash tem que ser byte a byte idêntico ao corpo enviado. Serializar o JSON duas vezes, ou deixar a biblioteca HTTP reserializar o dicionário, produz espaçamento diferente e derruba a assinatura. Serialize uma vez, use a mesma string nos dois lugares — é o que o separators e o data=body garantem acima.

6. Listar dispositivos e ler o estado

Com o token na mão, o primeiro objetivo é enxergar os dispositivos. O identificador do dispositivo (device_id) é a chave de tudo daqui pra frente, e você pode obtê-lo pelo console, na lista de dispositivos do projeto, ou pelas APIs de listagem.

token = get_token()

# metadados do dispositivo
print(api_get(f"/v1.0/devices/{DEVICE_ID}", token))

# estado atual — a lista de data points
print(api_get(f"/v1.0/devices/{DEVICE_ID}/status", token))

# o que este modelo aceita como comando
print(api_get(f"/v1.0/devices/{DEVICE_ID}/functions", token))

O endpoint de functions é o mais subestimado dos três. Ele responde exatamente quais comandos aquele modelo aceita, com o tipo e a faixa de cada valor. Consultá-lo uma vez por modelo, durante o desenvolvimento, evita a maior parte das tentativas às cegas.

Data points: o conceito central

A Tuya não expõe "ligar a lâmpada". Ela expõe data points: pares de código e valor que representam cada função do dispositivo. Uma tomada simples pode ter switch_1 booleano; um medidor pode ter cur_power, cur_voltage e cur_current; uma lâmpada colorida tem modo, brilho, temperatura e cor, cada um com sua própria escala.

Esses códigos não são padronizados entre fabricantes. Dois dispositivos da mesma categoria, de marcas diferentes, podem usar códigos distintos para a mesma função — e escalas diferentes para o mesmo valor. Fixar switch_1 no código funciona até chegar o modelo que usa outro identificador.

A arquitetura correta é uma camada de normalização: um mapa por modelo que traduz os data points brutos para o vocabulário do seu domínio. Custa uma tarde para escrever e economiza a reescrita que acontece quando o cliente compra o segundo lote de outro fornecedor.

7. Enviar comandos

api_post(
    f"/v1.0/devices/{DEVICE_ID}/commands",
    token,
    {"commands": [{"code": "switch_1", "value": True}]},
)

Duas coisas importam aqui e costumam ser ignoradas. A primeira: a resposta de sucesso significa que a nuvem aceitou o comando, não que o dispositivo executou. Se o aparelho estiver offline, a chamada retorna sucesso e nada acontece no mundo físico. Confirmação real exige reconsultar o estado ou receber o evento correspondente.

A segunda: comandos em lote no mesmo array são mais eficientes e mais confiáveis do que várias chamadas seguidas — especialmente quando você precisa mudar modo e valor de uma vez, e a ordem importa.

8. Tempo real: pare de fazer polling

O reflexo natural é consultar o endpoint de status em laço. Funciona com cinco dispositivos e desmorona com quinhentos: estoura a cota de requisições, gera custo desnecessário e ainda entrega dado atrasado.

O caminho correto é o serviço de mensageria da Tuya, que publica eventos de mudança de estado, de conexão e de alarme. Você assina a fila do seu projeto e recebe os eventos conforme acontecem. Dois pontos práticos:

  • As mensagens vêm cifradas, com chave derivada do seu Access Secret. Você precisa decifrar antes de usar.
  • A entrega é ao menos uma vez. Eventos podem chegar duplicados ou fora de ordem — seu processamento precisa ser idempotente e usar o carimbo de tempo do evento, não o de recebimento.

Um bom desenho combina os dois: eventos para reagir em tempo real, e uma reconciliação periódica de baixa frequência para corrigir divergências acumuladas.

9. Os erros mais comuns e o que eles realmente significam

SintomaCausa provável
Assinatura inválida Timestamp em segundos em vez de milissegundos; corpo serializado duas vezes; esquecer o access_token na concatenação das chamadas de negócio; relógio do servidor fora de sincronia.
Sem permissão para a API O produto de API não foi assinado, ou foi assinado mas não autorizado para este projeto. Confira na aba de serviços do projeto.
Token inválido ou expirado O token tem validade curta. Sem renovação automática, a integração funciona no teste e falha depois. Trate a expiração como caminho normal, não como exceção.
Lista de dispositivos vazia Data center errado, ou vínculo da conta do aplicativo desfeito. Quase sempre um dos dois — dificilmente é o código.
Dispositivo não encontrado O device_id pertence a outra conta ou a outra região; ou o aparelho foi removido do app e o vínculo caiu junto.
Comando aceito, nada acontece Dispositivo offline, ou o código do data point não existe naquele modelo. Consulte o endpoint de funções do dispositivo específico.

10. O que separa um teste de uma integração de produção

O código acima liga tudo e é suficiente para provar o conceito. Para colocar no ar e dormir tranquilo, faltam seis coisas:

  1. Cache e renovação de token com proteção contra corrida — várias requisições simultâneas não podem disparar várias renovações.
  2. Retentativa com recuo exponencial para falhas temporárias e limites de taxa, com teto e desistência.
  3. Normalização de data points por modelo, isolando o resto do sistema das particularidades de cada fabricante.
  4. Idempotência no consumo de eventos, com deduplicação por identificador e carimbo de tempo.
  5. Observabilidade — registro das chamadas, latência, taxa de erro por endpoint e alerta quando dispositivos ficam offline em bloco.
  6. Segredos fora do código, com rotação prevista. O Access Secret assina tudo; vazá-lo entrega o controle dos dispositivos.

Conclusão

A API Tuya Cloud não é difícil — ela é específica. Praticamente todo o tempo perdido em uma primeira integração se concentra em quatro pontos: a região errada, o produto de API não autorizado, a assinatura montada com uma diferença sutil e o vínculo de conta que ninguém sabia que existia. Resolvidos esses, o resto é uma API REST comum.

A partir daí o trabalho interessante começa: transformar leitura de sensor em decisão, cruzar telemetria com dados do negócio e automatizar o que hoje alguém faz olhando um painel. Escrevemos sobre esse próximo passo aqui.

Precisa dessa integração pronta e funcionando?

A NasteSoft faz integração Tuya de ponta a ponta — e também assume projetos existentes que estão instáveis em produção.

Vamos construir

Tem dispositivos Tuya e precisa de software em volta?

Conte o cenário — quantidade de dispositivos, categorias, se já existe app ou integração. Respondemos com uma leitura honesta do caminho.

Chamar no WhatsApp

WhatsApp +55 41 99511-2870 · e-mail rafael.naste@nastesoft.com.br

WhatsApp