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

# 冪等性與重試

> 如何安全地重試請求並防止重複建立標籤

<Note>
  此頁面由英文翻譯而成。[英文版](/introduction)為官方權威來源。如翻譯內容有任何不一致之處，請以英文版為準。
</Note>

# 冪等性與重試

配送標籤涉及實際的成本和物流影響。重複標籤會導致營運混亂、配送費用浪費以及庫存追蹤錯誤。Flex Forward API 內建冪等性來防止此問題。

## 冪等性的運作方式

`POST /labels` 端點使用 `idempotencyKey` 欄位來確保每個標籤建立請求只會被處理一次。

**第一次請求** — API 建立標籤並回傳 HTTP 201：

```bash theme={null}
curl -X POST https://api.flexforward.com/labels \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "idempotencyKey": "N-2026-05-27-TEST-03",
    "courier": "yunexpress",
    ...
  }'
```

```json 201 Created theme={null}
{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "status": "created",
  "courier": "yunexpress",
  "courierOrderNumber": "YT2503010001",
  "courierTrackingNumber": "YT2503010001CN",
  "error": null
}
```

**重放的請求** — 相同的 `idempotencyKey` 會回傳原始結果（HTTP 200），而不會建立新標籤：

```json 200 OK（冪等重放） theme={null}
{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "status": "created",
  "courier": "yunexpress",
  "courierOrderNumber": "YT2503010001",
  "courierTrackingNumber": "YT2503010001CN",
  "error": null
}
```

冪等性金鑰的範圍限於您的 API 帳戶。不同帳戶可以使用相同的金鑰而不會衝突。

## 選擇冪等性金鑰

金鑰應該唯一識別預期的標籤建立。良好的模式：

| 模式      | 範例                                     | 使用場景     |
| ------- | -------------------------------------- | -------- |
| 訂單 ID   | `N-2026-05-27-TEST-03`                 | 每個訂單一個標籤 |
| 訂單 + 序號 | `N-2026-05-27-TEST-03-1`               | 每個訂單多個標籤 |
| UUID    | `f47ac10b-58cc-4372-a567-0e02b2c3d479` | 通用       |

<Warning>
  重試相同的邏輯請求時，絕不要產生新的 `idempotencyKey`。請重複使用原始金鑰，以便 API 能偵測重複。
</Warning>

<Note>
  400 驗證錯誤後，由於未建立標籤，可以重複使用相同的 `idempotencyKey`。修正請求後使用相同金鑰重試。
</Note>

## 重試策略

對於暫時性失敗（HTTP 500、502 或網路逾時），請使用指數退避重試：

<Steps>
  <Step title="設定請求逾時">
    為 HTTP 請求設定合理的逾時時間（例如 30 秒）。
  </Step>

  <Step title="失敗時等待再重試">
    使用指數退避：1 秒、2 秒、4 秒、8 秒。
  </Step>

  <Step title="重複使用相同的冪等性金鑰">
    始終使用與原始請求相同的 `idempotencyKey` 重試。即使原始請求已成功但回應遺失，也能確保不會建立重複標籤。
  </Step>

  <Step title="限制重試次數">
    在 3–5 次重試後停止。如果請求仍然失敗，記錄錯誤並升級調查。
  </Step>
</Steps>

```
嘗試 1: POST /labels → 逾時
  等待 1 秒
嘗試 2: POST /labels → 502
  等待 2 秒
嘗試 3: POST /labels → 200（冪等重放 — 標籤在嘗試 1 時已建立）
```

## 各端點的冪等性

| 端點                   | 冪等 | 機制                            |
| -------------------- | -- | ----------------------------- |
| `POST /labels`       | 是  | `idempotencyKey` 欄位 — 每個請求中必填 |
| `GET /labels/{id}`   | 是  | 唯讀 — 天然冪等                     |
| `GET /tracking/{id}` | 是  | 唯讀 — 天然冪等                     |

## 失敗場景

<AccordionGroup>
  <Accordion title="收到回應前的網路逾時">
    標籤可能已建立也可能未建立。使用相同的 `idempotencyKey` 重試。如果標籤已建立，API 會回傳 HTTP 200 和原始結果。如果未建立，API 會建立標籤並回傳 HTTP 201。
  </Accordion>

  <Accordion title="HTTP 500 內部伺服器錯誤">
    暫時性伺服器錯誤。使用相同的 `idempotencyKey` 並以退避策略重試。
  </Accordion>

  <Accordion title="HTTP 502 錯誤閘道（物流業者錯誤）">
    物流業者服務回傳錯誤。標籤以 `status: failed` 保存。重試前請檢查錯誤訊息 — 部分物流業者錯誤需要修改請求（如無效地址）。對於暫時性的物流業者問題，使用相同的 `idempotencyKey` 重試。
  </Accordion>

  <Accordion title="HTTP 400 驗證錯誤">
    請求無效。未修正請求前請勿重試。由於未建立標籤，修正請求本文後可以重複使用相同的 `idempotencyKey`。
  </Accordion>
</AccordionGroup>
