Bulk Update User Roles
PUT/api/users/roles/bulk
Add or remove Spatie roles across many users at once (sanctum guard). Each user's other roles are left unchanged — this is NOT a sync/replace.
This endpoint currently requires session authentication; Personal Access Token scope support is in progress.
Two targeting modes:
- Selected rows — pass
ids(array of user IDs). - All filtered — pass
apply_to_all: trueandfilters(the same filter set as the users list); every user matching the filters is targeted. Emptyfilterstargets all tenant users.
Body fields:
- ids (array of user IDs; required unless filters/apply_to_all provided)
- apply_to_all (boolean; optional)
- filters (object; required unless ids provided — flat
column.operatorkeys and/or afilter_groupstree) - action (string; required; one of: add, remove)
- roles (array of role names; required, min 1; each must exist in roles)
Only users attached to the current tenant are affected — cross-tenant IDs are silently ignored.
Returns a count message. If no users matched, returns 200 with a "No users matched" message.
Authentication: Requires Bearer token AND the users.update permission (403 Forbidden otherwise).
Errors:
- 403 Forbidden — authenticated user lacks the
users.updatepermission - 422 Unprocessable Entity — invalid action, empty roles, or a role name that does not exist
Requires permission: users.update
Request
Responses
- 200
- 401
- 403
- 422
- 429
OK
Response Headers
Unauthenticated — the bearer token is missing, revoked, expired, or malformed. Never retry automatically; fix the credential. See the Errors guide.
Forbidden — the token lacks a required scope, the endpoint is not available to API tokens, or the user behind the token lacks the permission. A human must adjust the token scopes or user permissions; do not retry.
Unprocessable Entity
Response Headers
Rate limited — platform limit is 1,000 requests/min; individual tokens may carry lower limits. Honor the Retry-After header before retrying. See the Rate Limits guide.