跳到主要内容

今日水印相机-验真api技术文档

联系方式

联系方式:17360234063(手机,微信)

工作时间:工作日 10:00~20:00

png2

1 简介

1.1 什么是今日水印相机-验真api

开放平台支持今日水印相机用户自有系统接入,进行验真、查询验真结果等,获得对数据的二次开发的能力,从而满足各类定制化需求。

1.2 今日水印相机-验真api能做什么

初步开放以下功能,更多功能正在逐步开发中。 - 异步获取结果

1.3 今日水印相机api的安全保障说明

开放平台 API 数据传输全程加密(密钥按月更新,可以支持更高安全标准的密钥动态下发),用户通过开放平台 API 传输的数据全程不存储、不落库,保证用户数据隐私和安全,系统全流程符合国家三级等保标准,系统无被入侵风险,数据无泄漏风险。

2. 接入流程图

2.1 主动拉取数据

png2

3. 开放平台加签流程

对接沟通后,我们会给提供跟团队绑定的唯一key和secret。

3.1 加签流程

以v2/department/sublist接口为例:

  1. 接口请求参数为:
{
"departmentID": 1
}
  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
}
  1. 把groupKey、参数签名(第二步的结果)、timestamp拼接为一个字符串
timestamp := time.Now().Unix()
groupKey := "groupKey"
str := fmt.Sprintf("groupKey=%s&sign=%s&timestamp=%s",
groupKey,
sign,
strconv.FormatInt(timestamp, 10),
)
  1. 把第三步拼接后的字符串再进行一次签名,并得到最终签名。
signature := sign(str, "groupSecret")
  1. 把对应的信息设置至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&timestamp=%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}&timestamp={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/group/photo/4efce4e5-806b-4273-9e33-232f8f1a3cb6.jpg"]照片链接列表,推荐一批次数据少于10条,需要支持通过GET请求直接下载该图片
photoBase64List[]String["iVBORw0KGgoAAAANSUhEUgAA...(图片的标准base64,此处省略)"]照片 base64 列表。要求标准 base64(StdEncoding),且不含 data:image/...;base64, 前缀;与 photoUrlList 至少二选一,也可同时传入,合计条数推荐少于10条、最多50条

说明:photoUrlListphotoBase64List 至少需要传入一个,可单独使用,也可同时使用(服务端会合并处理);两个列表的条数合计不得超过 50。photoBase64List 的每个元素必须是图片的标准 base64 编码(如 Go base64.StdEncoding、Java Base64.getEncoder()、Python base64.b64encode、JS btoa 的默认输出),请勿包含 data:image/png;base64, 这类 data URI 前缀,否则将返回参数错误。

返回参数

名称类型示例值描述
codeInteger200状态码
msgStringsuccess状态码对应的提示内容
dataObject返回数据
--data[]Object任务列表
----taskIDString2061412837985579008任务id,用于查询验真的结果
--statusInteger0业务状态码(0=成功)
--msgString业务提示信息
timestampInteger1780314094请求时间,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/group/photo/4efce4e5-806b-4273-9e33-232f8f1a3cb6.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&timestamp=%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())

请求示例(Golang API,使用 photoBase64List)

与上面的 photoUrlList 示例相比仅请求体不同:把本地图片编码为标准 base64 后放入 photoBase64List,其余加签、请求头、发送流程完全一致。

    // 读取本地图片并编码为标准 base64(StdEncoding);注意不要添加 data:image/...;base64, 前缀
imgBytes, _ := os.ReadFile("/path/to/photo.png")
photoBase64 := base64.StdEncoding.EncodeToString(imgBytes)

reqBytes, _ := json.Marshal(map[string][]string{
"photoBase64List": {photoBase64},
})
reqStr := string(reqBytes) // 使用 reqStr 进行加签,请求体发送 reqBytes

返回示例

{
"code": 200,
"msg": "success",
"data": {
"data": [
{"taskID": "2061412837985579008"}
],
"status": 0,
"msg": ""
},
"timestamp": 1780314094
}

5.2 验真结果查询

验真结果查询

基本信息

请求方式:POST

请求地址:https://openapi.xhey.top/v2/truth_build/query

请求参数

名称类型示例值描述
taskIDString"2061632364592914432"由 5.1 创建接口返回的 taskID

返回参数

经纬度坐标系为gcj02

