API v2 文档

本文档介绍星楼网络平台 API v2 的鉴权方式与接口调用方法。所有接口均使用 API Key + HMAC-SHA256 签名 鉴权。

1. 基础信息

  • 接口地址:https://api.starloft.cn/v2
  • 请求格式:application/json
  • 鉴权方式:请求头携带 API Key 与签名(见「请求鉴权」)

2. 调用前提(必读)

调用本 API 前,账户必须同时满足以下条件:

  1. 账户已完成实名认证。实名状态(realname_status)按产品区分: 人脸核验(fv)需企业实名(realname_status=2); 短信(sms)完成个人实名(realname_status=1)即可, 未实名(0)时所有服务均不可用。请在星楼网络控制台完成对应实名认证。
  2. 创建 API 密钥。在控制台「API 密钥管理」中创建,可创建多把并各自配置权限; 密钥对(API Key + API Secret)创建后展示,API Secret 用于请求签名与回调验签。
  3. API 密钥权限覆盖所调用的接口。密钥权限范围(permission)为 all(全部接口),或按接口逐项授权的标识集合(逗号分隔,如 fv_auth,sms_send)。可授权的接口标识见各接口说明与「错误码」章节, 在控制台「API 密钥管理」中创建或编辑密钥时勾选。 人脸核验(fv)与短信(sms)接口权限各自独立。

未完成对应实名、密钥权限未覆盖,或密钥无效时调用相应接口, 将返回 code: 403 提示。

3. 请求鉴权

服务端同时兼容两版签名协议:hmac_sha256_v2(推荐,新接入一律使用)与 hmac_sha256(存量兼容,仅过渡期保留,未来会择期下线)。

注意:以下 v1 / v2 指签名协议版本,与接口路径版本(/v1、/v2)无关——两版签名协议均可用于任一接口路径。

通用请求头如下(v2 全带 5 个;v1 可不带 X-Nonce):

请求头说明
X-Api-Key控制台「API 密钥管理」中获取的 API Key
X-Sign签名,算法见下方
X-Sign-Version签名版本:hmac_sha256_v2(推荐)或 hmac_sha256(存量兼容)
X-Timestamp当前 Unix 时间戳(秒),允许 ±5 分钟误差(防重放)
X-Noncev2 必填:每次请求唯一的随机字符串,至少 16 字符;10 分钟内不得重复。v1 可不带;若带上则同样纳入防重放校验

签名算法(v2,hmac_sha256_v2,推荐)

先计算原始请求体 SHA-256,再把方法、调用方可见路径、原始查询串、时间戳、nonce 与正文摘要用换行符拼接:

canonical = METHOD + "\n" + PATH + "\n" + RAW_QUERY + "\n" + TIMESTAMP + "\n" + NONCE + "\n" + hex(SHA256(body))
sign = hex(HMAC-SHA256(api_secret, canonical))

PHP 示例:

$bodyHash = hash('sha256', $body);
$canonical = implode("\n", [$method, $path, $rawQuery, $timestamp, $nonce, $bodyHash]);
$sign = hash_hmac('sha256', $canonical, $apiSecret);

签名算法(v1,hmac_sha256,存量兼容)

签名为对原始请求体(POST 的 JSON 字符串,与发送内容完全一致)进行 HMAC-SHA256 运算后的小写十六进制字符串。该版本不强制 X-Nonce、不做原子防重放,请尽快迁移到 v2:

sign = hex(HMAC-SHA256(api_secret, 原始请求体))

PHP 示例:

$sign = hash_hmac('sha256', $body, $apiSecret); // 小写十六进制

4. 接口列表

本产品接口

4.4 产品与资源包

平台提供的下游能力与人脸核验子产品计费方式如下:

产品服务标识说明
有源人脸(FV)fv_auth人脸 + 公安库真实身份比对

人脸核验按子产品 fv_auth 计费,对应独立资源包。 短信服务(sms)按短信资源包计费,先扣资源包、余额兜底; 短信发送时通过 sign_name 选择签名、template_id 与 template_params 选择模板与参数, 短信类别(验证码 / 通知 / 营销,验证码与通知同属通知类,计费一致;仅营销短信单独扣营销资源包)由平台在模板审核环节判定,不随请求传递。

