perkun.eu Services Portfolio Blog About Contact PL
← Blog

5/15/2023

Tuya Cloud API — control smart home devices from your own application

TL;DR: Tuya Cloud API lets you control Tuya devices programmatically — Python + requests, OAuth token, GET/POST to the API. No dependence on the official mobile app.

Most cheap smart home devices on AliExpress and in European shops run on the Tuya platform. Bulbs, plugs, sensors, thermostats, blinds — behind the official Tuya Smart or Smart Life app lies a unified API. When you want to automate without Home Assistant or build your own control panel, Tuya Cloud API is the right place to start.

Registering on the Tuya IoT Platform

Start by creating an account at iot.tuya.com. After logging in, create a new project under Cloud → Development → Create Cloud Project. Select the project category — for smart home, “Smart Home” is sufficient. The platform will generate a Client ID and Client Secret — these will be your API keys.

Then, in the Devices → Link Tuya App Account section, you need to link your account from the Tuya Smart app (the one you use to configure physical devices). This is a step many people skip and then wonder why their device list is empty. After linking the account, your UID will appear — needed for device list queries.

Authentication

Tuya API uses OAuth 2.0 with HMAC-SHA256 signing. Every request must be signed with a combination of Client ID, timestamp, and query string. Full Python implementation:

import hashlib
import hmac
import time
import requests

CLIENT_ID = "twoj_client_id"
CLIENT_SECRET = "twoj_client_secret"
BASE_URL = "https://openapi.tuyaeu.com"

def get_token():
    timestamp = str(int(time.time() * 1000))
    string_to_sign = CLIENT_ID + timestamp
    sign = hmac.new(
        CLIENT_SECRET.encode(),
        string_to_sign.encode(),
        hashlib.sha256
    ).hexdigest().upper()

    headers = {
        "client_id": CLIENT_ID,
        "sign": sign,
        "t": timestamp,
        "sign_method": "HMAC-SHA256"
    }
    resp = requests.get(f"{BASE_URL}/v1.0/token?grant_type=1", headers=headers)
    return resp.json()["result"]["access_token"]

Important: for Europe the endpoint is openapi.tuyaeu.com. For the US: openapi.tuyaus.com. Signing authenticated token requests works similarly, but the string to sign also includes the token itself.

Device list and status

Once you have a token, you can fetch device data. Endpoint for the user’s device list:

def get_devices(token, uid):
    resp = requests.get(
        f"{BASE_URL}/v1.0/users/{uid}/devices",
        headers={"client_id": CLIENT_ID, "access_token": token, ...}
    )
    return resp.json()["result"]

The example response contains id (device_id), name, category (e.g. dj for bulbs, cz for plugs), and online (boolean). You fetch the current device state via:

GET /v1.0/devices/{device_id}/status

The response is a list of objects like {"code": "switch_1", "value": true} — the codes depend on the device category.

Controlling a device

Control is done via POST with an array of commands:

def control_device(token, device_id, commands):
    payload = {"commands": commands}
    resp = requests.post(
        f"{BASE_URL}/v1.0/devices/{device_id}/commands",
        headers={"client_id": CLIENT_ID, "access_token": token, ...},
        json=payload
    )
    return resp.json()

# Turn on a plug
control_device(token, "abc123", [{"code": "switch_1", "value": True}])

# Set bulb brightness to 50%
control_device(token, "xyz789", [
    {"code": "bright_value_v2", "value": 500},
    {"code": "colour_temperature_v2", "value": 400}
])

Command codes for each device category can be found in the Tuya documentation under “Standard Instruction Set”.

Pitfalls

The access token expires after 2 hours. In a production application, you need to handle automatic refresh — Tuya returns a refresh_token alongside the access_token. The API rate limit allows a maximum of 5 requests per second per device — when controlling multiple devices simultaneously, add delays.

Command names vary between device categories. A plug has switch_1, a bulb has switch_led, an air conditioner has switch. The simplest approach is to fetch the current device status and inspect the returned codes — then you know exactly what to control.

Summary

Tuya Cloud API is a good entry point for programmatic smart home automation. It works with thousands of devices available across Europe. For more advanced scenarios where low latency or independence from the internet is important, it’s worth looking into local Tuya integration over LAN (the tinytuya Python project). But as a starting point — the cloud API is the simplest path.