# put\_\_user\_{userId}\_role

`PUT /user/{userId}/role`

*Update User Role*

Update the organization role for a specific user. This endpoint allows authorized users to modify role assignments within their organization. The endpoint includes comprehensive validation to ensure proper permissions, organization membership, and role combination validity.

#### Organization Role System

Flashback uses a **flag-based role system** where each role is represented by a hexadecimal value. This system provides granular control over user permissions and allows for future role expansion.

**Role Hierarchy (from lowest to highest privilege):**

| Role Value | Hex Code | Role Name          | Description               | Permissions                                                                           |
| ---------- | -------- | ------------------ | ------------------------- | ------------------------------------------------------------------------------------- |
| 0          | 0x00     | **USER**           | Default role - basic user | Basic access to assigned resources, view-only access to organization settings         |
| 1          | 0x01     | **BILLING**        | Billing management        | Can manage billing, subscriptions, payment methods, and view usage reports            |
| 2          | 0x02     | **WORKSPACES**     | Workspace management      | Can create, modify, and delete workspaces, manage team members, and assign user roles |
| 254        | 0xfe     | **ADMINISTRATORS** | Administrative access     | Full administrative control, can manage all aspects except ownership transfer         |
| 255        | 0xff     | **OWNER**          | Full organization access  | Complete control over the organization, including ownership transfer and deletion     |

**Key Features of the Flag-Based System:**

1. **Scalable Design**: The system reserves values between 0x03 and 0xfd for future role types, allowing for up to 251 additional custom roles.
2. **Permission Inheritance**: Higher-level roles automatically inherit permissions from lower-level roles. For example, a WORKSPACES user can perform all USER and BILLING operations.
3. **Role Modification Rules**: Users can only modify roles that are at or below their own permission level. An OWNER can modify any role, while a WORKSPACES user can only modify USER and BILLING roles.
4. **Organization Protection**: The system prevents the last OWNER from removing their role, ensuring organizations always have at least one owner.
5. **Cross-Organization Isolation**: Users can only modify roles within their own organization, maintaining strict security boundaries.

**Common Use Cases:**

* **Startup Teams**: Begin with USER roles for most team members, promote key members to WORKSPACES for project management
* **Enterprise Organizations**: Use ADMINISTRATORS for IT teams, BILLING for finance teams, and WORKSPACES for project managers
* **Multi-Department Companies**: Assign BILLING roles to finance teams, WORKSPACES to engineering teams, and maintain ADMINISTRATORS for system administration

#### TypeScript Client Library

```typescript
public updateUserRole = async (userId: string, orgRole: number): Promise<UpdateUserRoleResponse> => {
  return this.makeRequest<UpdateUserRoleResponse>(`user/${userId}/role`, 'PUT', { orgRole });
};
```

#### Code Samples

{% tabs %}
{% tab title="Shell" %}

```shell
# You can also use wget
curl -X PUT https://backend.flashback.tech/user/{userId}/role \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}' \
  -d '{
    "orgRole": 2
  }'
```

{% endtab %}

{% tab title="HTTP" %}

```http
PUT https://backend.flashback.tech/user/{userId}/role HTTP/1.1
Host: localhost:3000
Content-Type: application/json
Accept: application/json
Authorization: Bearer {access-token}

{
  "orgRole": 2
}
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const inputBody = '{
  "orgRole": 2
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://backend.flashback.tech/user/{userId}/role',
{
  method: 'PUT',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});
```

{% endtab %}

{% tab title="Ruby" %}

```ruby
require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.put 'https://backend.flashback.tech/user/{userId}/role',
  params: {
  }, headers: headers

p JSON.parse(result)
```

{% endtab %}

{% tab title="Python" %}

```python
import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

r = requests.put('https://backend.flashback.tech/user/{userId}/role', headers = headers)

print(r.json())
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array(
    'orgRole' => 2
);

try {
    $response = $client->request('PUT','https://backend.flashback.tech/user/{userId}/role', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...
```

{% endtab %}

{% tab title="Java" %}

```java
URL obj = new URL("https://backend.flashback.tech/user/{userId}/role");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("PUT");
con.setRequestProperty("Content-Type", "application/json");
con.setRequestProperty("Accept", "application/json");
con.setRequestProperty("Authorization", "Bearer {access-token}");
con.setDoOutput(true);

String jsonInputString = "{\"orgRole\": 2}";
try(OutputStream os = con.getOutputStream()) {
    byte[] input = jsonInputString.getBytes("utf-8");
    os.write(input, 0, input.length);           
}

int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());
```

{% endtab %}

{% tab title="Go" %}

```go
package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/json"},
        "Accept": []string{"application/json"},
        "Authorization": []string{"Bearer {access-token}"},
    }

    data := bytes.NewBuffer([]byte{`{"orgRole": 2}`})
    req, err := http.NewRequest("PUT", "https://backend.flashback.tech/user/{userId}/role", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}
```

{% endtab %}
{% endtabs %}

#### Parameters <a href="#put__user_-userid-_role-parameters" id="put__user_-userid-_role-parameters"></a>

| Name   | In   | Type   | Required | Description                          |
| ------ | ---- | ------ | -------- | ------------------------------------ |
| userId | path | string | true     | Unique identifier of the target user |

#### Request Body <a href="#put__user_-userid-_role-request-body" id="put__user_-userid-_role-request-body"></a>

