---
title: "Team and Roles API Reference"
description: "List bot members and invites, and create, rotate, re-role or remove virtual users. Changing the team always needs a bot Admin's personal API token."
canonical_url: https://chatfuel.com/docs/public-api/team-and-roles
markdown_url: https://chatfuel.com/docs/public-api/team-and-roles.md
last_updated: 2026-10-06
lang: en
site: https://chatfuel.com/docs
llms_txt: https://chatfuel.com/llms.txt
---

# Team and Roles API Reference

List bot members and invites, and create, rotate, re-role or remove virtual users. Changing the team always needs a bot Admin's personal API token.

The team of a Chatfuel bot is its list of members, human teammates and virtual users, each with a role: Admin, Editor, Agent or Custom. Any member can read the team; changing it, including everything to do with virtual users, needs the [personal API token](https://chatfuel.com/docs/public-api/authentication) of a bot Admin. This page lists the team operations; [virtual users](https://chatfuel.com/docs/public-api/virtual-users) walks through the virtual user lifecycle step by step.

## How to read members, roles and invites [#how-to-read-members-roles-and-invites]

Any virtual user of the bot can read the team (**Agent**):

```graphql
query Team($botID: BotID!) {
  bot(id: $botID) {
    members {
      id                                   # BotTeamMemberID, used by all team mutations
      role { roleTypeV2 botPermissions { object action } }
      user { id name accountType }         # accountType: Regular or Virtual
      removalWarnings                      # FuelySwitchToHumanAssignee if Fuely AI hands chats to this member
    }
    invites { id role { roleTypeV2 } used }
    rolesConfig {
      editorRoleSettings { allowOnlyAssignedToMeContacts allowContactsWithEmptyAssignee }
      agentRoleSettings { allowOnlyAssignedToMeContacts allowContactsWithEmptyAssignee }
    }
  }
}
```

`bot.member(id: BotTeamMemberID!)` returns one member. `currentUser.botRole(botID:)` returns the role of the token's owner in a bot.

## How roles and permissions work [#how-roles-and-permissions-work]

A role is a `roleTypeV2` plus a list of `botPermissions`, each an `object` with an `action` of `None`, `View` or `Edit`. The objects are `Ai`, `Configure`, `Roles`, `Pro`, `Inbox`, `Broadcasting`, `People`, `Analyze`, `Home`, `Bot`, `Workspaces`, `Flows`, `ContactsAssignedToOthers` and `ContactsUnassigned`.

Admin, Editor and Agent have fixed permission sets; only a Custom role uses the permissions you send. Virtual users can only be Editor or Agent. The bot's `rolesConfig` applies on top: when `allowOnlyAssignedToMeContacts` is on for a role, members with that role, virtual users included, see and change only contacts assigned to them. Keep this in mind when an Agent virtual user can't find contacts it expects.

## Virtual user operations [#virtual-user-operations]

All of these are **Personal token only** and need the Admin role in the bot:

```graphql
type Mutation {
  # Creates a virtual user and returns its token once. Role: Editor or Agent.
  # Errors: VirtualUserRoleNotAllowed, VirtualUserNameInvalid, VirtualUsersLimitReached
  createVirtualUser(botID: BotID!, name: String!, role: BotRoleInputV2!): VirtualUserCreateResult!
  # Revokes the current token of a virtual user and returns a new one. Errors: NotVirtualUser
  regenerateVirtualUserToken(memberID: BotTeamMemberID!): AuthToken!
}

type VirtualUserCreateResult {
  member: TeamMember!
  authToken: AuthToken!
}

input BotRoleInputV2 {
  roleType: BotRoleTypeV2!            # Admin, Editor, Agent or Custom
  botPermissions: [PermissionInput!]! # used only for Custom; pass [] otherwise
}
```

## Teammate and invite operations [#teammate-and-invite-operations]

These operations change the team, so they are **Personal token only**:

```graphql
type Mutation {
  # Changes a member's role. A virtual user can only be switched between Editor and Agent.
  # Errors: CustomRoleNotSupported, VirtualUserRoleNotAllowed
  changeBotMemberRoleV2(memberID: BotTeamMemberID!, newRole: BotRoleInputV2!): TeamMember!
  # Removes a member. For a virtual user this deletes the account and its token.
  removeMemberFromBot(memberID: BotTeamMemberID!): Bot!
  # Creates an invite link for a human teammate. Errors: CustomRoleNotSupported
  createBotInviteV2(botID: BotID!, role: BotRoleInputV2!, wlLogin: String): BotInviteCreateResult
  botInviteDelete(inviteID: BotInviteID!): Bot!
  # Leaves a bot you are a member of. Not available to virtual users (VirtualUserNotAllowed).
  leaveBot(botID: BotID!): CurrentUserAccount!
}
```

`createBotInviteV2` returns `botInviteToken`, which a person opens in the dashboard to join the bot. Virtual users can't accept invites; create them with `createVirtualUser` instead.

## Subscription [#subscription]

```graphql
type Subscription {
  # Fires when the role of the token's owner changes in any bot. role is null after removal.
  currentUserAccountRoleInBotUpdated: CurrentUserAccountRoleInBotUpdate!
}
```

An integration can listen to this subscription with its virtual user token to notice when an Admin changes its role or removes it.

## Common issues [#common-issues]

### An Agent virtual user gets "NotEnoughPermissions" or empty lists for some contacts [#an-agent-virtual-user-gets-notenoughpermissions-or-empty-lists-for-some-contacts]

Check `bot.rolesConfig.agentRoleSettings`. When `allowOnlyAssignedToMeContacts` is on, an Agent only works with contacts assigned to it; when `allowContactsWithEmptyAssignee` is off, unassigned contacts are hidden.

### "CustomRoleNotSupported" [#customrolenotsupported]

Invites and role changes accept Admin, Editor and Agent. Custom roles can't be assigned through these mutations.

### The removal warning "FuelySwitchToHumanAssignee" [#the-removal-warning-fuelyswitchtohumanassignee]

The member is set as the person Fuely AI hands conversations to. After removal, choose another person in the automation's **Switch to human** setting so chats are not left without an assignee.
