OpenAPI Provisioning

Corresponding example: examples/posix/pair/api-activate/

tip

OpenAPI Provisioning requires creating a new cloud project and associating an App. First follow Create an App and a cloud project to complete the cloud-side configuration.

This chapter introduces the third Provisioning method: without relying on the Tuya App, use the Tuya OpenAPI (Cloud API) to create the user and generate the Provisioning token on the server side, then pass the token to the device to complete Activation.

The first two Provisioning methods both require users to install and use the Tuya App to complete scan-based Provisioning. However, in some scenarios, device manufacturers may:

  • Have their own App or backend system and do not want to depend on the Tuya App
  • Have devices with neither a screen nor a camera

In this case, you can use the Tuya OpenAPI to synchronize the user and generate the Provisioning token directly on the server side, then pass the token to the device by any means (serial port, Bluetooth, HTTP, etc.). The device then calls iot_client_init_on_boarding_with_token() to complete Activation.

Overall flow​

[Server / script] [Device]
| |
| 1. POST /v1.0/apps/{schema}/user |
| (create/sync user, obtain uid) |
| |
| 2. POST /v1.0/device/paring/token |
| (generate Provisioning token, region, secret) |
| |
| 3. Concatenate {region}{token}{secret} |
| Pass to device ----------------------> |
| |
| 4. iot_client_init_on_boarding_with_token()
| (activate the device with the token)
| |
| 5. GET /v1.0/device/paring/tokens/{token} |
| (poll to confirm the Provisioning result) |

OpenAPIs involved​

1. User sync — POST /v1.0/apps/{schema}/user​

Create or synchronize a user in the Tuya cloud; returns the user's uid.

ParameterTypeRequiredDescription
country_codestringYesCountry code, e.g. "86"
usernamestringYesUsername
passwordstringYesPassword (MD5 hash)
username_typeintYes1 = mobile number, 2 = email, 3 = other

2. Generate a Provisioning token — POST /v1.0/device/paring/token​

ParameterTypeRequiredDescription
uidstringYesUser uid
paring_typestringYesProvisioning type: BLE, AP, EZ
time_zone_idstringYesTime zone

3. Query the Provisioning result — GET /v1.0/device/paring/tokens/{token}​

Query whether the device has completed Activation with this token.

4. Device reset (restore factory defaults) — POST /v2.0/cloud/thing/{device_id}/reset​

Unbind the device and restore it to factory defaults based on the device ID. After a reset, the binding between the device and the original user is cleared, and the device must go through the Provisioning and Activation flow again before it can be used.

ParameterTypeLocationRequiredDescription
device_idstringpathYesDevice ID

Return example:

{
"tid": "b8a2b49abbbc11eda71e169efc83a172",
"result": true,
"t": 1678065474602,
"success": true
}

After the device receives the reset notification from the cloud, it should clear the locally stored Activation information (uuid, authkey, etc.) and return to the pending-Provisioning state.

Reference: Restore Factory Defaults

Token format​

The token the device receives must be concatenated from three parts:

{region}{token}{secret}

For example: region="AY", token="H73H8u7A", secret="p4pX" → the complete token is AYH73H8u7Ap4pX.

The device-side iot_client_init_on_boarding_with_token() automatically parses the Region information from the first two characters.

Environment configuration​

Environment variableDescriptionExample
TUYA_CLIENT_IDTuya IoT Platform Access IDxwm........
TUYA_CLIENT_SECRETTuya IoT Platform Access Secret95f13d4a616d407a...
TUYA_BASE_URLOpenAPI endpointhttps://openapi.tuyacn.com
SCHEMAApp schema identifier (used by the shell script; the Python script also supports the TUYA_SCHEMA or --schema argument)marsid

TUYA_BASE_URL for each data center:

Data centerURL
Chinahttps://openapi.tuyacn.com
US Westhttps://openapi.tuyaus.com
Europehttps://openapi.tuyaeu.com
Indiahttps://openapi.tuyain.com

Running the example​

export TUYA_CLIENT_ID="your_client_id"
export TUYA_CLIENT_SECRET="your_secret"
export TUYA_BASE_URL="https://openapi.tuyacn.com"
export SCHEMA="your_schema"

# One-shot script
./build/activate-demo.sh

# Or run step by step
python3 ./build/tuya_openapi.py sync-user --schema marsid --country-code 86 \
--username "test_user" --password "mypassword" --username-type 3

python3 ./build/tuya_openapi.py pairing-token --uid "ay..." --paring-type BLE \
--time-zone-id "Asia/Shanghai"

./build/activate_demo "$PAIRING_TOKEN" <uuid> <authkey> <product_key>

# Unbind after activation and print binding status before and after the reset
./build/activate_demo "$PAIRING_TOKEN" <uuid> <authkey> <product_key> --release

--release queries cloud binding status before and after iot_client_reset(), printing enable (still bound), reset (unbound), or reset_factory (factory reset requested). A failed query prints its error code. After unbinding, the cloud may reject the old device credentials; the demo reports that query failure as returned. The final query calls iot_get_binding_status() with credentials saved before reset destroyed the original client. It does not create another client.

Notes​

  • The Provisioning token has an expiry; the device must complete Activation before it expires. You can poll for the result with tuya_openapi.py pairing-result --poll (--timeout defaults to 100 seconds).
  • tuya_openapi.py is implemented with the Python standard library and requires no extra dependencies.
  • In a real product, OpenAPI calls should be made in the manufacturer's own backend service; do not expose the Access Secret on the client or the device.
© 2026 Tuya Inc.Tuya Physical AI · Agentic-kit