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

# Batch Operations

> Tracking the results of bulk job trigger requests.

A `BatchOperation` tracks the outcome of a bulk trigger request against a [Job](/concepts/jobs). When you trigger a job with multiple items in a single request (via `POST /v1/jobs/{jobID}/trigger-bulk`), Strait creates a batch operation to record how many items were submitted and how many [Runs](/concepts/runs) were actually created.

## BatchOperation Model

The `BatchOperation` struct (defined in `apps/strait/internal/domain/types.go`) contains the following fields:

| Field           | Type         | Description                                                                                      |
| :-------------- | :----------- | :----------------------------------------------------------------------------------------------- |
| `id`            | `string`     | Unique identifier for the batch operation.                                                       |
| `project_id`    | `string`     | The project this batch operation belongs to.                                                     |
| `job_id`        | `string`     | The job that was bulk-triggered.                                                                 |
| `item_count`    | `int`        | Number of items submitted in the bulk trigger request.                                           |
| `created_count` | `int`        | Number of runs actually created (may be less than `item_count`).                                 |
| `created_by`    | `string`     | Actor ID who initiated the bulk trigger (user ID or `apikey:<id>`).                              |
| `created_at`    | `time.Time`  | Timestamp when the batch operation was created.                                                  |
| `finished_at`   | `*time.Time` | Timestamp when all items in the batch have been processed. Null while processing is in progress. |

## How Batch Operations Work

Batch operations are **not** created directly through the API. They are created automatically when a bulk trigger request is made:

1. A client sends a `POST /v1/jobs/{jobID}/trigger-bulk` request containing multiple items.
2. Strait creates a `BatchOperation` record with `item_count` set to the number of items in the request.
3. For each item, Strait attempts to create a run. The resulting runs have their `batch_id` field set to the batch operation's `id`.
4. `created_count` reflects the number of runs that were actually created. This may be lower than `item_count` if some items were deduplicated (see [dedup\_window\_secs](/concepts/jobs)).
5. Once all items have been processed, `finished_at` is set.

<Note>
  The difference between `item_count` and `created_count` is a useful signal. A large gap typically indicates deduplication is filtering out duplicate payloads within the configured window.
</Note>

## Querying Batch Status

Two read-only endpoints are available for inspecting batch operations:

| Method | Endpoint                                        | Description                                                  |
| :----- | :---------------------------------------------- | :----------------------------------------------------------- |
| `GET`  | `/v1/batch-operations?project_id=...`           | List batch operations for a project (paginated with cursor). |
| `GET`  | `/v1/batch-operations/{batchID}?project_id=...` | Get a specific batch operation by ID.                        |

To find all runs that belong to a specific batch, query runs and filter by `batch_id`:

```
GET /v1/jobs/{jobID}/runs?project_id=...&batch_id={batchID}
```

A batch operation is considered complete when `finished_at` is non-null.

## Related Concepts

* [Jobs](/concepts/jobs): The job definition that was bulk-triggered.
* [Runs](/concepts/runs): Individual execution instances created by the batch. Each run's `batch_id` links back to its originating batch operation.
