/api/v1/object/data/{objectSlug}/bulk-actionsUpdate, assign or delete many records in one call.
Update, assign or delete many records in one call.
kind picks the action: update writes data (keyed by field slug) to
every selected record; assign sets assignee_slugs as the full
assignee list of every selected record, with the same owner rule as
POST /object/data/{objectSlug}/bulk-assign; delete deletes them.
Choose the records in one of two ways:
record_slugs— the slugs of the records, one by one.select_all: true— every record the credential can see that matchesscope, the same filters a record list takes (search,filtersorfilter_tree,admin_slugs,unassigned). Omitscopeto select every record the credential can see.
excluded_record_slugs removes records from either form. Sending both
record_slugs and select_all answers 400
(code: BULK_SELECTION_AMBIGUOUS).
Up to 100 selected records run during the request: the response is
200 with data.mode sync and the finished report. A larger
selection is queued: the response is 202 with data.mode async and a
job_id; poll GET /object/data/{objectSlug}/bulk-actions/{jobId} for the
report. Each record is checked and written on its own, so one failure does
not stop the rest; failed records are listed in report.failed with a
reason. Nothing is rolled back.
Scope: update.<object slug>, for example update.contacts. Each record
is also checked against the credential's access to it.
Errors:
400— the selection is empty (code: BULK_EMPTY_SELECTION) or ambiguous (code: BULK_SELECTION_AMBIGUOUS).422— the body is invalid, for example an unknownkind, or neitherrecord_slugsnorselect_allis sent.
Request:
{
"kind": "update",
"record_slugs": ["9f2c4b7a1e03", "c83e1a5f2d97", "7b0d3e9c4a18"],
"data": { "stage-k2j9h4g7": "6a1f3c9e-2b7d-4e8a-9f0c-1d2e3f4a5b6c" }
}
Response 200:
{
"status": 200,
"message": "Bulk action completed",
"data": {
"mode": "sync",
"report": {
"job_id": "d41c7b9e2a60",
"status": "partial",
"kind": "update",
"object_slug": "contacts",
"total": 3,
"succeeded": 2,
"failed": [
{
"record_slug": "7b0d3e9c4a18",
"reason": "You do not have permission to edit this record"
}
],
"created_slugs": [],
"chunks_done": 1,
"chunks_total": 1,
"started_by": 17,
"started_at": "2026-09-14T10:00:00.000Z",
"finished_at": "2026-09-14T10:00:01.000Z"
}
}
}
Response 202:
{
"status": 202,
"message": "Bulk action queued",
"data": { "mode": "async", "job_id": "d41c7b9e2a60" }
}
Send request
Use the documented inputs to call this endpoint directly.
Parameters
Values are applied to the request and the example on the right.
Request body
application/jsonrequiredupdate only — field values applied to every selected record.
assign only — the assignee set to put on every selected record.
Responses
Successful response
{
"message": "string",
"data": "string"
}Bad request
{
"status": 1,
"message": "string",
"code": "string",
"data": {}
}The HTTP status code of the response.
What went wrong. Several validation messages are joined with ", ".
A stable, machine-readable reason. Only some errors set it.
Extra detail about the error. Only some errors set it.
Unauthorized
{
"status": 1,
"message": "string",
"code": "string",
"data": {}
}The HTTP status code of the response.
What went wrong. Several validation messages are joined with ", ".
A stable, machine-readable reason. Only some errors set it.
Extra detail about the error. Only some errors set it.
Internal server error
{
"status": 1,
"message": "string",
"code": "string",
"data": {}
}The HTTP status code of the response.
What went wrong. Several validation messages are joined with ", ".
A stable, machine-readable reason. Only some errors set it.
Extra detail about the error. Only some errors set it.
Powered by heyo-docs