> ## Documentation Index
> Fetch the complete documentation index at: https://www.dynamic.xyz/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Custom Roles

> Define named roles that inherit a built-in role's authority, so members hold a role your product recognizes by name.

<Note>
  Business Accounts are in **early access**. See [Business Accounts](/docs/business-accounts/accounts) for the model.
</Note>

A custom role is a name your account defines that inherits a built-in role's authority: `admin` or `viewer`, never `owner`. A member holding `cfo`, for example, has exactly what `admin` grants, but your product can show and reason about the distinct name instead of a generic `admin`. See [Members & roles](/docs/javascript/reference/business-accounts/members-and-roles) for the built-in roles a custom role builds on.

## Define a role

`defineBusinessAccountRole` creates a custom role for the account. Owner or admin only.

<Tabs>
  <Tab title="JavaScript">
    ```javascript theme={"system"}
    import { defineBusinessAccountRole } from '@dynamic-labs-sdk/client/waas';

    await defineBusinessAccountRole({
      businessAccountId: account.id,
      role: 'cfo',
      inherits: 'admin',
    });
    ```
  </Tab>

  <Tab title="React">
    ```tsx theme={"system"}
    import { useDefineBusinessAccountRole } from '@dynamic-labs-sdk/react-hooks';

    const { mutate } = useDefineBusinessAccountRole();
    mutate({ businessAccountId, role: 'cfo', inherits: 'admin' });
    ```
  </Tab>
</Tabs>

<Info>
  A role name is case-insensitive: `CFO` and `cfo` name the same role, and the account stores it lowercase. It cannot reuse a built-in name (`owner`, `admin`, `viewer`) or a name another live role in the account already uses.
</Info>

## List roles

`listBusinessAccountRoles` returns the account's custom roles, keyed by name.

<Tabs>
  <Tab title="JavaScript">
    ```javascript theme={"system"}
    import { listBusinessAccountRoles } from '@dynamic-labs-sdk/client/waas';

    const roles = await listBusinessAccountRoles({ businessAccountId: account.id });
    // roles.cfo?.inherits === 'admin'
    ```
  </Tab>

  <Tab title="React">
    ```tsx theme={"system"}
    import { useListBusinessAccountRoles } from '@dynamic-labs-sdk/react-hooks';

    const RoleList = ({ businessAccountId }: { businessAccountId: string }) => {
      const { data: roles, isLoading } = useListBusinessAccountRoles({ businessAccountId });
      if (isLoading) return null;
      return (
        <ul>
          {Object.entries(roles ?? {}).map(([name, def]) => (
            <li key={name}>{name} (inherits {def.inherits})</li>
          ))}
        </ul>
      );
    };
    ```
  </Tab>
</Tabs>

An account with no custom roles returns an empty map. That is an answer, not a missing resource.

## Assign a role

A custom role's name is a valid `role` value anywhere a built-in role is: `addBusinessAccountMember` and `updateBusinessAccountMemberRole` both accept it. See [Members & roles](/docs/javascript/reference/business-accounts/members-and-roles) for both calls. Assigning a role your account has not defined fails, so define it first.

```javascript theme={"system"}
import { updateBusinessAccountMemberRole } from '@dynamic-labs-sdk/client/waas';

await updateBusinessAccountMemberRole({
  businessAccountId: account.id,
  userId,
  role: 'cfo',
});
```

## Read a member's custom role

A member's `role` on `detail.members` is always the built-in it inherits, so a `cfo` holder still reads `admin` there. The member's `customRole` field carries the actual name and what it inherits.

```javascript theme={"system"}
import { getBusinessAccount } from '@dynamic-labs-sdk/client/waas';

const detail = await getBusinessAccount({ businessAccountId: account.id });
const member = detail.members.find((m) => m.userId === userId);
// member.role === 'admin'
// member.customRole === { name: 'cfo', inherits: 'admin' }
```

`customRole` is `null` for a member holding a built-in role directly.

## Delete a role

`deleteBusinessAccountRole` removes the definition. Owner or admin only.

<Tabs>
  <Tab title="JavaScript">
    ```javascript theme={"system"}
    import { deleteBusinessAccountRole } from '@dynamic-labs-sdk/client/waas';

    await deleteBusinessAccountRole({ businessAccountId: account.id, role: 'cfo' });
    ```
  </Tab>

  <Tab title="React">
    ```tsx theme={"system"}
    import { useDeleteBusinessAccountRole } from '@dynamic-labs-sdk/react-hooks';

    const { mutate } = useDeleteBusinessAccountRole();
    mutate({ businessAccountId, role: 'cfo' });
    ```
  </Tab>
</Tabs>

<Warning>
  Deleting a role does not remove its holders or their authority: each one keeps reading the role's inherited base (`admin` or `viewer`), only the distinct name goes away. Deletion is refused while a governance requirement still names the role. Remove it from governance first.
</Warning>

## Governance

Defining and deleting a role are themselves governed actions (`Define role`, `Delete role`), and a governance requirement's eligible approvers or initiators can name a custom role alongside the built-in ones. This requirement asks for one approval from a `cfo` holder whenever a member is added:

```javascript theme={"system"}
import {
  getBusinessAccountGovernance,
  setBusinessAccountGovernance,
} from '@dynamic-labs-sdk/client/waas';

const businessAccountId = 'ba_123';
const current = await getBusinessAccountGovernance({ businessAccountId });

await setBusinessAccountGovernance({
  businessAccountId,
  governance: {
    ...current,
    addMember: [
      {
        id: 'cfo-signoff',
        schemaVersion: 1,
        requiredApprovals: 1,
        eligibleApproverRoles: ['cfo'],
      },
    ],
  },
});
```

The custom role must already exist when the requirement is set, and a role cannot be deleted while a requirement still names it. See [Governance](/docs/javascript/reference/business-accounts/governance) for the full requirement fields and [Approvals](/docs/business-accounts/approvals) for the model and how a signed change becomes a proposal.

## Next steps

<CardGroup cols={2}>
  <Card title="Members & roles" icon="users" href="/docs/javascript/reference/business-accounts/members-and-roles">
    Add and remove members, and change who holds a role.
  </Card>

  <Card title="Governance" icon="code" href="/docs/javascript/reference/business-accounts/governance">
    Require approvals before a role is defined, deleted, or assigned.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.