外部API对接文档
一、接口概述
本文档提供给需要对接设备数据查询的外部开发者使用。
接口特性
- SK 鉴权:Header 携带
X-Saas-Id+X-SK,不使用平台 JWT Token - IP 白名单:可在后台为用户配置 IP 白名单(多个具体 IP,英文逗号分隔);为空则不限制
- 频次控制:按平台配置的限流规则执行(支持账号专属或全局默认)
- 查询接口:设备状态、配置、收益等均为
GET - 写操作接口:设备绑定/解绑为
POST(需 SK 鉴权,无需交易密码)
二、基础信息
服务地址
正式环境:https://api.morphogenai.top当前暂未提供独立测试环境。
对外业务接口路径前缀为 /api,完整示例:
https://api.morphogenai.top/api/device/status在线文档(Markdown,UTF-8):
GET https://api.morphogenai.top/api/docs/integration
Content-Type: text/markdown;charset=UTF-8字符编码
| 场景 | Content-Type |
|---|---|
| 业务接口 JSON 响应 | application/json;charset=UTF-8 |
在线文档 /api/docs/integration | text/markdown;charset=UTF-8 |
公共请求头
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
X-Saas-Id | String | 是 | 平台开通时下发的账号标识(与 SK 一并提供,无需自行查询) |
X-SK | String | 是 | 平台开通时下发的 SK 明文(与 X-Saas-Id 一并提供) |
统一响应格式
业务接口响应体为 JSON,字段如下:
| 字段名 | 类型 | 说明 |
|---|---|---|
code | String | E_000 成功;E_001 失败(见第四节) |
msg | String | 成功时为「成功」;失败时为具体原因 |
data | Object / null | 业务数据;失败时一般为 null |
成功示例:
{
"code": "E_000",
"msg": "成功",
"data": { }
}失败示例:
{
"code": "E_001",
"msg": "鉴权失败: SK校验失败",
"data": null
}时间字段格式: 字符串,形如 2026-05-31T09:30:25(LocalDateTime JSON 序列化,无时区后缀)。
参数缺失: Query 必填参数缺失时,框架返回 HTTP 400,不会进入业务 ResultVo。
默认频次配置
平台默认频次如下(管理员可为单个账号单独调整):
| 接口 | api_code | time_window | max_requests | 说明 |
|---|---|---|---|---|
| 设备在线状态 | DEVICE_STATUS | 1_MINUTE | 1 | 1 分钟 1 次 |
| Token 结算 | TOKEN_SETTLE | 1_HOUR | 1 | 1 小时 1 次 |
| 设备配置 | DEVICE_CONFIG | 1_DAY | 1 | 1 天 1 次 |
| 配置占用 | DEVICE_CONFIG_OCCUPY | 1_HOUR | 1 | 1 小时 1 次 |
| 设备位置 | DEVICE_LOCATION | 5_MINUTE | 1 | 5 分钟 1 次 |
| 单设备分润 | DEVICE_EARNINGS | 1_DAY | 1 | 1 天 1 次 |
| 账号设备收益汇总 | ACCOUNT_DEVICE_EARNINGS | 1_DAY | 1 | 1 天 1 次 |
| 绑定设备 | DEVICE_BIND | 1_MINUTE | 5 | 1 分钟 5 次 |
| 解绑设备 | DEVICE_UNBIND | 1_MINUTE | 5 | 1 分钟 5 次 |
收益说明:
| 类型 | 单设备分润接口 | 账号收益汇总接口 |
|---|---|---|
| 静态释放收益 | 有(staticRelease) | 有(staticRelease) |
| 动态收益 | 无(dynamic 固定为 0) | 有(dynamic) |
收益金额单位为 USD。
三、接口清单
1. 设备在线状态
| 项目 | 说明 |
|---|---|
| 接口地址 | GET /api/device/status |
| api_code | DEVICE_STATUS |
| 默认频次 | 1 分钟 1 次 |
请求参数
Header
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
X-Saas-Id | String | 是 | 平台开通时下发的 X-Saas-Id |
X-SK | String | 是 | 调用方 SK |
Query
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
deviceId | String | 是 | 设备序列号(sn_code) |
响应 data 字段
| 字段名 | 类型 | 说明 |
|---|---|---|
deviceId | String | 与入参一致 |
onlineStatus | Integer | 1 在线,0 离线 |
lastHeartbeat | String / null | 最近同步或上下线时间;可能为 null |
networkType | String | 运营商(isp);无数据时为 UNKNOWN |
仅查询已绑定到当前
X-Saas-Id的设备。
示例:
{
"code": "E_000",
"msg": "成功",
"data": {
"deviceId": "CL20260327103546870813300",
"onlineStatus": 1,
"lastHeartbeat": "2026-06-08T10:30:25",
"networkType": "Verizon"
}
}2. Token 结算数据
| 项目 | 说明 |
|---|---|
| 接口地址 | GET /api/token/settlement |
| api_code | TOKEN_SETTLE |
| 默认频次 | 1 小时 1 次 |
请求参数
Header
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
X-Saas-Id | String | 是 | 平台开通时下发的 X-Saas-Id |
X-SK | String | 是 | 调用方 SK |
Query: 无
响应 data 字段
| 字段名 | 类型 | 说明 |
|---|---|---|
saasId | String | 与 X-Saas-Id 一致 |
totalTokens | Integer | 已释放 Token 合计 |
settledTokens | Integer | 已日结 Token 合计 |
unsettledTokens | Integer | 未日结 Token(totalTokens - settledTokens,最小为 0) |
lastSettlementTime | String / null | 最近日结时间;无记录时为 null |
示例:
{
"code": "E_000",
"msg": "成功",
"data": {
"saasId": "test_saas_001",
"totalTokens": 10000,
"settledTokens": 8500,
"unsettledTokens": 1500,
"lastSettlementTime": "2026-05-31T08:00:00"
}
}3. 设备配置查询
| 项目 | 说明 |
|---|---|
| 接口地址 | GET /api/device/config |
| api_code | DEVICE_CONFIG |
| 默认频次 | 1 天 1 次 |
请求参数
Header: X-Saas-Id、X-SK(必填,同第一节)
Query
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
deviceId | String | 是 | 设备序列号(sn_code) |
响应 data 字段
| 字段名 | 类型 | 说明 |
|---|---|---|
deviceId | String | 与入参一致 |
model | String | CPU 型号或上游名称;无数据时为 UNKNOWN |
version | String | 操作系统或架构;无数据时为 UNKNOWN |
memoryGb | Integer | 内存总量(GB,取整) |
storageGb | Integer | 磁盘总量(GB,取整) |
仅查询已绑定到当前
X-Saas-Id的设备。
示例:
{
"code": "E_000",
"msg": "成功",
"data": {
"deviceId": "CL20260327103546870813300",
"model": "Intel(R) Core(TM) i7-12700",
"version": "Linux",
"memoryGb": 32,
"storageGb": 1024
}
}4. 设备配置占用查询
| 项目 | 说明 |
|---|---|
| 接口地址 | GET /api/device/config/occupy |
| api_code | DEVICE_CONFIG_OCCUPY |
| 默认频次 | 1 小时 1 次 |
请求参数
Header: X-Saas-Id、X-SK(必填)
Query
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
deviceId | String | 是 | 设备序列号(sn_code) |
响应 data 字段
| 字段名 | 类型 | 说明 |
|---|---|---|
deviceId | String | 与入参一致 |
isBound | Boolean | 是否已被某账号绑定 |
boundSaasId | String / null | 绑定账号的 X-Saas-Id;未绑定时为 null |
boundTime | String / null | 绑定时间;未绑定时为 null |
expireTime | null | 固定为 null(当前无到期字段) |
示例:
{
"code": "E_000",
"msg": "成功",
"data": {
"deviceId": "CL20260327103546870813300",
"isBound": true,
"boundSaasId": "2a2cc29053144a6fb84c41039d9717ed",
"boundTime": "2026-05-01T10:00:00",
"expireTime": null
}
}5. 设备在线位置
| 项目 | 说明 |
|---|---|
| 接口地址 | GET /api/device/location |
| api_code | DEVICE_LOCATION |
| 默认频次 | 5 分钟 1 次 |
请求参数
Header: X-Saas-Id、X-SK(必填)
Query
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
deviceId | String | 是 | 设备序列号(sn_code) |
响应 data 字段
| 字段名 | 类型 | 说明 |
|---|---|---|
deviceId | String | 与入参一致 |
longitude | null | 当前不提供经纬度,固定 null |
latitude | null | 当前不提供经纬度,固定 null |
address | String | 地域描述(region);无数据时为 UNKNOWN |
updateTime | String | 设备信息最近同步时间 |
仅查询已绑定到当前
X-Saas-Id的设备。
示例:
{
"code": "E_000",
"msg": "成功",
"data": {
"deviceId": "CL20260327103546870813300",
"longitude": null,
"latitude": null,
"address": "California, USA",
"updateTime": "2026-06-08T10:30:25"
}
}6. 单设备分润(按设备号)
| 项目 | 说明 |
|---|---|
| 接口地址 | GET /api/device/earnings |
| api_code | DEVICE_EARNINGS |
| 默认频次 | 1 天 1 次 |
按设备序列号查询静态释放收益;dynamic 固定为 0(动态收益请使用账号收益汇总接口)。
请求参数
Header: X-Saas-Id、X-SK(必填)
Query
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
deviceId | String | 是 | 设备序列号(sn_code) |
响应 data 字段
| 字段名 | 类型 | 说明 |
|---|---|---|
deviceId | String | 与入参一致 |
currency | String | 固定 USD |
staticRelease | Object | 静态释放收益(见下表) |
dynamic | Object | 动态收益(单设备固定为 0,字段结构同 staticRelease) |
updateTime | String | 统计更新时间 |
staticRelease / dynamic 子字段:
| 字段名 | 类型 | 说明 |
|---|---|---|
total | Number | 累计 |
today | Number | 当日 |
yesterday | Number | 昨日 |
staticRelease.total:该设备累计已日结静态释放(USD)staticRelease.today:当日已释放(USD,含未日结部分)staticRelease.yesterday:昨日已日结静态释放(USD)dynamic:单设备接口固定全 0
示例:
{
"code": "E_000",
"msg": "成功",
"data": {
"deviceId": "CL20260327103546870813300",
"currency": "USD",
"staticRelease": {
"total": 12.34500,
"today": 0.51200,
"yesterday": 0.49800
},
"dynamic": {
"total": 0,
"today": 0,
"yesterday": 0
},
"updateTime": "2026-06-08T10:30:00"
}
}7. 账号设备收益汇总
| 项目 | 说明 |
|---|---|
| 接口地址 | GET /api/account/device/earnings |
| api_code | ACCOUNT_DEVICE_EARNINGS |
| 默认频次 | 1 天 1 次 |
查询当前 X-Saas-Id 账号下所有已绑定设备的静态释放与动态收益总和。
请求参数
Header: X-Saas-Id、X-SK(必填)
Query: 无
响应 data 字段
| 字段名 | 类型 | 说明 |
|---|---|---|
saasId | String | 与 X-Saas-Id 一致 |
deviceCount | Integer | 当前已绑定设备台数 |
currency | String | 固定 USD |
staticRelease | Object | 账号静态释放收益合计(USD) |
dynamic | Object | 账号动态团队奖励合计(USD) |
totalEarnings | Number | staticRelease.total + dynamic.total |
updateTime | String | 统计更新时间 |
示例:
{
"code": "E_000",
"msg": "成功",
"data": {
"saasId": "test_saas_001",
"deviceCount": 3,
"currency": "USD",
"staticRelease": {
"total": 45.67800,
"today": 1.53600,
"yesterday": 1.49400
},
"dynamic": {
"total": 8.12000,
"today": 0.32000,
"yesterday": 0.28000
},
"totalEarnings": 53.79800,
"updateTime": "2026-06-08T10:30:00"
}
}8. 绑定设备
| 项目 | 说明 |
|---|---|
| 接口地址 | POST /api/device/bind |
| api_code | DEVICE_BIND |
| 默认频次 | 1 分钟 5 次 |
| Content-Type | application/json;charset=UTF-8 |
将设备序列号(sn_code)绑定到 Header 中的 X-Saas-Id 账号。设备须已在平台 SN 白名单内,且未被其他账号占用。
请求参数
Header: X-Saas-Id、X-SK(必填)
Body(JSON):
| 字段名 | 类型 | 必填 | 说明 |
|---|---|---|---|
deviceId | String | 是 | 设备序列号 |
remarkName | String | 否 | 备注名 |
响应 data 字段
| 字段名 | 类型 | 说明 |
|---|---|---|
deviceId | String | 设备序列号 |
saasId | String | 绑定账号 |
bindTime | String | 绑定时间 |
onlineStatus | Integer | 1 在线,0 离线 |
示例:
curl -X POST "https://api.morphogenai.top/api/device/bind" \
-H "Content-Type: application/json" \
-H "X-Saas-Id: <客服提供的X-Saas-Id>" \
-H "X-SK: <客服提供的X-SK>" \
-d '{"deviceId":"CL20260327103546870813300","remarkName":"机房A-01"}'9. 解绑设备
| 项目 | 说明 |
|---|---|
| 接口地址 | POST /api/device/unbind |
| api_code | DEVICE_UNBIND |
| 默认频次 | 1 分钟 5 次 |
| Content-Type | application/json;charset=UTF-8 |
解除当前 X-Saas-Id 账号与指定设备的绑定关系。外部 API 使用 SK 鉴权,无需交易密码。
请求参数
Header: X-Saas-Id、X-SK(必填)
Body(JSON):
| 字段名 | 类型 | 必填 | 说明 |
|---|---|---|---|
deviceId | String | 是 | 设备序列号 |
响应 data 字段
| 字段名 | 类型 | 说明 |
|---|---|---|
deviceId | String | 设备序列号 |
saasId | String | 解绑账号 |
unbindTime | String | 解绑时间 |
示例:
curl -X POST "https://api.morphogenai.top/api/device/unbind" \
-H "Content-Type: application/json" \
-H "X-Saas-Id: <客服提供的X-Saas-Id>" \
-H "X-SK: <客服提供的X-SK>" \
-d '{"deviceId":"CL20260327103546870813300"}'常见失败原因:
| msg | 说明 |
|---|---|
| 非法设备号 | SN 不在平台白名单 |
| 未查询到该设备 | OpenAPI 侧无此设备 |
| 该设备已被其他用户绑定 | 已被其他账号占用 |
| 您已绑定该设备 | 重复绑定 |
| 未绑定该设备 | 解绑时当前账号无有效绑定 |
四、错误码说明
| code | 典型 msg | 说明 |
|---|---|---|
E_000 | 成功 | 业务处理成功 |
E_001 | 鉴权失败: saasId或SK不能为空 | Header 缺参 |
E_001 | 鉴权失败: 用户不存在 | 未开通外部 API |
E_001 | 鉴权失败: 用户已禁用 | 账号 status ≠ 1 |
E_001 | 鉴权失败: SK校验失败 | SK 不匹配 |
E_001 | 请求IP不在白名单中 | IP 白名单校验失败 |
E_001 | 接口调用频次超限,请稍后再试 | 触发限流 |
失败时
msg以实际返回为准;鉴权类失败统一带前缀鉴权失败:。
五、调用示例
# 将 X-Saas-Id、X-SK、deviceId 替换为客服开通后提供的值及真实设备序列号
curl -G "https://api.morphogenai.top/api/device/status" \
--data-urlencode "deviceId=CL20260327103546870813300" \
-H "X-Saas-Id: <客服提供的X-Saas-Id>" \
-H "X-SK: <客服提供的X-SK>"六、开通与使用流程
- 申请开通:联系masf58722@gmail.com,说明业务用途及调用来源 IP(如需 IP 白名单)。无需自行查找
X-Saas-Id。 - 获取凭证:审核通过后,客服一次性提供
X-Saas-Id与X-SK明文,请当场保存。 - 配置白名单(可选):向客服提供多个具体 IP(英文逗号分隔,不支持通配符);留空表示不限制。
- 调用接口:按第五节示例,使用客服提供的
X-Saas-Id、X-SK访问/api/**业务接口。 - 后续变更:SK 重置、IP 白名单、限额调整等请联系masf58722@gmail.com。
七、注意事项
- SK 安全:SK 等同密钥,泄露后请联系masf58722@gmail.com重置。
- 限流:以平台实际配置为准;账号专属规则优先于全局默认。
- IP 白名单:白名单非空时,仅 listed 中的具体 IP 可调用(精确匹配,不支持通配符)。
- 编码:请求 URL、Header、JSON 响应均为 UTF-8。
八、联系支持
开通申请、SK 重置、IP 白名单、限额调整等,请统一联系masf58722@gmail.com。
文档版本:v2.0
最后更新:2026-06-08