今日水印相机-验真api技术文档
联系方式
联系方式:17360234063(手机,微信)
工作时间:工作日 10:00~20:00
1 简介
1.1 什么是今日水印相机-验真api
开放平台支持今日水印相机用户自有系统接入,进行验真、查询验真结果等,获得对数据的二次开发的能力,从而满足各类定制化需求。
1.2 今日水印相机-验真api能做什么
初步开放以下功能,更多功能正在逐步开发中。 - 异步获取结果
1.3 今日水印相机api的安全保障说明
开放平台 API 数据传输全程加密(密钥按月更新,可以支持更高安全标准的密钥动态下发),用户通过开放平台 API 传输的数据全程不存储、不落库,保证用户数据隐私和安全,系统全流程符合国家三级等保标准,系统无被入侵风险,数据无泄漏风险。
2. 接入流程图
2.1 主动拉取数据

3. 开放平台加签流程
对接沟通后,我们会给提供跟团队绑定的唯一key和secret。
3.1 加签流程
以v2/department/sublist接口为例:
- 接口请求参数为:
{
"departmentID": 1
}
- 将该请求参数序列化并进行一次签名,目前仅支持HmacSha256算法,签名函数如下:
// data是加密的内容
func sign(data string, groupSecret string) (ret string) {
hmacObj := hmac.New(sha256.New, []byte(groupSecret))
hmacObj.Write([]byte(data))
ret = base64.StdEncoding.EncodeToString(hmacObj.Sum(nil))
return ret
}
- 把groupKey、参数签名(第二步的结果)、timestamp拼接为一个字符串
timestamp := time.Now().Unix()
groupKey := "groupKey"
str := fmt.Sprintf("groupKey=%s&sign=%s×tamp=%s",
groupKey,
sign,
strconv.FormatInt(timestamp, 10),
)
- 把第三步拼接后的字符串再进行一次签名,并得到最终签名。
signature := sign(str, "groupSecret")
- 把对应的信息设置至header头中。
req, _ := http.NewRequest(http.MethodGet, "url", nil)
req.Header.Set("GroupKey", groupKey)
req.Header.Set("Timestamp", strconv.FormatInt(timestamp, 10))
req.Header.Set("Signature", signature)
完整Http客户端代码如下:
func main() {
data := map[string]interface{}{
"departmentID": 1,
}
buf, _ := json.Marshal(data)
groupKey := "groupKey" // 需申请
groupSecret := "groupSecret" // 需申请
dataSign := sign(string(buf), groupSecret)
timestamp := strconv.FormatInt(time.Now().Unix(), 10)
str := fmt.Sprintf("groupKey=%s&sign=%s×tamp=%s",
groupKey,
dataSign,
timestamp,
)
// sign为加签流程中定义的函数
signature := sign(str, groupSecret)
url := "https://openapi.xhey.top/v2/department/sublist"
client := &http.Client{}
req, _ := http.NewRequest("POST", url, bytes.NewBuffer(buf))
req.Header.Set("GroupKey", groupKey)
req.Header.Set("Timestamp", timestamp)
req.Header.Set("Signature", signature)
_, _ = client.Do(req)
}
func sign(source string, groupSecret string) string {
hmacObj := hmac.New(sha256.New, []byte(groupSecret))
hmacObj.Write([]byte(source))
return base64.StdEncoding.EncodeToString(hmacObj.Sum(nil))
}
Python版本
# -*- coding: utf-8 -*-
import json
import requests
import hashlib
import time
import base64
import hmac
# 计算签名
def generate_signature(data, secret_key):
hmac_obj = hmac.new(secret_key.encode('utf-8'), data.encode('utf-8'), hashlib.sha256)
return base64.b64encode(hmac_obj.digest()).decode('utf-8')
# 请求数据
data = {
"departmentID": 1,
}
json_data = json.dumps(data)
group_secret = "groupSecret"
group_key, timestamp = "groupKey", str(int(time.time()))
data_sign = generate_signature(json_data, group_secret)
str_to_sign = "groupKey={0}&sign={1}×tamp={2}".format(group_key, data_sign, timestamp)
signature = generate_signature(str_to_sign, group_secret)
url = "https://openapi.xhey.top/v2/department/sublist"
# 构建请求头
headers = {
"GroupKey": group_key,
"Timestamp": timestamp,
"Signature": signature
}
# 发送HTTP POST请求
response = requests.post(url, data=json_data, headers=headers)
4. API总览
- 创建验真任务
- 查询验真结果
5. API列表
5.1 创建验真任务
创建验真任务
基本信息
请求方式:POST
请求地址:https://openapi.xhey.top/v2/truth_build/create
请求参数
| 名称 | 类型 | 示例值 | 描述 |
|---|---|---|---|
| photoUrlList | []String | ["https://net-cloud.xhey.top/SKU/71c506de1f1541f2aa0dcf60af07778f.jpg"] | 照片链接列表,推荐一批次数据少于10条,需要支持通过GET请求直接下载该图片 |
返回参数
| 名称 | 类型 | 示例值 | 描述 |
|---|---|---|---|
| code | Integer | 200 | 状态码 |
| msg | String | success | 状态码对应的提示内容 |
| data | []Object | 返回数据 | |
| -- taskID | string | 任务id,用于查询验真的结果 | |
| timestamp | Integer | 1629092630 | 请求时间,Unix时间戳 |
示例
请求示例(HTTP)
POST https://openapi.xhey.top/v2/truth_build/create
请求示例(Golang API)
url := "https://openapi.xhey.top/v2/truth_build/create"
reqStr := `{
"photoUrlList": ["https://net-cloud.xhey.top/SKU/71c506de1f1541f2aa0dcf60af07778f.jpg"]
}`
reader := bytes.NewReader(([]byte)(reqStr))
groupSecret := "groupSecret" // 需申请
groupKey := "groupKey" // 需申请
dataSign := sign(reqStr, groupSecret)
timestamp := strconv.FormatInt(time.Now().Unix(), 10)
str := fmt.Sprintf("groupKey=%s&sign=%s×tamp=%s",
groupKey,
dataSign,
timestamp,
)
signature := sign(str, groupSecret)
req, _ := http.NewRequest("POST", url, reader)
req.Header.Add("Content-Type", "application/json")
req.Header.Set("GroupKey", groupKey)
req.Header.Set("Timestamp", timestamp)
req.Header.Set("Signature", signature)
client := &http.Client{}
defer client.CloseIdleConnections()
resp, err := client.Do(req)
if err != nil {
fmt.Println(err)
return
}
defer resp.Body.Close()
var buf bytes.Buffer
_, err = buf.ReadFrom(resp.Body)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(buf.String())
返回示例
{
"code": 200,
"msg": "success",
"data": [{"taskID":"1916812048797622272"],
"timestamp": 1629099324
}
5.2 验真结果查询
验真结果查询
基本信息
请求方式:POST
请求地址:https://openapi.xhey.top/v2/truth_build/query
请求参数
| 名称 | 类型 | 示例值 | 描述 |
|---|---|---|---|
| taskID | String | "1916812048797622272" |
返回参数
经纬度坐标系为gcj02
| 名称 | 类型 | 示例值 | 描述 |
|---|---|---|---|
| code | Integer | 200 | 状态码 |
| msg | String | success | 状态码对应的提示内容 |
| taskStatus | int | 1 | 任务状态,1-未处理,2-处理中,5-处理完成,6-任务撤销 |
| list | []Object | 返回数据 | |
| --photoUrl | String | 照片的地址 | |
| --status | Integer | 1是处理中,0为验真成功 | 部分错误码 RESOLUTION_TOO_LOW = -1 # 分辨率过低 ;NETWORK_ISSUES = -1001 ;# 网络连接出错或照片损坏 ALG_ISSUES = -1002 # 程序出错;UNKNOWN_ERROR = -1003 # 未知错误;OCR_INIT_ERR = -2300 # OCR启动错误;NO_ANTICODE = -2301 # 无防伪码;OCR_ERR = -2302 # OCR识别错误;ANTICODE_LENGTH_FAIL = -2303 # 防伪码长度错误;NO_TODAY_CAMER_OR_NO_WATERMARK = -2305 # 非今拍或者无水印 |
| --msg | string | 错误原因 | 如:非今拍或者无水印 |
| --lat | string | 纬度 | 30.539732 |
| --lng | string | 经度 | 104.066506 |
| --photoTime | string | 拍照时间 | 2025年07月28日 15:01 |
| --photoAddress | string | 拍照地点 | 四川省成都市武侯区桂溪街道天府软件园E区 |
示例
请求示例(HTTP)
POST https://openapi.xhey.top/v2/truth_build/query
请求示例(Golang API)
url := "https://openapi.xhey.top/v2/truth_build/query"
reqStr := `{
"taskID": "1916812048797622272"
}`
reader := bytes.NewReader(([]byte)(reqStr))
groupSecret := "groupSecret" // 需申请
groupKey := "groupKey" // 需申请
dataSign := sign(reqStr, groupSecret)
timestamp := strconv.FormatInt(time.Now().Unix(), 10)
str := fmt.Sprintf("groupKey=%s&sign=%s×tamp=%s",
groupKey,
dataSign,
timestamp,
)
signature := sign(str, groupSecret)
req, _ := http.NewRequest("POST", url, reader)
req.Header.Add("Content-Type", "application/json")
req.Header.Set("GroupKey", groupKey)
req.Header.Set("Timestamp", timestamp)
req.Header.Set("Signature", signature)
client := &http.Client{}
defer client.CloseIdleConnections()
resp, err := client.Do(req)
if err != nil {
fmt.Println(err)
return
}
defer resp.Body.Close()
var buf bytes.Buffer
_, err = buf.ReadFrom(resp.Body)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(buf.String())
返回示例
{
"code": 200,
"msg": "success",
"taskStatus":2,
"list":[{"photoUrl":"https://net-cloud.xhey.top/authVerify/photos/android_certification_photo_6fc47239bd2f58ef_1745838578630.jpg","status":1,"msg":""}]}
"timestamp": 1629099324
}
6. 状态码列表
当code值不等于200时,返回数据的data为null
| code值 | 类型 | 错误内容 |
|---|---|---|
| 200 | Integer | success |
| 2001 | Integer | you can query a maximum of 1000 records, please be precise with your query conditions |
| 400 | Integer | param error |
| 401 | Integer | verify error |
| 403 | Integer | forbidden |
| 404 | Integer | not found |
| 500 | Integer | service error |
| 4002 | Integer | invalid token |
| 4007 | Integer | group key or secret not right |
| 4008 | Integer | you can query a maximum of 1000 personnel information at a time |
| 4009 | Integer | time param error |
| 4010 | Integer | you can query longest of 180 days data |
| 4011 | Integer | you can use a maximum of three keywords to search |
| 4012 | Integer | one keyword contain a maximum of 15 characters |
| 4013 | Integer | not support watermark ids query |