API reqquest example- Get Administrator Token - Imou Open Platform
API request example
Reference: Development specification · accessToken · v2 device APIs: Capability usage.
Using the accessToken API as an example, copy the code below into your project to quickly debug API requests. After you finish debugging this sample, use it as a reference when calling other APIs.
1. Java Example
/**
* Imou Open Platform — accessToken (Get administrator token) Java sample
*
* API docs: https://open.imoulife.com/book/05-api/02.accessToken.html
* Development specification (sign calculation): https://open.imou.com/document/pages/c20750/
*
* Notes:
* 1. Get appId / appSecret from Console → My Applications → Application Info. Do not commit real secrets to the repo.
* 2. accessToken is valid for about 3 days. Refresh only when it is about to expire or TK1002 is returned; avoid frequent calls.
* 3. Replace [DataCenter] in the request host with your application's data center (e.g. sg, or).
* 4. This sample demonstrates the call flow only; appId/appSecret below are placeholders.
*/
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.time.Duration;
import java.time.Instant;
import java.util.Base64;
import java.util.UUID;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
public class AccessTokenDemoEn {
/** Replace with your real data-center host, e.g. openapi-sg.easy4ip.com */
private static final String OPENAPI_HOST = "https://openapi-[DataCenter].easy4ip.com";
/** Replace with the appId from the console (placeholder, not a real value) */
private static final String APP_ID = "your_appId_here";
/** Replace with the appSecret from the console (placeholder, not a real value) */
private static final String APP_SECRET = "your_appSecret_here";
public static void main(String[] args) throws Exception {
log("========== Start requesting accessToken ==========");
String responseBody = requestAccessToken(APP_ID, APP_SECRET);
log("========== Request finished ==========");
log("Raw API response: " + responseBody);
}
/**
* Call the accessToken API to obtain an administrator accessToken.
*
* @param appId Application ID
* @param appSecret Application secret
* @return Raw JSON response body
*/
public static String requestAccessToken(String appId, String appSecret) throws Exception {
// 1. Build auth parameters
log("[Step 1] Generate auth parameters");
long time = Instant.now().getEpochSecond(); // Unix seconds; must be within 5 minutes of server time
String nonce = UUID.randomUUID().toString(); // Must not repeat within 5 minutes
String requestId = UUID.randomUUID().toString(); // Unique ID per request
log(" time = " + time);
log(" nonce = " + nonce);
log(" requestId = " + requestId);
log(" appId = " + appId);
log("[Step 2] Calculate sign (HMAC-SHA256 + Base64)");
String sign = calcSign(time, nonce, appSecret);
log(" sign = " + sign);
// 2. Build request body (params can be an empty object)
log("[Step 3] Build request body");
String body = ""
+ "{"
+ "\"system\":{"
+ "\"ver\":\"1.0\","
+ "\"appId\":\"" + escapeJson(appId) + "\","
+ "\"sign\":\"" + escapeJson(sign) + "\","
+ "\"time\":" + time + ","
+ "\"nonce\":\"" + escapeJson(nonce) + "\""
+ "},"
+ "\"id\":\"" + escapeJson(requestId) + "\","
+ "\"params\":{}"
+ "}";
log(" requestBody = " + body);
// 3. Send POST request
String url = OPENAPI_HOST + "/openapi/accessToken";
log("[Step 4] Send HTTP POST");
log(" url = " + url);
HttpClient client = HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(10))
.build();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.timeout(Duration.ofSeconds(30))
.header("Content-Type", "application/json;charset=UTF-8")
.POST(HttpRequest.BodyPublishers.ofString(body, StandardCharsets.UTF_8))
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8));
log("[Step 5] Response received");
log(" httpStatus = " + response.statusCode());
if (response.statusCode() / 100 != 2) {
log(" error body = " + response.body());
throw new IllegalStateException("Unexpected HTTP status: " + response.statusCode() + ", body=" + response.body());
}
return response.body();
/*
* Successful data example:
* {
* "result": {
* "code": "0",
* "msg": "Successful operation.",
* "data": {
* "accessToken": "At_xxxxxxxx",
* "expireTime": 259176 // remaining validity in seconds
* }
* },
* "id": "..."
* }
*/
}
/**
* Calculate sign per https://open.imou.com/document/pages/c20750/
* 1) SIGN_TEMPLATE = time:{time},nonce:{nonce},appSecret:{appSecret}
* 2) password = LowerCase(Hex(SHA-256(appSecret)))
* 3) sign = Base64(HMAC-SHA256(SIGN_TEMPLATE, password))
*
* Official verification sample:
* time=1706511734
* nonce=f5a1ae2d-c09c-4d39-a744-83a5c2c653c2
* appSecret=test123456789test123456789
* expected sign=xjhCQBoJ9hRDsCjyDcHjtDNzRZ3ZJezcawsfWeiaoxU=
*/
public static String calcSign(long time, String nonce, String appSecret) throws Exception {
String signTemplate = "time:" + time + ",nonce:" + nonce + ",appSecret:" + appSecret;
// Mask appSecret in logs to avoid leaking secrets to console/log files
String rawForLog = "time:" + time + ",nonce:" + nonce + ",appSecret:***";
log(" sign raw string (masked) = " + rawForLog);
// password = LowerCase(Hex(SHA-256(appSecret)))
MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
byte[] secretDigest = sha256.digest(appSecret.getBytes(StandardCharsets.UTF_8));
StringBuilder passwordBuilder = new StringBuilder(64);
for (byte b : secretDigest) {
passwordBuilder.append(String.format("%02x", b));
}
String password = passwordBuilder.toString();
// sign = Base64(HMAC-SHA256(SIGN_TEMPLATE, password))
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(password.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
byte[] digest = mac.doFinal(signTemplate.getBytes(StandardCharsets.UTF_8));
return Base64.getEncoder().encodeToString(digest);
}
/** Unified log prefix for easy step-by-step reading in the console. */
private static void log(String message) {
System.out.println("[AccessTokenDemoEn] " + message);
}
/** Simple JSON escaping for placeholders (prefer Jackson / Gson in production). */
private static String escapeJson(String value) {
if (value == null) {
return "";
}
return value
.replace("\\", "\\\\")
.replace("\"", "\\\"");
}
}
2. Python Example
"""
Imou Open Platform — accessToken (Get administrator token) Python sample
API docs: https://open.imoulife.com/book/05-api/02.accessToken.html
Development specification (sign calculation): https://open.imou.com/document/pages/c20750/
Notes:
1. Get appId / appSecret from Console → My Applications → Application Info. Do not commit real secrets to the repo.
2. accessToken is valid for about 3 days. Refresh only when it is about to expire or TK1002 is returned; avoid frequent calls.
3. Replace [DataCenter] in the request host with your application's data center (e.g. sg, or).
4. This sample demonstrates the call flow only; appId/appSecret below are placeholders.
"""
from __future__ import annotations
import base64
import hashlib
import hmac
import json
import time
import uuid
import urllib.error
import urllib.request
# Replace with your real data-center host, e.g. openapi-sg.easy4ip.com
OPENAPI_HOST = "https://openapi-[DataCenter].easy4ip.com"
# Replace with the appId from the console (placeholder, not a real value)
APP_ID = "your_appId_here"
# Replace with the appSecret from the console (placeholder, not a real value)
APP_SECRET = "your_appSecret_here"
def log(message: str) -> None:
"""Unified log prefix for easy step-by-step reading in the console."""
print(f"[AccessTokenDemoEn] {message}")
def calc_sign(ts: int, nonce: str, app_secret: str) -> str:
"""
Calculate sign per https://open.imou.com/document/pages/c20750/
1) SIGN_TEMPLATE = time:{time},nonce:{nonce},appSecret:{appSecret}
2) password = LowerCase(Hex(SHA-256(appSecret)))
3) sign = Base64(HMAC-SHA256(SIGN_TEMPLATE, password))
Official verification sample:
time=1706511734
nonce=f5a1ae2d-c09c-4d39-a744-83a5c2c653c2
appSecret=test123456789test123456789
expected sign=xjhCQBoJ9hRDsCjyDcHjtDNzRZ3ZJezcawsfWeiaoxU=
"""
sign_template = f"time:{ts},nonce:{nonce},appSecret:{app_secret}"
# Mask appSecret in logs to avoid leaking secrets to console/log files
raw_for_log = f"time:{ts},nonce:{nonce},appSecret:***"
log(f" sign raw string (masked) = {raw_for_log}")
password = hashlib.sha256(app_secret.encode("utf-8")).hexdigest().lower()
digest = hmac.new(
password.encode("utf-8"),
sign_template.encode("utf-8"),
hashlib.sha256,
).digest()
return base64.b64encode(digest).decode("utf-8")
def request_access_token(app_id: str, app_secret: str) -> str:
"""
Call the accessToken API to obtain an administrator accessToken.
:param app_id: Application ID
:param app_secret: Application secret
:return: Raw JSON response body
"""
# 1. Build auth parameters
log("[Step 1] Generate auth parameters")
ts = int(time.time()) # Unix seconds; must be within 5 minutes of server time
nonce = str(uuid.uuid4()) # Must not repeat within 5 minutes
request_id = str(uuid.uuid4()) # Unique ID per request
log(f" time = {ts}")
log(f" nonce = {nonce}")
log(f" requestId = {request_id}")
log(f" appId = {app_id}")
log("[Step 2] Calculate sign (HMAC-SHA256 + Base64)")
sign = calc_sign(ts, nonce, app_secret)
log(f" sign = {sign}")
# 2. Build request body (params can be an empty object)
log("[Step 3] Build request body")
body_obj = {
"system": {
"ver": "1.0",
"appId": app_id,
"sign": sign,
"time": ts,
"nonce": nonce,
},
"id": request_id,
"params": {},
}
body = json.dumps(body_obj, ensure_ascii=False, separators=(",", ":"))
log(f" requestBody = {body}")
# 3. Send POST request
url = f"{OPENAPI_HOST}/openapi/accessToken"
log("[Step 4] Send HTTP POST")
log(f" url = {url}")
request = urllib.request.Request(
url,
data=body.encode("utf-8"),
headers={"Content-Type": "application/json;charset=UTF-8"},
method="POST",
)
try:
with urllib.request.urlopen(request, timeout=30) as response:
response_body = response.read().decode("utf-8")
http_status = response.getcode()
except urllib.error.HTTPError as e:
error_body = e.read().decode("utf-8", errors="replace")
log(f" httpStatus = {e.code}")
log(f" error body = {error_body}")
raise RuntimeError(f"Unexpected HTTP status: {e.code}, body={error_body}") from e
log("[Step 5] Response received")
log(f" httpStatus = {http_status}")
if http_status // 100 != 2:
log(f" error body = {response_body}")
raise RuntimeError(f"Unexpected HTTP status: {http_status}, body={response_body}")
return response_body
# Successful data example:
# {
# "result": {
# "code": "0",
# "msg": "Successful operation.",
# "data": {
# "accessToken": "At_xxxxxxxx",
# "expireTime": 259176 # remaining validity in seconds
# }
# },
# "id": "..."
# }
if __name__ == "__main__":
log("========== Start requesting accessToken ==========")
response_body = request_access_token(APP_ID, APP_SECRET)
log("========== Request finished ==========")
log(f"Raw API response: {response_body}")
