鉴权与签名
所有开放 API 请求都用 API Key 鉴权。对安全要求更高的场景,可以给单个 Key 开启「必须签名」,防篡改、防重放。
API Key
- 在开放平台的「API Key」页创建。Key 以
sk-开头,后接 48 位字母和数字。 - 明文只在创建时显示一次,之后只显示首尾片段(如
sk-ab12…wxyz)。遗失请删除后重建。 - 每个 Key 可以单独设置:名称、可调用的模型、每分钟请求数、并发数、有效期、额度上限(可按日 / 周 / 月自动重置)、是否必须签名;可随时停用或删除。
- Key 调用产生的费用从 Key 所属秒做账号的点数中扣除。
- Key 只能调用
/v1开放接口;官网、开放平台的登录状态不能用来调用/v1。
Key 只应保存在你的服务器端。不要写进网页、小程序或 App 的代码里,也不要提交到代码仓库。
Bearer 鉴权(默认)
在每个请求的 HTTP 头里带上 Key:
Authorization: Bearer sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxPOST /v1/messages(Messages 格式)另外接受 x-api-key: sk-… 头,方便直接使用对应 SDK;其他接口只认 Authorization 头。
缺少 Key,或 Key 无效、已停用、已过期、已删除时返回 HTTP 401,错误码 unauthorized,不扣点。完整列表见错误码。
请求签名(可选)
在开放平台编辑 Key 时开启「必须签名」,系统会为这个 Key 生成一个签名密钥(sig_ 开头,只显示一次;可在开放平台重置,旧密钥立即失效)。此后用这个 Key 发起的每个请求(包括文本模型接口),除了 Authorization 头,还必须带上以下三个头。没开启签名的 Key 带了也不校验。
| 请求头 | 说明 |
|---|---|
X-Mz-Timestamp | 当前 Unix 时间戳(秒)。与服务器时间相差超过 300 秒的请求会被拒绝。 |
X-Mz-Nonce | 随机串,16~64 位字母或数字。同一个 Key 10 分钟内不能重复使用,用于防重放。 |
X-Mz-Signature | 签名值:用签名密钥对「签名串」做 HMAC-SHA256,结果转为小写十六进制。 |
签名串拼法
按顺序取以下 5 项,用换行符 \n 连接,末尾不加换行:
- HTTP 方法,大写,如
POST。 - 请求路径,含
/v1前缀;有查询串时原样带上,如/v1/tasks?status=succeeded。 - 与
X-Mz-Timestamp相同的时间戳。 - 与
X-Mz-Nonce相同的随机串。 - 请求体原始字节的 SHA-256,小写十六进制;没有请求体(如 GET)时取空串的 SHA-256。
例:签名密钥为 sig_demoSigningSecret0123456789abcdefghijKLM,POST /v1/tasks 的请求体为 {"model":"qwen-image-3.0","input":{"prompt":"一只橘猫","count":1}}(UTF-8,不含多余空格)时,签名串为:
POST
/v1/tasks
1791536400
3f9a1c7e5b2d4086a1e9c3b7d5f20e48
a544feafab06035562a597bb71c9cc9990178079ab414baef6a196806701d65f对应的请求头如下,可用来核对你的实现:
Authorization: Bearer sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
X-Mz-Timestamp: 1791536400
X-Mz-Nonce: 3f9a1c7e5b2d4086a1e9c3b7d5f20e48
X-Mz-Signature: 2180aa868bed353d9d294ed61d22ba69d3524184bb2eb6c9e7818cfc6c62569c签名必须基于实际发送的请求体字节计算。先签名、再改动请求体(例如重新序列化 JSON)会导致验签失败。
签名示例
# 需要 bash 与 openssl
KEY="$MIAOZUO_API_KEY" # sk- 开头的 API Key
SECRET="$MIAOZUO_SIGNING_SECRET" # 开启签名时生成的签名密钥(sig_ 开头)
BODY='{"model":"qwen-image-3.0","input":{"prompt":"一只橘猫","count":1}}'
TS=$(date +%s)
NONCE=$(openssl rand -hex 16)
BODY_HASH=$(printf '%s' "$BODY" | openssl dgst -sha256 -hex | sed 's/^.* //')
STRING_TO_SIGN=$(printf 'POST\n/v1/tasks\n%s\n%s\n%s' "$TS" "$NONCE" "$BODY_HASH")
SIGNATURE=$(printf '%s' "$STRING_TO_SIGN" | openssl dgst -sha256 -hmac "$SECRET" -hex | sed 's/^.* //')
curl https://api.miaozuo.cn/v1/tasks \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-H "X-Mz-Timestamp: $TS" \
-H "X-Mz-Nonce: $NONCE" \
-H "X-Mz-Signature: $SIGNATURE" \
-d "$BODY"签名失败
缺少签名头、时间戳超出 300 秒、随机串重复或签名不匹配时,返回 HTTP 401,错误码 signature_invalid,message 会说明具体原因,不扣点。
开启了「必须签名」的 Key 调用文本模型接口时也要带签名头。主流 SDK 默认只发送 Bearer 头,如果不方便给 SDK 加自定义请求头,请另建一个不开启签名的 Key 专门用于文本调用,并用「可调用的模型」限制它的范围。