> ## 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.

# Submit a Bulk Operation

> Run a write or a large export across many connected users in one asynchronous call. You submit a job, poll its status, and (for exports and writes) download a results file.

Runs a bulk operation across your connected users in one call. Unlike the synchronous reads ([Get Bulk Balances](/get-bulk-balances), [Get Bulk Transactions](/get-bulk-transactions)), `submitBulkOperation` is **asynchronous**: it validates the request, creates a job plus one item per target, and returns immediately with a `jobId`. The work runs in the background — [track the job](/track-bulk-job) to follow progress and retrieve results.

<Note>
  Available in `staging` only at this point.
</Note>

One mutation covers all five operations, selected by the `operation` field:

| `operation`                   | What it does                                                    | Required grant scopes (per user)                     |
| ----------------------------- | --------------------------------------------------------------- | ---------------------------------------------------- |
| `GET_BALANCES_EXPORT`         | Export cash balances to a file                                  | `LIST_PAYMENT`                                       |
| `GET_TRANSACTIONS_EXPORT`     | Export transactions to a file                                   | `LIST_PAYMENT`, `LIST_PURCHASES`                     |
| `CREATE_TRANSFER`             | Move funds between the operator and/or connected users          | `MAKE_PAYOUT_TRANSFER_SEND` (on the **source** user) |
| `DEPOSIT_CASH_BALANCE`        | Fund a connected user's spend account from their payment method | `MAKE_DEPOSIT`                                       |
| `UPDATE_TRANSACTION_METADATA` | Edit memo / category on transactions                            | `LIST_PAYMENT`, `LIST_PURCHASES`                     |

## Requirements

* `Authorization: Basic <API_KEY>`
* The bulk API capability on your application.
* The scopes the chosen operation needs, granted by each target user (see the table above). A target missing them becomes a per-item failure — it never fails the whole job.

