# Creating user roles

Both Business accounts and Child accounts require clients to set up users with specific roles. To help facilitate this, Upvest provides the `/roles` API.

User activation is role-based: the specific actions a user is permitted to perform on an account group or business are determined by the role(s) assigned to them. For more information, refer to [Role-based activation](/products/byol/guides/users/role_based_activation).

## Prerequisites

- **Authentication scopes** — `roles:admin`
For more information, refer to [Authentication scopes](/products/byol/concepts/api_concepts/authentication/authentication_oauth#list-of-authentication-scopes).
- **Webhook handler ready** — Set up a webhook endpoint to listen for user role events.
  - Subscribe to [`ROLE.*`](/products/byol/guides/users/users_webhooks) events.
For more information, refer to [Implementing webhooks](/products/byol/getting_started/implementing_webhooks).


Prior to adding a user role, you must first create both the user and either a child account group, joint account group, or business entity.

In addition you must work with Upvest to enable the `roles:admin` and `roles:read` scopes for authentication.

## Setting the user’s role

The approach to setting user roles depends on the type of account as described below.

Each user may be assigned multiple roles. Submit a separate **POST** `/roles` request for each role you want to assign.

### Personal account roles

Personal accounts map directly to a single user so Upvest automatically assigns the user the `OWNER` role.

### Child account roles

Child accounts require multiple user roles:

- `CHILD`: The beneficiary of the account. This role is automatically assigned to the child user when the child account group is created — no `POST /roles` call is required.
- `GUARDIAN`: The authorised legal guardian(s) on the account. Unlike the Child role, each Guardian must be explicitly assigned via their own `POST /roles` call (see the example below). For child accounts, the number of required guardians is set by the `custody_type` field:
  - `SOLE_CUSTODY` — A single guardian has custody of the child account group.
  - `JOINT_CUSTODY` — Multiple guardians are required for the child account group.


### Joint account roles

For joint accounts, Upvest automatically assigns the first end user an `OWNER` role. Clients must add the `OWNER` role to the second end user.

### Business account roles

You can set a user’s role for business account users as follows:

POST /roles

| **Field** | **Required** | **Description** |
|  --- | --- | --- |
| `user_id` | Required | The user’s unique identifier. |
| `entity_type` | Required | Sets whether the `entity_id` parameter equals the `id` of a child account group or business entity. Accepts the following values:- `ACCOUNT_GROUP`: Used for child accounts groups.- `BUSINESS`: Used for business entities. |
| `entity_id` | Required | Unique identifier for either the child account group or the business entity depending on the value of the `entity_type` parameter. |
| `role_type` | Required | Sets the specific role to map to the user.For child accounts: - `GUARDIAN`: The user is a legal custodian for the child account group. This is the only `role_type` you can send for an account group — the `CHILD` and `OWNER` roles are assigned by Upvest.For business accounts:  - `LEGAL_REPRESENTATIVE`: a designated individual that serves as an official legal representative for the business. -  `AUTHORISED_SIGNATORY`: an individual that is given the legal right to sign documents/make commitments on behalf of a business. -  `ULTIMATE_BENEFICIAL_OWNER`: individual who ultimately owns or controls the business. - `CONTRACTING_EXECUTIVE`: an individual that is able to enter contracts on behalf of a business. - `TRADER`: an individual that is permitted to trade on behalf of a business. - `SOLE_TRADER`: an individual that trades on behalf of a sole trader entity.NOTE: Corporate business accounts must assign at least one (1) Ultimate beneficial owner, at least one (1) Legal representative, and one (1) Contracting executive to the business. This is not required for sole traders. |
| **Additional parameter for child accounts** |  |  |
| `custody_type` |  | Sets whether a single or multiple guardian roles are required for the child account group. - `SOLE_CUSTODY` - Single guardian - `JOINT_CUSTODY` - Multiple guardians required |


## Examples request and response for child accounts

### Example Account Group role request

Request
```json
{
  "user_id": "9c36af78-91a0-4174-a515-fc81214e3dab",
  "entity_type": "ACCOUNT_GROUP",
  "entity_id": "413715f2-5401-4b97-8055-034a6b879f8c",
  "role_type": "GUARDIAN"
}
```

Response
```json
{
  "id": "baf05386-0459-4e8c-9ac9-cd6442f194dd",
  "created_at": "2025-04-01T10:11:40Z",
  "updated_at": "2025-04-01T10:11:40Z",
  "user_id": "9c36af78-91a0-4174-a515-fc81214e3dab",
  "entity_type": "ACCOUNT_GROUP",
  "entity_id": "413715f2-5401-4b97-8055-034a6b879f8c",
  "role_type": "GUARDIAN",
  "status": "PENDING"
}
```

### Example Business role request

Request
```json
{
  "user_id": "0d10c51f-33f2-4399-b8ab-92ec84e6b2f0",
  "entity_type": "BUSINESS",
  "entity_id": "6deb17c8-950e-4377-b500-5522af5ef712",
  "role_type": "LEGAL_REPRESENTATIVE"
}
```

Response
```json
{
  "id": "e8b5a51d-8baf-4d0b-8a3b-8f8f8f8f8f8f",
  "created_at": "2025-04-01T10:11:40Z",
  "updated_at": "2025-04-01T10:11:40Z",
  "user_id": "0d10c51f-33f2-4399-b8ab-92ec84e6b2f0",
  "entity_type": "BUSINESS",
  "entity_id": "6deb17c8-950e-4377-b500-5522af5ef712",
  "role_type": "LEGAL_REPRESENTATIVE",
  "status": "ACTIVE"
}
```

## Listing roles

You can retrieve a list of all created roles by submitting the following GET request:

GET /roles

You can also retrieve details for a specific /role using the following:

GET /roles/{role_id}

## User roles status

When assigning or retrieving  users’ roles, the following statuses appear in the response message.

| Status | Description |
|  --- | --- |
| PENDING | The role is not yet activated. This may occur if the account group requirements are not met. For example: A child account does not have at least two guardians assigned when `custody_type=JOINT_CUSTODY`. A corporate business account does not have at least one ultimate beneficial owner, one legal representative, and one contracting executive assigned. |
| ACTIVE | The role is active and mapped to the user and account group/business. |
| DEACTIVATED | The role is deactivated. For example, a guardian’s role deactivates when the child user comes of age. |


## Role lifecycle

Account group roles and business roles have different lifecycles.

**Account group roles** (`OWNER`, `GUARDIAN`, and `CHILD`) cannot be deactivated or deleted by clients. Attempting to deactivate one through **DELETE** `/roles/{role_id}` returns a `403 Forbidden` error; Upvest may still deactivate `GUARDIAN` and `CHILD` roles automatically when a child account group converts to a personal account group.

**Business roles** can change over the lifetime of the entity. You can deactivate a business role by including the `{role_id}` in the path of the request:

**DELETE** [`/roles/{role_id}`](/api/roles/role_deactivation)

Note the following behaviour:

- Deactivation is a final state. Once an end user's role has been deactivated, it cannot be reactivated.
- Deactivation is idempotent. Calling the endpoint on an already deactivated role returns a `202 Accepted` without further effect.
- The role remains queryable and returns the status `DEACTIVATED`.
- A `ROLE.DEACTIVATED` event is emitted on the first successful deactivation.


## Roles event webhooks

You can use the Roles event webhook to track the status of the roles creation. Both the account group role and business role events use the following statuses:

| Status | Description |
|  --- | --- |
| ROLE.CREATED | The role is added to the system but not yet activated. This may occur if the account group requirements are not met. |
| ROLE.ACTIVATED | The role is active and mapped to the user and account group/business. |
| ROLE.DEACTIVATED | The role is deactivated. For example, a guardian’s role deactivates when the child user comes of age. |


### Example response account group role creation

Response
```json
{  
  "id": "2df83681-6a42-4837-a554-a8197335bcfa",  
  "created_at": "2021-11-22T09:04:42Z",  
  "type": "ROLE.CREATED",  
  "object": {  
    "id": "baf05386-0459-4e8c-9ac9-cd6442f194dd",  
    "created_at": "2025-04-01T10:11:40Z",  
    "updated_at": "2025-04-01T10:11:40Z",  
    "user_id": "9c36af78-91a0-4174-a515-fc81214e3dab",  
    "entity_type": "ACCOUNT_GROUP",  
    "entity_id": "413715f2-5401-4b97-8055-034a6b879f8c",  
    "role_type": "GUARDIAN",  
    "custody_type": "JOINT_CUSTODY",  
    "status": "PENDING"  
  },  
  "webhook_id": "1b097e06-8a14-4181-b72a-de0972a3c57b"  
}
```

### Example response business role activation

Response
```json
{  
  "id": "2df83681-6a42-4837-a554-a8197335bcfa",  
  "created_at": "2021-11-22T09:04:42Z",  
  "type": "ROLE.ACTIVATED",  
  "object": {  
    "id": "e8b5a51d-8baf-4d0b-8a3b-8f8f8f8f8f8f",  
    "created_at": "2025-04-01T10:11:40Z",  
    "updated_at": "2025-04-01T10:11:40Z",  
    "user_id": "0d10c51f-33f2-4399-b8ab-92ec84e6b2f0",  
    "entity_type": "BUSINESS",  
    "entity_id": "6deb17c8-950e-4377-b500-5522af5ef712",  
    "role_type": "LEGAL_REPRESENTATIVE",  
    "status": "ACTIVE"  
  },  
  "webhook_id": "1b097e06-8a14-4181-b72a-de0972a3c57b"  
}
```