> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tapapi.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# 失败不扣规则

> 哪些失败不扣，哪些请求会正常计费

Tapapi 的信任承诺之一是失败不扣。这里说的是最终结算结果：系统可能先预扣额度，请求失败后再返还；成功后按实际用量结算，多退少补。

预扣、结算和返还可能不是同一毫秒完成。对账时不要只看“请求刚发出后的余额”，要以最终用量日志、余额变化和任务状态为准。

## 原则

| 情况                   | 计费                                           |
| -------------------- | -------------------------------------------- |
| 参数错误 400 / 413 / 422 | 未进入正式生成时不应扣费                                 |
| 鉴权失败 401             | 不应扣费                                         |
| 账户、权限或余额不足 403       | 未进入生成时不应扣费，余额不足常见为 `insufficient_user_quota` |
| 平台或上游失败，且没有有效结果      | 最终不应扣费                                       |
| 连接失败，且没有有效结果         | 最终不应扣费                                       |
| 超时且没有生成结果            | 最终不应扣费                                       |
| HTTP 200 且返回图片       | 正常计费                                         |
| HTTP 200 但 `data=[]` | 当前图片价格模型按 0 张处理                              |
| 部分成功返回图片             | 按成功返回的有效图片数计费                                |
| 成功生成但用户未下载           | 通常正常计费                                       |
| 成功生成但客户转存失败          | 通常正常计费，这是业务保存链路问题                            |

<Note>对账时以控制台用量、最终余额和请求记录为准。前端显示失败不等于模型一定失败，必须结合服务端响应和保存结果判断。</Note>

## 预扣、结算和返还

生产请求可能经历这条链路：

```text theme={null}
请求进入 -> 预扣额度 -> 调用模型 -> 按实际结果结算
                         -> 失败则返还预扣
```

这意味着你可能在短时间内看到余额先变化，再随着最终结算调整。不要把“请求刚发出后的余额”当成最终账单。

### 同步请求

文本和普通图片同步请求的常见链路是：

| 阶段   | 行为                    |
| ---- | --------------------- |
| 请求进入 | 校验 API Key、模型、参数和账户额度 |
| 预扣额度 | 按模型和请求参数预估成本          |
| 调用上游 | 如果失败且无有效结果，返还预扣       |
| 成功结算 | 按实际 token、图片张数或固定价格结算 |

### 异步任务

视频或其他异步任务可能先创建任务并预扣额度。提交任务成功后会先形成一笔任务消费记录；后续轮询发现任务失败，会返还任务额度。任务成功后，只有在上游返回可用于重算的用量信息、并且该模型按倍率计费时，才可能根据实际用量做差额调整。

```text theme={null}
提交任务 -> 预扣额度 -> 任务进入队列
                     -> 成功：通常按提交时任务价格结算；满足条件时按实际用量差额调整
                     -> 失败：返还预扣额度
```

<Warning>不要用“用户关闭页面”判断是否应该退款。只有平台或上游最终没有有效结果，才按失败返还处理。</Warning>

## 图片接口的特殊情况

| 情况              | 说明                                      |
| --------------- | --------------------------------------- |
| 返回 1 张，请求 `n=1` | 按 1 张计费                                 |
| 返回 2 张，请求 `n=2` | 按 2 张计费                                 |
| 上游多返回图片         | 当前公开主路径会把计费张数封顶到用户请求的 `n`               |
| 上游 200 但没有图片    | 按 0 张处理，并记录异常                           |
| fanout 部分成功     | 返回多少张有效图片，就按多少张计费，并在 `metadata` 里标记部分成功 |
| 用户拿到 URL 后未下载   | 模型已经成功生成，通常正常计费                         |

图片公开主路径的计费口径是：看实际返回的 `data.length`，再和请求的 `n` 取较小值。也就是说，请求 `n=1` 但上游意外返回 2 张，当前主路径最多按 1 张计费；请求 `n=2` 但只返回 1 张，则按 1 张处理。

如果响应里出现 `metadata.tapapi_partial`，说明图片 fanout 过程中有部分子请求失败。此时要同时记录 `requested_n`、`returned_n` 和 `failed_requests`，并把已返回图片先转存；不要把已经成功返回的图片也当失败重新生成。

<Warning>图片 URL 下载失败、对象存储上传失败或前端展示失败，不等同于模型生成失败。只要平台已经拿到有效结果，通常仍按有效结果计费。</Warning>

## 不应自动重试的计费错误

| 错误                               | 原因                     |
| -------------------------------- | ---------------------- |
| `insufficient_user_quota`        | 余额、订阅或令牌额度不足，重试不会成功    |
| `pre_consume_token_quota_failed` | 预扣失败，通常需要补余额或检查 Key 额度 |
| 401 / 权限类 403                    | 需要修鉴权或权限，不是临时失败        |
| 400 / 413 / 422                  | 请求本身有问题，重复提交只会制造更多失败记录 |

## 开发者建议

* 保存每次请求的响应状态
* 保存平台返回的 `request_id`、`upstream_request_id` 和业务侧 `task_id`
* 保存返回图片数量和返回字段：`url` / `b64_json`
* 记录请求的 `n` 和实际返回的 `data.length`
* 如果是图片部分成功，记录 `metadata.tapapi_partial`、`returned_n` 和 `failed_requests`
* 如果是任务或视频，记录顶层 `code`、`message`、任务 `status` 和 `fail_reason`
* 不要把“前端显示失败”和“服务端生成失败”混为一类
* 发现异常先带请求时间和模型名联系支持

## 联系支持时带上

* 请求时间和时区
* 模型名
* `request_id`
* `upstream_request_id`
* HTTP 状态码
* `error.type`、`error.code` 和 `error.message`
* 任务或视频接口的顶层 `code`、`message` 和 `data`
* 业务 `task_id`
* 请求的 `n`、实际返回图片数、部分成功元数据和保存状态
* 控制台用量截图或余额变化截图
