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

# Cancel a Bulk Operation

> Stop a bulk job that hasn't finished. Items not yet started are cancelled; items already running are allowed to finish.

`cancelBulkOperation` stops a job you [submitted](/submit-bulk-operation). It is **best-effort and irreversible**: items still `QUEUED` are cancelled, while items already `RUNNING` are allowed to finish and record their results. It does not roll back work that has already completed.

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

## Requirements

* `Authorization: Basic <API_KEY>`
* The bulk API capability on your application.
* The job must belong to your application — an unknown or other-app job id returns not-found.

## Mutation

```graphql theme={null}
mutation CancelBulkOperation($bulkJobId: UUID!) {
  cancelBulkOperation(bulkJobId: $bulkJobId) {
    jobId
    status
    succeededItemCount
    failedItemCount
    skippedItemCount
  }
}
```

```json theme={null}
{
  "bulkJobId": "9c1e6f2a-1d4b-4a2e-8f0c-2b7e5a9d1234"
}
```

## Response

```json theme={null}
{
  "data": {
    "cancelBulkOperation": {
      "jobId": "9c1e6f2a-1d4b-4a2e-8f0c-2b7e5a9d1234",
      "status": "CANCELLED",
      "succeededItemCount": 4,
      "failedItemCount": 0,
      "skippedItemCount": 0
    }
  }
}
```

## Arguments

| Parameter   | Type    | Description                                   |
| ----------- | ------- | --------------------------------------------- |
| `bulkJobId` | `UUID!` | The job id returned by `submitBulkOperation`. |

## Response fields

| Field                                                         | Description                                                                                                             |
| ------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| `status`                                                      | `CANCELLED` once the job has stopped accepting new work. Items that had already succeeded or failed keep their outcome. |
| `succeededItemCount` / `failedItemCount` / `skippedItemCount` | Final per-item counters, including any items that finished after the cancel call landed.                                |

## Errors

| Error                 | HTTP | When                                                                                          |
| --------------------- | ---- | --------------------------------------------------------------------------------------------- |
| `BulkApiAccessDenied` | 403  | Your application does not have the bulk API capability.                                       |
| `BulkJobNotFound`     | 404  | The job id is unknown **or** belongs to another application (deliberately indistinguishable). |

Cancelling an already-finished or already-cancelled job is **not** an error — it returns the job unchanged (see below).

<Note>
  Cancel is **idempotent and safe to retry**. Calling it on a job that is already finished (`COMPLETED`, `COMPLETED_WITH_ERRORS`, `FAILED`) or already `CANCELLED` returns the job unchanged — it never errors and never reverses completed items. Because in-flight items are allowed to finish, poll the job with [Track a Bulk Job](/track-bulk-job) if you need the settled counts after cancelling.
</Note>
