Run the same edit, delete, or FSM transition against many entity records at once. Admin-only. Always two-step — preview the change, review what would happen, then commit (or cancel).
Bulk operations
Bulk operations let you run the same change against many entity records at once. Three operations ship today — Edit records, Delete records (with cascade), and fire an FSM Transition on every record. Every bulk operation is admin-only, and every one is two-step: you preview the change, the platform tells you exactly what would happen row-by-row, and then you commit (or cancel).
Three operations
- Edit — set one or more fields to new values on every selected record.
- Delete — hard-delete the records. Cascades to their FSM jobs and to the event-log rows that referenced them.
- Transition — fire the same FSM event on every selected
record. Each record's guard evaluates independently — some rows
may succeed and others may surface a
guard_failedoutcome.
How you select records
Two selection modes:
- By id (
ids) — explicit list of record ids. Use this when you've checkboxed rows in the EntityListRenderer. - By filter (
filter) — afilter_exprstring plus acount_at_previewsnapshot. Use this when you want to bulk-apply to every record matching a filter. The platform re-counts at commit time; rows that have changed since preview surface asselection_driftper-row.
The preview-commit lifecycle
Every bulk operation runs through a five-state session: the
platform first computes a preview (previewed), then on commit
moves the session through committing to either committed or
errored. You can also cancel from previewed.
The preview tells you total_resolved, would_succeed,
would_skip, would_error, a sample of affected rows, and the
list of per-row errors. Read the preview before committing —
this is the only opportunity to catch mistakes before the change
applies.
Commits under 1000 rows run synchronously on the request and
return when done. Commits at or above 1000 rows enqueue on the
cron worker; the response carries the session id and you poll
GET /sessions/:id until status reaches committed or errored.
Per-row outcomes
Each row in a bulk operation gets one outcome code. The session
continues past per-row errors — succeeded, skipped, and
errored counts are recorded, and you can download errors.csv
for the full per-row report.
The eight codes are documented in the API reference. The two that surface most often:
guard_failed— for transitions, the FSM guard returned false for this record.selection_drift— for filter-mode operations, the row didn't match the filter at commit time even though it did at preview.
Hard-delete cascade
When you bulk-delete entity records, the platform hard-deletes
the records AND every FSM job that referenced them AND every
event-log row that referenced those jobs. The preview surfaces
the cascade as a CascadeSummary reporting jobs_to_delete and
event_log_rows_added — review these numbers before committing.
Hard-delete is permanent — there's no rollback, no undo, and no recovery once a delete commits.
Who can run bulk operations
Admin role only. Every bulk-operations endpoint rejects non-admin callers with 403. There's no per-permission gate beyond admin; admin is the gate.
There are no tier caps on bulk operations — every tier that has admin users can run them.
What's not bulk operations today
Documentary list of explicit non-features today:
- Bulk insert — only edit, delete, and transition ship today. Creating many records at once isn't supported.
- Cross-entity operations — a session targets one entity at a time. You can't bulk-edit records across two different entity types in one operation.
- Scheduled commits — commit fires immediately or on the next cron tick (for async). There's no "run this tomorrow at 3am."
- Rollback of a committed session.
- Approval / two-party authorization before commit.
- Resume from partial failure — a session that errors stops where it stopped; re-run with a corrected selection.
See also
- API reference — REST endpoints, session lifecycle states, and the full set of per-row outcome codes.
- Entities — where you select records from.
- Jobs — for bulk transitions and the event log.