| Name    | Type    | Required | Description                             |
| ------- | ------- | -------- | --------------------------------------- |
| orgRole | integer | true     | New organization role value (0x00-0xff) |

> Body parameter

```json
{
  "orgRole": 2
}
```

> Example responses

> 200 Response

```json
{
  "success": true,
  "data": {
    "userId": "550e8400-e29b-41d4-a716-446655440000",
    "previousRole": 0,
    "newRole": 2,
    "message": "User role updated to WORKSPACES"
  }
}
```

> 400 Response

```json
{
  "success": false,
  "message": "Invalid role combination"
}
```

> 400 Response (Owner Role Protection)

```json
{
  "success": false,
  "message": "Cannot remove OWNER role: must have at least one other user with OWNER role in the organization"
}
```

> 403 Response (Organization Mismatch)

```json
{
  "success": false,
  "message": "Access denied: users must be in the same organization"
}
```

> 403 Response (No Organization)

```json
{
  "success": false,
  "message": "User not associated with any organization"
}
```

> 403 Response (Insufficient Permissions)

```json
{
  "success": false,
  "message": "Access denied: insufficient permissions to modify user role"
}
```

> 404 Response

```json
{
  "success": false,
  "message": "User not found"
}
```

> 500 Response

```json
{
  "success": false,
  "message": "Internal server error",
  "error": "Database connection failed"
}
```

#### Responses <a href="#put__user_-userid-_role-responses" id="put__user_-userid-_role-responses"></a>

| Status | Meaning                                                                    | Description                                                                                                    | Schema |
| ------ | -------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | ------ |
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)                    | User role updated successfully                                                                                 | Inline |
| 400    | [Bad Request](https://tools.ietf.org/html/rfc7231#section-6.5.1)           | Invalid role combination or owner role removal restriction                                                     | Inline |
| 403    | [Forbidden](https://tools.ietf.org/html/rfc7231#section-6.5.3)             | Access denied due to insufficient permissions, organization mismatch, or user not associated with organization | Inline |
| 404    | [Not Found](https://tools.ietf.org/html/rfc7231#section-6.5.4)             | User not found                                                                                                 | Inline |
| 500    | [Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1) | Internal server error                                                                                          | Inline |

#### Response Schema <a href="#put__user_-userid-_role-responseschema" id="put__user_-userid-_role-responseschema"></a>

Status Code **200**

| Name            | Type    | Required | Restrictions | Description                                |
| --------------- | ------- | -------- | ------------ | ------------------------------------------ |
| » success       | boolean | false    | none         | Indicates if the request was successful    |
| » data          | object  | false    | none         | Role update confirmation data              |
| »» userId       | string  | false    | none         | Unique identifier for the target user      |
| »» previousRole | integer | false    | none         | User's previous organization role          |
| »» newRole      | integer | false    | none         | User's new organization role               |
| »» message      | string  | false    | none         | Confirmation message describing the change |

Status Code **400**

| Name      | Type    | Required | Restrictions | Description                                   |
| --------- | ------- | -------- | ------------ | --------------------------------------------- |
| » success | boolean | false    | none         | Indicates if the request was successful       |
| » message | string  | false    | none         | Error message describing the validation issue |

Status Code **403**

| Name      | Type    | Required | Restrictions | Description                                     |
| --------- | ------- | -------- | ------------ | ----------------------------------------------- |
| » success | boolean | false    | none         | Indicates if the request was successful         |
| » message | string  | false    | none         | Error message describing the access restriction |

Status Code **404**

| Name      | Type    | Required | Restrictions | Description                             |
| --------- | ------- | -------- | ------------ | --------------------------------------- |
| » success | boolean | false    | none         | Indicates if the request was successful |
| » message | string  | false    | none         | Error message describing the issue      |

Status Code **500**

| Name      | Type    | Required | Restrictions | Description                             |
| --------- | ------- | -------- | ------------ | --------------------------------------- |
| » success | boolean | false    | none         | Indicates if the request was successful |
| » message | string  | false    | none         | Error message describing the issue      |
| » error   | string  | false    | none         | Detailed error information              |

**Enumerated Values**

| Parameter | Value | Description                                         |
| --------- | ----- | --------------------------------------------------- |
| » orgRole | 0x00  | USER - Default role with basic access               |
| » orgRole | 0x01  | BILLING - Can manage billing and subscriptions      |
| » orgRole | 0x02  | WORKSPACES - Can manage workspaces and team members |
| » orgRole | 0xfe  | ADMINISTRATORS - Administrative access              |
| » orgRole | 0xff  | OWNER - Full organization access                    |

#### Security & Validation

This endpoint includes comprehensive validation and security checks:

**Organization Membership Validation**

* Both the current user and target user must be associated with the same organization
* Users not associated with any organization cannot perform role updates

**Permission Validation**

* Current user must have sufficient permissions to modify the target user's role
* Role modification follows hierarchical permission rules

**Role Combination Validation**

* The requested role combination must be valid according to business rules
* Invalid role combinations are rejected with a 400 status

**Owner Role Protection**

* Users cannot remove their own OWNER role unless there's at least one other user with OWNER role in the organization
* This prevents organizations from being left without an owner

**Authentication Required**

* Valid access token must be provided in the Authorization header
* User must be authenticated and associated with an organization


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.flashback.tech/support-reference/platform-api-reference/user-account/put__user_-userid-_role.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
