> For the complete documentation index, see [llms.txt](https://developer.celigo.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developer.celigo.com/api/api-reference/roles.md).

# Roles

Roles are named, reusable bundles of resource grants. Assign them to end users directly or pin them to groups; their grants are compiled into each member's effective access.

### Role schema

## The Role object

```json
{"openapi":"3.2.0","info":{"title":"End Users","version":"1.0.0"},"components":{"schemas":{"Role":{"type":"object","description":"A named, reusable bundle of resource grants. Roles are assigned to end\nusers directly (`_roleIds` on the end-user record) or pinned to groups,\nand their grants are compiled into each member's effective access.","required":["_id","name"],"properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Unique identifier for the role."},"_userId":{"type":"string","format":"objectId","readOnly":true,"description":"Account owner's user id."},"name":{"type":"string","description":"Role name, unique within the account (case-insensitive)."},"description":{"type":"string","description":"Free-text description of the role's purpose."},"resourceGrants":{"type":"array","description":"Resource grants this role carries.","items":{"$ref":"#/components/schemas/ResourceGrant"}},"createdAt":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the role was created."},"lastModified":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the role was last updated."}}},"ResourceGrant":{"type":"object","description":"Grants access to a resource (currently MCP servers only). A grant names\nthe resource, or applies as a wildcard across all resources of the type,\nand lists the capabilities granted on it.","required":["resourceType","capabilities"],"properties":{"resourceType":{"type":"string","enum":["mcpServer"],"description":"Resource type this grant applies to."},"_resourceId":{"type":["string","null"],"format":"objectId","description":"MCP server this grant applies to. Omit or set to null for a wildcard\ngrant across all MCP servers in the account."},"capabilities":{"type":"array","minItems":1,"description":"Capabilities granted on the target resource. Each `:all` capability\ncovers only its own kind — grant `tool:all`, `api:all`, `prompt:all`,\nand `resource:all` together to open every item on a server.","items":{"type":"string","pattern":"^(?:tool|api|prompt|resource):(?:[a-fA-F0-9]{24}|all)$|^pset:[a-fA-F0-9]{24}$","description":"Capability string for an `mcpServer` grant. `tool:`, `api:`,\n`prompt:`, and `resource:` take `all` or a 24-hex id on the target\nserver — a `tools[]._toolId` or upstream tool row `_id`, an\n`apis[]._apiId`, a `prompts[]._id`, or a `resources[]._id`; `pset:`\ntakes a `permissionSets[]._id`. Grant prompts with `prompt:<_id>`:\nolder grants written as `tool:<prompt _id>` still validate but are\nnot reported by effective access. Any other shape is rejected with\n400 `validation_failed` (\"Invalid capability\"), and an id that is\nnot attached to the target server with 400 `validation_failed`\nnaming the missing item."}}}}}}}
```

## List roles

> Returns all active roles in the account. Requires account owner or\
> administrator access.

```json
{"openapi":"3.2.0","info":{"title":"End Users","version":"1.0.0"},"tags":[{"name":"Roles","description":"Roles are named, reusable bundles of resource grants. Assign them to\nend users directly or pin them to groups; their grants are compiled\ninto each member's effective access.\n\n## Role schema\n\n{% openapi-schemas spec=\"enduser\" schemas=\"Role\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"Role":{"type":"object","description":"A named, reusable bundle of resource grants. Roles are assigned to end\nusers directly (`_roleIds` on the end-user record) or pinned to groups,\nand their grants are compiled into each member's effective access.","required":["_id","name"],"properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Unique identifier for the role."},"_userId":{"type":"string","format":"objectId","readOnly":true,"description":"Account owner's user id."},"name":{"type":"string","description":"Role name, unique within the account (case-insensitive)."},"description":{"type":"string","description":"Free-text description of the role's purpose."},"resourceGrants":{"type":"array","description":"Resource grants this role carries.","items":{"$ref":"#/components/schemas/ResourceGrant"}},"createdAt":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the role was created."},"lastModified":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the role was last updated."}}},"ResourceGrant":{"type":"object","description":"Grants access to a resource (currently MCP servers only). A grant names\nthe resource, or applies as a wildcard across all resources of the type,\nand lists the capabilities granted on it.","required":["resourceType","capabilities"],"properties":{"resourceType":{"type":"string","enum":["mcpServer"],"description":"Resource type this grant applies to."},"_resourceId":{"type":["string","null"],"format":"objectId","description":"MCP server this grant applies to. Omit or set to null for a wildcard\ngrant across all MCP servers in the account."},"capabilities":{"type":"array","minItems":1,"description":"Capabilities granted on the target resource. Each `:all` capability\ncovers only its own kind — grant `tool:all`, `api:all`, `prompt:all`,\nand `resource:all` together to open every item on a server.","items":{"type":"string","pattern":"^(?:tool|api|prompt|resource):(?:[a-fA-F0-9]{24}|all)$|^pset:[a-fA-F0-9]{24}$","description":"Capability string for an `mcpServer` grant. `tool:`, `api:`,\n`prompt:`, and `resource:` take `all` or a 24-hex id on the target\nserver — a `tools[]._toolId` or upstream tool row `_id`, an\n`apis[]._apiId`, a `prompts[]._id`, or a `resources[]._id`; `pset:`\ntakes a `permissionSets[]._id`. Grant prompts with `prompt:<_id>`:\nolder grants written as `tool:<prompt _id>` still validate but are\nnot reported by effective access. Any other shape is rejected with\n400 `validation_failed` (\"Invalid capability\"), and an id that is\nnot attached to the target server with 400 `validation_failed`\nnaming the missing item."}}}},"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"400-bad-request":{"description":"Bad request. The server could not understand the request because of malformed syntax or invalid parameters.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"403-forbidden":{"description":"Forbidden. The authenticated caller does not have permission to perform this operation.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v1/roles":{"get":{"summary":"List roles","operationId":"listRoles","tags":["Roles"],"description":"Returns all active roles in the account. Requires account owner or\nadministrator access.","responses":{"200":{"description":"List of roles.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Role"}}}}},"204":{"description":"No roles exist in the account."},"400":{"$ref":"#/components/responses/400-bad-request"},"401":{"$ref":"#/components/responses/401-unauthorized"},"403":{"$ref":"#/components/responses/403-forbidden"}}}}}}
```

## Create a role

> Creates a role. Role names must be unique within the account\
> (case-insensitive), and \`resourceGrants.\_resourceId\` values must\
> reference resources owned by the same account. Requires account owner or\
> administrator access.

```json
{"openapi":"3.2.0","info":{"title":"End Users","version":"1.0.0"},"tags":[{"name":"Roles","description":"Roles are named, reusable bundles of resource grants. Assign them to\nend users directly or pin them to groups; their grants are compiled\ninto each member's effective access.\n\n## Role schema\n\n{% openapi-schemas spec=\"enduser\" schemas=\"Role\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"RoleRequest":{"type":"object","description":"Writable fields for creating or replacing a role.","required":["name"],"properties":{"name":{"type":"string","description":"Role name, unique within the account (case-insensitive)."},"description":{"type":"string","description":"Free-text description of the role's purpose."},"resourceGrants":{"type":"array","description":"Resource grants this role carries. `_resourceId` values must reference resources owned by the same account.","items":{"$ref":"#/components/schemas/ResourceGrant"}}}},"ResourceGrant":{"type":"object","description":"Grants access to a resource (currently MCP servers only). A grant names\nthe resource, or applies as a wildcard across all resources of the type,\nand lists the capabilities granted on it.","required":["resourceType","capabilities"],"properties":{"resourceType":{"type":"string","enum":["mcpServer"],"description":"Resource type this grant applies to."},"_resourceId":{"type":["string","null"],"format":"objectId","description":"MCP server this grant applies to. Omit or set to null for a wildcard\ngrant across all MCP servers in the account."},"capabilities":{"type":"array","minItems":1,"description":"Capabilities granted on the target resource. Each `:all` capability\ncovers only its own kind — grant `tool:all`, `api:all`, `prompt:all`,\nand `resource:all` together to open every item on a server.","items":{"type":"string","pattern":"^(?:tool|api|prompt|resource):(?:[a-fA-F0-9]{24}|all)$|^pset:[a-fA-F0-9]{24}$","description":"Capability string for an `mcpServer` grant. `tool:`, `api:`,\n`prompt:`, and `resource:` take `all` or a 24-hex id on the target\nserver — a `tools[]._toolId` or upstream tool row `_id`, an\n`apis[]._apiId`, a `prompts[]._id`, or a `resources[]._id`; `pset:`\ntakes a `permissionSets[]._id`. Grant prompts with `prompt:<_id>`:\nolder grants written as `tool:<prompt _id>` still validate but are\nnot reported by effective access. Any other shape is rejected with\n400 `validation_failed` (\"Invalid capability\"), and an id that is\nnot attached to the target server with 400 `validation_failed`\nnaming the missing item."}}}},"Role":{"type":"object","description":"A named, reusable bundle of resource grants. Roles are assigned to end\nusers directly (`_roleIds` on the end-user record) or pinned to groups,\nand their grants are compiled into each member's effective access.","required":["_id","name"],"properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Unique identifier for the role."},"_userId":{"type":"string","format":"objectId","readOnly":true,"description":"Account owner's user id."},"name":{"type":"string","description":"Role name, unique within the account (case-insensitive)."},"description":{"type":"string","description":"Free-text description of the role's purpose."},"resourceGrants":{"type":"array","description":"Resource grants this role carries.","items":{"$ref":"#/components/schemas/ResourceGrant"}},"createdAt":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the role was created."},"lastModified":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the role was last updated."}}},"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"400-bad-request":{"description":"Bad request. The server could not understand the request because of malformed syntax or invalid parameters.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"403-forbidden":{"description":"Forbidden. The authenticated caller does not have permission to perform this operation.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422-unprocessable-entity":{"description":"Unprocessable entity. The request was well-formed but was unable to be followed due to semantic errors.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v1/roles":{"post":{"summary":"Create a role","operationId":"createRole","tags":["Roles"],"description":"Creates a role. Role names must be unique within the account\n(case-insensitive), and `resourceGrants._resourceId` values must\nreference resources owned by the same account. Requires account owner or\nadministrator access.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleRequest"}}}},"responses":{"201":{"description":"Role created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Role"}}}},"400":{"$ref":"#/components/responses/400-bad-request"},"401":{"$ref":"#/components/responses/401-unauthorized"},"403":{"$ref":"#/components/responses/403-forbidden"},"409":{"description":"A role with this name already exists in the account.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"$ref":"#/components/responses/422-unprocessable-entity"}}}}}}
```

## Get a role

> Retrieves a single role by ID.

```json
{"openapi":"3.2.0","info":{"title":"End Users","version":"1.0.0"},"tags":[{"name":"Roles","description":"Roles are named, reusable bundles of resource grants. Assign them to\nend users directly or pin them to groups; their grants are compiled\ninto each member's effective access.\n\n## Role schema\n\n{% openapi-schemas spec=\"enduser\" schemas=\"Role\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"Role":{"type":"object","description":"A named, reusable bundle of resource grants. Roles are assigned to end\nusers directly (`_roleIds` on the end-user record) or pinned to groups,\nand their grants are compiled into each member's effective access.","required":["_id","name"],"properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Unique identifier for the role."},"_userId":{"type":"string","format":"objectId","readOnly":true,"description":"Account owner's user id."},"name":{"type":"string","description":"Role name, unique within the account (case-insensitive)."},"description":{"type":"string","description":"Free-text description of the role's purpose."},"resourceGrants":{"type":"array","description":"Resource grants this role carries.","items":{"$ref":"#/components/schemas/ResourceGrant"}},"createdAt":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the role was created."},"lastModified":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the role was last updated."}}},"ResourceGrant":{"type":"object","description":"Grants access to a resource (currently MCP servers only). A grant names\nthe resource, or applies as a wildcard across all resources of the type,\nand lists the capabilities granted on it.","required":["resourceType","capabilities"],"properties":{"resourceType":{"type":"string","enum":["mcpServer"],"description":"Resource type this grant applies to."},"_resourceId":{"type":["string","null"],"format":"objectId","description":"MCP server this grant applies to. Omit or set to null for a wildcard\ngrant across all MCP servers in the account."},"capabilities":{"type":"array","minItems":1,"description":"Capabilities granted on the target resource. Each `:all` capability\ncovers only its own kind — grant `tool:all`, `api:all`, `prompt:all`,\nand `resource:all` together to open every item on a server.","items":{"type":"string","pattern":"^(?:tool|api|prompt|resource):(?:[a-fA-F0-9]{24}|all)$|^pset:[a-fA-F0-9]{24}$","description":"Capability string for an `mcpServer` grant. `tool:`, `api:`,\n`prompt:`, and `resource:` take `all` or a 24-hex id on the target\nserver — a `tools[]._toolId` or upstream tool row `_id`, an\n`apis[]._apiId`, a `prompts[]._id`, or a `resources[]._id`; `pset:`\ntakes a `permissionSets[]._id`. Grant prompts with `prompt:<_id>`:\nolder grants written as `tool:<prompt _id>` still validate but are\nnot reported by effective access. Any other shape is rejected with\n400 `validation_failed` (\"Invalid capability\"), and an id that is\nnot attached to the target server with 400 `validation_failed`\nnaming the missing item."}}}},"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"400-bad-request":{"description":"Bad request. The server could not understand the request because of malformed syntax or invalid parameters.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"403-forbidden":{"description":"Forbidden. The authenticated caller does not have permission to perform this operation.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v1/roles/{_id}":{"get":{"summary":"Get a role","operationId":"getRole","tags":["Roles"],"description":"Retrieves a single role by ID.","parameters":[{"name":"_id","in":"path","required":true,"description":"Role ID.","schema":{"type":"string","format":"objectId"}}],"responses":{"200":{"description":"Role details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Role"}}}},"400":{"$ref":"#/components/responses/400-bad-request"},"401":{"$ref":"#/components/responses/401-unauthorized"},"403":{"$ref":"#/components/responses/403-forbidden"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
```

## Update a role

> Replaces the role's writable fields. Prefer resending the complete\
> object — omitted fields are not preserved. Requires account owner or\
> administrator access.

```json
{"openapi":"3.2.0","info":{"title":"End Users","version":"1.0.0"},"tags":[{"name":"Roles","description":"Roles are named, reusable bundles of resource grants. Assign them to\nend users directly or pin them to groups; their grants are compiled\ninto each member's effective access.\n\n## Role schema\n\n{% openapi-schemas spec=\"enduser\" schemas=\"Role\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"RoleRequest":{"type":"object","description":"Writable fields for creating or replacing a role.","required":["name"],"properties":{"name":{"type":"string","description":"Role name, unique within the account (case-insensitive)."},"description":{"type":"string","description":"Free-text description of the role's purpose."},"resourceGrants":{"type":"array","description":"Resource grants this role carries. `_resourceId` values must reference resources owned by the same account.","items":{"$ref":"#/components/schemas/ResourceGrant"}}}},"ResourceGrant":{"type":"object","description":"Grants access to a resource (currently MCP servers only). A grant names\nthe resource, or applies as a wildcard across all resources of the type,\nand lists the capabilities granted on it.","required":["resourceType","capabilities"],"properties":{"resourceType":{"type":"string","enum":["mcpServer"],"description":"Resource type this grant applies to."},"_resourceId":{"type":["string","null"],"format":"objectId","description":"MCP server this grant applies to. Omit or set to null for a wildcard\ngrant across all MCP servers in the account."},"capabilities":{"type":"array","minItems":1,"description":"Capabilities granted on the target resource. Each `:all` capability\ncovers only its own kind — grant `tool:all`, `api:all`, `prompt:all`,\nand `resource:all` together to open every item on a server.","items":{"type":"string","pattern":"^(?:tool|api|prompt|resource):(?:[a-fA-F0-9]{24}|all)$|^pset:[a-fA-F0-9]{24}$","description":"Capability string for an `mcpServer` grant. `tool:`, `api:`,\n`prompt:`, and `resource:` take `all` or a 24-hex id on the target\nserver — a `tools[]._toolId` or upstream tool row `_id`, an\n`apis[]._apiId`, a `prompts[]._id`, or a `resources[]._id`; `pset:`\ntakes a `permissionSets[]._id`. Grant prompts with `prompt:<_id>`:\nolder grants written as `tool:<prompt _id>` still validate but are\nnot reported by effective access. Any other shape is rejected with\n400 `validation_failed` (\"Invalid capability\"), and an id that is\nnot attached to the target server with 400 `validation_failed`\nnaming the missing item."}}}},"Role":{"type":"object","description":"A named, reusable bundle of resource grants. Roles are assigned to end\nusers directly (`_roleIds` on the end-user record) or pinned to groups,\nand their grants are compiled into each member's effective access.","required":["_id","name"],"properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Unique identifier for the role."},"_userId":{"type":"string","format":"objectId","readOnly":true,"description":"Account owner's user id."},"name":{"type":"string","description":"Role name, unique within the account (case-insensitive)."},"description":{"type":"string","description":"Free-text description of the role's purpose."},"resourceGrants":{"type":"array","description":"Resource grants this role carries.","items":{"$ref":"#/components/schemas/ResourceGrant"}},"createdAt":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the role was created."},"lastModified":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the role was last updated."}}},"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"400-bad-request":{"description":"Bad request. The server could not understand the request because of malformed syntax or invalid parameters.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"403-forbidden":{"description":"Forbidden. The authenticated caller does not have permission to perform this operation.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422-unprocessable-entity":{"description":"Unprocessable entity. The request was well-formed but was unable to be followed due to semantic errors.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v1/roles/{_id}":{"put":{"summary":"Update a role","operationId":"updateRole","tags":["Roles"],"description":"Replaces the role's writable fields. Prefer resending the complete\nobject — omitted fields are not preserved. Requires account owner or\nadministrator access.","parameters":[{"name":"_id","in":"path","required":true,"description":"Role ID.","schema":{"type":"string","format":"objectId"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleRequest"}}}},"responses":{"200":{"description":"Updated role.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Role"}}}},"400":{"$ref":"#/components/responses/400-bad-request"},"401":{"$ref":"#/components/responses/401-unauthorized"},"403":{"$ref":"#/components/responses/403-forbidden"},"404":{"$ref":"#/components/responses/404-not-found"},"409":{"description":"A role with this name already exists in the account.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"$ref":"#/components/responses/422-unprocessable-entity"}}}}}}
```

## Delete a role

> Soft-deletes the role and removes it from the \`\_roleIds\` of every group\
> in the account. Requires account owner or administrator access.

```json
{"openapi":"3.2.0","info":{"title":"End Users","version":"1.0.0"},"tags":[{"name":"Roles","description":"Roles are named, reusable bundles of resource grants. Assign them to\nend users directly or pin them to groups; their grants are compiled\ninto each member's effective access.\n\n## Role schema\n\n{% openapi-schemas spec=\"enduser\" schemas=\"Role\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"responses":{"400-bad-request":{"description":"Bad request. The server could not understand the request because of malformed syntax or invalid parameters.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"403-forbidden":{"description":"Forbidden. The authenticated caller does not have permission to perform this operation.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}}},"paths":{"/v1/roles/{_id}":{"delete":{"summary":"Delete a role","operationId":"deleteRole","tags":["Roles"],"description":"Soft-deletes the role and removes it from the `_roleIds` of every group\nin the account. Requires account owner or administrator access.","parameters":[{"name":"_id","in":"path","required":true,"description":"Role ID.","schema":{"type":"string","format":"objectId"}}],"responses":{"204":{"description":"Role deleted."},"400":{"$ref":"#/components/responses/400-bad-request"},"401":{"$ref":"#/components/responses/401-unauthorized"},"403":{"$ref":"#/components/responses/403-forbidden"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
```
