Bulk Update Entities
Bulk update multiple user entities in a single request.
This endpoint is optimized for updating many users at once (e.g. changing roles, departments, or status in bulk) and is built on top of the shared bulk infrastructure from accountsession:
- Manager layer:
GeneralizedManager.bulk_update_entities() - DB layer:
DBSessionBulkOps.bulk_update_entities_by_id()
Those layers:
- Batch updates for Spanner, grouped by field sets for efficiency.
- Treat each user update independently (no all-or-nothing transaction).
- Return per-user success and error details via a
BulkUpdateResult/BulkOperationResult.
The operation is partial-safe:
- If some users fail to update, successful updates are still committed.
- The HTTP status is set to
206 Partial Contentwhen at least one update fails. - The response body always reflects the true per-user outcome.
Args:
entities_info:
List of user objects to update. Each item:
- Must include id (user ID, e.g. "u-johs-f47ac10b").
- May include only the fields to change (partial update per user).
user:
Authenticated user performing the bulk operation.
response:
FastAPI response object, used to set status to 206 when needed.
Returns:
BulkUpdateResponse with:
- successful_count: number of users updated successfully
- failed_count: number of users that failed to update
- successful_ids: list of user IDs updated successfully
- failed_ids: list of user IDs that failed (when available)
- errors: mapping of user ID → error description
Error semantics:
- If a user ID does not exist, that ID is added to failed_ids and
errors[user_id] is typically set to "Entity not found".
- If the base update succeeds but processing of custom fields or linked
fields fails in the manager/DB layer, the user is moved from
successful_ids to failed_ids and errors[user_id] is set to
"Entity updated but failed to process custom fields: ..." (or similar).
- A database-level failure for a sub-batch marks only that sub-batch as
failed; other sub-batches can still succeed.
Email handling:
- For any entity where email is changed, the endpoint:
- Detects the change by comparing current and new values.
- After a successful update, sends an email update notification to
frontegghook so the identity provider stays in sync.
HTTP status codes:
- 200 OK:
All requested users updated successfully.
- 206 Partial Content:
At least one user failed to update (see errors in response body).
- 500 Internal Server Error:
Unexpected error or complete bulk failure.
Example request body:
[
{
"id": "u-johs-f47ac10b",
"roleId": 2,
"departmentId": 5
},
{
"id": "u-annb-f47ac10b",
"status": 1,
"email": "new.email@company.com"
}
]
Example response (partial success):
{
"successfulCount": 1,
"failedCount": 1,
"successfulIds": ["u-johs-f47ac10b"],
"failedIds": ["u-annb-f47ac10b"],
"errors": {
"u-annb-f47ac10b": "Email domain not allowed"
}
}
Body·Entities Info
- Type: array of accountsession__api__messages__create_eased_base_model___locals___EasedBaseModel__3Properties: 16
Responses
- application/json
- application/json
curl https://crm.dreamhub.ai/api/v1/users/bulk/ \
--request PUT \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN' \
--data '[
{
"lastName": "Smith",
"displayName": "John Smith",
"department": 1,
"areaOfResponsibility": 1,
"email": "john.smith@company.com",
"role": 1,
"jobTitle": "Account Executive",
"userLanguage": "en",
"avatarUrl": "https://example.com/avatars/user123.jpg",
"groupIds": [
"g-sales",
"g-enterprise"
],
"quotaPlan": 1,
"managerId": "u-manager123",
"timezone": "America/New_York",
"id": "u-user123",
"firstName": "John",
"additionalProperty": "anything"
}
]'
{
"successfulCount": 1,
"failedCount": 1,
"successfulIds": [
"string"
],
"failedEntities": [
{
"additionalProperty": "anything"
}
],
"errors": {
"additionalProperty": "string"
}
}
