教程
HiAPI 请求失败为何仍会扣费?
- 失败任务(fail)的扣费
- $0(自动全额退回)
- 创建阶段被拒绝(如 402)的扣费
- $0(从未创建任务)
- Idempotency-Key 重放
- 同一个 taskId,不会二次扣费
问题现象
你把一个生成任务 POST 到 https://api.hiapi.ai/v1/tasks,然后用 GET /v1/tasks/:id 轮询,结果拿到的是 "status": "fail",外加一个 error 对象,比如 {"code": "TASK_FAILED", "message": "task failed"}。这次轮询调用本身的 HTTP 状态码是正常的 200——HiAPI 把失败信息包在 JSON body 里,不是放在状态码上。因为这个任务确实经过了 queued → handling 才失败,很容易以为这次尝试跟正常调用一样被扣了钱。实际上,任务进入终态 fail 并不等于被扣费——但如果退款还没到账你就先去看了余额,创建时那笔预扣确实会让账面看起来像是扣了钱。
常见原因
- 把"预扣"当成了"扣费"。 HiAPI 在任务刚创建、还没真正开始跑的那一刻就会预扣这个任务的预估费用。这笔预扣会立刻反映在你的余额里——但它还不是扣费。
- 在任务进行中查余额。 从
queued/handling到终态之间,这笔预扣本来就是"挂着"的,这是设计好的行为。只有终态(success或fail)才会把它结清。 - 把"下游真的跑了但失败了"和"创建阶段就被拒绝"混为一谈。 一个走到
status: "fail"(比如error.code: "TASK_FAILED")的任务,是真的被创建、真的跑过、下游失败了——HiAPI 文档明确说明,任务进入这个终态后预扣金额会全额自动退回。而一个从未拿到taskId的请求——比如同步返回的402 INSUFFICIENT_QUOTA——是在任务存在之前就被拒绝了,根本没有东西被预扣过。两者从外部看都是"失败了",但只有前者真的碰过预扣这个机制。 Idempotency-Key用错了。 用同一个 key、同一个请求体重放,只会拿到原来那个taskId,不会创建、也不会扣第二次。但同一个 key 换了请求体重放,会在创建阶段直接返回422 IDEMPOTENCY_KEY_MISMATCH;同一个 key 在第一次调用还没处理完时再打一次,会返回409 IDEMPOTENCY_KEY_PROCESSING。这两条路径都不会创建出可计费的任务。
修复步骤
- 轮询
GET /v1/tasks/:id,直接看data.status——不要只凭某一次余额截图去猜计费结果。queued、handling、archiving都是非终态;只有success和fail才是终态。 - 如果
data.status是"fail",这就是一个会被退款的结果。看一下data.error.code(比如TASK_FAILED)了解原因,然后再查一次余额——退款会在任务进入这个终态后自动到账。 - 如果
POST /v1/tasks这次调用本身就返回了非 2xx 状态码(400/402/409/415/422)且 body 里没有taskId,那就没有任务可退——因为本来就没有任务被创建或被扣费。余额不足的具体情形会表现为402响应里的error_code: "INSUFFICIENT_QUOTA"。 - 去 HiAPI 账单后台 核对"预扣—退款"这一对交易记录,而不是只看某个时间点的余额数字。
- 重试失败任务时,给这次真正的新尝试换一个新的
Idempotency-Key。不要用旧 key 换请求体重放(会触发422),也不要在第一次请求还在处理中时用同一个 key 再发一次(会触发409)。 - 如果你确认任务已经到达
fail终态,但过了一段时间预扣金额仍然没有退回,这已经超出了这个自动退款机制的范围——直接联系支持,不要假设它会自己恢复。
最小验证示例
curl -s -X POST https://api.hiapi.ai/v1/tasks \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"model": "gpt-image-2/text-to-image",
"input": { "prompt": "a minimalist desk setup, studio lighting" }
}'
这里 model 字段带了路由后缀 /text-to-image。截至本文撰写时,HiAPI 模型索引 里 gpt-image-2 这一组只收录了带路由后缀的条目(/text-to-image、/image-to-image),没有裸 id 条目。具体要不要带后缀、带哪个后缀,务必以这份实时模型索引里 availability: "online" 的条目为准,不要照抄别的模型或旧文档里的写法。
拿到返回的 taskId 后轮询:
curl -s https://api.hiapi.ai/v1/tasks/$TASK_ID \
-H "Authorization: Bearer $HIAPI_API_KEY"
一个被退款的失败任务长这样:
{
"code": 200,
"message": "success",
"data": {
"taskId": "tk-hiapi-...",
"model": "gpt-image-2/text-to-image",
"status": "fail",
"created": 1777282033,
"completed": 1777282099,
"error": { "code": "TASK_FAILED", "message": "task failed" }
}
}
相关内链
- HiAPI 账单后台
- HiAPI 统一异步任务 API:错误码与状态说明
- HiAPI 任务卡住或超时:诊断与重试指南
- HiAPI "model not found" / "model not available" 报错修复指南
FAQ
图片或视频任务失败,HiAPI 会扣我钱吗?
不会。任务一旦进入终态 fail,创建时预扣的金额会全额自动退回。
我提交任务之后余额立刻就少了,这个任务后来还失败了,为什么余额没变回来?
那笔减少是创建时的预扣,不是扣费。它会在任务进入终态后自动结清——fail 退回,success 才真正消耗掉。
402 报错和任务失败有什么区别?
402 INSUFFICIENT_QUOTA 意味着任务根本没有被创建出来,所以没有东西可以预扣、也没有东西可以退。而一个拿到了 taskId、后来 status 变成 "fail" 的任务,是真的被创建、真的跑过、然后下游失败了;HiAPI 会自动退回这笔预扣。
用同一个 Idempotency-Key 重试,会被扣两次钱吗?
不会。同一个 key、同一个请求体重放,只会拿到原来那个 taskId,不会创建新任务。如果在同一个 key 下换了请求体,会直接报 422 IDEMPOTENCY_KEY_MISMATCH,也不会创建出重复任务。
预扣和退款的记录在哪里能看到? 在 HiAPI 账单后台 的账单和交易记录里。