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

# 提交大量作業

> 以一次非同步呼叫，對多位已連結使用者執行寫入或大量匯出。您提交一個工作、輪詢其狀態，並且（對於匯出與寫入）下載結果檔案。

以一次呼叫，對您已連結的使用者執行大量作業。不同於同步讀取（[取得大量餘額](/get-bulk-balances)、[取得大量交易](/get-bulk-transactions)），`submitBulkOperation` 是**非同步**的：它會驗證請求、建立一個工作及每個目標一個項目，並立即回傳 `jobId`。作業在背景執行 — [追蹤該工作](/track-bulk-job) 以查看進度並擷取結果。

一個 mutation 涵蓋所有五種操作，藉由 `operation` 欄位選擇：

| `operation`                   | 作用                  | 每位使用者所需授權範圍                              |
| ----------------------------- | ------------------- | ---------------------------------------- |
| `GET_BALANCES_EXPORT`         | 將現金餘額匯出至檔案          | `LIST_PAYMENT`                           |
| `GET_TRANSACTIONS_EXPORT`     | 將交易匯出至檔案            | `LIST_PAYMENT`, `LIST_PURCHASES`         |
| `CREATE_TRANSFER`             | 在營運方與/或已連結使用者之間移轉資金 | `MAKE_PAYOUT_TRANSFER_SEND`（在**來源**使用者上） |
| `DEPOSIT_CASH_BALANCE`        | 由連結使用者的付款方式為其消費帳戶加值 | `MAKE_DEPOSIT`                           |
| `UPDATE_TRANSACTION_METADATA` | 編輯交易上的備註/類別         | `LIST_PAYMENT`, `LIST_PURCHASES`         |

## 需求

* `Authorization: Basic <API_KEY>`
* 您的應用程式已啟用大量 API 能力。
* 所選操作所需的 scope，且由每位目標使用者授與（見上表）。缺少者會成為逐項失敗—永遠不會讓整個工作失敗。

<Note>
  每次提交**必須**帶有冪等性金鑰——可使用 `idempotencyKey` 輸入欄位或 `Idempotency-Key` 標頭（若同時傳送，兩者必須相符）。在請求內容位元組完全相同的情況下，重新提交相同金鑰會回傳原始工作而不會建立重複；若在相同金鑰下送出不同請求，則會被拒絕。對於扇出式寫入沒有安全預設，因此必須提供此金鑰。
</Note>

## Mutation

```graphql theme={null}
mutation SubmitBulkOperation($input: SubmitBulkOperationInput!) {
  submitBulkOperation(input: $input) {
    jobId
    status
    operation
    requestedTargetCount
    acceptedItemCount
    succeededItemCount
    failedItemCount
    skippedItemCount
    createdAt
  }
}
```

成功提交會回傳狀態為 `QUEUED` 的工作。`acceptedItemCount` 為實際會被處理的目標數；`skippedItemCount` 為在前置階段被拒絕的數量（例如缺少必要的 scope）。輪詢該工作以觀察 `succeededItemCount` / `failedItemCount` 的增減 — 參見 [追蹤大量工作](/track-bulk-job)。

## 變數 — 匯出餘額 / 交易