名称类型示例值描述
codeInteger200状态码
msgStringsuccess状态码对应的提示内容
dataObject返回数据
--taskStatusInteger5任务状态,1-未处理,2-处理中,5-处理完成,6-任务撤销
--statusInteger0业务状态码(0=成功)
--msgString业务提示信息
--list[]Object单张照片的验真结果列表
----photoUrlStringhttps://net-cloud.xhey.top/authVerify/photos/f9c24b58-b628-4fcb-9484-dfc0e8ad107a.png照片地址。photoUrlList 创建时返回调用方原始 URL;photoBase64List 创建时返回服务端重新上传后的 OSS URL
----photoBase64IdxInteger0仅当该图片由 photoBase64List 创建时返回;为该图片在创建请求 photoBase64List 中的下标(0 起)。photoUrlList 创建的图片不返回该字段
----statusInteger0验真结果:0=真,1=处理中;部分错误/假码 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 # 非今拍或者无水印
----msgString时间真实、地点真实、防伪码真实判定描述(真实情况说明或错误原因)
----latString34.384929纬度
----lngString115.839913经度
----photoTimeString2026年05月29日 19:30拍照时间
----photoAddressString虞城县·至信一路拍照地点
----antiFakeCodeStringCXPT4TX469K29W照片的防伪码
timestampInteger1780366439请求时间,Unix时间戳

示例

请求示例(HTTP)

POST https://openapi.xhey.top/v2/truth_build/query

请求示例(Golang API)

    url := "https://openapi.xhey.top/v2/truth_build/query"
reqStr := `{
"taskID": "2061632364592914432"
}`
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&timestamp=%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())

返回示例(验真为真,由 photoBase64List 创建,含 photoBase64Idx 字段)

{
"code": 200,
"msg": "success",
"data": {
"list": [
{
"status": 0,
"msg": "时间真实、地点真实、防伪码真实",
"photoUrl": "https://net-cloud.xhey.top/authVerify/photos/f9c24b58-b628-4fcb-9484-dfc0e8ad107a.png",
"photoBase64Idx": 0,
"lat": "34.384929",
"lng": "115.839913",
"photoTime": "2026年05月29日 19:30",
"photoAddress": "虞城县·至信一路",
"antiFakeCode": "CXPT4TX469K29W"
}
],
"taskStatus": 5,
"status": 0,
"msg": ""
},
"timestamp": 1780366439
}

说明:

  • photoBase64Idx 字段仅在该图片由 photoBase64List 创建时返回;由 photoUrlList 创建的图片不会返回该字段。
  • photoBase64List 创建时,photoUrl 为服务端重新上传后的 OSS 地址(如示例中的 …/authVerify/photos/f9c24b58-….png);当 photoUrlList 创建时,photoUrl 为调用方提交时的原始 URL。
  • status=0 表示验真为真,status<0 表示验真为假或处理异常(详见请求/响应参数表的状态码说明)。

5.3 生成验真报告

根据验真任务ID,生成验真报告图片并上传至OSS,返回报告图片地址。

基本信息

请求方式:POST

请求地址:https://openapi.xhey.top/v2/truth_build/verify_report

请求参数

名称类型示例值描述
taskIDString"2061632364592914432"验真任务ID
timeoutInteger60超时时间(秒),默认60,范围5-120

返回参数

名称类型示例值描述
codeInteger200状态码
msgStringsuccess状态码对应的提示内容
dataObject返回数据
--taskIDString2061632364592914432验真任务ID
--timestampInteger1780367810074报告生成时间戳(毫秒)
--ossUrlStringhttps://net-cloud.xhey.top/authVerify/reports/2061632364592914432-1780367810074.png报告图片OSS地址
--elapsedFloat2.4生成耗时(秒)
--statusInteger0报告生成结果状态码(0=成功)
--msgString状态码对应的提示内容
timestampInteger1780367812请求时间,Unix时间戳

示例

请求示例(HTTP)

POST https://openapi.xhey.top/v2/truth_build/verify_report

请求示例(Golang API)

    url := "https://openapi.xhey.top/v2/truth_build/verify_report"
reqStr := `{
"taskID": "2061632364592914432"
}`
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&timestamp=%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": "2061632364592914432",
"timestamp": 1780367810074,
"ossUrl": "https://net-cloud.xhey.top/authVerify/reports/2061632364592914432-1780367810074.png",
"elapsed": 2.4,
"status": 0,
"msg": ""
},
"timestamp": 1780367812
}

错误返回示例

{
"code": 504,
"msg": "报告生成超时(60s)",
"data": null,
"timestamp": 1776062479
}

6. 状态码列表

当code值不等于200时,返回数据的data为null

code值类型错误内容
200Integersuccess
2001Integeryou can query a maximum of 1000 records, please be precise with your query conditions
400Integerparam error
401Integerverify error
403Integerforbidden
404Integernot found
500Integerservice error
4002Integerinvalid token
4007Integergroup key or secret not right
4008Integeryou can query a maximum of 1000 personnel information at a time
4009Integertime param error
4010Integeryou can query longest of 180 days data
4011Integeryou can use a maximum of three keywords to search
4012Integerone keyword contain a maximum of 15 characters
4013Integernot support watermark ids query