https://edu.hiholo.com/open/api/v2快速接入
先完成登录和令牌交换,再回传实验结果。学习时长与试卷接口按实验需要接入。
- 01客户端登录账号密码 → project
- 02获取令牌project + 项目签名 → access_token
- 03回传实验结果成绩、步骤、用时 → 结果记录
- 04上传报告附件使用同一 originId,按需调用
接入前准备
| 名称 | 作用 | 来源 |
|---|---|---|
username / password | 平台用户的登录账号和密码 | 与网站登录账号一致;用户账号必须可正常使用。 |
appid | 标识一个实验项目 | 由管理员在实验项目中配置,接入方从项目管理页获取。 |
secret | 计算项目签名 | 与 appid 配套。请保存在接入方的受控配置中。 |
project | 用户登录凭证 | 客户端登录接口返回;平台启动 Web 实验时也会在启动地址中携带。 |
access_token | 后续接口调用凭证 | 使用 project 和项目签名换取。 |
appid / secret 配置完成后再联调。本文中的 APP_ID、APP_SECRET、PROJECT、ACCESS_TOKEN 等均为占位符。
project 时,直接进入“获取令牌”步骤,随后执行相同的数据回传流程。接口一览
| 用途 | 方法 | 路径 |
|---|---|---|
| 客户端登录 | POST | /client/login |
| 获取令牌 | POST | /token |
| 实验结果回传 | POST | /data_upload |
| 报告附件上传 | POST | /attachment_upload |
| 学习时长回传 | POST | /duration_upload |
| 获取试卷 | GET | /paper/list |
上表路径均以 https://edu.hiholo.com/open/api/v2 为前缀。客户端接入按本文展示的方法调用。
客户端登录
在客户端输入平台账号密码,登录成功后取得 project。账号密码通过 HTTPS 的 POST 表单提交。
/client/login请求格式:application/x-www-form-urlencoded
| 字段 | 位置 / 类型 | 要求 | 说明 |
|---|---|---|---|
username | Body / String | 必填 | 平台用户名、邮箱或已绑定手机号。 |
password | Body / String | 必填 | 对应账号的登录密码。 |
appid | Body / String | 必填 | 本次接入的实验项目编号。 |
cURL 示例
curl --request POST "https://edu.hiholo.com/open/api/v2/client/login" --data-urlencode "username=YOUR_USERNAME" --data-urlencode "password=YOUR_PASSWORD" --data-urlencode "appid=APP_ID"成功响应 JSON 示例
{
"code": 0,
"msg": "",
"project": "PROJECT_FROM_LOGIN",
"un": "example_user",
"dis": "示例用户"
}保留返回的 project,下一步换取 access_token。un 是回传结果时使用的平台用户名;即使用邮箱或手机号登录,也应使用返回的 un 填写成绩中的 username。
查看本接口错误码
| code | 含义 |
|---|---|
| 1 | 缺少 username、password 或 appid。 |
| 2 | appid 无效,或项目尚未配置 secret。 |
| 8 | 找不到该平台用户。 |
| 16 | 用户已锁定。 |
| 17 | 账号或密码错误。 |
获取调用令牌
project 用于换取 access_token。后续回传、上传和试卷接口使用 access_token。
/token请求格式:application/x-www-form-urlencoded
| 字段 | 位置 / 类型 | 要求 | 说明 |
|---|---|---|---|
project | Body / String | 必填 | 登录返回或平台启动地址携带的原始 project。 |
appid | Body / String | 必填 | 实验项目编号。 |
signature | Body / String | 必填 | 按下方规则计算的 32 位小写 MD5 字符串。 |
签名规则
signature = MD5(project + appid + secret)将三个原始字符串直接拼接,按 UTF-8 编码计算 MD5,输出小写十六进制。计算签名时使用 URL 编码前的 project。
Python 签名 示例
signature = hashlib.md5((project + appid + secret).encode("utf-8")).hexdigest()cURL 示例
curl --request POST "https://edu.hiholo.com/open/api/v2/token" --data-urlencode "project=PROJECT_FROM_LOGIN" --data-urlencode "appid=APP_ID" --data-urlencode "signature=CALCULATED_SIGNATURE"成功响应 JSON 示例
{
"code": 0,
"msg": "",
"access_token": "ACCESS_TOKEN_FROM_RESPONSE",
"created_time": 1700000000,
"expired_time": 1700086400,
"created_at": "2023-11-15 06:13:20",
"expired_at": "2023-11-16 06:13:20",
"un": "example_user",
"dis": "示例用户"
}有效期与重新登录
project 和 access_token 当前有效期均为 24 小时。以响应中的 expired_time 判断令牌到期时间;到期后重新执行“客户端登录 → 获取令牌”。重新取得的令牌用于后续请求。
created_time / expired_time 是秒级 Unix 时间戳,created_at / expired_at 是可读时间字符串。服务端返回字段名使用 created / expired。
查看本接口错误码
| code | 含义 |
|---|---|
| 1 | 缺少 project、appid 或 signature。 |
| 2 | appid 无效,或项目未配置 secret。 |
| 3 | signature 验证失败,请核对 appid、secret、拼接顺序与原始 project。 |
| 4 | project 签名错误。 |
| 5 | project 已过期,请重新登录。 |
| 6 | 其他令牌解析错误,查看 msg。 |
回传实验结果
实验结束后提交成绩、总用时和步骤记录。返回 code=0 后,本次实验结果才算回传成功。
/data_upload?access_token=ACCESS_TOKEN请求格式:application/json
| 字段 | 位置 / 类型 | 要求 | 说明 |
|---|---|---|---|
access_token | Query / String | 必填 | 获取令牌接口返回的 access_token。 |
username | JSON / String | 必填 | 使用登录响应中的 un,须与令牌用户一致。 |
title | JSON / String | 必填 | 实验名称。 |
status | JSON / Integer | 必填 | 1:完成;2:未完成。 |
score | JSON / Number | 必填 | 百分制,范围 0–100。 |
startTime / endTime | JSON / Integer | 必填 | 13 位毫秒 Unix 时间戳。 |
timeUsed | JSON / Integer | 必填 | 本次实验总用时,单位:秒。 |
appid | JSON / String | 必填 | 须与 access_token 所属项目一致。 |
originId | JSON / String | 必填 | 客户端为本次实验生成的唯一记录标识;在同一 appid 下不可重复。 |
steps | JSON / Array | 必填 | 步骤数组,最多 200 项;没有步骤时传空数组 []。 |
请求 JSON · 保存为 result.json 示例
{
"username": "example_user",
"title": "示例实验",
"status": 1,
"score": 95,
"startTime": 1700000000000,
"endTime": 1700000600000,
"timeUsed": 600,
"appid": "APP_ID",
"originId": "CLIENT_RECORD_UNIQUE_ID",
"steps": [
{
"seq": 1,
"title": "完成实验操作",
"startTime": 1700000000000,
"endTime": 1700000600000,
"timeUsed": 600,
"expectTime": 600,
"maxScore": 100,
"score": 95,
"repeatCount": 1,
"evaluation": "操作完成",
"scoringModel": "按实验规则评分",
"remarks": ""
}
]
}cURL 示例
curl --request POST "https://edu.hiholo.com/open/api/v2/data_upload?access_token=ACCESS_TOKEN" --header "Content-Type: application/json" --data-binary @result.json成功响应 JSON 示例
{
"code": 0,
"id": 123
}steps 中的字段
每个步骤按下表提供完整字段。当前接口校验要求包含 remarks 键,没有备注时传空字符串。
| 字段 | 类型 | 说明 |
|---|---|---|
seq | Integer | 步骤序号。 |
title | String | 步骤名称。 |
startTime / endTime | Integer | 13 位毫秒时间戳。 |
timeUsed / expectTime | Integer | 实际用时 / 参考用时,单位均为秒。 |
maxScore / score | Number | 步骤满分 / 实际得分。 |
repeatCount | Integer | 操作次数。 |
evaluation | String | 步骤评价。 |
scoringModel | String | 赋分规则说明。 |
remarks | String | 备注,允许空字符串。 |
originId 由客户端生成;响应中的 id 是服务端记录编号。后续上传报告仍使用原来的 originId。
查看本接口错误码
| code | 含义 |
|---|---|
| 1 | 缺少 access_token。 |
| 2 | 令牌签名错误。 |
| 3 | 令牌已过期。 |
| 4 | 其他令牌解析错误。 |
| 5 | JSON 格式、主字段或步骤字段不完整。 |
| 6 | 无效的 appid。 |
| 7 | 同一 appid 下 originId 已存在。 |
| 8 | 未知的平台用户。 |
| 9 | status 只能是 1 或 2。 |
| 10 | score 超出 0–100。 |
| 11 | startTime 不是 13 位时间戳。 |
| 12 | endTime 不是 13 位时间戳。 |
| 13 | 步骤超过 200 项。 |
| 14 | 用户与令牌不一致,或结果保存失败;结合 msg 判断。 |
| 15 | appid 与令牌所属项目不一致。 |
上传报告附件
为已经保存的实验结果附上报告。由表单上传文件,和 JSON 成绩请求分开调用。
/attachment_upload请求格式:multipart/form-data
| 字段 | 位置 / 类型 | 要求 | 说明 |
|---|---|---|---|
access_token | Form / String | 必填 | 当前用户、当前项目的有效令牌。 |
appid | Form / String | 必填 | 与令牌和结果记录一致。 |
originId | Form / String | 必填 | 已保存的实验结果标识。 |
filename | Form / String | 必填 | 带扩展名的文件名,例如 report.pdf。 |
title | Form / String | 必填 | 报告标题;同一项目和 originId 下不能重复上传同名报告。 |
remarks | Form / String | 必填 | 当前接口要求非空;没有备注可填“无”。 |
attachment | Form / File | 必填 | 文件字段名固定为 attachment。 |
支持 doc / docx / xls / xlsx / pdf,文件大小不超过 5 MiB;上传时提供与文件类型对应的 MIME 类型。
cURL 示例
curl --request POST "https://edu.hiholo.com/open/api/v2/attachment_upload" --form "access_token=ACCESS_TOKEN" --form "appid=APP_ID" --form "originId=CLIENT_RECORD_UNIQUE_ID" --form "filename=report.pdf" --form "title=实验报告" --form "remarks=无" --form "attachment=@report.pdf;type=application/pdf"成功响应 JSON 示例
{
"code": 0,
"id": 456
}查看本接口错误码
| code | 含义 |
|---|---|
| 1 | 缺少 access_token。 |
| 2 | 令牌签名错误。 |
| 3 | 令牌过期。 |
| 4 | 令牌解析错误。 |
| 5 | 缺少必填表单参数。 |
| 6 | 无效的 appid。 |
| 7 | appid 与令牌不一致。 |
| 8 | 对应结果记录不存在,或缺少 attachment 文件;查看 msg / data。 |
| 9 | 重复上传同名实验报告。 |
| 10 | 目标文件已经存在。 |
| 11 | 文件类型或大小不符合要求。 |
回传学习时长
用于累计练习、操作等学习时长,可在实验过程中按需调用。
/duration_upload请求格式:application/x-www-form-urlencoded
| 字段 | 位置 / 类型 | 要求 | 说明 |
|---|---|---|---|
access_token | Body / String | 必填 | 服务端从令牌识别用户和 appid。 |
exp_time | Body / Integer | 必填 | 本次新增的正整数时长,单位:秒。 |
cURL 示例
curl --request POST "https://edu.hiholo.com/open/api/v2/duration_upload" --data-urlencode "access_token=ACCESS_TOKEN" --data-urlencode "exp_time=60"成功响应 JSON 示例
{
"code": 0
}平台按用户和项目累加 exp_time。每次发送本次新增量,例如刚完成的 60 秒。重复提交同一时间段会再次累加,客户端应记录已确认上报的区间。
查看本接口错误码
| code | 含义 |
|---|---|
| 1 | 缺少 exp_time 或 access_token。 |
| 2 | 令牌签名错误。 |
| 3 | 令牌过期。 |
| 4 | 令牌解析错误。 |
| 6 | 无效的 appid。 |
| 8 | 未知的平台用户。 |
| 14 | 保存时长失败,查看 msg。 |
获取项目试卷
获取当前项目配置的课程试卷及题目,用于实验中的测验环节。
/paper/list?access_token=ACCESS_TOKEN请求格式:Query 参数
| 字段 | 位置 / 类型 | 要求 | 说明 |
|---|---|---|---|
access_token | Query / String | 必填 | 用于识别实验项目。 |
appid | Query / String | 可选 | 传入时必须与令牌中的 appid 一致。 |
cURL 示例
curl "https://edu.hiholo.com/open/api/v2/paper/list?access_token=ACCESS_TOKEN"成功响应 JSON 示例
{
"code": 0,
"msg": "success",
"data": [
{
"title": "示例试卷",
"questions": [
{
"ID": "123",
"TypeName": "单选题",
"Subject": "示例题干",
"Options": [
"选项 A",
"选项 B"
],
"Answers": [
0
],
"UserAnswers": [],
"Score": 5
}
]
}
]
}data 为试卷数组;没有试卷时返回空数组。Answers 使用 Options 中从 0 开始的下标。字段名区分大小写。
查看本接口错误码
| code | 含义 |
|---|---|
| 1 | 缺少或无效的 access_token。 |
| 2 | 令牌签名错误。 |
| 3 | 令牌过期。 |
| 4 | 令牌解析错误。 |
| 5 | 请求 appid 与令牌不匹配。 |
| 6 | 对应的实验项目不存在。 |
错误排查与约定
先确认请求地址、数据格式和 code,再按接口对应的错误说明处理。
先判断业务结果
HTTP 200 表示请求已到达接口;业务是否成功以 code 为准。0 为成功,其他值按该接口的错误码处理。兼容数字或数字字符串形式的 code;错误说明可能位于 msg 或 data。
时间与字段约定
| 内容 | 统一约定 |
|---|---|
startTime / endTime | 13 位毫秒 Unix 时间戳,包含结果和步骤字段。 |
timeUsed / expectTime / exp_time | 单位均为秒。 |
created_time / expired_time | 10 位秒级 Unix 时间戳,用于令牌创建和到期时间。 |
username | 使用登录或令牌响应中的 un。 |
originId | 客户端生成;在同一 appid 下唯一,成绩与附件始终复用同一个值。 |
常见问题
客户端登录成功后,为什么还不能回传?
登录返回的是 project。先调用获取令牌接口,得到 access_token 后再回传。
signature 验证失败,先检查什么?
确认 appid 与 secret 属于同一实验项目;按 project、appid、secret 的顺序直接拼接,使用原始字符串计算小写 MD5。
报告上传返回“originId 数据不存在”怎么办?
先确认结果回传返回 code=0,再用同一 appid 和 originId 上传附件。服务端返回的结果 id 不用于替代 originId。
网络超时后怎样处理重复结果?
保留本次实验的 originId。重复回传会返回 code=7,表示该项目下已存在相同标识;先确认已有记录,避免将同一实验作为新记录重复上报。
令牌到期后怎么办?
重新执行客户端登录与令牌交换,使用新的 access_token 发送后续请求。
客户端账号能直接用于网站登录吗?
两者使用同一套平台账号。项目 appid / secret 用于实验接入,用户 username / password 用于用户登录。