短信下游接口统一走 /v2/sms/*(平台短信通道),功能完整:资质/签名/模板人工报备与审核状态查询、 模板变量用 {s} 且必填 variables、回执走推送、回复本地查询。

4.8 短信资质(sms)

POST/v2/sms/qualifications(服务标识 sms_sign)

提交短信资质:资质是签名报备的材料主体(法人/经办人身份与营业执照、身份证等)。 需 API 密钥权限覆盖 sms_sign(或 all),账户完成个人实名(realname_status ≥ 1);提交不收费。

资质材料以图片 URL 形式传入:平台不做图片上传、转存或压缩,原样报备上游。 因此图片需你自行上传到可公网访问的地址(HTTPS、可直接下载,平台会主动拉取)。 资质与签名均由平台管理员人工在平台提交:创建后平台记录状态为 0-待提交,管理员回填平台资质 ID 后进入 1-审核中,可通过查询接口核对结果。

请求参数

参数类型必填说明
legal_namestring是法人姓名
business_license_urlstring是营业执照照片 URL
identity_typeint否身份证提供方:1-法人(默认) 2-经办人
legal_id_card_front_url / legal_id_card_back_urlstring是法人身份证人像面 / 国徽面图片 URL
agent_id_card_front_url / agent_id_card_back_urlstring否经办人身份证人像面 / 国徽面图片 URL(identity_type=2 时必填)
agent_auth_letter_urlstring否经办人授权书图片 URL(identity_type=2 时必填)

响应示例

{
  "code": 0,
  "message": "success",
  "data": {
    "qualification_id": 8,
    "status": 0
  }
}

GET/v2/sms/qualifications/:id 查询资质审核状态,返回资质 ID、状态、法人姓名与审核结果:

{
  "code": 0,
  "message": "success",
  "data": {
    "qualification": {
      "qualification_id": 8,
      "status": 2,
      "legal_name": "张三",
      "result_message": ""
    }
  }
}

资质状态:0-待提交 1-审核中 2-通过 3-驳回。 签名须关联一个资质(见下节 qualification_id);创建签名前请先创建资质并等待审核通过。

4.8.1 创建短信签名(sms)

POST/v2/sms/signs(服务标识 sms_sign)

提交短信签名报备(平台统一以「他公司」主体代下游客户报备)。需 API 密钥权限覆盖 sms_sign(或 all), 账户完成个人实名(realname_status ≥ 1);签名提交不收费。签名材料由所关联的资质承载,本条仅登记签名名称、类型与关联资质。

请求参数

参数类型必填说明
sign_namestring是签名名称,仅中文/英文/数字与圆括号(自动去【】、中文括号转英文)
sign_typeint否签名类型:1-企业名称(当前仅支持)
qualification_idint是关联资质 ID(POST /v2/sms/qualifications 创建后返回的 qualification_id)

响应示例

{
  "code": 0,
  "message": "success",
  "data": {
    "sign_id": 12,
    "status": 0
  }
}

sign_id 为平台签名记录 ID(平台唯一对外开放标识,后续查询/删除/绑定模板与发送均以它为准),status 为平台审核状态(0-待提交 1-审核中 2-通过 3-驳回)。 签名审核通过后可创建模板(POST /v2/sms/templates,以 sign_id / sign_name 指定绑定签名,见「4.8.3 短信模板管理」)并发送短信。

4.8.2 查询与删除短信签名(sms)

GET/v2/sms/signs/:id(服务标识 sms_sign_get)

查询某个签名的审核状态。:id 传平台签名记录 ID(创建接口返回的 sign_id,推荐); 存量调用方仍可传平台签名 ID(过渡兼容,后续废弃)。仅能查询本账号的签名。需 API 密钥权限覆盖 sms_sign_get(或 all)。

响应示例

{
  "code": 0,
  "message": "success",
  "data": {
    "sign": {
      "sign_id": 12,
      "status": 2,
      "sign_name": "示例科技",
      "result_message": ""
    }
  }
}

DELETE/v2/sms/signs/:id(服务标识 sms_sign_delete)

删除签名:平台仅软删除本地平台记录(标记 deleted_at,记录保留、后台「回收站」可恢复),不调用上游删除;上游签名保留,恢复后即可继续使用。 :id 取值同查询接口;需 API 密钥权限覆盖 sms_sign_delete(或 all)。

响应示例

{ "code": 0, "message": "success" }

除主动查询外,平台还会在签名/模板审核状态变更时向下游推送(后台「系统设置 → 短信服务」配置回调地址 SMS_STATUS_NOTIFY_URL): 请求体为 {"biz_type":"sign|template","record_id":12,"up_id":"360974","status":2,"reason":"","sign":"..."}, 签名算法为对 biz_type / reason / record_id / status / up_id 按字段名字典序拼接后取 HMAC-SHA256(小写十六进制), 密钥为该账号主 API 密钥的 api_secret;接收方校验通过后应返回 2xx,否则平台按指数退避补推。

4.8.3 短信模板管理(sms)

模板是发送短信的必填实体:平台统一以「他公司」主体代下游客户报备,模板须绑定一个已审核通过的签名。 各接口需 API 密钥权限覆盖对应服务标识(或 all),且账户完成个人实名(realname_status ≥ 1):

  • POST/v2/sms/templates(服务标识 sms_template_create)创建模板
  • GET/v2/sms/templates/:id(服务标识 sms_template_get)查询模板状态
  • PUT/v2/sms/templates/:id(服务标识 sms_template_update)修改模板内容
  • DELETE/v2/sms/templates/:id(服务标识 sms_template_delete)删除模板

:id 传平台模板主键(推荐)。 创建/查询/修改接口返回的 template_id 一律为平台模板主键,可原样用于后续的查询、修改、删除与短信发送。 模板内容中的变量占位符统一使用 {s}(如 您的验证码是{s}), 按出现顺序依次对应下方的变量属性与发送时的 template_params(与平台格式一致)。

创建模板:请求参数

参数类型必填说明
titlestring是模板标题(便于识别)
contentstring是模板内容,变量占位统一用 {s}
sign_idint否关联签名(平台签名记录 ID,优先)
sign_namestring否关联签名内容(兼容字段,sign_id 优先)
variablesarray是(有变量时)变量属性,按 {s} 出现顺序排列:[{ "type": "字符型", "length": 6 }],数量须与 {s} 个数一致;type 取 字符型/整数型/小数型/字符数据混合型,length 为长度(字)

模板类别(验证码 / 通知 / 营销)不在请求参数中:由平台在审核环节判定填写,并据此到平台报备。 历史上传入的 sms_type 已不受支持,传入会被忽略。

sign_id 与 sign_name 均未传时,回落该账号最近一条已审核通过的签名; 指定的签名须属于当前账号(或为平台公共签名)且已审核通过,否则拒绝。

响应示例(创建 / 修改)

{
  "code": 0,
  "message": "success",
  "data": {
    "template": {
      "template_id": "39342",
      "template_status": 1
    }
  }
}

查询模板:响应示例

{
  "code": 0,
  "message": "success",
  "data": {
    "template": {
      "template_id": "39342",
      "template_status": 2,
      "msg": ""
    }
  }
}

template_status:1-待审核(含待平台审核 / 待上游审核) 2-审核通过(可用于发送) 3-驳回;驳回原因见 msg(仅查询接口返回)。

所有模板(无论绑定公共签名还是自有签名)都先落地为「待平台审核」;模板类别由平台在审核环节判定填写 (创建/修改请求均不传类别),审核通过后转为待服务审核, 但上游报备为人工操作(平台管理员按该类别在上游控制台创建模板并回填其模板 ID)后才可发送。 该阶段对下游统一显示为 1-待审核(不区分平台审核/上游审核),暂不可发送。 修改模板内容会重置为待审核并重新报备上游。 营销模板需平台已开通营销短信通道(平台短信通道同一应用即支持营销,无需单独配置),未开通时审核通过营销类别会被拒绝。 业务约束在审核环节落地:绑定公共签名的模板只允许判为验证码类别,通知/营销模板必须绑定账号自有签名。

删除模板

删除模板:仅软删除平台记录(标记 deleted_at,后台「回收站」可恢复;上游模板的上报与删除均为人工操作,平台不调用上游建/删模板接口, 如需清理上游模板请由平台管理员在创蓝(上游)控制台处理)。删除前请确认该模板已不被发送调用引用。

{ "code": 0, "message": "success" }

4.9 短信发送(sms)

POST/v2/sms/send(服务标识 sms_send)

需 API 密钥权限覆盖 sms_send(或 all),且账户完成个人实名(realname_status=1)即可。 本接口由平台短信网关发送,仅支持模板发送(通知 / 营销场景,验证码属通知类); 成功后按短信资源包扣除费用——按所发模板的类型匹配资源包(营销模板扣营销资源包,通知模板(含验证码)扣通用短信资源包,两类互不通用),余额兜底。

计费按短信条数(长短信分条)。国内短信一条按 70 字符计费(含标点与空格,签名与正文一并计入); 超过 70 字符按每 67 字符递增 1 条(71-134 字 2 条、135-201 字 3 条……),最多 1000 字符 / 15 条。 计费条数 = 号码数 × 单条分条数,实际以平台返回的预扣费条数为准。 扣费时机:平台返回成功后才扣费——被平台拦截的失败不扣费;命中短信资源包时按条扣减(发送记录「扣费」列显示扣减条数),未命中则扣余额。 若后续回执失败(未送达),平台会自动退还本次扣费(资源包退回条数 / 余额原路退还)。 发送前平台会校验额度(资源包剩余条数或余额是否足够),不足时直接拒绝发送、不产生发送记录;发送失败仍会保留记录并写入失败原因。

资质、签名与模板须先报备审核。使用本接口前,请在星楼网络控制台「短信资质 / 短信签名 / 短信模板」页面在线提交 资质、签名与模板,经平台报备上游并审核通过后方可发送:先创建资质(法人/经办人身份与营业执照、身份证等材料), 签名须关联一个资质(详见「4.8 短信资质」);发送时通过 sign_id(优先)或 sign_name 选择审核通过的签名 (两者均不传时,使用该模板报备时绑定的签名), template_id 与 template_params 选择审核通过的模板并填充参数。 模板报备时须绑定一个已审核通过的签名(控制台「短信模板—关联签名」选择,或创建模板接口的 sign_id / sign_name 指定)。 所有模板(无论绑定公共签名还是自有签名)均需先经平台审核,通过后才报备上游(审核期间统一显示为待审核,暂不可发送)。 平台会校验归属:模板与所传签名(sign_id / sign_name)均须属于当前账号且已审核通过,否则拒绝发送。 template_id 优先使用平台返回的模板 ID;平台同时兼容存量客户传入的平台模板 ID。 同一账号下模板正文与签名组合重复提交会被拒绝且不会调用上游;不同账号可持有相同组合并复用已有平台模板 ID。

请求参数

参数类型必填说明
phone_number_setstring[]是接收手机号列表
sign_idint否发送所用签名(平台签名记录 ID,优先)
sign_namestring否发送所用签名内容(兼容字段,sign_id 优先)
template_idstring是短信模板 ID(平台模板主键,推荐;存量调用方可传平台模板 ID,过渡兼容)
template_paramsstring[]否模板参数(顺序与模板占位符一致)
session_contextstring否会话上下文(原样回传)
notify_urlstring否回执主动推送地址:平台回执到达后,平台将主动 POST 通知该地址(携带 HMAC 签名),详见「4.10 回执主动推送」

请求示例

{
  "phone_number_set": ["13800138000"],
  "sign_name": "星楼网络",
  "template_id": "1001",
  "template_params": ["123456", "5"],
  "notify_url": "https://yourdomain.com/sms/receipt"
}

4.10 查询发送回执(sms)

POST/v2/sms/report

按发送接口返回的 biz_no(平台业务号) 查询该批短信的回执状态。 平台回执为被动推送,本接口回显本地已落库的批次状态(逐号码明细请通过发送时配置的 notify_url 获取)。

请求参数

参数类型必填说明
biz_nostring是发送接口返回的平台业务号 biz_no(推荐)
task_idstring否存量兼容:历史调用方已保存的平台任务号 message_sid;新接入请使用 biz_no
page_noint否页码,从 1 开始
page_sizeint否每页条数,默认 10

响应示例

{
  "code": 0,
  "message": "success",
  "data": {
    "biz_no": "46382671905182934716",
    "reports": [
      {
        "sequenceId": "100941727",
        "phone": "15601862749",
        "content": "【星楼网络】您正在验证,验证码123456...",
        "status": "1",
        "respTime": "2026-09-18 17:10:20",
        "respCode": "DELIVRD",
        "codeDesc": "发送成功"
      }
    ]
  }
}

reports[].respCode 为 DELIVRD 表示该号码发送成功,其余为失败(见短信状态码表)。

4.11 回执主动推送(sms)

发送短信时若提供了 notify_url,平台在收到回执推送后, 会以 POST 方式(Content-Type: application/json)主动推送至你指定的 notify_url,无需再主动拉取。每一条号码回执推送一次。

请求体(平台 → 下游)

{
  "biz_no": "46382671905182934716",
  "message_sid": "202203170025179000005",
  "phone": "13800138000",
  "status": "success",
  "resp_code": "DELIVRD",
  "code_desc": "发送成功",
  "resp_time": "2026-09-18 17:10:20",
  "sequence_id": "100941727",
  "fail_message": "",
  "sign": "a1b2c3d4e5f6..."
}

字段说明

字段类型说明
biz_nostring平台发送记录业务号(发送接口返回的 biz_no)
message_sidstring平台任务 ID,仅用于回执关联与兼容,不在发送响应中返回
phonestring本次回执对应的接收号码
statusstring本号码送达状态:success 成功 / fail 失败
resp_codestring平台回执码,DELIVRD 为成功
code_descstring回执码中文描述
resp_timestring回执时间(状态未知时为空)
sequence_idstring平台回执序列 ID(唯一)
fail_messagestring失败原因(成功时为空)
signstringHMAC-SHA256 签名,基于你的 API Secret,供校验防伪造

签名校验

取 biz_no、code_desc、message_sid、phone、 resp_code、status 六个字段,按 key 字典序拼接为 k=v&k=v...(不做 URL 编码),再以 HMAC-SHA256(api_secret, canonical) 计算十六进制小写签名:

canonical = "biz_no=xxx&code_desc=xxx&message_sid=xxx&phone=xxx&resp_code=xxx&status=xxx"
sign = hex(HMAC-SHA256(api_secret, canonical))

校验失败应拒绝该通知(返回非 2xx)。若通知丢失,可调用 /v2/sms/report 按 biz_no(平台业务号)主动查询。

4.12 短信回复推送与查询(sms)

发送短信后,若接收号码回复短信,平台会推送回复给平台;平台会 主动 POST 到发送时配置的 notify_url。同时提供主动查询接口 /v2/sms/replies:提供 date 时平台先按日拉取回复并落库,再返回本用户回复记录。

回执式主动推送(平台 → 下游 notify_url)

{
  "biz_no": "46382671905182934716",
  "message_sid": "202203170025179000005",
  "phone": "13800138000",
  "content_down": "【星楼网络】您的验证码是123456",
  "content_up": "T",
  "sequence_id": "107067357",
  "timestamp": "1647485562153",
  "status": "00",
  "tag": "",
  "sign": "a1b2c3d4e5f6..."
}

签名校验

取 biz_no、content_down、content_up、message_sid、 phone、status 六个字段,按 key 字典序拼接后以 HMAC-SHA256(api_secret, canonical) 计算十六进制小写签名(与 4.10 同算法),校验失败应拒绝该通知。

主动查询

POST/v2/sms/replies

参数类型必填说明
datestring否回复日期(yyyyMMdd);提供时先拉取该日回复并落库
task_idstring否回执查询响应或异步通知中的 message_sid,按平台任务过滤
page_noint否页码,从 1 开始
page_sizeint否每页条数,默认 10

响应示例

{
  "code": 0,
  "message": "success",
  "data": {
    "total": 1,
    "replies": [
      {
        "task_id": "202203170025179000005",
        "phone": "13800138000",
        "sequence_id": "107067357",
        "content_down": "【星楼网络】您的验证码是123456",
        "content_up": "T",
        "resp_time": "1647485562153",
        "status": "00",
        "tag": ""
      }
    ]
  }
}

平台已拉取的回复会标记「已读」,再次拉取不再返回;平台拉取后落库本地(去重), 后续按 date / task_id 查询由本地兜底,不依赖平台重复拉取。

6. 调用示例(curl)

以短信发送为例:

BODY='{"phone_number_set":["13800138000"],"sign_name":"星楼网络","template_id":"1001","template_params":["123456","5"]}'
TS=$(date +%s)
NONCE=$(openssl rand -hex 16)
BODY_HASH=$(printf '%s' "$BODY" | openssl dgst -sha256 | awk '{print $2}')
CANONICAL=$(printf '%s\n%s\n%s\n%s\n%s\n%s' 'POST' '/v2/sms/send' '' "$TS" "$NONCE" "$BODY_HASH")
SIGN=$(printf '%s' "$CANONICAL" | openssl dgst -sha256 -hmac "your_api_secret" | awk '{print $2}')

curl -X POST "https://api.starloft.cn/v2/sms/send" \
  -H "Content-Type: application/json" \
  -H "X-Api-Key: your_api_key" \
  -H "X-Sign: $SIGN" \
  -H "X-Sign-Version: hmac_sha256_v2" \
  -H "X-Timestamp: $TS" \
  -H "X-Nonce: $NONCE" \
  -d "$BODY"

7. 错误码

code说明
0成功
400参数错误 / 余额不足
401鉴权失败(API Key 无效、签名错误或时间戳过期)
403权限不足(用户被禁用、实名等级不满足该接口要求、密钥权限未覆盖该接口)
404订单不存在
500系统内部错误