API Wiki 开发注意事项
接入 TIB IoT API 前必读的开发指南和认证说明
1. 域名配置
- 接口请求基础地址:
https://oac.tibiot.com/ - 注意:生成签名时不需要拼接 BaseURL,仅使用请求路径(URI)参与签名计算。
2. 应用凭证与 SDK 获取
2.1 创建应用
访问:https://dmc.tibiot.com/ApplicationCenter
- 点击「添加应用」,创建成功后系统将分配:
APP ID:企业编码,用于标识调用方身份APP Secret:加密密钥,请妥善保管,切勿泄露
2.2 SDK 下载
在应用管理平台中可直接下载对应语言的 SDK,推荐使用 SDK 进行接口调用,以简化签名生成与请求处理。
3. 签名生成规则
所有 API 请求(包括 GET 与 POST)必须携带签名,签名通过 ApiSignUtils.generateClientSign 方法生成。
3.1 签名参数说明
| 参数名 | 类型 | 说明 |
|---|---|---|
| appId | String | 应用中心分配的应用 ID |
| secret | String | 应用中心分配的 Secret |
| uri | String | 请求路径(不包含 BaseURL),如 /api/v1/order |
| bodyParams | Map | POST 请求体参数(GET 请求传空 Map) |
| timestamp | long | 当前毫秒级时间戳,用于防重放攻击 |
| nonce | String | 随机字符串,建议使用 UUID,每次请求不同 |
3.2 签名生成步骤
- 若 URI 包含查询参数,按参数名 ASCII 升序排序后拼接为
key1=value1&key2=value2格式,并对 value 进行 URL 编码(空格编码为%20)。 - POST 请求体参数(JSON 或 Form)同样按 key 升序排序,拼接为
key1=value1&key2=value2格式,并对 value 进行 URL 编码。 - 将以下字段按顺序用竖线
|连接:- 若某个字段为空,则跳过该字段及其前后分隔符(即不出现连续的
||)。
- 若某个字段为空,则跳过该字段及其前后分隔符(即不出现连续的
- 使用 3DES(DESede) 算法对上一步生成的字符串进行加密,密钥为
secret(不足24位补足,超过24位截取前24位)。 - 加密后得到 Base64 字符串,即为最终签名。
3.3 签名示例代码(Java)
DES3Util.java
Java
import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import java.util.Base64; public class DES3Util { private DES3Util() {} public static String encrypt(String content, String desKey, String charset) throws Exception { if (desKey == null || desKey.length() < 24) { throw new Exception("3des key's length must be 24"); } if (desKey.length() > 24) { desKey = desKey.substring(0, 24); } if (content == null || content.isEmpty()) { return ""; } SecretKeySpec key = new SecretKeySpec(desKey.getBytes(charset), "DESede"); Cipher cipher = Cipher.getInstance("DESede"); cipher.init(Cipher.ENCRYPT_MODE, key); byte[] encryptBytes = cipher.doFinal(content.getBytes(charset)); return Base64.getEncoder().encodeToString(encryptBytes); } }
ApiSignUtils.java
Java
import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.util.*; import java.util.stream.Collectors; public class ApiSignUtils { public static String generateClientSign(String appId, String secret, String uri, Map<String, Object> bodyParams, long timestamp, String nonce) throws Exception { String[] path = uri.split("\\?", 2); String queryParamsStr = parseQueryParams(path); String postParamsStr = parsePostParams(bodyParams); List<String> joinParams = Arrays.asList(appId, secret, path[0], String.valueOf(timestamp), nonce, queryParamsStr, postParamsStr); joinParams = joinParams.stream().filter(s -> s != null && !s.isEmpty()).collect(Collectors.toList()); String signData = String.join("|", joinParams); return DES3Util.encrypt(signData, secret, StandardCharsets.UTF_8.name()); } private static String parsePostParams(Map<String, Object> bodyParams) { if (bodyParams == null || bodyParams.isEmpty()) { return ""; } Map<String, Object> params = new TreeMap<>(bodyParams); return params.entrySet().stream() .filter(entry -> entry.getValue() != null) .map(entry -> entry.getKey() + "=" + urlEncode(String.valueOf(entry.getValue()))) .collect(Collectors.joining("&")); } private static String parseQueryParams(String[] query) { if (query == null || query.length <= 1) { return ""; } Map<String, String> params = new TreeMap<>(); String pathParams = query[1]; Arrays.stream(pathParams.split("&")) .map(pair -> pair.split("=")) .forEach(pair -> params.put(pair[0], urlEncode(pair.length > 1 ? pair[1] : ""))); return params.entrySet().stream() .map(entry -> entry.getKey() + "=" + entry.getValue()) .collect(Collectors.joining("&")); } private static String urlEncode(String val) { return URLEncoder.encode(val, StandardCharsets.UTF_8).replace("+", "%20"); } }
卡接口
物联网卡管理相关接口,包括卡详情查询、网络操作、使用量统计等功能
卡详情
查询单张物联网卡的详细信息,包括 ICCID、IMEI、IMSI、流量使用情况、卡状态等
Request Headers
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| X-App-Id | string | ● 是 | 应用ID |
| X-Sign | string | ● 是 | 请求签名 |
| X-Timestamp | long | ● 是 | 时间戳(毫秒) |
| X-Nonce | string | ● 是 | 随机字符串 |
Query Parameters
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| iccid | string | ● 是 | 物联网卡 ICCID 号码 |
Response Body
| 参数名 | 类型 | 说明 |
|---|---|---|
| code | number | 响应状态码,200 表示成功 |
| message | string | 响应消息 |
| traceId | string | 请求追踪ID |
| data.iccid | string | 物联网卡 ICCID 号码 |
| data.imei | string | 设备 IMEI 号 |
| data.imsi | string | SIM 卡 IMSI 号 |
| data.msisdn | string | 卡号 |
| data.totalFlow | number | 总流量(字节) |
| data.useMonthFlow | number | 本月已用流量(字节) |
| data.useFlow | number | 累计已用流量(字节) |
| data.billingMethod | number | 计费方式 |
| data.apn | string | 接入点名称 |
| data.cardStatus | number | 卡状态:1-沉默期,4-停机,8-正常,12-测试期,16-停机保号,18-清算,99-异常 |
Response Example
JSON
{
"code": 200,
"message": "success",
"traceId": "abc123def456",
"data": {
"iccid": "89860000000000000000",
"imei": "860000000000000",
"imsi": "460000000000000",
"msisdn": "13800138000",
"totalFlow": 1073741824,
"useMonthFlow": 104857600,
"useFlow": 524288000,
"billingMethod": 1,
"apn": "cmiot",
"cardStatus": 8
}
}
操作卡网络
批量操作物联网卡网络状态,支持开通或关闭网络,最多支持 10 张卡同时操作
Request Headers
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| X-App-Id | string | ● 是 | 应用ID |
| X-Sign | string | ● 是 | 请求签名 |
| X-Timestamp | long | ● 是 | 时间戳(毫秒) |
| X-Nonce | string | ● 是 | 随机字符串 |
| Content-Type | string | ● 是 | application/json |
Request Body
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| iccids | string[] | ● 是 | ICCID 数组,最多 10 个 |
| switchOn | boolean | ● 是 | true 开通,false 关闭 |
Response Body
| 参数名 | 类型 | 说明 |
|---|---|---|
| code | number | 响应状态码,200 表示成功 |
| message | string | 响应消息 |
| traceId | string | 链路追踪 ID |
| data.batchCode | string | 批次编码,用于查询操作状态 |
| data.successCount | number | 切换检查成功数量 |
| data.errorInfo | array | 切换检查失败详细列表 |
| data.errorInfo[].iccid | string | ICCID |
| data.errorInfo[].infoMessage | string | 详细信息 |
Request Example
JSON
{
"iccids": [
"89860000000000000001",
"89860000000000000002"
],
"switchOn": true
}
Response Example
JSON
{
"code": 200,
"message": "success",
"traceId": "abc123def456",
"data": {
"batchCode": "BATCH202504220001",
"successCount": 2,
"errorInfo": []
}
}
获取卡历史12月的某一月的使用量
查询物联网卡在指定月份的使用量统计
Request Headers
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| X-App-Id | string | ● 是 | 应用ID |
| X-Sign | string | ● 是 | 请求签名 |
| X-Timestamp | long | ● 是 | 时间戳(毫秒) |
| X-Nonce | string | ● 是 | 随机字符串 |
Query Parameters
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| iccid | string | ● 是 | ICCID 号码 |
| queryMonth | string | ● 是 | 查询月份,格式:2025-04 |
Response Body
| 参数名 | 类型 | 说明 |
|---|---|---|
| code | number | 响应状态码 |
| message | string | 响应消息 |
| traceId | string | 链路追踪 ID |
| data.iccid | string | ICCID 号码 |
| data.month | string | 日期,格式:yyyy-MM |
| data.useFlowKb | number | 使用量,单位 KB |
Response Example
JSON
{
"code": 200,
"message": "success",
"traceId": "abc123def456",
"data": {
"iccid": "89860000000000000001",
"month": "2025-04",
"useFlowKb": 102400
}
}
获取卡近30天的某一天的使用量
查询物联网卡在指定日期的使用量统计
Request Headers
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| X-App-Id | string | ● 是 | 应用ID |
| X-Sign | string | ● 是 | 请求签名 |
| X-Timestamp | long | ● 是 | 时间戳(毫秒) |
| X-Nonce | string | ● 是 | 随机字符串 |
Query Parameters
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| iccid | string | ● 是 | ICCID 号码 |
| queryDay | string | ● 是 | 查询日期,格式:2025-04-01 |
Response Body
| 参数名 | 类型 | 说明 |
|---|---|---|
| code | number | 响应状态码 |
| message | string | 响应消息 |
| traceId | string | 请求追踪ID |
| data.iccid | string | ICCID 号码 |
| data.day | string | 日期,格式 yyyy-MM-dd |
| data.useFlowKb | number | 使用量,单位 KB |
Response Example
{
"code": 200,
"message": "success",
"traceId": "abc123def456",
"data": {
"iccid": "89860000000000000001",
"day": "2025-04-01",
"useFlowKb": 5120
}
}
操作批次查询
查询批量操作的执行状态和结果
检查卡操作完成状态
根据批次编码查询批量操作的执行状态
Request Headers
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| X-App-Id | string | ● 是 | 应用ID |
| X-Sign | string | ● 是 | 请求签名 |
| X-Timestamp | long | ● 是 | 时间戳(毫秒) |
| X-Nonce | string | ● 是 | 随机字符串 |
Query Parameters
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| batchCode | string | ● 是 | 批次编码 |
Response Body
| 参数名 | 类型 | 说明 |
|---|---|---|
| code | number | 响应状态码 |
| message | string | 消息提示 |
| traceId | string | 链路编码 |
| data[].iccid | string | ICCID 号码 |
| data[].msisdn | string | 卡号 |
| data[].operationCardStatus | number | 操作卡状态:2-操作完成 |
Response Example
JSON
{
"code": 200,
"message": "success",
"traceId": "abc123def456",
"data": [
{
"iccid": "89860000000000000001",
"msisdn": "13800138000",
"operationCardStatus": 2
}
]
}
流量池接口
流量池管理和使用量统计相关接口
池详情
查询流量池详细信息,包括池类型、流量使用情况、绑定卡数量等
Request Headers
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| X-App-Id | string | ● 是 | 应用ID |
| X-Sign | string | ● 是 | 请求签名 |
| X-Timestamp | long | ● 是 | 时间戳(毫秒) |
| X-Nonce | string | ● 是 | 随机字符串 |
Query Parameters
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| poolCode | string | ● 是 | 流量池编码 |
Response Body
| 参数名 | 类型 | 说明 |
|---|---|---|
| code | integer | 返回状态码 |
| message | string | 消息提示 |
| traceId | string | 链路编码 |
| data.upoolCode | string | 流量池code |
| data.upoolName | string | 流量池名称 |
| data.enUpoolName | string | 流量池名称(英语) |
| data.poolType | number | 池类型:1.用户池,2.使用量计费池,3.统付池 |
| data.useFlow | number | 使用量 KB |
| data.totalFlow | number | 总流量 KB(对于 poolType = 2 的,此字段不做使用) |
| data.billingCycle | number | 周期类型: 计费周期(1.月度套餐 3.季度 6.半年 12.一年) |
| data.totalCard | integer | 总卡数 |
| data.rawAddTime | string | 创建时间 |
| data.poolStatus | number | 池状态:1.有效,2.无效 |
| data.bindCardStatusCount | object[] | 卡状态统计数组 |
| data.bindCardStatusCount[].cardStatus | number | 卡状态 |
| data.bindCardStatusCount[].total | integer | 总量 |
| data.packageInfo | object | 企业资费包信息 |
| data.packageInfo.flowPackageType | number | 资费包类型:1普通套餐流量包;2按量计费流量包;3统付池 |
| data.packageInfo.clientFlowPackageName | string | 客户端流量包名称,用于展示给客户 |
| data.packageInfo.channelName | string | 通道名称 |
| data.epiConfigs | object[] | 当前资费包的配置列表 |
| data.epiConfigs[].epiConfigCode | string | 企业资费包配置业务code |
| data.epiConfigs[].epiCode | string | 企业资费包code |
| data.epiConfigs[].standardCharge | number | 企业资费包(实际服务费,单位元) |
| data.epiConfigs[].realFenStandardCharge | number | 企业资费包(实际资费,单位分) |
| data.epiConfigs[].epiConfigType | number | 企业资费包类型:1.购卡,2.续费,3.叠加 |
| data.unit | string | 单位 KB MB GB TB(使用量计费池) |
| data.startTime | string | 池开始时间(统付池) |
| data.endTime | string | 池结束时间(统付池) |
| data.upoolStatus | number | 池状态:1.有效,2.无效 |
Response Example
{
"code": 200,
"message": "success",
"traceId": "a1b2c3d4e5f6g7h8",
"data": {
"upoolCode": "POOL202504220001",
"upoolName": "测试流量池",
"enUpoolName": "Test Data Pool",
"poolType": 1,
"useFlow": 1024000,
"totalFlow": 10485760,
"billingCycle": 1,
"totalCard": 100,
"rawAddTime": "2025-01-15 10:30:00",
"poolStatus": 1,
"upoolStatus": 1,
"unit": "KB",
"startTime": "2025-01-01",
"endTime": "2025-12-31",
"bindCardStatusCount": [
{
"cardStatus": 8,
"total": 80
},
{
"cardStatus": 4,
"total": 20
}
],
"packageInfo": {
"flowPackageType": 1,
"clientFlowPackageName": "企业标准套餐100M",
"channelName": "中国移动"
},
"epiConfigs": [
{
"epiConfigCode": "EPC001",
"epiCode": "EP001",
"standardCharge": 100.00,
"realFenStandardCharge": 10000,
"epiConfigType": 1
}
]
}
}
获取池历史12月的某一月的使用量
查询流量池在指定月份的使用量统计
Request Headers
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| X-App-Id | string | ● 是 | 应用ID |
| X-Sign | string | ● 是 | 请求签名 |
| X-Timestamp | long | ● 是 | 时间戳(毫秒) |
| X-Nonce | string | ● 是 | 随机字符串 |
Query Parameters
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| poolCode | string | ● 是 | 流量池编码 |
| queryMonth | string | ● 是 | 查询月份,格式:2025-04 |
Response Body
| 参数名 | 类型 | 说明 |
|---|---|---|
| code | number | 响应状态码 |
| message | string | 响应消息 |
| traceId | string | 请求追踪ID |
| data.poolCode | string | 流量池编码 |
| data.month | string | 日期,格式 yyyy-MM |
| data.useFlowKb | number | 使用量,单位 KB |
Response Example
{
"code": 200,
"message": "success",
"traceId": "abc123def456",
"data": {
"poolCode": "POOL001",
"month": "2025-04",
"useFlowKb": 204800
}
}
获取池近30天的某一天的使用量
查询流量池在指定日期的使用量统计
Request Headers
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| X-App-Id | string | ● 是 | 应用ID |
| X-Sign | string | ● 是 | 请求签名 |
| X-Timestamp | long | ● 是 | 时间戳(毫秒) |
| X-Nonce | string | ● 是 | 随机字符串 |
Query Parameters
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| poolCode | string | ● 是 | 流量池编码 |
| queryDay | string | ○ 否 | 查询日期,格式:2025-04-01 |
Response Body
| 参数名 | 类型 | 说明 |
|---|---|---|
| code | number | 响应状态码 |
| message | string | 响应消息 |
| traceId | string | 请求追踪ID |
| data.poolCode | string | 流量池编码 |
| data.day | string | 日期,格式 yyyy-MM-dd |
| data.useFlowKb | number | 使用量,单位 KB |
Response Example
{
"code": 200,
"message": "success",
"traceId": "abc123def456",
"data": {
"poolCode": "POOL001",
"day": "2025-04-01",
"useFlowKb": 10240
}
}
短信服务
短信发送、查询和状态追踪相关接口
上行回复记录查询
分页查询用户回复的短信记录
Request Headers
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| X-App-Id | string | ● 是 | 应用ID |
| X-Sign | string | ● 是 | 请求签名 |
| X-Timestamp | long | ● 是 | 时间戳(毫秒) |
| X-Nonce | string | ● 是 | 随机字符串 |
| Content-Type | string | ● 是 | application/json |
Request Body
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| page | integer | ○ 否 | 页码,默认 1 |
| pageSize | integer | ○ 否 | 每页数量,默认 20 |
| iccid | string | ○ 否 | ICCID 号码(ICCID 和卡号至少需要填写一个) |
| msisdn | string | ○ 否 | 卡号(ICCID 和卡号至少需要填写一个) |
Response Body
| 参数名 | 类型 | 说明 |
|---|---|---|
| code | integer | 返回状态码 |
| message | string | 消息提示 |
| traceId | string | 链路编码 |
| total | integer | 总数 |
| pageSize | integer | 页大小 |
| totalPage | integer | 总页数 |
| page | integer | 当前页 |
| data | array | 返回数据数组 |
| data[].id | integer | 主键 ID |
| data[].smsMsgCode | string | 短信消息记录业务主键 |
| data[].iccid | string | ICCID |
| data[].msisdn | string | 卡号 |
| data[].content | string | 短信内容 |
| data[].sendReplyTime | string | 发送/回复时间 |
| data[].statusReplyTime | string | 发送成功时间 |
| data[].smsMsgState | number | 消息状态:0-未发送,1-发送中,2-发送失败,3-成功,4-重试中 |
Response Example
{
"code": 200,
"message": "success",
"traceId": "abc123def456",
"total": 100,
"pageSize": 20,
"totalPage": 5,
"page": 1,
"data": [
{
"id": 1,
"smsMsgCode": "SMS001",
"iccid": "89860000000000000001",
"msisdn": "13800138000",
"content": "测试短信",
"sendReplyTime": "2025-04-01 10:00:00",
"statusReplyTime": "2025-04-01 10:00:05",
"smsMsgState": 3
}
]
}
发送短信
批量发送短信到指定的卡号列表,最多支持 50 个号码
Body Parameters
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| cardNumber | string[] | ● 是 | 卡号集合,最大 50 个 |
| content | string | ● 是 | 短信内容,最大 150 字符 |
| cardNumberType | number | ● 是 | 1-ICCID,2-卡号 |
Response Parameters
| 参数名 | 类型 | 说明 |
|---|---|---|
| code | number | 响应状态码 |
| message | string | 响应消息 |
| traceId | string | 链路编码 |
| data | object | 返回数据 |
| data.errorMessageInfoResponses | array | 发送失败结果记录数组 |
| data.errorMessageInfoResponses[].errorCode | string | 错误码 |
| data.errorMessageInfoResponses[].errorVal | string | 错误值 |
| data.errorMessageInfoResponses[].errorMessage | string | 错误信息 |
| data.successMessageInfoResponses | array | 发送成功结果记录数组 |
| data.successMessageInfoResponses[].iccid | string | ICCID |
| data.successMessageInfoResponses[].msisdn | string | 卡号 |
| data.successMessageInfoResponses[].smsMsgCode | string | 短信消息id |
Request Example
JSON
{
"cardNumber": [
"89860000000000000001",
"89860000000000000002"
],
"content": "您的设备已激活,请查收。",
"cardNumberType": 1
}
Response Example
JSON
{
"code": 200,
"message": "success",
"traceId": "abc123def456",
"data": {
"errorMessageInfoResponses": [],
"successMessageInfoResponses": [
{
"iccid": "89860000000000000001",
"msisdn": "13800138000",
"smsMsgCode": "SMS20250401001"
}
]
}
}
短信状态查询
根据短信消息编码查询短信发送结果
Request Headers
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| X-App-Id | string | ● 是 | 应用ID |
| X-Sign | string | ● 是 | 请求签名 |
| X-Timestamp | long | ● 是 | 时间戳(毫秒) |
| X-Nonce | string | ● 是 | 随机字符串 |
Query Parameters
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| smsMsgCode | string | ● 是 | 短信消息编码 |
Response Body
| 参数名 | 类型 | 说明 |
|---|---|---|
| code | number | 响应状态码 |
| message | string | 响应消息 |
| traceId | string | 链路编码 |
| data | object | 返回数据 |
| data.id | integer | 主键 ID |
| data.smsMsgCode | string | 短信消息记录业务主键 |
| data.iccid | string | ICCID |
| data.msisdn | string | 卡号 |
| data.content | string | 短信内容 |
| data.sendReplyTime | string | 发送/回复时间 |
| data.statusReplyTime | string | 发送成功时间 |
| data.smsMsgState | number | 消息状态:0-未发送,1-发送中,2-发送失败,3-成功,4-重试中 |
Response Example
{
"code": 200,
"message": "success",
"traceId": "abc123def456",
"data": {
"id": 1,
"smsMsgCode": "SMS001",
"iccid": "89860000000000000001",
"msisdn": "13800138000",
"content": "测试短信内容",
"sendReplyTime": "2025-04-01 10:00:00",
"statusReplyTime": "2025-04-01 10:00:05",
"smsMsgState": 3
}
}