Overview & Quick Start
Product Overview
Tuya's open capabilities for end users, covering 3,000+ smart hardware categories across 200+ countries and regions. With this API you can: • Query homes, rooms, devices and their status • Issue control commands (on/off, brightness, temperature, mode, etc.) • Subscribe to real-time device property changes and online/offline events • Query weather information • Send SMS, voice calls, emails, and App push notifications • Query device energy usage and other statistics • Trigger IPC camera cloud snapshots and short video recordings
Get API Key
API Key format: sk-<PREFIX><rest>. The first two letters of the prefix determine the data center region. China users: https://tuyasmart.com/ International users: https://tuya.ai/
Auth & Data Centers
Authentication
All REST API requests authenticate via HTTP Header:
Authorization: Bearer {API_KEY}
Example:
curl -H "Authorization: Bearer sk-AYxxx..." \
https://openapi.tuyacn.com/v1.0/end-user/homes/allData Center Mapping
The first two chars after sk- auto-map to a data center: • AY → China → openapi.tuyacn.com • AZ → US West → openapi.tuyaus.com • EU → Central EU → openapi.tuyaeu.com • IN → India → openapi.tuyain.com • UE → US East → openapi-ueaz.tuyaus.com • WE → West EU → openapi-weaz.tuyaeu.com • SG → Singapore → openapi-sg.iotbing.com
Home & Space Management
Returns all homes for the current user, including home ID, name, role, and geo-location.
Response Example
{
"success": true,
"result": {
"homes": [
{
"home_id": "123456",
"name": "My Apartment",
"role": "admin",
"create_time": 1593661208,
"latitude": {"Value": "30.3"},
"longitude": {"Value": "120.07"}
}
]
}
}Field Descriptions
| Field | Type | Description |
|---|---|---|
| home_id | String | Home ID |
| name | String | Home name |
| role | String | User role: owner / admin / member |
| create_time | Long | Creation time (Unix timestamp, seconds) |
| latitude/longitude | Object | Home geo-location (optional), usable for weather queries |
Returns all rooms in the specified home, including room ID and name.
Request Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| home_id | String | Yes | Home ID (path parameter) |
Response Example
{
"success": true,
"result": {
"rooms": [
{ "room_id": "123123", "name": "Living Room" }
]
}
}Device Query
Returns all devices for the current user in a single response (no pagination). Includes device ID, name, category, and online status.
Response Example
{
"success": true,
"result": {
"devices": [
{
"device_id": "0620068884f3eb414579",
"name": "Living Room Light",
"category": "dj",
"category_name": "Light Source",
"online": true
}
],
"total": 3
}
}Field Descriptions
| Field | Type | Description |
|---|---|---|
| device_id | String | Device ID |
| name | String | Device name |
| category | String | Category code |
| category_name | String | Category name |
| online | Boolean | Whether the device is online |
Returns all devices in the specified home.
Request Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| home_id | String | Yes | Home ID (path parameter) |
Returns all devices in the specified room.
Request Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| room_id | String | Yes | Room ID (path parameter) |
Returns full device info including all current property states (properties field is a key-value map). result is null if device not found.
Request Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| device_id | String | Yes | Device ID (path parameter) |
Response Example
{
"success": true,
"result": {
"device_id": "0620068884f3eb414579",
"name": "Living Room Light",
"online": true,
"firmware_version": "1.0.0",
"firmware_update_available": false,
"properties": {
"switch_led": true,
"bright_value": 100,
"work_mode": "colour"
}
}
}Field Descriptions
| Field | Type | Description |
|---|---|---|
| online | Boolean | Whether the device is online |
| firmware_update_available | Boolean | Whether a firmware update is available |
| properties | Map | Current device property key-value map; key is the dp code |
Device Control
The Thing Model describes what functional properties the device supports. Recommended before issuing commands. Note: result.model is a JSON string — must be parsed again (JSON.parse).
Request Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| device_id | String | Yes | Device ID (path parameter) |
Response Example
{
"services": [{
"properties": [
{
"code": "switch_led",
"name": "Switch",
"accessMode": "rw",
"typeSpec": { "type": "bool" }
},
{
"code": "bright_value",
"name": "Brightness",
"accessMode": "rw",
"typeSpec": { "type": "value", "min": 10, "max": 1000, "step": 1 }
}
]
}]
}Field Descriptions
| Field | Type | Description |
|---|---|---|
| code | String | Property code — used as key when issuing commands |
| accessMode | String | ro = read-only / wr = write-only / rw = read-write |
| typeSpec.type | String | bool / value / enum / string |
| typeSpec.min/max | Number | Value range for numeric properties (value type only) |
| typeSpec.range | Array | Allowed values list (enum type only) |
Send control commands to a device. Note: the properties field must be a JSON string (not an object) — double-serialize the property object.
Request Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| device_id | String | Yes | Device ID (path parameter) |
| properties | String | Yes | Serialized JSON string of property key-value pairs |
Response Example
// Request body
{
"properties": "{\"switch_led\": true, \"bright_value\": 500}"
}
// Success response
{ "success": true, "t": 1710234567890, "result": {} }Device Management
Update the display name of a device.
Request Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| device_id | String | Yes | Device ID (path parameter) |
| name | String | Yes | New device name (request body) |
Response Example
// Request body
{ "name": "Bedside Lamp" }Weather Service
Returns current and hourly weather forecast for a given lat/lon. Response key format: {property_code}.{time_index} — index 0 = current, 1 = 1 hour later, etc.
Request Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| lat | String | Yes | Latitude (query parameter) |
| lon | String | Yes | Longitude (query parameter) |
| codes | String | Yes | JSON array string of weather codes, e.g. ["w.temp","w.humidity","w.hour.7"] |
Response Example
GET /v1.0/end-user/services/weather/recent
?codes=["w.temp","w.humidity","w.condition","w.hour.7"]
&lat=39.9042&lon=116.4074
// Response
{
"result": {
"data": {
"w.temp.0": 7,
"w.temp.1": 6,
"w.humidity.0": 44,
"w.condition.0": "no precipitation"
},
"expiration": 15
}
}Field Descriptions
| Field | Type | Description |
|---|---|---|
| w.temp | Number | Temperature |
| w.humidity | Number | Humidity |
| w.condition | String | Weather description (English) |
| w.pressure | Number | Atmospheric pressure |
| w.realFeel | Number | Feels-like temperature |
| w.uvi | Number | UV index |
| w.windDir | String | Wind direction |
| w.windSpeed | Number | Wind speed |
| w.hour.N | String | Time granularity — N is the number of hours (e.g. w.hour.7 returns the next 7 hours) |
Notifications
Notes
All notification APIs are self-send only — messages can only be sent to the currently logged-in user. Rate limits: • SMS/Voice: max 15 per phone per 24h; max 2 identical messages per 50s • Email: max 30 per email per 24h; max 2 identical messages per 50s
Send an SMS to the current user's phone number. Rate limit: ≤15/24h; ≤2 identical messages/50s.
Request Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| message | String | Yes | SMS content (request body) |
Response Example
{ "message": "Security alert: door sensor detected abnormal opening" }Initiate a voice call to the current user's phone number. Same rate limits as SMS.
Request Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| message | String | Yes | Voice message content (request body) |
Response Example
{ "message": "Security alert: abnormal activity detected" }Send an email to the current user's email address. Rate limit: ≤30/24h.
Request Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| subject | String | Yes | Email subject (request body) |
| content | String | Yes | Email body (request body) |
Response Example
{ "subject": "Device Offline Alert", "content": "Your living room AC went offline" }Send a push notification to the current user's Tuya App.
Request Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| subject | String | Yes | Push title (request body) |
| content | String | Yes | Push content (request body) |
Response Example
{ "subject": "Security Alert", "content": "Camera detected motion at entrance" }Data Statistics
Recommended Workflow
1. Call the statistics config API first to confirm the supported dp_code and statistic_type for the device. 2. Then call the statistics data API to fetch values. Note: time window must not exceed 24 hours. For longer ranges, make multiple requests and merge the results.
Returns the statistics capabilities for all devices of the current user.
Response Example
{
"result": [
{
"dev_id": "0620068884f3eb414579",
"dp_id": 17,
"dp_code": "ele_usage",
"statistic_type": "SUM",
"interval": "hour"
}
]
}Field Descriptions
| Field | Type | Description |
|---|---|---|
| dp_code | String | Data point code, e.g. ele_usage (energy usage) |
| statistic_type | String | Aggregation type: SUM / COUNT / MAX / MIN |
Query statistics data for a device within a time range. Time format: yyyyMMddHH. Max window: 24 hours.
Request Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| dev_id | String | Yes | Device ID |
| dp_code | String | Yes | Data point code |
| statistic_type | String | Yes | Aggregation type (SUM/COUNT/MAX/MIN) |
| start_time | String | Yes | Start time, format yyyyMMddHH, e.g. 2024010110 |
| end_time | String | Yes | End time, format yyyyMMddHH (must be within 24h of start_time) |
Response Example
{
"result": [
{"2024010110": "123.45"},
{"2024010111": "234.56"}
]
}IPC Cloud Capture
Flow Overview
IPC capture is a two-step process: 1. Allocate — trigger the camera to capture, get cloud storage location 2. Resolve — poll until capture is done, then retrieve the accessible media URL The Python SDK wraps both steps into a single call with automatic polling and retry.
Trigger the camera device to perform a cloud snapshot or short video recording.
Request Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| device_id | String | Yes | Camera device ID (path parameter) |
| capture_json | String | Yes | Capture config JSON string with capture_type (PIC/VIDEO), pic_count (1-5), video_duration_seconds (1-60) |
Response Example
{
"capture_json": "{\"device_id\":\"your_device_id\",\"capture_type\":\"PIC\",\"pic_count\":1}"
}Poll for the capture result URL. If status is NOT_READY, wait and retry (recommended interval: every 2 seconds).
Request Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| device_id | String | Yes | Camera device ID (path parameter) |
Response Example
// Success (PIC)
{
"status": "READY",
"decrypt_image_url": "https://..."
}
// Success (VIDEO)
{
"status": "READY",
"decrypt_video_url": "https://...",
"decrypt_cover_url": "https://..."
}
// Still processing
{ "status": "NOT_READY" }Real-time Events (WebSocket)
Important Restrictions
The WebSocket client must run server-side only. Direct connections from browsers or mobile clients are prohibited to prevent API Key exposure. To push real-time data to the frontend, have the server subscribe and relay events via SSE, a custom WebSocket, or polling.
Message Format
All WebSocket messages are JSON with two top-level fields: eventType and data.
Property change event:
{
"eventType": "devicePropertyChange",
"data": {
"devId": "36040531cc50e35ee60d",
"status": [
{ "code": "led_switch", "value": true, "time": 1773668532000 }
]
}
}
Online/offline event:
{
"eventType": "onlineStatusChange",
"data": {
"devId": "6c8b3a57470efd4d9cun7h",
"status": "online",
"time": 1773668467323
}
}WebSocket URI
• AY → wss://wsmsgs.tuyacn.com • AZ → wss://wsmsgs.iot-wus.com • EU → wss://wsmsgs.iot-eu.com • IN → wss://wsmsgs.iot-ap.com • UE → wss://wsmsgs.iot-eus.com • WE → wss://wsmsgs.iot-weu.com • SG → wss://wsmsgs.iot-sea.com
Error Handling
Common Error Codes
• 1010 — Token invalid or expired → Refresh API Key • 1108 — Invalid API path → Check the request path • 10001 — Invalid request parameters → Validate parameter format • 10010 — User not found → Check API Key validity • 10011 — User has no contact info → Bind phone/email in Tuya App • 40000901 — Device not found → Check device_id • 40000903 — Device Thing Model not found → Device may not support Thing Model • 429 — Rate limit exceeded → Retry with exponential backoff • 500 — Server error → Retry later
Notification Error Codes
• 20001 — Invalid phone number • 20002 — SMS daily limit exceeded (15/24h) • 20003 — Same content sent too frequently (50s cooldown) • 30001 — Invalid email address • 30002 — Email daily limit exceeded (30/24h) • 40002 — Voice call daily limit exceeded (15/24h)
Business Exception Handling
• Device result is null → Device not found or no permission • Device online is false → Device offline; do not issue commands • Property accessMode is ro → Read-only; cannot be controlled • Property value out of range → Show valid range and ask user to re-enter • Multiple devices match same name → List all candidates and ask user to confirm
