跳到主要内容

Palm 掌纹识别开放 API 对接文档

面向对象:接入方后端开发工程师

本文档帮助您完成 后端业务接口 对接,以及 SDK 用户 Token 签发。


一、快速开始​

对接分为 3 步:

  1. 申请 API Key(一次性)—— 前往开发者控制台创建应用并生成 api_key。
  2. 服务端调用接口 —— 通过 HTTPS 携带 Authorization: Bearer <api_key> 调用业务接口。
  3. 处理业务响应 —— 按统一响应结构 {code, message, requestId, data} 判断结果。
┌─────────────────┐ HTTPS + Bearer <api_key> ┌────────────────────────────────┐
│ 您的后端服务 │ ─────────────────────────▶ │ open.intl.palm.tencent.com │
│ │ │ /palm/openai/* │
│ │ ◀───────────────────────── │ (Palm 开放平台网关) │
└─────────────────┘ JSON 响应 └────────────────────────────────┘
│
│ 服务端替终端用户签发
│ CreateSdkUserToken → sdk_user_token(sut_xxx)
▼
┌─────────────────┐ HTTPS + Bearer <sdk_user_token> ┌──────────────────────────┐
│ 终端 SDK/客户端│ ──────────────────────────────▶ │ open.intl.palm.tencent.com│
│ (App / 小程序)│ │ /palm/openai/* │
└─────────────────┘ 仅能操作该用户数据 └──────────────────────────┘

🔐 两种凭证的分工

  • api_key(ak_ 前缀)—— 服务端专用、权限最大,可访问全部接口与全部用户数据;不得下发到端。
  • sdk_user_token(sut_ 前缀)—— 绑定到单个用户的受限凭证,通过 §5.1 CreateSdkUserToken 由业务方后端替某个 UserId 签发;只能操作该用户自己的数据,有过期时间。业务方既可以在自己的 Web 后端直接使用,也可以下发给移动端 SDK / 小程序 / 桌面客户端使用。

二、Token 申请(API Key)​

2.1 申请入口​

前往官网开发者控制台申请 API Key:

🔑 https://palm.tencent.com/developer/api-keys

2.2 申请流程​

  1. 使用您的账号登录官网。
  2. 进入 开发者中心 → API Keys。
  3. 点击 「创建应用」,填写应用名称、选择产品类型(掌纹管理)。
  4. 应用创建成功后,点击 「生成 API Key」。
  5. 立即复制并妥善保存明文 api_key(形如 ak_xxxxxxxxxxxxxxxxxxxxxxxxxxxx)—— 明文仅本次一次性返回,后续控制台只展示脱敏串(如 ak_abcd******wxyz),若丢失只能删除后重新生成。

2.3 使用方式​

在每次 HTTP 请求头中加入:

Authorization: Bearer ak_xxxxxxxxxxxxxxxxxxxxxxxxxxxx

⚠️ 安全注意事项

  • api_key 属于服务端凭证,严禁放到前端页面 / App 客户端 / 移动端源码 / 公开仓库;仅可保存在您服务端环境变量或密钥管理服务(KMS)中。
  • 一旦泄露,请立即到控制台删除并重新生成。
  • 每个应用至多 1 把有效 api_key;如需轮换,先创建新 key,再删除旧 key。

三、通用约定​

3.1 接口域名​

环境域名
正式环境(海外)https://open.intl.palm.tencent.com

所有业务接口均使用 HTTPS + POST + JSON。

3.2 URL 前缀​

业务接口的路径统一以 /palm/openai/ 开头(CreateSdkUserToken 除外,见 §5.1):

POST https://open.intl.palm.tencent.com/palm/openai/<接口名>

3.3 请求头(HTTP Headers)​

字段是否必填说明
Content-Type是固定为 application/json; charset=utf-8
Authorization是固定格式 Bearer <credential>,其中 <credential> 为 api_key(ak_ 前缀,见 §2)或 sdk_user_token(sut_ 前缀,见 §5.1)
X-TraceId否32 位小写 hex 字符串。用于全链路追踪,若不传由网关自动生成;建议接入方自行生成并记录,便于排障

3.4 请求体(Body)​

  • 均为 JSON 对象。
  • 字段名统一使用 首字母大写驼峰(PascalCase),如 UserId、RgbImage。
  • 图片二进制数据字段 Data 使用 Base64 编码字符串。

3.5 通用响应结构​

所有接口成功时统一返回如下 JSON 结构:

{
"code": 0,
"message": "ok",
"requestId": "4d5912a82af144f8a982c2da031c1035",
"data": {}
}

(data 字段的具体业务字段见各接口小节。)

字段类型说明
codeInteger业务错误码。0 表示成功;非 0 表示失败,请对照 §6 错误码表
messageString错误描述(成功时为 "ok")
requestIdString服务端请求唯一 ID,排障时请提供
dataObject业务数据;失败时可能为空对象 {}

3.6 频率限制​

  • 默认:20 次/秒 / 凭证(api_key 与 sdk_user_token 独立计数)。
  • 超限返回 HTTP 429,请合理控制并发或联系官方申请提额。

四、公共数据类型​

以下类型在多个接口中复用,统一说明。

4.1 PalmDirectionType 枚举​

枚举值含义
1LEFT_PALM(左手掌)
2RIGHT_PALM(右手掌)

4.2 PalmState 枚举(掌纹状态)​

枚举值常量名含义
1ACTIVATED绑定成功,可用于比对 / 检索
2HIGH_SIMILARITY高相似(与其他用户存在高相似风险,暂不可用)

五、业务接口​

接口一览​

序号能力接口名MethodPath支持的凭证
1令牌鉴权CreateSdkUserTokenPOST/palm/openai/x/oauth/sdk/usertoken/create仅 api_key
2掌纹注册查询GetPalmPOST/palm/openai/get_palmapi_key / sdk_user_token
31:1 核验GetSessionResultPOST/palm/openai/get_session_resultapi_key / sdk_user_token
4手掌删除DeletePalmPOST/palm/openai/delete_palmapi_key / sdk_user_token

使用 sdk_user_token 调用接口时,请求体中的 UserId 必须等于签发该 token 时传入的 UserId(服务端会把签发时的 UserId 作为该 token 的绑定用户),否则将返回 403。


5.1 令牌鉴权(签发 SDK 用户 Token,CreateSdkUserToken)​

🔗 路径特别说明:本接口路径为 /palm/openai/x/oauth/sdk/usertoken/create,与其他业务接口(/palm/openai/<接口名>)不同,请勿写错。

接口描述​

为业务方指定的最终用户签发一枚受限的 sdk_user_token(JWT,sut_ 前缀)。得到的 token 既可以由业务方自己在 Web 后端 直接使用,也可以下发给 移动端 SDK / 小程序 / 桌面客户端(特别适用于无法安全保管 api_key 的端侧场景)。

签发后的 sdk_user_token:

  • 只能操作该用户自己的数据:调用 §5.2 / §5.3 / §5.4 时,请求体中的 UserId 必须等于签发时传入的 UserId;不匹配一律返回 403。
  • 有过期时间:默认 30 分钟(1800 秒),最长 24 小时(86400 秒);TtlSeconds 传 0 或缺省即取默认。
  • 明文仅本次一次性返回:请由业务方后端下发到端上使用,不要持久化到不受信任的存储。
  • 可撤销:api_key 被吊销 / 应用被禁用后即失效;异常情况下平台可通过后台密钥轮换一刀切吊销所有已签发的 sdk_user_token(业务方需重新签发)。

⚠️ 本接口必须由业务方服务端调用:仅接受 api_key 鉴权。严禁将本接口(包括 api_key)暴露到端侧,否则等同于把 api_key 泄露。

  • 默认频率限制:20 次/秒。

请求参数​

参数必填类型说明
UserId是String业务方最终用户标识(业务方自定义命名空间,Palm 侧不落表;与其他业务接口中的 UserId 同一个取值空间),长度 ≤ 64
TtlSeconds否IntegerToken 有效期(秒)。0 或缺省 → 默认 1800(30 分钟);硬上限 86400(24 小时),超出直接返回错误码 2090021(不会静默截断)
Scope否Array<String>预留权限点数组,v1 不校验,仅回填到 JWT,可传空 [] 或不传

响应参数(data)​

参数类型说明
TokenString签发的 sdk_user_token,形如 sut_xxxxxxxxxxxxxxxx(内部为 JWT)。明文仅本次返回,请立即保存或下发给对应终端
ExpiresAtIntegerToken 过期时间戳(Unix 秒,UTC)

示例​

请求

POST /palm/openai/x/oauth/sdk/usertoken/create HTTP/1.1
Host: open.intl.palm.tencent.com
Content-Type: application/json; charset=utf-8
Authorization: Bearer ak_xxxxxxxxxxxxxxxxxxxxxxxxxxxx

{
"UserId": "user001",
"TtlSeconds": 1800,
"Scope": []
}

响应

{
"code": 0,
"message": "ok",
"requestId": "4d5912a82af144f8a982c2da031c1035",
"data": {
"Token": "sut_eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.xxx.yyy",
"ExpiresAt": 1783691400
}
}

cURL

curl -X POST "https://open.intl.palm.tencent.com/palm/openai/x/oauth/sdk/usertoken/create" \
-H "Content-Type: application/json; charset=utf-8" \
-H "Authorization: Bearer ak_xxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-d '{
"UserId": "user001",
"TtlSeconds": 1800,
"Scope": []
}'

使用拿到的 sdk_user_token 调用业务接口(后端 Web / SDK / 小程序 均适用)​

拿到 sdk_user_token 后,调用方式和 api_key 完全一致,只是把 Header 中的 ak_xxx 换成 sut_xxx:

POST /palm/openai/get_palm HTTP/1.1
Host: open.intl.palm.tencent.com
Content-Type: application/json; charset=utf-8
Authorization: Bearer sut_eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.xxx.yyy

{
"UserId": "user001"
}

服务端会自动从 sdk_user_token 反解出所绑定的 UserId(即请求体中的 UserId),并执行下列校验:

  1. sdk_user_token 签名有效、未过期。
  2. 请求体中的 UserId 必须等于 token 绑定的 UserId,否则返回 403。
  3. 调用的接口在 sdk_user_token 允许清单内(§5.2 GetPalm / §5.3 GetSessionResult / §5.4 DeletePalm)。

✅ 推荐做法(特别针对 SDK / 端侧):端上每次冷启动 / token 剩余寿命不足 20% 时,向业务方自己的后端请求最新 sdk_user_token;由业务方后端在内部登录态校验通过后,再调用本接口签发。这样即便 token 被抓包也仅影响该用户,且很快过期。


5.2 掌纹注册查询(GetPalm)​

接口描述​

查询指定用户当前已注册的左/右手掌纹信息,用于业务侧展示"是否已开通刷掌 / 什么时候注册的 / 状态是否正常"等。

  • 默认频率限制:20 次/秒。
  • 只读接口,不会修改任何数据。
  • 若用户从未注册过某一方向的掌纹,则该方向对应的 PalmInfo 字段将被省略或为空对象。

请求参数​

参数必填类型说明
UserId是String用户唯一标识(与 §5.1 中的 UserId 语义一致)

响应参数(data)​

顶层:

参数类型说明
LeftPalmPalmInfo左手掌纹信息
RightPalmPalmInfo右手掌纹信息

PalmInfo 结构:

参数类型说明
PalmStateInteger掌纹状态,见 §4.2;1 表示绑定成功、可用于比对
PalmDirectionPalmDirectionType手掌方向,见 §4.1
RegisterTimeInteger首次注册时间(Unix 秒,UTC)

示例​

请求

POST /palm/openai/get_palm HTTP/1.1
Host: open.intl.palm.tencent.com
Content-Type: application/json; charset=utf-8
Authorization: Bearer ak_xxxxxxxxxxxxxxxxxxxxxxxxxxxx

{
"UserId": "user001"
}

响应(用户仅开通左手)

{
"code": 0,
"message": "ok",
"requestId": "4d5912a82af144f8a982c2da031c1035",
"data": {
"LeftPalm": {
"PalmState": 1,
"PalmDirection": 1,
"RegisterTime": 1783600000
},
"RightPalm": {
"PalmState": 0,
"PalmDirection": 0,
"RegisterTime": 0
}
}
}

cURL

curl -X POST "https://open.intl.palm.tencent.com/palm/openai/get_palm" \
-H "Content-Type: application/json; charset=utf-8" \
-H "Authorization: Bearer ak_xxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-d '{
"UserId": "user001"
}'

5.3 查询识别结果(GetSessionResult)​

接口描述​

查询客户端/SDK 完成 1:1 比对后生成的临时识别结果详情。比对完成后,palm_mgr 会返回一个临时 SessionId(UUID,有效期 2 小时),业务方后端凭该 SessionId 查询本次比对的目标用户 ID、掌纹 ID、手掌方向、是否命中、分数与算法版本,避免识别结果详情被直接暴露。

  • 默认频率限制:20 次/秒。
  • 只读接口,不会修改任何数据。
  • SessionId 有效期为 2 小时,过期后需重新发起比对获取新的 SessionId。
  • 该接口无需在请求中指定 UserId,服务端根据 SessionId 反查出对应的识别结果。

请求参数​

参数必填类型说明
SessionId是String识别结果临时查询凭据,即比对接口响应中的 SessionId

响应参数(data)​

参数类型说明
UserIdString本次识别的目标用户 ID
PalmIdString参与识别的掌纹 ID
PalmDirectionPalmDirectionType参与识别的手掌方向,见 §4.1
SearchResultObject识别结果(识别类 session 返回),结构见下表
RegisterResultObject注册结果(注册类 session 返回),当前无额外字段

SearchResult 结构:

字段类型说明
IsMatchBoolean是否命中(1:1 比对为是否同一人;1:N 检索为是否检索到)
ScoreInteger识别分数
AlgorithmVersionString本次识别使用的算法版本

示例​

请求

POST /palm/openai/get_session_result HTTP/1.1
Host: open.intl.palm.tencent.com
Content-Type: application/json; charset=utf-8
Authorization: Bearer ak_xxxxxxxxxxxxxxxxxxxxxxxxxxxx

{
"SessionId": "3f2b1a6d-8c4e-4b7a-9d5f-1e2c3a4b5c6d"
}

响应

{
"code": 0,
"message": "ok",
"requestId": "4d5912a82af144f8a982c2da031c1035",
"data": {
"UserId": "user001",
"PalmId": "8db884f9-1fb8-44f5-bdaa-f98fdcb3cd47",
"PalmDirection": 1,
"SearchResult": {
"IsMatch": true,
"Score": 92,
"AlgorithmVersion": "rgb_v3"
}
}
}

cURL

curl -X POST "https://open.intl.palm.tencent.com/palm/openai/get_session_result" \
-H "Content-Type: application/json; charset=utf-8" \
-H "Authorization: Bearer ak_xxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-d '{
"SessionId": "3f2b1a6d-8c4e-4b7a-9d5f-1e2c3a4b5c6d"
}'

5.4 手掌删除(DeletePalm)​

接口描述​

删除指定用户的掌纹信息。支持按左/右手方向单独删除,也可以同时删除双手。删除后该用户对应方向的掌纹将无法再被比对命中。

  • 默认频率限制:20 次/秒。
  • 删除是幂等的:对不存在的方向重复删除不会报错。

请求参数​

参数必填类型说明
UserId是String用户唯一标识
PalmDirectionList是Array<PalmDirectionType>要删除的手掌方向列表。可以同时传入左右手,或仅左手/仅右手。见 §4.1

响应参数(data)​

无业务字段,data 为空对象 {}。

示例​

请求(同时删除双手)

POST /palm/openai/delete_palm HTTP/1.1
Host: open.intl.palm.tencent.com
Content-Type: application/json; charset=utf-8
Authorization: Bearer ak_xxxxxxxxxxxxxxxxxxxxxxxxxxxx

{
"UserId": "user001",
"PalmDirectionList": [1, 2]
}

响应

{
"code": 0,
"message": "ok",
"requestId": "4d5912a82af144f8a982c2da031c1035",
"data": {}
}

六、错误码​

除业务错误码外,也可能返回 HTTP 层的状态码,请按下表处理。

6.1 HTTP 状态码​

HTTP Code含义处理建议
200请求已抵达业务层请解析 body 中的 code 字段判断是否真正成功
401未授权检查 Authorization 头是否携带、api_key 是否已被删除或格式错误
403无权限检查该应用是否被禁用、api_key 是否被吊销
429请求过快降低 QPS,或联系官方申请提额
5xx服务端异常携带 requestId 联系官方支持

6.2 业务错误码(code 字段)​

响应体中 code 为业务错误码:0 表示成功;非 0 表示失败,请按下表定位原因,并结合 message 字段与 requestId 排障。

错误码采用 7 位十进制编码,格式为 XXX YYYY:前 3 位为模块号(标识错误来源),后 4 位为模块内序号。PaaS 接口涉及以下 4 段:

  • 1000xxx 通用兜底:参数校验、内部异常等所有接口都可能返回。
  • 2060xxx 凭证/鉴权(网关层):所有接口在鉴权阶段都可能返回。
  • 2080xxx 掌纹业务(palm_mgr):接口业务逻辑本身抛出的错误。
  • 2090xxx OAuth / SDK 凭证签发:仅 §5.1 CreateSdkUserToken 场景可能返回。

6.2.1 通用错误码​

codemessage含义 / 排查建议
0ok请求成功。
1000000invalid param请求参数校验失败(必填字段缺失 / 格式非法 / 长度超限等)。请对照各接口"请求参数"表核对。
1000001internal error服务端内部异常,请携带 requestId 联系官方支持。
1000011database operation failed数据库操作失败(超时 / 连接异常等)。可稍后重试;持续复现请携带 requestId 反馈。
1000013forbidden无操作权限(应用被禁用 / 凭证被吊销等)。请核对应用状态。

6.2.2 凭证与鉴权错误码​

由网关层在鉴权阶段返回;出现此段错误时业务逻辑尚未执行。

codemessage含义 / 排查建议
2060000unauthorized未携带 Authorization 头、api_key/sdk_user_token 无效或已过期。请检查 §3.3 请求头格式与凭证有效性。
2060002too many requests触发调用频率限制。请降低 QPS,或联系官方申请提额。
2060200openapi credential not found凭证不存在。可能已被删除,请到控制台确认或重新生成。
2060201openapi credential of this type already exists同一类型凭证已存在(api_key 按 app_id 唯一,sdk_user_token 按用户唯一)。仅在 §5.1 CreateSdkUserToken 场景可能出现,需先删除旧凭证。
2060202openapi credential revoked凭证已被吊销。请到控制台重新生成。
2060203openapi credential invalid凭证格式非法或签名校验失败;或凭证类型对应的必填字段(如 user_token 的 uid、sdk_user_token 的 userid/app_id)为空。请核对复制的 api_key/sdk_user_token 是否完整。
2060204openapi credential type invalid凭证类型非法:Authorization: Bearer <credential> 中的 <credential> 前缀非 ak_ / ut_ / sut_(例如误把控制台 JWT 当作 OpenAPI 凭证使用);或 §5.1 签发场景请求的凭证类型不在 api_key / user_token 白名单内。
2060205openapi credential not allowed for this pathsdk_user_token 的 scope 未覆盖当前接口路径。仅 sut_ 前缀凭证可能出现,请核对签发时的 scope 配置。
2060207OpenAPI app not configured凭证对应的应用未在平台完成配置。请联系官方开通。
2090021sdk user token ttl exceeds max limit§5.1 CreateSdkUserToken 请求的 TtlSeconds 超过硬上限(默认 86400,即 24 小时)。平台直接拒绝而非静默截断,请将 TtlSeconds 调整到 1~86400 范围内后重试。

6.2.3 业务错误码(掌纹业务)​

由 palm_mgr 业务层返回;code 与接口的对应关系见每条备注。

codemessage含义 / 排查建议
2080000no available version无可用算法/掌纹版本。请联系官方确认应用是否已正确开通产品版本。
2080001unknown image type未知图片类型。请确认 RgbImage.Data 为合法的 Base64 编码 JPG/PNG 图片。
2080002image MD5 mismatch图片 MD5 校验失败,通常为传输过程中数据被截断或篡改。建议客户端重试。
2080003liveness check failed活体检测未通过。可能采集时用户使用了照片/翻拍;请引导用户重新采集清晰的真实手掌图像。
2080004quality check failed图像质量检测未通过(模糊 / 手掌不完整 / 光线差等)。请引导用户按 SDK 提示重新采集。
2080005liveness video check failed视频活体检测未通过(ActionLiveness 场景)。请引导用户按 SDK 指引重新录制动作视频。
2080006palmId does not exist, please re-record the palmPalmId 已过期或不存在,需重新录掌。
2080007already bound该 UserId + PalmDirection 已注册过掌纹。若确需覆盖,请使用强制覆盖方式重新注册。
2080008palmId may have been bound by someone else检索到的 PalmId 已被其他用户绑定,通常出现在异常并发场景。请携带 requestId 联系官方核查。
2080009data not found数据不存在。§5.2 GetPalm 场景下表示指定 UserId/PalmDirection 尚未注册。
2080010user not found in search1:N 检索未在掌库中匹配到任何用户。属于业务正常返回,非系统错误。
2080011table capacity full掌库分表容量已满。请联系官方扩容。
2080012user's assistant image count exceeds limit用户辅助图片数量超限。
2080013verification id expired验证 ID 已过期。请重新走完整流程。
2080014palm capacity full掌纹容量已满(应用维度)。请联系官方扩容或先删除历史掌纹。
2080015user has been deleted用户已删除(仅空中开掌场景使用)。
2080016user does not exist in DB用户不存在。请确认用户已成功注册掌纹后再调用比对/删除类接口。
2080017user palm direction does not exist in DB用户指定手掌方向对应掌纹不存在。请核对 PalmDirection 参数或先完成注册。
2080018concurrent operation in DB, please retry并发操作冲突。请客户端稍后重试;同一用户避免并行调用注册/删除类接口。
2080019insertFeatureCurrentSyncIndex already exists特征同步索引冲突(内部一致性错误)。请携带 requestId 联系官方核查。
2080020palm capacity quota exceeded掌库特征配额超限(平台总配额不足)。请联系官方申请扩容。
2080021palm mobile (online register) not supported by platform license当前平台 License 未授权空中开掌功能。请联系官方开通。
2080022palm capacity cannot be less than current usage配额调整时低于当前已使用量。
2080023app does not exist应用不存在(应用维度接口)。请核对凭证对应的应用是否已正确创建。
2080024compare session expired or not exist比对结果 SessionId 不存在或已过期(有效期 2 小时)。请重新发起比对获取新的 SessionId。

📌 排障建议:

  • 务必保留 requestId:所有响应都会返回,是官方定位问题的核心线索。
  • 遇到未列在本表的 code 或不确定的错误,请携带 requestId、接口名、请求时间联系官方支持。
  • 1000xxx 段属于服务端通用兜底错误,若频繁出现请优先检查请求参数与网络状况;持续复现请上报。

七、集成示例(Go)​

下面以一个 掌纹注册查询(GetPalm) 为例,演示 Go 服务端的完整调用流程。其余接口调用方式一致,只需替换请求路径与请求体字段(各接口字段见 §五)。

package main

import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
)

const baseURL = "https://open.intl.palm.tencent.com"

// commonResp 通用响应包装。
type commonResp struct {
Code int `json:"code"`
Message string `json:"message"`
RequestID string `json:"requestId"`
Data json.RawMessage `json:"data"`
}

// call 发起一次 POST 请求,返回 requestId(用于排障)。
func call(apiKey, path string, reqBody, out any) (string, error) {
body, _ := json.Marshal(reqBody)
req, _ := http.NewRequest("POST", baseURL+path, bytes.NewReader(body))
req.Header.Set("Content-Type", "application/json; charset=utf-8")
req.Header.Set("Authorization", "Bearer "+apiKey)

resp, err := http.DefaultClient.Do(req)
if err != nil {
return "", err
}
defer resp.Body.Close()
raw, _ := io.ReadAll(resp.Body)

var wrap commonResp
if err := json.Unmarshal(raw, &wrap); err != nil {
return "", fmt.Errorf("decode resp: %w, raw=%s", err, string(raw))
}
if wrap.Code != 0 {
return wrap.RequestID, fmt.Errorf("api error code=%d message=%s requestId=%s", wrap.Code, wrap.Message, wrap.RequestID)
}
if out != nil && len(wrap.Data) > 0 {
if err := json.Unmarshal(wrap.Data, out); err != nil {
return wrap.RequestID, err
}
}
return wrap.RequestID, nil
}

func main() {
apiKey := "ak_xxxxxxxxxxxxxxxxxxxxxxxxxxxx"

reqBody := map[string]any{
"UserId": "user001",
}
var out struct {
LeftPalm struct {
PalmState int `json:"PalmState"`
PalmDirection int `json:"PalmDirection"`
RegisterTime int64 `json:"RegisterTime"`
} `json:"LeftPalm"`
RightPalm struct {
PalmState int `json:"PalmState"`
PalmDirection int `json:"PalmDirection"`
RegisterTime int64 `json:"RegisterTime"`
} `json:"RightPalm"`
}
requestID, err := call(apiKey, "/palm/openai/get_palm", reqBody, &out)
if err != nil {
fmt.Printf("get palm failed: %v (requestId=%s)\n", err, requestID)
return
}
fmt.Printf("LeftPalm=%+v RightPalm=%+v\n", out.LeftPalm, out.RightPalm)
}