<Note>
  Every submit **must** carry an idempdempotencyKey` input or an`Idempotency-Key\` header (if both are sent they must match). Re-submitting the same key returns the original job instead of creating a dequest is byte-for-byte identical; a different request under the same key is rejected. There is no safe default for a fan-out write, so the key is required.
</Note>

## Mutation

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

A successful submit returns the job in `QUEUED` status. `acceptedItemCount` is how many targets will be processed; `skippedItemCountd up front (e.g. missing the required scope). Poll the job to watch `succeededItemCount`/`failedItemCount\` fill in — see [Track a Bulk Job](/track-bulk-job).

## Variables — export balances / transactions

`exportOptions` bounds the window (defaults to the last 90 days; `GET_BALANCES_EXPORT` is a point-in-time snapshot and ignores tselection]\(/bulk-api#selecting-target-users) like the reads.

```json theme={null}
{
  "input": {
    "operation": "GET_TRANSACTIONS_E
    "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
    }
  }
}
```

## Variables — create transfer

Each item names its own `from` and `to` endpoint, so one job can mix directions: operator→user, user→operator, and user→user. An endpoint is **either** `{ "operator": true }` (your application's payout account) **or** `{ "externalReferenceId": "…" }` (a connected user). `from` and `to` must differ. The **source** user's grant RANSFER\_SEND`; the destination onlyneeds to be connected. A transfer stays within one sponsor bank. `targetSpec\` is not required for transfers — participants are taken f

```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": { "externalReferen { "externalReferenceId": "user-456"}, "amount": 5.00 }
      ]
    }
  }
}
```

## Variables — deposit cash balance

Funds a connected user's spend account from a payment method **they own** — exactly one of `bankCardId` or `bankAccountId` per own target user, so there's no`targetSpec` — the deposit targets are derived from the items (each user at most once). `userCashBalanceId` is optional (defted/default spend account).

```json theme={null}
{
  "input": {
    "operation": "DEPOSIT_CASH_BALANCE",
    "idempotencyKey": "deposits-2024
    "depositOptions": {
      "items": [
        { "externalReferenceId": "user-123", "amount": 10.00, "bankCardId": "b1a2…", "memo": "Top-up" },
        { "externalReferenceId": "us"bankAccountId": "c3d4…" }
      ]
    }
  }
}
```

## Variables — update transaction metadata

Edits `memo` and/or `transactionCateions. Each item names its own targetuser, so there's no `targetSpec`— the targets are derived from the items (each user at most once). **At most 100 edits in total** per submission. A field set to`null\` clears it; an omitted field is left untouched. Metadata edits execute **synchronously** — the returned job is already terminal, so you can read per-edit results immediately without polling.

```json theme={null}
{
  "input": {
    "operation": "UPDATE_TRANSACTION
    "idempotencyKey": "metadata-2024-06-01-a",
    "metadataOptions": {
      "items": [
        {
          "externalReferenceId": "user-123",
          "edits": [
            { "recordId": "3f2a…", "sactionCategory": "Meals" },
            { "recordId": "9b7c…", "memo": null }
          ]
        }
      ]
    }
  }
}
```

## Response

```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"
    }
  }
}
```

## Arguments

| Parameter                          | Type                                                                                                                                                                                                                                                  | Description                                                                                         |
| ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
| `input.operation`                  | `BulkOperationType!`                                                                                                                                                                                                                                  | One of `GET_BALANCES_EXPORT`, `GET_TRANSACTIONS_EXPORT`, `CREATE_TRANSFER`, `DEPOSIT_CASH_BALANCE`, |
| `UPDATE_TRANSACTION_METADATA`.     |                                                                                                                                                                                                                                                       |                                                                                                     |
| `input.idempotencyKey`             | `String`                                                                                                                                                                                                                                              | Your unique key for this submission. Required (via this field or the `Idempotency-Key` header).     |
| `input.targetSpec`                 | `BulkTargetSp users the operation applies to.Required **only** for the exports (`GET\_\*\_EXPORT`). The write operations — `CREATE\_TRANSFER`, `DEPOSIT\_CASH\_BALANCE`, `UPDATE\_TRANSACTION\_METADATA\` — name their targets in their own items, so |                                                                                                     |
| `targetSpec` is ignored for those. |                                                                                                                                                                                                                                                       |                                                                                                     |
| `input.exportOptions`              | `BulkExportOptionsInput`                                                                                                                                                                                                                              | `createdGte` / `createdLte` window and `includeMetadata`. Export operations only.                   |
| `input.transferOptions.items`      | `[ Per-transfer `from`/`to`endpoints, `amount`, optional `memo`. `CREATE\_TRANSFER\` only.                                                                                                                                                            |                                                                                                     |
| `input.depositOptions.items`       | `[Ber-target `amount`, one of`bankCardId`/`bankAccountId`, optional `userCashBalanceId`/`memo`. `DEPOSIT\_CASH\_BALANCE\` only.                                                                                                                       |                                                                                                     |
| `input.metadataOptions.items`      | `[ Per-target `edits` (`recordId`,`memo?`, `transactionCategory?`). `UPDATE\_TRANSACTION\_METADATA\` only; ≤100 edits total.                                                                                                                          |                                                                                                     |

## Response fields

| Field                                    | Description                                                                            |
| ---------------------------------------- | -------------------------------------------------------------------------------------- |
| `jobId`                                  | The job's id. Use it to (/track-bulk-job).                                             |
| `status`                                 | Lifecycle status: `QUEUED`, `RUNNING`, `COMPLETED`, `COMPLETED_WITH_ERRORS`, `FAILED`, |
| or `CANCELLED`.                          |                                                                                        |
| `operation`                              | The submitted operation.                                                               |
| `requestedTargetCount`                   | Targets addressed by the request.                                                      |
| `acceptedItemCount`                      | Items that waccepted target).                                                          |
| `succeededItemCount` / `failedItemCount` | Per-item outcomes; fill in as the job runs.                                            |
| `skippedItemCount`                       | Targets rejected at submit (e.g. missing the required scope).                          |
| `createdAt`                              | When the job was created.                                                              |

<Note>
  Failures are **per item** — one target's failure never fails the job (see the \[per-target failure contract]\(/bulk-api#per-target-failu itself is only rejected for an authfailure, an invalid operation, a cap exceeded, or when *every* target is unresolvable. After a terminal status, read per-item detai each write produced — with [Track aBulk Job](/track-bulk-job).
</Note>

## Errors

The whole submission is rejected (nohese cases. Everything else becomes a per-item result you read via [Track a Bulk Job](/track-bulk-job#per-item-failure-codes).

| Error                                | HTTP | When                                                                                                                                                                                                             |
| ------------------------------------ | ---- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `BulkApiAccessDenied`                | 403  | Your the bulk API capability.                                                                                                                                                                                    |
| `IdempotencyKeyConflict`             | 409  | The `Idempotency-Key` header and the `idempotencyKey` input were                                                                                                                                                 |
| both sent and do not match.          |      |                                                                                                                                                                                                                  |
| `IdempotencyKeyReused`               | 409  | This idempotency key was already used for a **different** request.                                                                                                                                               |
| (An identical resubmit returns the o |      |                                                                                                                                                                                                                  |
| `TargetLimitExceeded`                | 422  | The request references more than 10,000 distinct users. Split the batch and resubmit.                                                                                                                            |
| `ArgumentsInvalid`                   | 400  | Payload transfer endpoint that isn't exactly one of operator/user, `from` == `to`, a sub-cent amount, an over-long memo, >100 metadata edits) **or** every target was unresolvable / missing the required scope. |
| `AmbiguousSourceCashBalance`         | 422  | *(`CREATE_TRANSFER` only)* An operator-sourced transfer, but your payout routing names multiple clt. Contact Fluz to configure adefault payout balance.                                                          |
