docs: improve bulk actions docs (#4211)

- Combine SDK and dashboard bulk actions docs
- Fix API reference pages for bulk actions
- Fix weird rendering on bulk actions page

## Todo
- [ ] not sure about having the SDK+dashboard combined and under "Using
the dashboard"... need to find the right place
This commit is contained in:
Chris Arderne
2026-07-10 11:49:45 +01:00
committed by GitHub
parent e6e8aeb993
commit b4866f0184
9 changed files with 566 additions and 34 deletions
+51 -24
View File
@@ -1,9 +1,15 @@
---
title: "Bulk actions"
description: "Perform actions like replay and cancel on multiple runs at once."
description: "Replay or cancel multiple runs from the dashboard using filters or selected run IDs."
---
Bulk actions allow you to perform replaying and canceling on multiple runs at once. This is especially useful when you need to retry a batch of failed runs with a new version of your code, or when you need to cancel multiple in-progress runs.
**Bulk actions let you replay or cancel multiple runs asynchronously from the dashboard.**
Use bulk actions when you need to retry failed runs after deploying a fix, or stop a group of queued or executing runs.
<Note>
For backend code, see [Bulk actions with the SDK](/runs/bulk-actions).
</Note>
<video
src="https://content.trigger.dev/bulk-actions.mp4"
@@ -16,34 +22,55 @@ Bulk actions allow you to perform replaying and canceling on multiple runs at on
height="100%"
/>
## How to create a new bulk action
## Create a bulk action in the dashboard
<Icon icon="circle-1" iconType="solid" color="#FF2D6B" size="20" /> Open the bulk action panel from the top right of the runs page
<Steps>
<Step title="Open the bulk action panel">
Open the runs page and click **Bulk action** in the top right.
![Access bulk actions](/images/bulk-action-open-panel.png)
![Open the bulk action panel from the runs page](/images/bulk-action-open-panel.png)
</Step>
<Step title="Choose the runs">
Filter the runs table to target a group of runs, or select individual runs from the table.
</Step>
<Icon icon="circle-2" iconType="solid" color="#FF2D6B" size="20" /> Filter the runs table to show the runs you want to bulk action
<Step title="Configure the action">
Choose **Replay** or **Cancel**, add an optional name, then confirm the action.
<Icon icon="circle-3" iconType="solid" color="#FF2D6B" size="20" /> Alternatively, you can select individual runs
![Configure and create a bulk action](/images/bulk-action-create.png)
</Step>
<Icon icon="circle-4" iconType="solid" color="#FF2D6B" size="20" /> Choose the runs you want to bulk action
<Step title="Track progress">
Open the bulk action page to see progress, view affected runs, or replay the action.
<Icon icon="circle-5" iconType="solid" color="#FF2D6B" size="20" /> Name your bulk action (optional)
<Icon icon="circle-6" iconType="solid" color="#FF2D6B" size="20" /> Choose the action you want to perform, replay or cancel
<Icon icon="circle-7" iconType="solid" color="#FF2D6B" size="20" /> Click the "Replay" or "Cancel" button and confirm in the dialog
![Access bulk actions](/images/bulk-action-create.png)
<Icon icon="circle-8" iconType="solid" color="#FF2D6B" size="20" /> You'll now view the bulk action processing from the bulk action page
<Icon icon="circle-9" iconType="solid" color="#FF2D6B" size="20" /> You can replay or view the runs from this page
![Access bulk actions](/images/bulk-action-page.png)
![View bulk action progress](/images/bulk-action-page.png)
</Step>
</Steps>
<Note>
You can only cancel runs that are in states that allow cancellation (like QUEUED or EXECUTING).
Runs that are already completed, failed, or in other final states by the time the bulk action process gets to them, cannot be canceled.
</Note>
You can only cancel runs that are still cancelable, such as queued or executing runs. Runs that have already reached a final state cannot be canceled.
</Note>
## Create a bulk action from the SDK
Use `runs.bulk.replay()` or `runs.bulk.cancel()` when you want to create a bulk action from your backend code.
```ts Your backend code
import { runs } from "@trigger.dev/sdk";
const action = await runs.bulk.replay({
filter: {
status: "FAILED",
taskIdentifier: "sync-customer",
period: "24h",
},
name: "Replay failed customer syncs",
});
const completed = await runs.bulk.poll(action.id);
console.log(completed.status, completed.counts);
```
See [Bulk actions with the SDK](/runs/bulk-actions) for canceling, listing, polling, and aborting bulk actions from your backend code.
+15 -2
View File
@@ -77,7 +77,8 @@
"run-usage",
"context",
"runs/priority",
"hidden-tasks"
"hidden-tasks",
"runs/bulk-actions"
]
},
{
@@ -339,7 +340,6 @@
"management/runs/retrieve",
"management/runs/replay",
"management/runs/cancel",
"management/runs/bulk-actions",
"management/runs/reschedule",
"management/runs/update-metadata",
"management/runs/add-tags",
@@ -348,6 +348,15 @@
"management/runs/retrieve-result"
]
},
{
"group": "Bulk actions API",
"pages": [
"management/bulk-actions/create",
"management/bulk-actions/list",
"management/bulk-actions/retrieve",
"management/bulk-actions/abort"
]
},
{
"group": "Errors API",
"pages": [
@@ -751,6 +760,10 @@
"source": "/reattempting-replaying",
"destination": "/replaying"
},
{
"source": "/management/runs/bulk-actions",
"destination": "/runs/bulk-actions"
},
{
"source": "/tasks-overview",
"destination": "/tasks/overview"
+4
View File
@@ -377,3 +377,7 @@ export const openaiTask = task({
},
});
```
## Replay failed runs in bulk
After you deploy a fix, use [bulk actions](/bulk-actions) to replay multiple failed runs from the dashboard, or [bulk actions with the SDK](/runs/bulk-actions) to replay them from backend code. Bulk replay creates an asynchronous action that targets selected run IDs or a `runs.list()` filter, so you can retry a known failure set without replaying each run individually.
+4
View File
@@ -0,0 +1,4 @@
---
title: "Abort bulk action"
openapi: "v3-openapi POST /api/v1/bulk-actions/{bulkActionId}/abort"
---
+4
View File
@@ -0,0 +1,4 @@
---
title: "Create bulk action"
openapi: "v3-openapi POST /api/v1/bulk-actions"
---
+4
View File
@@ -0,0 +1,4 @@
---
title: "List bulk actions"
openapi: "v3-openapi GET /api/v1/bulk-actions"
---
@@ -0,0 +1,4 @@
---
title: "Retrieve bulk action"
openapi: "v3-openapi GET /api/v1/bulk-actions/{bulkActionId}"
---
@@ -1,9 +1,9 @@
---
title: "Bulk actions"
description: "Cancel or replay many runs from the SDK using run IDs or the same filters as runs.list()."
description: "Cancel or replay many runs from the SDK using run IDs or SDK run-list filters."
---
**Bulk actions let you cancel or replay many runs asynchronously from the SDK by selecting runs with run IDs or `runs.list()` filters.**
**Bulk actions let you cancel or replay many runs asynchronously from the SDK by selecting runs with run IDs or SDK run-list filters.**
A bulk action returns a handle immediately. Use the handle to retrieve progress, poll until completion, list previous actions, or abort pending work.
@@ -28,18 +28,14 @@ const completed = await runs.bulk.poll(action.id);
console.log(completed.status, completed.counts);
```
`filter` accepts the same filters as [`runs.list()`](/management/runs/list), excluding pagination fields. Provide at least one filter field; use `runIds` when you want to target specific runs. Relative time filters such as `period` are resolved when the bulk action is created, so later batches process the same fixed time range.
`filter` accepts the SDK run-list filter fields, excluding pagination fields such as `limit`, `after`, and `before`. This is the TypeScript SDK shape used by `runs.list()` (`from`, `to`, and `period` are top-level fields), not the nested `filter[createdAt]` query shape shown in the raw HTTP list-runs endpoint. Provide at least one filter field; use `runIds` when you want to target specific runs. Relative time filters such as `period` are resolved when the bulk action is created, so later batches process the same fixed time range.
<Warning>
Filters inherit the same time semantics as `runs.list()`: when you don't pass `from`, `to`, or `period`, the action defaults to the **last 7 days** and won't target older matching runs. To cover a wider range, pass an explicit `period` (such as `"30d"`), a `from` timestamp, or a `from`/`to` pair. This default only applies to `filter` selections; `runIds` selections are never time-bounded.
</Warning>
<Note>
Each environment can only run a limited number of bulk replays at the same time. If you start a replay while too many are still in progress, the call fails and returns an error. Wait for an in-progress replay to finish (or [abort](#abort-a-bulk-action) one) before starting another. Bulk cancels are not subject to this limit.
</Note>
<ParamField body="filter" type="BulkActionFilter">
Selects runs using the same filter shape as `runs.list()`, excluding `limit`, `after`, and `before`.
Selects runs using the SDK run-list filter shape, excluding `limit`, `after`, and `before`. In raw HTTP requests these fields are sent as JSON body properties, so time fields are top-level (`from`, `to`, `period`) instead of nested under `createdAt`.
</ParamField>
<ParamField body="runIds" type="string[]">
@@ -148,6 +144,10 @@ await runs.bulk.abort("bulk_1234");
Abort is best effort. Runs already being processed in the current batch may still finish.
<Note>
Each environment can only run a limited number of bulk replays at the same time. If you start a replay while too many are still in progress, the call fails and returns an error. Wait for an in-progress replay to finish or abort one before starting another. Bulk cancels are not subject to this limit.
</Note>
## List bulk actions
Use `runs.bulk.list()` to page through previous bulk actions in the current environment.
@@ -171,3 +171,12 @@ for await (const action of runs.bulk.list({ limit: 25 })) {
console.log(action.id, action.status);
}
```
## API reference
The SDK methods use the bulk actions HTTP API:
- [Create bulk action](/management/bulk-actions/create)
- [List bulk actions](/management/bulk-actions/list)
- [Retrieve bulk action](/management/bulk-actions/retrieve)
- [Abort bulk action](/management/bulk-actions/abort)
+463
View File
@@ -1699,6 +1699,182 @@ paths:
console.log(`Run ID: ${run.id}, Status: ${run.status}`);
}
"/api/v1/bulk-actions":
get:
operationId: list_bulk_actions_v1
summary: List bulk actions
description: List bulk actions in the current environment. Bulk actions are returned newest first and can be paginated with cursor pagination.
parameters:
- $ref: "#/components/parameters/bulkActionsCursorPagination"
responses:
"200":
description: Successful request
content:
application/json:
schema:
$ref: "#/components/schemas/ListBulkActionsResult"
"400":
description: Invalid query parameters
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"401":
description: Unauthorized request
tags:
- bulk-actions
security:
- secretKey: []
x-codeSamples:
- lang: typescript
label: List bulk actions
source: |-
import { runs } from "@trigger.dev/sdk";
let page = await runs.bulk.list({ limit: 20 });
for (const action of page.data) {
console.log(action.id, action.type, action.status);
}
post:
operationId: create_bulk_action_v1
summary: Create bulk action
description: Create an asynchronous bulk action to cancel or replay runs selected by run IDs or filters.
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/CreateBulkActionRequestBody"
responses:
"202":
description: Bulk action accepted
content:
application/json:
schema:
$ref: "#/components/schemas/CreateBulkActionResponse"
"400":
description: Invalid request parameters or body
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"401":
description: Unauthorized request
"422":
description: Unprocessable entity
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"429":
description: Too many concurrent bulk replays
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
tags:
- bulk-actions
security:
- secretKey: []
x-codeSamples:
- lang: typescript
label: Replay matching runs
source: |-
import { runs } from "@trigger.dev/sdk";
const action = await runs.bulk.replay({
filter: {
status: "FAILED",
taskIdentifier: "sync-customer",
period: "24h",
},
name: "Replay failed customer syncs",
});
console.log(action.id);
- lang: typescript
label: Cancel selected runs
source: |-
import { runs } from "@trigger.dev/sdk";
const action = await runs.bulk.cancel({
runIds: ["run_1234", "run_5678"],
name: "Cancel selected runs",
});
console.log(action.id);
"/api/v1/bulk-actions/{bulkActionId}":
get:
operationId: retrieve_bulk_action_v1
summary: Retrieve bulk action
description: Retrieve the status and aggregate processing counts for a bulk action.
parameters:
- $ref: "#/components/parameters/bulkActionId"
responses:
"200":
description: Successful request
content:
application/json:
schema:
$ref: "#/components/schemas/BulkActionObject"
"401":
description: Unauthorized request
"404":
description: Resource not found
tags:
- bulk-actions
security:
- secretKey: []
x-codeSamples:
- lang: typescript
source: |-
import { runs } from "@trigger.dev/sdk";
const action = await runs.bulk.retrieve("bulk_1234");
console.log(action.status, action.counts);
"/api/v1/bulk-actions/{bulkActionId}/abort":
post:
operationId: abort_bulk_action_v1
summary: Abort bulk action
description: Abort a pending bulk action so it stops processing additional runs. Runs already processed by the action are not undone.
parameters:
- $ref: "#/components/parameters/bulkActionId"
responses:
"200":
description: Bulk action aborted
content:
application/json:
schema:
$ref: "#/components/schemas/AbortBulkActionResponse"
"400":
description: Invalid request
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"401":
description: Unauthorized request
"404":
description: Resource not found
tags:
- bulk-actions
security:
- secretKey: []
x-codeSamples:
- lang: typescript
source: |-
import { runs } from "@trigger.dev/sdk";
const aborted = await runs.bulk.abort("bulk_1234");
console.log(aborted.id);
"/api/v1/projects/{projectRef}/runs":
parameters:
- $ref: "#/components/parameters/projectRef"
@@ -3787,6 +3963,36 @@ components:
before:
type: string
description: The ID of the session to start the page before. Sets the pagination direction to backward.
bulkActionId:
in: path
name: bulkActionId
required: true
schema:
type: string
description: The ID of a bulk action, starts with `bulk_`.
example: bulk_1234
bulkActionsCursorPagination:
in: query
name: page
style: deepObject
explode: true
description: |
Use this parameter to paginate bulk actions. Pass `page[after]` or `page[before]` using the cursor returned in the previous response.
schema:
type: object
properties:
size:
type: integer
maximum: 100
minimum: 1
default: 25
description: Number of bulk actions per page. Maximum is 100.
after:
type: string
description: The cursor to start the page after.
before:
type: string
description: The cursor to start the page before.
errorId:
in: path
name: errorId
@@ -4499,6 +4705,263 @@ components:
ignoredUntilTotalOccurrences:
type: integer
nullable: true
BulkActionFilter:
type: object
description: Selects runs using SDK-style run-list filter fields, excluding pagination fields. In HTTP requests these fields are sent as JSON body properties, so time fields are top-level (`from`, `to`, `period`) instead of nested under `createdAt`. Provide at least one property.
minProperties: 1
properties:
status:
oneOf:
- type: string
enum:
- PENDING_VERSION
- QUEUED
- EXECUTING
- REATTEMPTING
- FROZEN
- COMPLETED
- CANCELED
- FAILED
- CRASHED
- INTERRUPTED
- SYSTEM_FAILURE
- type: array
items:
type: string
enum:
- PENDING_VERSION
- QUEUED
- EXECUTING
- REATTEMPTING
- FROZEN
- COMPLETED
- CANCELED
- FAILED
- CRASHED
- INTERRUPTED
- SYSTEM_FAILURE
taskIdentifier:
oneOf:
- type: string
- type: array
items:
type: string
description: The identifier of the task that was run.
version:
oneOf:
- type: string
- type: array
items:
type: string
description: The worker version that executed the run.
from:
oneOf:
- type: string
format: date-time
- type: number
description: Start of the time range as an ISO date string or Unix timestamp in milliseconds.
to:
oneOf:
- type: string
format: date-time
- type: number
description: End of the time range as an ISO date string or Unix timestamp in milliseconds.
period:
type: string
description: Relative time period to select, such as `24h` or `30d`.
example: 24h
bulkAction:
type: string
description: Select runs that were processed by another bulk action.
example: bulk_1234
tag:
oneOf:
- type: string
- type: array
items:
type: string
description: Select runs with one or more tags.
schedule:
type: string
description: Select runs created by a schedule.
example: sched_1234
isTest:
type: boolean
description: Select test or non-test runs.
batch:
type: string
description: Select runs in a batch.
example: batch_1234
queue:
oneOf:
- $ref: "#/components/schemas/QueueTypeName"
- type: array
items:
$ref: "#/components/schemas/QueueTypeName"
machine:
oneOf:
- type: string
- type: array
items:
type: string
description: Select runs by machine preset.
region:
oneOf:
- type: string
- type: array
items:
type: string
description: Select runs by region.
QueueTypeName:
type: object
required:
- type
- name
properties:
type:
type: string
enum:
- task
- custom
name:
type: string
CreateBulkActionRequestBody:
oneOf:
- type: object
required:
- action
properties:
action:
type: string
enum:
- cancel
filter:
$ref: "#/components/schemas/BulkActionFilter"
runIds:
type: array
minItems: 1
maxItems: 500
items:
type: string
name:
type: string
maxLength: 255
oneOf:
- required:
- filter
- required:
- runIds
- type: object
required:
- action
properties:
action:
type: string
enum:
- replay
filter:
$ref: "#/components/schemas/BulkActionFilter"
runIds:
type: array
minItems: 1
maxItems: 500
items:
type: string
name:
type: string
maxLength: 255
targetRegion:
type: string
description: Region identifier to replay runs in. When omitted, each replay keeps the original run's region.
oneOf:
- required:
- filter
- required:
- runIds
BulkActionObject:
type: object
required:
- id
- type
- status
- counts
- createdAt
properties:
id:
type: string
description: The bulk action ID, prefixed with `bulk_`.
example: bulk_1234
name:
type: string
description: The name provided when the bulk action was created.
type:
type: string
enum:
- CANCEL
- REPLAY
status:
type: string
enum:
- PENDING
- COMPLETED
- ABORTED
counts:
type: object
required:
- total
- success
- failure
properties:
total:
type: integer
description: The number of runs selected when the bulk action was created.
success:
type: integer
description: The number of runs processed successfully.
failure:
type: integer
description: The number of runs that could not be processed.
createdAt:
type: string
format: date-time
completedAt:
type: string
format: date-time
CreateBulkActionResponse:
type: object
required:
- id
properties:
id:
type: string
example: bulk_1234
AbortBulkActionResponse:
type: object
required:
- id
properties:
id:
type: string
example: bulk_1234
ListBulkActionsResult:
type: object
required:
- data
- pagination
properties:
data:
type: array
items:
$ref: "#/components/schemas/BulkActionObject"
pagination:
type: object
properties:
next:
type: string
description: Pass this cursor as `page[after]` to retrieve the next page.
previous:
type: string
description: Pass this cursor as `page[before]` to retrieve the previous page.
ListRunsResult:
type: object
properties: