---
title: "Return all or a set of roles in the organization"
method: GET
path: "/v1/org/{orgId}/role"
tags: ["role"]
---

# Return all or a set of roles in the organization

`GET /v1/org/{orgId}/role`

## Path parameters

- `orgId` string, required

## Query parameters

- `ids` string
- `type` string
- `expand` boolean

## Response `200`

successful operation

- ResultsRole
  - `data` Role[], required
    - `id` string, required — globally unique id
    - `orgId` string — parent organization id (empty if global)
    - `label` string, required — human-readable full name of role
    - `description` string — description of role
    - `policyIds` string[] — the policies that define the role
    - `policies` Policy[] — the policies attached to the role
      - `id` string, required — globally unique id
      - `orgId` string — parent organization id (empty if global)
      - `label` string, required — human-readable full name of policy
      - `description` string — description of policy
      - `rules` PolicyRule[] — the rules that define the policy
        - `allow` string[] — allow rules
        - `deny` string[] — deny rules
        - `categories` string[] — categories the rule is limited to
        - `fields` string[] — fields the rule is limited to
        - `departmentIds` string[] — departments the rule is limited to
        - `filter` string — custom filter the rule is limited to
        - `directions` string[] — directions that the rule applies to -- either self or under
        - `types` string[] — types that the rule applies to
        - `targets` PolicyRuleTarget[] — targets allowed for messaging (email addresses, chat channels, user ids)
          - `userId` string
          - `personId` string
          - `channel` string
          - `email` string
        - `visibleSensitive` string[] — if specified, controls visibility of sensitive entities -- for example, ['Manager Shared', 'Manager Only']
        - `fieldsSensitive` string[] — if specified, controls applicability of fields by sensitivity -- for example, ['Manager Shared', 'Manager Only']
      - `roles` Role[] — the roles the policy is attached to
      - `users` User[] — the users the policy is attached to
        - `id` string, required — globally unique id
        - `appId` string — if the user is an app user, the id of the app
        - `name` Name, required
          - `first` string — first name
          - `middle` string — middle name
          - `last` string, required — last name
          - `pref` string — preferred first name
          - `prefLast` string — preferred last name
        - `email` string — email address of user
        - `password` string — password of user (encrypted)
        - `orgs` OrgAccess[] — list of member orgs with permission levels
          - `orgId` string, required — org id
          - `personId` string — person id, if this user directly corresponds with a person
          - `access` 'NONE' | 'PREBOARDING' | 'VIEW' | 'LIMITED' | 'MEMBER_LIMITED_COMP' | 'MEMBER' | 'CUSTOM' | 'TECH_OWNER' | 'TIMEOFF' | 'CONTACT' | 'COMP_CASH' | 'COMP_EQUITY' | 'COMP_ALL' | 'RECRUIT_SENSITIVE' | 'RECRUIT_PRIMARY' | 'SENSITIVE_LIMITED_COMP' | 'SENSITIVE' | 'PRIMARY' | 'PEOPLE_OPS_ADMIN' | 'PEOPLE_OPS_ADMIN_NO_COMP_DATA' | 'PEOPLE_OPS_ADMIN_NO_SENSITIVE_DATA' | 'OWNER', required — legacy access permission level
          - `groupIds` string[] — group ids that the above access applies to
          - `expr` string — expression that the above access applies to
          - `expireAt` string — timestamp that this org access will expire
          - `roleId` string — the role id that defines the users access
          - `policyIds` string[] — additional policy ids, applied additively on top of the policies defined by the role
          - `status` 'INACTIVE' | 'PREBOARDING' | 'ACTIVATION' | 'ACTIVE' | 'OFFBOARDED' — Onboarding status of the user in this org
          - `homeEmail` string — Personal email address of user, while they are preboarding
          - `workEmail` string — Work email address of user, once they have started
          - `workRoleId` string — Active role ID that defines the user's access once they have started
        - `imagePath` string — path to full-sized profile image in storage
        - `status` 'SUPERUSER' | 'NORMAL' | 'INACTIVE' | 'UNINSTALLED' — current status of user
        - `type` 'USER' | 'APP' — type of user
        - `options` object — for apps, options (specific options are specific to the particular app); for users, user-set preferences
        - `internalOptions` object — internal (ChartHop controlled) options
        - `bundleInstall` BundleInstall
          - `entities` BundleInstallEntity[], required
            - `entityType` 'ACTION' | 'CALENDAR' | 'CALENDAR_ENTRY' | 'CATEGORY' | 'FIELD' | 'FORM' | 'GROUP' | 'PROFILE_TAB' | 'QUESTION' | 'REPORT' | 'REPORT_CHART' | 'TASK_CONFIG' | 'TEMPLATE' | 'TIME_OFF_POLICY' | 'CONTENT', required
            - `entityId` string, required
            - `originalId` string, required
        - `secrets` object — write-only secrets; the content of these secrets are not retrievable via the external-facing API
        - `activeAt` string — last activity timestamp
        - `loginAt` string — last login timestamp
        - `appRunCheckAt` string — for apps, last time the app was checked for a scheduled sync
        - `loginCount` integer — number of lifetime successful logins
        - `sessionCount` integer — number of lifetime sessions
        - `loginFailCount` integer — number of consecutive failed logins
        - `title` string — job title, if available
        - `remoteIp` string — last IP address used
        - `createId` string — created by user id
        - `createBehalfId` string — created on behalf of user id
        - `createAttribution` Attribution
          - `principalUserId` string
          - `agentUserIds` string[]
          - `eventId` string
          - `aiChatId` string
          - `aiToolUseId` string
          - `channel` 'WEB' | 'MOBILE' | 'SLACK' | 'TEAMS' | 'MCP'
        - `createAt` string — created timestamp
        - `updateId` string — last updated by user id
        - `updateBehalfId` string — last updated on behalf of user id
        - `updateAttribution` Attribution
          - `principalUserId` string
          - `agentUserIds` string[]
          - `eventId` string
          - `aiChatId` string
          - `aiToolUseId` string
          - `channel` 'WEB' | 'MOBILE' | 'SLACK' | 'TEAMS' | 'MCP'
        - `updateAt` string — last updated timestamp
        - `verifyAt` string — email verified timestamp, if the email has been verified
        - `mfas` WebRegisteredCredential[] — list of registered 2FA registered credentials
          - `credentialId` string, required — Credential id
          - `publicKeyBase64` string, required — The public key we're saving
          - `userHandleBase64` string, required — The user handle - a random 64 bits of data
          - `signatureCount` integer, required — This is used to protect against duplicated key attacks
          - `createdAt` string, required — When was this created
        - `emailSettings` UserEmailSetting[] — Email settings for the user
          - `category` 'ADMINISTRATIVE' | 'BILLING' | 'DATA_IMPORT_AND_SYNC_STATUS' | 'TRIAL_REMINDERS' | 'APPROVAL_NOTIFICATIONS', required — Category of emails
          - `subscribed` boolean, required — Is user subscribed to the category of emails
        - `sensitive` 'GLOBAL' | 'ORG' | 'SENSITIVE' | 'PERSONAL' | 'MANAGER' | 'HIGH' | 'PRIVATE' — sensitivity level of the user's configuration; only applicable to APP users
        - `shareAccess` ShareAccess[] — users and groups who have access to configure this user; only applicable to APP users
          - `access` 'NONE' | 'LIMITED_READ' | 'LIMITED_WRITE' | 'STANDARD_READ' | 'STANDARD_WRITE' | 'COMPENSATION_READ' | 'FULL_READ' | 'COMP_PLANNING_PARTICIPANT' | 'COMPENSATION_WRITE' | 'WRITE' | 'COMPENSATION_OWNER' | 'OWNER', required — access permission level
          - `userId` string — user id
          - `groupId` string — group id
          - `everyone` boolean — grant this access level to everyone in the org (mutually exclusive with userId/groupId)
          - `fields` string — fields
        - `agentConfig` AiAgentConfig
          - `personality` string
          - `instructions` string
          - `guardrails` string
          - `enableMemory` boolean
          - `enableMcpServer` boolean — whether this agent exposes an MCP server endpoint for per-user OAuth access
          - `enableMcpWrite` boolean — whether this agent's MCP server may invoke write/mutating tools (e.g. a non-read-only AskAgent delegation). Read-only by default: when unset or false, a tool that mutates on the call is rejected at the MCP edge regardless of the agent's role/policy. This is defense in depth layered on top of the role, never a grant beyond it.
          - `isExternal` boolean — whether this agent is an external (non-ChartHop) client, e.g. Claude Code or ChatGPT. External agents have no ChartHop-side prompt/behavior config: only permissions, MCP, and activity are configurable.
          - `approvedPolicyRules` PolicyRule[]
            - `allow` string[] — allow rules
            - `deny` string[] — deny rules
            - `categories` string[] — categories the rule is limited to
            - `fields` string[] — fields the rule is limited to
            - `departmentIds` string[] — departments the rule is limited to
            - `filter` string — custom filter the rule is limited to
            - `directions` string[] — directions that the rule applies to -- either self or under
            - `types` string[] — types that the rule applies to
            - `targets` PolicyRuleTarget[] — targets allowed for messaging (email addresses, chat channels, user ids)
              - …
            - `visibleSensitive` string[] — if specified, controls visibility of sensitive entities -- for example, ['Manager Shared', 'Manager Only']
            - `fieldsSensitive` string[] — if specified, controls applicability of fields by sensitivity -- for example, ['Manager Shared', 'Manager Only']
          - `approvalGuidelines` string
          - `managerJobId` string
          - `messagingConfig` MessagingConfig
            - `slackAppId` string
            - `slackClientId` string
            - `slackBotUserId` string
          - `contentIds` string[] — pinned content document IDs; when merging user and app configs, both lists are unioned (not replaced); validate with validateContentIds before persisting
          - `modelTier` 'HIGH' | 'MEDIUM' | 'LOW' — requested model tier for the agent; defaults to MEDIUM when not set
          - `targetedInstructions` TargetedInstruction[] — audience-scoped instruction snippets injected into the chat prompt when the filter matches the current viewer's person record; size and filter syntax are checked by AgentValidationService before persisting
            - `filter` string, required — filter expression matched against the current viewer's person record
            - `instructions` string, required — instructions injected into the chat prompt when filter matches
      - `userCount` integer — number of users the policy is attached to; populated when expand=true on the list endpoint
      - `directUsers` User[] — the users the policy is assigned to directly (via orgs.policyIds), not through a role
        - `id` string, required — globally unique id
        - `appId` string — if the user is an app user, the id of the app
        - `name` Name, required
          - `first` string — first name
          - `middle` string — middle name
          - `last` string, required — last name
          - `pref` string — preferred first name
          - `prefLast` string — preferred last name
        - `email` string — email address of user
        - `password` string — password of user (encrypted)
        - `orgs` OrgAccess[] — list of member orgs with permission levels
          - `orgId` string, required — org id
          - `personId` string — person id, if this user directly corresponds with a person
          - `access` 'NONE' | 'PREBOARDING' | 'VIEW' | 'LIMITED' | 'MEMBER_LIMITED_COMP' | 'MEMBER' | 'CUSTOM' | 'TECH_OWNER' | 'TIMEOFF' | 'CONTACT' | 'COMP_CASH' | 'COMP_EQUITY' | 'COMP_ALL' | 'RECRUIT_SENSITIVE' | 'RECRUIT_PRIMARY' | 'SENSITIVE_LIMITED_COMP' | 'SENSITIVE' | 'PRIMARY' | 'PEOPLE_OPS_ADMIN' | 'PEOPLE_OPS_ADMIN_NO_COMP_DATA' | 'PEOPLE_OPS_ADMIN_NO_SENSITIVE_DATA' | 'OWNER', required — legacy access permission level
          - `groupIds` string[] — group ids that the above access applies to
          - `expr` string — expression that the above access applies to
          - `expireAt` string — timestamp that this org access will expire
          - `roleId` string — the role id that defines the users access
          - `policyIds` string[] — additional policy ids, applied additively on top of the policies defined by the role
          - `status` 'INACTIVE' | 'PREBOARDING' | 'ACTIVATION' | 'ACTIVE' | 'OFFBOARDED' — Onboarding status of the user in this org
          - `homeEmail` string — Personal email address of user, while they are preboarding
          - `workEmail` string — Work email address of user, once they have started
          - `workRoleId` string — Active role ID that defines the user's access once they have started
        - `imagePath` string — path to full-sized profile image in storage
        - `status` 'SUPERUSER' | 'NORMAL' | 'INACTIVE' | 'UNINSTALLED' — current status of user
        - `type` 'USER' | 'APP' — type of user
        - `options` object — for apps, options (specific options are specific to the particular app); for users, user-set preferences
        - `internalOptions` object — internal (ChartHop controlled) options
        - `bundleInstall` BundleInstall
          - `entities` BundleInstallEntity[], required
            - `entityType` 'ACTION' | 'CALENDAR' | 'CALENDAR_ENTRY' | 'CATEGORY' | 'FIELD' | 'FORM' | 'GROUP' | 'PROFILE_TAB' | 'QUESTION' | 'REPORT' | 'REPORT_CHART' | 'TASK_CONFIG' | 'TEMPLATE' | 'TIME_OFF_POLICY' | 'CONTENT', required
            - `entityId` string, required
            - `originalId` string, required
        - `secrets` object — write-only secrets; the content of these secrets are not retrievable via the external-facing API
        - `activeAt` string — last activity timestamp
        - `loginAt` string — last login timestamp
        - `appRunCheckAt` string — for apps, last time the app was checked for a scheduled sync
        - `loginCount` integer — number of lifetime successful logins
        - `sessionCount` integer — number of lifetime sessions
        - `loginFailCount` integer — number of consecutive failed logins
        - `title` string — job title, if available
        - `remoteIp` string — last IP address used
        - `createId` string — created by user id
        - `createBehalfId` string — created on behalf of user id
        - `createAttribution` Attribution
          - `principalUserId` string
          - `agentUserIds` string[]
          - `eventId` string
          - `aiChatId` string
          - `aiToolUseId` string
          - `channel` 'WEB' | 'MOBILE' | 'SLACK' | 'TEAMS' | 'MCP'
        - `createAt` string — created timestamp
        - `updateId` string — last updated by user id
        - `updateBehalfId` string — last updated on behalf of user id
        - `updateAttribution` Attribution
          - `principalUserId` string
          - `agentUserIds` string[]
          - `eventId` string
          - `aiChatId` string
          - `aiToolUseId` string
          - `channel` 'WEB' | 'MOBILE' | 'SLACK' | 'TEAMS' | 'MCP'
        - `updateAt` string — last updated timestamp
        - `verifyAt` string — email verified timestamp, if the email has been verified
        - `mfas` WebRegisteredCredential[] — list of registered 2FA registered credentials
          - `credentialId` string, required — Credential id
          - `publicKeyBase64` string, required — The public key we're saving
          - `userHandleBase64` string, required — The user handle - a random 64 bits of data
          - `signatureCount` integer, required — This is used to protect against duplicated key attacks
          - `createdAt` string, required — When was this created
        - `emailSettings` UserEmailSetting[] — Email settings for the user
          - `category` 'ADMINISTRATIVE' | 'BILLING' | 'DATA_IMPORT_AND_SYNC_STATUS' | 'TRIAL_REMINDERS' | 'APPROVAL_NOTIFICATIONS', required — Category of emails
          - `subscribed` boolean, required — Is user subscribed to the category of emails
        - `sensitive` 'GLOBAL' | 'ORG' | 'SENSITIVE' | 'PERSONAL' | 'MANAGER' | 'HIGH' | 'PRIVATE' — sensitivity level of the user's configuration; only applicable to APP users
        - `shareAccess` ShareAccess[] — users and groups who have access to configure this user; only applicable to APP users
          - `access` 'NONE' | 'LIMITED_READ' | 'LIMITED_WRITE' | 'STANDARD_READ' | 'STANDARD_WRITE' | 'COMPENSATION_READ' | 'FULL_READ' | 'COMP_PLANNING_PARTICIPANT' | 'COMPENSATION_WRITE' | 'WRITE' | 'COMPENSATION_OWNER' | 'OWNER', required — access permission level
          - `userId` string — user id
          - `groupId` string — group id
          - `everyone` boolean — grant this access level to everyone in the org (mutually exclusive with userId/groupId)
          - `fields` string — fields
        - `agentConfig` AiAgentConfig
          - `personality` string
          - `instructions` string
          - `guardrails` string
          - `enableMemory` boolean
          - `enableMcpServer` boolean — whether this agent exposes an MCP server endpoint for per-user OAuth access
          - `enableMcpWrite` boolean — whether this agent's MCP server may invoke write/mutating tools (e.g. a non-read-only AskAgent delegation). Read-only by default: when unset or false, a tool that mutates on the call is rejected at the MCP edge regardless of the agent's role/policy. This is defense in depth layered on top of the role, never a grant beyond it.
          - `isExternal` boolean — whether this agent is an external (non-ChartHop) client, e.g. Claude Code or ChatGPT. External agents have no ChartHop-side prompt/behavior config: only permissions, MCP, and activity are configurable.
          - `approvedPolicyRules` PolicyRule[]
            - `allow` string[] — allow rules
            - `deny` string[] — deny rules
            - `categories` string[] — categories the rule is limited to
            - `fields` string[] — fields the rule is limited to
            - `departmentIds` string[] — departments the rule is limited to
            - `filter` string — custom filter the rule is limited to
            - `directions` string[] — directions that the rule applies to -- either self or under
            - `types` string[] — types that the rule applies to
            - `targets` PolicyRuleTarget[] — targets allowed for messaging (email addresses, chat channels, user ids)
              - …
            - `visibleSensitive` string[] — if specified, controls visibility of sensitive entities -- for example, ['Manager Shared', 'Manager Only']
            - `fieldsSensitive` string[] — if specified, controls applicability of fields by sensitivity -- for example, ['Manager Shared', 'Manager Only']
          - `approvalGuidelines` string
          - `managerJobId` string
          - `messagingConfig` MessagingConfig
            - `slackAppId` string
            - `slackClientId` string
            - `slackBotUserId` string
          - `contentIds` string[] — pinned content document IDs; when merging user and app configs, both lists are unioned (not replaced); validate with validateContentIds before persisting
          - `modelTier` 'HIGH' | 'MEDIUM' | 'LOW' — requested model tier for the agent; defaults to MEDIUM when not set
          - `targetedInstructions` TargetedInstruction[] — audience-scoped instruction snippets injected into the chat prompt when the filter matches the current viewer's person record; size and filter syntax are checked by AgentValidationService before persisting
            - `filter` string, required — filter expression matched against the current viewer's person record
            - `instructions` string, required — instructions injected into the chat prompt when filter matches
      - `directUserCount` integer — number of users the policy is assigned to directly; populated when expand=true on the list endpoint
      - `createId` string — created by user id
      - `createAt` string — created timestamp
      - `updateId` string — last updated by user id
      - `updateAt` string — last updated timestamp
      - `deleteId` string — deleted by user id
      - `deleteAt` string — deleted timestamp
    - `users` User[] — the users the role is attached to
      - `id` string, required — globally unique id
      - `appId` string — if the user is an app user, the id of the app
      - `name` Name, required
        - `first` string — first name
        - `middle` string — middle name
        - `last` string, required — last name
        - `pref` string — preferred first name
        - `prefLast` string — preferred last name
      - `email` string — email address of user
      - `password` string — password of user (encrypted)
      - `orgs` OrgAccess[] — list of member orgs with permission levels
        - `orgId` string, required — org id
        - `personId` string — person id, if this user directly corresponds with a person
        - `access` 'NONE' | 'PREBOARDING' | 'VIEW' | 'LIMITED' | 'MEMBER_LIMITED_COMP' | 'MEMBER' | 'CUSTOM' | 'TECH_OWNER' | 'TIMEOFF' | 'CONTACT' | 'COMP_CASH' | 'COMP_EQUITY' | 'COMP_ALL' | 'RECRUIT_SENSITIVE' | 'RECRUIT_PRIMARY' | 'SENSITIVE_LIMITED_COMP' | 'SENSITIVE' | 'PRIMARY' | 'PEOPLE_OPS_ADMIN' | 'PEOPLE_OPS_ADMIN_NO_COMP_DATA' | 'PEOPLE_OPS_ADMIN_NO_SENSITIVE_DATA' | 'OWNER', required — legacy access permission level
        - `groupIds` string[] — group ids that the above access applies to
        - `expr` string — expression that the above access applies to
        - `expireAt` string — timestamp that this org access will expire
        - `roleId` string — the role id that defines the users access
        - `policyIds` string[] — additional policy ids, applied additively on top of the policies defined by the role
        - `status` 'INACTIVE' | 'PREBOARDING' | 'ACTIVATION' | 'ACTIVE' | 'OFFBOARDED' — Onboarding status of the user in this org
        - `homeEmail` string — Personal email address of user, while they are preboarding
        - `workEmail` string — Work email address of user, once they have started
        - `workRoleId` string — Active role ID that defines the user's access once they have started
      - `imagePath` string — path to full-sized profile image in storage
      - `status` 'SUPERUSER' | 'NORMAL' | 'INACTIVE' | 'UNINSTALLED' — current status of user
      - `type` 'USER' | 'APP' — type of user
      - `options` object — for apps, options (specific options are specific to the particular app); for users, user-set preferences
      - `internalOptions` object — internal (ChartHop controlled) options
      - `bundleInstall` BundleInstall
        - `entities` BundleInstallEntity[], required
          - `entityType` 'ACTION' | 'CALENDAR' | 'CALENDAR_ENTRY' | 'CATEGORY' | 'FIELD' | 'FORM' | 'GROUP' | 'PROFILE_TAB' | 'QUESTION' | 'REPORT' | 'REPORT_CHART' | 'TASK_CONFIG' | 'TEMPLATE' | 'TIME_OFF_POLICY' | 'CONTENT', required
          - `entityId` string, required
          - `originalId` string, required
      - `secrets` object — write-only secrets; the content of these secrets are not retrievable via the external-facing API
      - `activeAt` string — last activity timestamp
      - `loginAt` string — last login timestamp
      - `appRunCheckAt` string — for apps, last time the app was checked for a scheduled sync
      - `loginCount` integer — number of lifetime successful logins
      - `sessionCount` integer — number of lifetime sessions
      - `loginFailCount` integer — number of consecutive failed logins
      - `title` string — job title, if available
      - `remoteIp` string — last IP address used
      - `createId` string — created by user id
      - `createBehalfId` string — created on behalf of user id
      - `createAttribution` Attribution
        - `principalUserId` string
        - `agentUserIds` string[]
        - `eventId` string
        - `aiChatId` string
        - `aiToolUseId` string
        - `channel` 'WEB' | 'MOBILE' | 'SLACK' | 'TEAMS' | 'MCP'
      - `createAt` string — created timestamp
      - `updateId` string — last updated by user id
      - `updateBehalfId` string — last updated on behalf of user id
      - `updateAttribution` Attribution
        - `principalUserId` string
        - `agentUserIds` string[]
        - `eventId` string
        - `aiChatId` string
        - `aiToolUseId` string
        - `channel` 'WEB' | 'MOBILE' | 'SLACK' | 'TEAMS' | 'MCP'
      - `updateAt` string — last updated timestamp
      - `verifyAt` string — email verified timestamp, if the email has been verified
      - `mfas` WebRegisteredCredential[] — list of registered 2FA registered credentials
        - `credentialId` string, required — Credential id
        - `publicKeyBase64` string, required — The public key we're saving
        - `userHandleBase64` string, required — The user handle - a random 64 bits of data
        - `signatureCount` integer, required — This is used to protect against duplicated key attacks
        - `createdAt` string, required — When was this created
      - `emailSettings` UserEmailSetting[] — Email settings for the user
        - `category` 'ADMINISTRATIVE' | 'BILLING' | 'DATA_IMPORT_AND_SYNC_STATUS' | 'TRIAL_REMINDERS' | 'APPROVAL_NOTIFICATIONS', required — Category of emails
        - `subscribed` boolean, required — Is user subscribed to the category of emails
      - `sensitive` 'GLOBAL' | 'ORG' | 'SENSITIVE' | 'PERSONAL' | 'MANAGER' | 'HIGH' | 'PRIVATE' — sensitivity level of the user's configuration; only applicable to APP users
      - `shareAccess` ShareAccess[] — users and groups who have access to configure this user; only applicable to APP users
        - `access` 'NONE' | 'LIMITED_READ' | 'LIMITED_WRITE' | 'STANDARD_READ' | 'STANDARD_WRITE' | 'COMPENSATION_READ' | 'FULL_READ' | 'COMP_PLANNING_PARTICIPANT' | 'COMPENSATION_WRITE' | 'WRITE' | 'COMPENSATION_OWNER' | 'OWNER', required — access permission level
        - `userId` string — user id
        - `groupId` string — group id
        - `everyone` boolean — grant this access level to everyone in the org (mutually exclusive with userId/groupId)
        - `fields` string — fields
      - `agentConfig` AiAgentConfig
        - `personality` string
        - `instructions` string
        - `guardrails` string
        - `enableMemory` boolean
        - `enableMcpServer` boolean — whether this agent exposes an MCP server endpoint for per-user OAuth access
        - `enableMcpWrite` boolean — whether this agent's MCP server may invoke write/mutating tools (e.g. a non-read-only AskAgent delegation). Read-only by default: when unset or false, a tool that mutates on the call is rejected at the MCP edge regardless of the agent's role/policy. This is defense in depth layered on top of the role, never a grant beyond it.
        - `isExternal` boolean — whether this agent is an external (non-ChartHop) client, e.g. Claude Code or ChatGPT. External agents have no ChartHop-side prompt/behavior config: only permissions, MCP, and activity are configurable.
        - `approvedPolicyRules` PolicyRule[]
          - `allow` string[] — allow rules
          - `deny` string[] — deny rules
          - `categories` string[] — categories the rule is limited to
          - `fields` string[] — fields the rule is limited to
          - `departmentIds` string[] — departments the rule is limited to
          - `filter` string — custom filter the rule is limited to
          - `directions` string[] — directions that the rule applies to -- either self or under
          - `types` string[] — types that the rule applies to
          - `targets` PolicyRuleTarget[] — targets allowed for messaging (email addresses, chat channels, user ids)
            - `userId` string
            - `personId` string
            - `channel` string
            - `email` string
          - `visibleSensitive` string[] — if specified, controls visibility of sensitive entities -- for example, ['Manager Shared', 'Manager Only']
          - `fieldsSensitive` string[] — if specified, controls applicability of fields by sensitivity -- for example, ['Manager Shared', 'Manager Only']
        - `approvalGuidelines` string
        - `managerJobId` string
        - `messagingConfig` MessagingConfig
          - `slackAppId` string
          - `slackClientId` string
          - `slackBotUserId` string
        - `contentIds` string[] — pinned content document IDs; when merging user and app configs, both lists are unioned (not replaced); validate with validateContentIds before persisting
        - `modelTier` 'HIGH' | 'MEDIUM' | 'LOW' — requested model tier for the agent; defaults to MEDIUM when not set
        - `targetedInstructions` TargetedInstruction[] — audience-scoped instruction snippets injected into the chat prompt when the filter matches the current viewer's person record; size and filter syntax are checked by AgentValidationService before persisting
          - `filter` string, required — filter expression matched against the current viewer's person record
          - `instructions` string, required — instructions injected into the chat prompt when filter matches
    - `userCount` integer — number of users the role is attached to; populated when expand=true on the list endpoint
    - `createId` string — created by user id
    - `createAt` string — created timestamp
    - `updateId` string — last updated by user id
    - `updateAt` string — last updated timestamp
    - `deleteId` string — deleted by user id
    - `deleteAt` string — deleted timestamp
  - `next` string

## Other responses

- `400` — bad request
- `401` — not authorized
- `404` — not found

---

[API](https://skmtc.net/charthop/apis/charthop-api.md) · [All operations](https://skmtc.net/charthop/apis/charthop-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/charthop/charthop-api/revisions/3040a9f4373f/schema)