`exportOptions` 用來界定時間窗（預設為最近 90 天；`GET_BALANCES_EXPORT` 為時間點快照，會忽略時間窗）。與讀取相同，使用[目標選取](/bulk-api#selecting-target-users)。

```json theme={null}
{
  "input": {
    "operation": "GET_TRANSACTIONS_EXPORT",
    "idempotencyKey": "export-2024-06-01-a",
    "targetSpec": { "mode": "ALL_CONNECTED" },
    "exportOptions": {
      "createdGte": "2024-05-01T00:00:00Z",
      "createdLte": "2024-06-01T00:00:00Z",
      "includeMetadata": false
    }
  }
}
```

## 變數 — 建立轉帳

每個項目都會指定自己的 `from` 與 `to` 端點，因此單一工作可以混合多種方向：營運方→使用者、使用者→營運方，以及使用者→使用者。端點**只能**是 `{ "operator": true }`（您應用程式的撥款帳戶）**或** `{ "externalReferenceId": "…" }`（一位已連結使用者）其中之一。`from` 與 `to` 必須不同。**來源**使用者的授權必須允許 `MAKE_PAYOUT_TRANSFER_SEND`；目的端僅需已連結。轉帳僅在同一贊助銀行內進行。`targetSpec` 對於轉帳並非必填——參與者來自項目本身。

```json theme={null}
{
  "input": {
    "operation": "CREATE_TRANSFER",
    "idempotencyKey": "payouts-2024-06-01-a",
    "transferOptions": {
      "items": [
        { "from": { "operator": true }, "to": { "externalReferenceId": "user-123" }, "amount": 10.00, "memo": "Reward" },
        { "from": { "externalReferenceId": "user-123" }, "to": { "operator": true }, "amount": 2.50 },
        { "from": { "externalReferenceId": "user-123" }, "to": { "externalReferenceId": "user-456" }, "amount": 5.00 }
      ]
    }
  }
}
```

## 變數 — 存入現金餘額

從連結使用者**本人擁有**的付款方式為其消費帳戶加值——每個項目必須在 `bankCardId` 或 `bankAccountId` 之間擇一。使用 `SELECTED` 目標模式，每個目標一個項目。`userCashBalanceId` 可選（預設為該使用者被允許/預設的消費帳戶）。

```json theme={null}
{
  "input": {
    "operation": "DEPOSIT_CASH_BALANCE",
    "idempotencyKey": "deposits-2024-06-01-a",
    "targetSpec": { "mode": "SELECTED", "targets": ["user-123", "user-456"] },
    "depositOptions": {
      "items": [
        { "externalReferenceId": "user-123", "amount": 10.00, "bankCardId": "b1a2…", "memo": "Top-up" },
        { "externalReferenceId": "user-456", "amount": 25.00, "bankAccountId": "c3d4…" }
      ]
    }
  }
}
```

## 變數 — 更新交易中繼資料

編輯使用者交易上的 `memo` 與/或 `transactionCategory`。使用 `SELECTED` 目標模式，每個目標一個項目，**每次提交最多 100 筆編輯**。將欄位設為 `null` 會清除它；省略的欄位則不變動。中繼資料編輯為**同步**執行——回傳的工作已是終態，因此您可立即讀取每筆編輯結果而無需輪詢。

```json theme={null}
{
  "input": {
    "operation": "UPDATE_TRANSACTION_METADATA",
    "idempotencyKey": "metadata-2024-06-01-a",
    "targetSpec": { "mode": "SELECTED", "targets": ["user-123"] },
    "metadataOptions": {
      "items": [
        {
          "externalReferenceId": "user-123",
          "edits": [
            { "recordId": "3f2a…", "memo": "Team lunch", "transactionCategory": "Meals" },
            { "recordId": "9b7c…", "memo": null }
          ]
        }
      ]
    }
  }
}
```

## 回應

```json theme={null}
{
  "data": {
    "submitBulkOperation": {
      "jobId": "9c1e6f2a-1d4b-4a2e-8f0c-2b7e5a9d1234",
      "status": "QUEUED",
      "operation": "CREATE_TRANSFER",
      "requestedTargetCount": 3,
      "acceptedItemCount": 3,
      "succeededItemCount": 0,
      "failedItemCount": 0,
      "skippedItemCount": 0,
      "createdAt": "2024-06-01T15:04:05Z"
    }
  }
}
```

## 參數

| 參數                            | 類型                         | 說明                                                                                                                           |
| ----------------------------- | -------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| `input.operation`             | `BulkOperationType!`       | 下列其一：`GET_BALANCES_EXPORT`、`GET_TRANSACTIONS_EXPORT`、`CREATE_TRANSFER`、`DEPOSIT_CASH_BALANCE`、`UPDATE_TRANSACTION_METADATA`。 |
| `input.idempotencyKey`        | `String`                   | 您對此提交的唯一金鑰。必填（透過此欄位或 `Idempotency-Key` 標頭）。                                                                                  |
| `input.targetSpec`            | `BulkTargetSpecInput`      | 此操作適用的已連結使用者。匯出、存入與中繼資料操作必填；`CREATE_TRANSFER` 會忽略（項目自我描述）。                                                                   |
| `input.exportOptions`         | `BulkExportOptionsInput`   | `createdGte` / `createdLte` 時間窗與 `includeMetadata`。僅適用於匯出操作。                                                                 |
| `input.transferOptions.items` | `[BulkTransferItemInput!]` | 每筆轉帳的 `from` / `to` 端點、`amount`、以及可選的 `memo`。僅 `CREATE_TRANSFER`。                                                            |
| `input.depositOptions.items`  | `[BulkDepositItemInput!]`  | 每個目標的 `amount`、`bankCardId` / `bankAccountId` 擇一、以及可選的 `userCashBalanceId` / `memo`。僅 `DEPOSIT_CASH_BALANCE`。                |
| `input.metadataOptions.items` | `[BulkMetadataItemInput!]` | 每個目標的 `edits`（`recordId`、`memo?`、`transactionCategory?`）。僅 `UPDATE_TRANSACTION_METADATA`；總計 ≤100 筆編輯。                        |

## 回應欄位

| 欄位                                       | 說明                                                                                    |
| ---------------------------------------- | ------------------------------------------------------------------------------------- |
| `jobId`                                  | 工作的 id。用於[追蹤狀態與結果](/track-bulk-job)。                                                  |
| `status`                                 | 生命週期狀態：`QUEUED`、`RUNNING`、`COMPLETED`、`COMPLETED_WITH_ERRORS`、`FAILED` 或 `CANCELLED`。 |
| `operation`                              | 已提交的操作。                                                                               |
| `requestedTargetCount`                   | 請求所涉及的目標數。                                                                            |
| `acceptedItemCount`                      | 會被處理的項目數（每個被接受的目標一項）。                                                                 |
| `succeededItemCount` / `failedItemCount` | 逐項結果；在工作執行期間逐步產生。                                                                     |
| `skippedItemCount`                       | 在提交時被拒絕的目標（例如缺少必要的 scope）。                                                            |
| `createdAt`                              | 工作建立時間。                                                                               |

<Note>
  失敗是**逐項**的——單一目標的失敗不會讓整個工作失敗（參見[逐目標失敗合約](/bulk-api#per-target-failure-contract)）。僅在授權失敗、無效操作、超出上限、或是\_所有\_目標皆無法解析時，請求本身才會被拒絕。達到終態後，請透過[追蹤大量工作](/track-bulk-job) 讀取逐項細節——包含每筆寫入所產生的資源。
</Note>

## 錯誤

僅在以下情況下，整個提交會被拒絕（不會建立工作）。其他情況皆會成為逐項結果，您可透過[追蹤大量工作](/track-bulk-job#per-item-failure-codes)讀取。

| 錯誤                           | HTTP | 何時發生                                                                                          |
| ---------------------------- | ---- | --------------------------------------------------------------------------------------------- |
| `BulkApiAccessDenied`        | 403  | 您的應用程式沒有大量 API 能力。                                                                            |
| `IdempotencyKeyConflict`     | 409  | 同時傳送了 `Idempotency-Key` 標頭與 `idempotencyKey` 輸入，且兩者不相符。                                       |
| `IdempotencyKeyReused`       | 409  | 此冪等性金鑰已用於**不同**的請求。（相同內容的重送將回傳原始工作。）                                                          |
| `TargetLimitExceeded`        | 422  | 請求參照了超過 10,000 位不同使用者。請分批並重新提交。                                                               |
| `ArgumentsInvalid`           | 400  | 承載驗證失敗（例如端點不是僅為營運方/使用者之一、`from` == `to`、金額小於 1 分、備註過長、>100 筆中繼資料編輯）**或**所有目標皆無法解析/缺少必要 scope。 |
| `AmbiguousSourceCashBalance` | 422  | *（僅 `CREATE_TRANSFER`）* 來自營運方的轉帳，但您的撥款路由指定了多個現金餘額且沒有預設值。請聯絡 Fluz 設定預設撥款餘額。                    |
