API reqquest example- Get Administrator Token - Imou Open Platform
API request example
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/http/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/http/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}")
