Update User
This endpoint updates an existing user by ID. Fields you leave out are not changed, except suppliers (see Behavior).
Endpoint
Section titled “Endpoint”PUT /v1/users/users/:idAuthentication
Section titled “Authentication”Include your API key in the x-api-key header. See Authentication.
Required Scope
Section titled “Required Scope”users:writePath Parameters
Section titled “Path Parameters”| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | User ID to update. |
Request Body
Section titled “Request Body”| Field | Type | Required | Description |
|---|---|---|---|
name | string | No | New display name. |
role | "tenant-admin" | "admin" | "assoc" | "emp" | "no-role" | No | New user role. See the role list on Create User. |
email | string | No | New email address. |
customFields | Record<string, string> | No | Replaces all custom field values. |
startDate | string | null | No | New start date in YYYY-MM-DD format. |
endDate | string | null | No | New end date in YYYY-MM-DD format. |
isArchived | boolean | No | Archive state. See Behavior for what this does and does not do. |
assignments | object | No | Replaces all direct project and task assignments. Same shape as on Create User. Both arrays are required when you send it. |
suppliers | object | No | Supplier for the user. Same shape as on Create User. If you leave it out, the user’s supplier is cleared. |
groupIds | string[] | No | Replaces all of the user’s user groups. Send [] to remove the user from every group. |
resendEmailsAndUpdatePassword | boolean | No | When true and email is also sent, sets a new temporary password and emails it to the user. |
The server does not check the format of email, startDate, endDate, or role. Send values in the documented formats.
Example Request Body
Section titled “Example Request Body”{ "name": "Updated User Name", "email": "placeholder@example.com", "groupIds": ["36b735f8-4dd7-4c3c-836f-35d2fe84e872"], "isArchived": false, "resendEmailsAndUpdatePassword": true}Example Request
Section titled “Example Request”curl -X PUT "https://api.crewsum.com/v1/users/users/user-a" \ -H "x-api-key: $CREWSUM_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "Updated User Name", "email": "placeholder@example.com", "groupIds": ["36b735f8-4dd7-4c3c-836f-35d2fe84e872"], "isArchived": false, "resendEmailsAndUpdatePassword": true }'const response = await fetch("https://api.crewsum.com/v1/users/users/user-a", { method: "PUT", headers: { "x-api-key": process.env.CREWSUM_API_KEY, "Content-Type": "application/json", }, body: JSON.stringify({ name: "Updated User Name", email: "placeholder@example.com", groupIds: ["36b735f8-4dd7-4c3c-836f-35d2fe84e872"], isArchived: false, resendEmailsAndUpdatePassword: true, }),});const result = await response.json();PUT /v1/users/users/user-a HTTP/1.1Host: api.crewsum.comx-api-key: <your-api-key>Content-Type: application/json
{ "name": "Updated User Name", "email": "placeholder@example.com", "groupIds": ["36b735f8-4dd7-4c3c-836f-35d2fe84e872"], "isArchived": false, "resendEmailsAndUpdatePassword": true}Response
Section titled “Response”On success, the API returns HTTP 201 Created, even though the endpoint updates an existing user.
Example Response
Section titled “Example Response”{ "message": "Successfully Updated User"}Behavior
Section titled “Behavior”- Omitting
suppliersclears the user’s supplier. Every request that leaves outsupplierssets the user’s supplier to none. Existing supplier contact links are kept. When the user later submits a timesheet without a supplier set, Crewsum uses the supplier of their linked supplier contacts, if any. To keep the supplier, sendsupplierson every update. - When you send
suppliers, itssupplierContactIdsreplace all of the user’s supplier contact links. isArchivedchanges only the archived flag. Archiving through this endpoint does not block the user from signing in, and it does not send theusers.archivedwebhook event. Onlyusers.updatedis sent.name,email, androleare also updated on the user’s sign-in profile. If that update fails, the error is ignored and the request can still succeed.assignmentsreplaces all direct project and task assignments. Default tasks are not added. Assignments the user receives through user groups are not changed. If a project does not exist in your account, or a task does not exist under theprojectIdsent with it, the request returns500and the existing assignments are not changed. Each task’sprojectIdmust also be inprojectAssignments, or the request returns500. That check runs after the old assignments are removed, so the user can be left with no direct assignments.groupIdsreplaces the user’s group memberships. The user loses the project and task assignments of any group they are removed from. Unknown group IDs return500.resendEmailsAndUpdatePasswordruns only whenemailis also in the body. It sets a new temporary password and emails a sign-in link and the password to the user’s stored email address. The user’s old password stops working.- The endpoint does not check that the user exists. A request for an unknown ID that changes only plain fields returns
201and changes nothing. - The update is not all-or-nothing. If a later step fails, earlier changes are kept.
- After the user is updated, Crewsum sends the
users.updatedwebhook event.
Error Responses
Section titled “Error Responses”| Status | Meaning |
|---|---|
400 | "User ID not found": the ID path segment was empty. |
500 | "Error Updating User": the update failed, for example because of an unknown group ID, an invalid assignment, or a failed password reset. Earlier changes may already be saved. |
Authentication and scope failures are described in Errors.
Related Webhooks
Section titled “Related Webhooks” users.updated View webhook event details.