> 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/account-and-admin/users.md).

# Users

Manage user access to a Celigo account. Each record represents a user's access grant, including their access level and invitation status.

Access is controlled at two levels:

* **accessLevel** — account-wide role (administrator, manage, monitor, etc.)
* **integrationAccessLevel** — per-integration overrides for finer control.

The account owner is not included — only invited users appear, plus any the identity provider provisioned through SCIM (`provisionedBy: scim`). Users can be disabled (reversible) or permanently removed. The license sets no user or seat limit.

### User schema

## The User object

```json
{"openapi":"3.2.0","info":{"title":"Users","version":"1.0.0"},"components":{"schemas":{"User":{"type":"object","required":["_id","createdAt","lastModified"],"if":{"properties":{"userType":{"const":"workspace"}}},"then":{"required":["integrationAccessLevel"]},"description":"A user's access record in the account. Each user who has been invited\n(or shared access), or whom the identity provider provisioned through\nSCIM, gets one record per account they belong to. The\n`_id` is the access-record id, not the user's own id — the user's\nidentity is in `sharedWithUser._id` on list and invite responses, and\nin `_sharedWithUserId` on `GET /v1/ashares/{_id}`. The account owner\ndoes not appear in this list.","allOf":[{"$ref":"#/components/schemas/UserBase"},{"type":"object","properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Access-record id for this user in the account."},"_sharedWithUserId":{"type":"string","format":"objectId","readOnly":true,"description":"The user's own account id. Present on `GET /v1/ashares/{_id}`, which\nreturns the bare record; the list and invite responses expand it into\n`sharedWithUser` instead."},"accepted":{"type":"boolean","readOnly":true,"description":"When true, the user has accepted the invitation to join the account."},"disabled":{"type":"boolean","readOnly":true,"description":"When true, the user's access to the account is suspended. Changed\nonly by `PUT /v1/ashares/{_userId}/disable` — a value sent on the\nupdate operation is accepted but not applied."},"userType":{"type":"string","readOnly":true,"enum":["workspace","end-user"],"description":"Discriminates workspace users from end users on the underlying\naccess-record model. An unfiltered list and `GET /v1/ashares/{_id}`\nreturn `workspace` records only; `end-user` records appear in the\nlist only when it is filtered with `userType=end-user` (or\n`workspace,end-user`) and are otherwise managed through the End\nUsers API, which shares the update and disable routes. Sending it\nback on update is rejected."},"lastSignIn":{"type":"string","format":"date-time","readOnly":true,"description":"When the user last signed in to this account."},"dismissed":{"type":"boolean","readOnly":true,"description":"When true, the invitation has been declined by the user."},"isProductionAdmin":{"type":"boolean","readOnly":true,"description":"When true, the user has production-admin privileges in this account."},"createdVia":{"type":"string","readOnly":true,"description":"How this user's access record was created.","enum":["existing_account_invite","existing_account_share_request","invited_during_signup","new_account_auto_join"]},"ssoSetupPending":{"type":"boolean","readOnly":true,"description":"When true, the user must complete SSO setup for this account\nbefore their SSO-required access is fully active. Set by the\nserver during SSO enrollment; cleared by removing the field, so\nit is never `false`."},"provisionedBy":{"type":"string","readOnly":true,"enum":["invite","jit","scim"],"description":"On workspace records, present only when the identity provider\nmanages the user through SCIM; every other workspace record omits\nthe field, so an invited workspace user has no value here rather\nthan `invite`. End-user records (`userType=end-user`) always carry\nit. The identity provider owns a SCIM-managed user's account-wide\naccess level and active state: `PUT /v1/ashares/{_id}` still accepts\na new `accessLevel` and `PUT /v1/ashares/{_userId}/disable` still\ntoggles `disabled`, but the identity provider's next push overwrites\nboth — change them in the IdP. SCIM never sets\n`integrationAccessLevel`, so integration-level grants made here stay."},"externalId":{"type":"string","readOnly":true,"description":"Identifier the identity provider uses for this person in its own\ndirectory, stored when the record is provisioned through SCIM.\nPresent only when `provisionedBy` is `scim`. SCIM matches people by\nemail, not by this value."},"_scimSsoClientId":{"type":"string","format":"objectId","readOnly":true,"description":"SSO client whose SCIM configuration provisioned this record. Present\nonly when `provisionedBy` is `scim`."},"resourceGrants":{"type":"array","readOnly":true,"description":"Present only on end-user records (`userType=end-user`): the MCP\nserver grants held directly by the end user, in addition to any\ngroup- or role-derived access. Replace them with the End Users\nbody on `PUT /v1/ashares/{_ashareId}`.","items":{"$ref":"#/components/schemas/ResourceGrant"}},"groupMemberships":{"type":"array","readOnly":true,"description":"Present only on end-user records that belong to at least one\ngroup. Each entry names the group and whether an administrator or\nthe identity provider created the membership.","items":{"$ref":"#/components/schemas/GroupMembership"}},"_groupIds":{"type":"array","readOnly":true,"description":"Group ids from `groupMemberships`, flattened for quick filtering.\nPresent exactly when `groupMemberships` is.","items":{"type":"string","format":"objectId"}},"sharedWithUser":{"type":"object","readOnly":true,"description":"Identity details of the invited/shared user. Present on the list and\ninvite responses; `GET /v1/ashares/{_id}` returns `_sharedWithUserId`\nin its place.","properties":{"_id":{"type":"string","format":"objectId","description":"The user's own account id."},"email":{"type":"string","format":"email","description":"Email address of the user."},"name":{"type":"string","description":"Display name of the user."},"lastSignIn":{"type":"string","format":"date-time","description":"When the user last signed in (across any account)."},"allowedToResetMFA":{"type":"boolean","description":"When true, the current requester can reset MFA for this user."},"accountSSOLinked":{"type":"string","description":"SSO linkage status for the user in this account.\n`this_account` means SSO is linked to the current account.\n`other_account` means SSO is linked to a different account.","enum":["not_linked","this_account","other_account"]}}}}},{"$ref":"#/components/schemas/ResourceResponse"}]},"UserBase":{"type":"object","description":"Writable fields shared by the request and response schemas.","properties":{"accessLevel":{"type":"string","description":"Account-level access for the user.\n\n**CRITICAL**: This controls account-wide access. Choose your strategy:\n\n- Integration-only access: omit `accessLevel` and specify integrations in `integrationAccessLevel`\n- Account-wide monitoring + selective management: set `accessLevel: monitor` and use `integrationAccessLevel`\n  to grant `manage` access for specific integrations\n- Full account access: set `accessLevel: manage` or `accessLevel: administrator` and leave\n  `integrationAccessLevel` undefined/empty\n\nIf per-integration level permissions are needed, omit `accessLevel` and instead populate `integrationAccessLevel`.\n\nOn update (`PUT /v1/ashares/{_id}`) the body replaces the access settings: `accessLevel`,\n`integrationAccessLevel` and `accountMFARequired` are cleared when omitted, so resend them to keep\nthem. `accountSSORequired`, `allowToEditRetryData`, `allowIntegrationWorkspaceCreation`,\n`mcpServerAccessLevel` and `allMcpServerAccess` are different — each changes only when the body\ncarries it. An update never writes `allowAccessToAPIM`.\n\n`none` is written by SCIM provisioning for a user who has no account-wide grant; do not send it\nyourself — omit `accessLevel` and use `integrationAccessLevel` for integration-only access.","enum":["monitor","manage","administrator","none"]},"integrationAccessLevel":{"type":"array","description":"Per-integration access levels for the user.\n\nUse this for granting access to specific integrations.\n\n- If `accessLevel` is omitted, this creates **integration-only** access.\n- If `accessLevel` is `monitor`, this grants **elevated access** (typically `manage`) for specific integrations.\n- If `accessLevel` is `manage` or `administrator`, do not set `integrationAccessLevel`.\n\nCleared when omitted on update — send `[]` explicitly only when you mean no per-integration grants.","items":{"type":"object","properties":{"_integrationId":{"type":"string","format":"objectId","description":"Integration ID the user should have access to."},"accessLevel":{"type":"string","description":"Access level for this integration.","enum":["monitor","manage"]}}}},"accountSSORequired":{"type":"boolean","description":"When true, the user must sign in through SSO to access this account. Written\nonly when present in the update body — omitting it on `PUT /v1/ashares/{_id}`\nleaves the stored value unchanged. While the account enforces SSO for every\nuser, the value sent is ignored and the stored value is kept until that\nenforcement is turned off.\n\nWhile SSO applies to the user (here or account-wide) and the account's SSO\nprovider is enabled, requests made through the user's access record — signed in\nto the UI, or with a personal access token, which acts through its creator's\nrecord — are refused with 403 `access_restricted` (\"You are required to sign in\nvia SSO configured for the account to access it.\") when the user's login isn't\nlinked to that provider. Account API tokens don't act through a user's access\nrecord, so SSO settings don't affect them."},"accountMFARequired":{"type":"boolean","description":"When true, MFA is required for this user in this account. Cleared when\nomitted on update — resend it with every `PUT /v1/ashares/{_id}`."},"allowAccessToAPIM":{"type":"boolean","readOnly":true,"description":"When true, the user has been set up in API Management (APIM) for this account. The platform\nsets it the first time an administrator opens API Management; `PUT /v1/ashares/{_id}` never\nwrites it."},"allowToEditRetryData":{"type":"boolean","description":"When true, the user can edit retry data when troubleshooting flow run errors (Error Management).\n\nAll users with **Monitor** access can view, retry, and resolve errant records. This flag controls whether they\ncan also **edit the retry data payload**. If set to false, the user cannot edit retry data for flow runs in any\nintegration workspace where they only have **Monitor** access.\n\nThis setting only applies when:\n- `accessLevel` is `monitor`, or\n- an entry in `integrationAccessLevel` grants `monitor` access for a specific integration.\n\nOn update it changes only when the body carries it, only for such a user, and only when the\nowner or an administrator sends it; omitted, the stored value is kept."},"allowIntegrationWorkspaceCreation":{"type":"boolean","description":"When true, a monitor or integration-level user can create integration workspaces, which\nincludes installing templates. Written on update only when the body carries it, by the\nowner or an administrator; omitted, the stored value is kept."}}},"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."}}}},"GroupMembership":{"type":"object","description":"An end user's membership in a group, with the source that created it.","properties":{"_groupId":{"type":"string","format":"objectId","description":"Group the end user belongs to."},"source":{"type":"string","enum":["manual","idp"],"description":"How the membership was created. IdP-synced memberships cannot be\nremoved through the group members API — change the person's group in\nthe identity provider instead (its group mapping, or the SCIM group\nassignment, whichever created the membership)."}}},"ResourceResponse":{"type":"object","description":"Response","properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Unique identifier for the resource. Format is a 24-character hexadecimal string."},"createdAt":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the resource was created. Set automatically and cannot be modified."},"lastModified":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the resource was last updated. Changes whenever any property is modified."},"deletedAt":{"type":["string","null"],"format":"date-time","readOnly":true,"description":"Timestamp when the resource was soft-deleted. When null or absent, the resource is active."}},"required":["_id"]}}}}
```

## List users

> Returns all users with access to the account. The account owner is\
> not included — only invited users appear. Without \`userType\` the list\
> holds workspace records only; end-user records (MCP-only consumers\
> managed through the End Users API) are included only when asked for.

```json
{"openapi":"3.2.0","info":{"title":"Users","version":"1.0.0"},"tags":[{"name":"Users","description":"Manage user access to a Celigo account. Each record represents a user's\naccess grant, including their access level and invitation status.\n\nAccess is controlled at two levels:\n- **accessLevel** — account-wide role (administrator, manage, monitor, etc.)\n- **integrationAccessLevel** — per-integration overrides for finer control.\n\nThe account owner is not included — only invited users appear, plus any\nthe identity provider provisioned through SCIM (`provisionedBy: scim`).\nUsers can be disabled (reversible) or permanently removed. The license\nsets no user or seat limit.\n\n## User schema\n\n{% openapi-schemas spec=\"user\" schemas=\"User\" 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":{"User":{"type":"object","required":["_id","createdAt","lastModified"],"if":{"properties":{"userType":{"const":"workspace"}}},"then":{"required":["integrationAccessLevel"]},"description":"A user's access record in the account. Each user who has been invited\n(or shared access), or whom the identity provider provisioned through\nSCIM, gets one record per account they belong to. The\n`_id` is the access-record id, not the user's own id — the user's\nidentity is in `sharedWithUser._id` on list and invite responses, and\nin `_sharedWithUserId` on `GET /v1/ashares/{_id}`. The account owner\ndoes not appear in this list.","allOf":[{"$ref":"#/components/schemas/UserBase"},{"type":"object","properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Access-record id for this user in the account."},"_sharedWithUserId":{"type":"string","format":"objectId","readOnly":true,"description":"The user's own account id. Present on `GET /v1/ashares/{_id}`, which\nreturns the bare record; the list and invite responses expand it into\n`sharedWithUser` instead."},"accepted":{"type":"boolean","readOnly":true,"description":"When true, the user has accepted the invitation to join the account."},"disabled":{"type":"boolean","readOnly":true,"description":"When true, the user's access to the account is suspended. Changed\nonly by `PUT /v1/ashares/{_userId}/disable` — a value sent on the\nupdate operation is accepted but not applied."},"userType":{"type":"string","readOnly":true,"enum":["workspace","end-user"],"description":"Discriminates workspace users from end users on the underlying\naccess-record model. An unfiltered list and `GET /v1/ashares/{_id}`\nreturn `workspace` records only; `end-user` records appear in the\nlist only when it is filtered with `userType=end-user` (or\n`workspace,end-user`) and are otherwise managed through the End\nUsers API, which shares the update and disable routes. Sending it\nback on update is rejected."},"lastSignIn":{"type":"string","format":"date-time","readOnly":true,"description":"When the user last signed in to this account."},"dismissed":{"type":"boolean","readOnly":true,"description":"When true, the invitation has been declined by the user."},"isProductionAdmin":{"type":"boolean","readOnly":true,"description":"When true, the user has production-admin privileges in this account."},"createdVia":{"type":"string","readOnly":true,"description":"How this user's access record was created.","enum":["existing_account_invite","existing_account_share_request","invited_during_signup","new_account_auto_join"]},"ssoSetupPending":{"type":"boolean","readOnly":true,"description":"When true, the user must complete SSO setup for this account\nbefore their SSO-required access is fully active. Set by the\nserver during SSO enrollment; cleared by removing the field, so\nit is never `false`."},"provisionedBy":{"type":"string","readOnly":true,"enum":["invite","jit","scim"],"description":"On workspace records, present only when the identity provider\nmanages the user through SCIM; every other workspace record omits\nthe field, so an invited workspace user has no value here rather\nthan `invite`. End-user records (`userType=end-user`) always carry\nit. The identity provider owns a SCIM-managed user's account-wide\naccess level and active state: `PUT /v1/ashares/{_id}` still accepts\na new `accessLevel` and `PUT /v1/ashares/{_userId}/disable` still\ntoggles `disabled`, but the identity provider's next push overwrites\nboth — change them in the IdP. SCIM never sets\n`integrationAccessLevel`, so integration-level grants made here stay."},"externalId":{"type":"string","readOnly":true,"description":"Identifier the identity provider uses for this person in its own\ndirectory, stored when the record is provisioned through SCIM.\nPresent only when `provisionedBy` is `scim`. SCIM matches people by\nemail, not by this value."},"_scimSsoClientId":{"type":"string","format":"objectId","readOnly":true,"description":"SSO client whose SCIM configuration provisioned this record. Present\nonly when `provisionedBy` is `scim`."},"resourceGrants":{"type":"array","readOnly":true,"description":"Present only on end-user records (`userType=end-user`): the MCP\nserver grants held directly by the end user, in addition to any\ngroup- or role-derived access. Replace them with the End Users\nbody on `PUT /v1/ashares/{_ashareId}`.","items":{"$ref":"#/components/schemas/ResourceGrant"}},"groupMemberships":{"type":"array","readOnly":true,"description":"Present only on end-user records that belong to at least one\ngroup. Each entry names the group and whether an administrator or\nthe identity provider created the membership.","items":{"$ref":"#/components/schemas/GroupMembership"}},"_groupIds":{"type":"array","readOnly":true,"description":"Group ids from `groupMemberships`, flattened for quick filtering.\nPresent exactly when `groupMemberships` is.","items":{"type":"string","format":"objectId"}},"sharedWithUser":{"type":"object","readOnly":true,"description":"Identity details of the invited/shared user. Present on the list and\ninvite responses; `GET /v1/ashares/{_id}` returns `_sharedWithUserId`\nin its place.","properties":{"_id":{"type":"string","format":"objectId","description":"The user's own account id."},"email":{"type":"string","format":"email","description":"Email address of the user."},"name":{"type":"string","description":"Display name of the user."},"lastSignIn":{"type":"string","format":"date-time","description":"When the user last signed in (across any account)."},"allowedToResetMFA":{"type":"boolean","description":"When true, the current requester can reset MFA for this user."},"accountSSOLinked":{"type":"string","description":"SSO linkage status for the user in this account.\n`this_account` means SSO is linked to the current account.\n`other_account` means SSO is linked to a different account.","enum":["not_linked","this_account","other_account"]}}}}},{"$ref":"#/components/schemas/ResourceResponse"}]},"UserBase":{"type":"object","description":"Writable fields shared by the request and response schemas.","properties":{"accessLevel":{"type":"string","description":"Account-level access for the user.\n\n**CRITICAL**: This controls account-wide access. Choose your strategy:\n\n- Integration-only access: omit `accessLevel` and specify integrations in `integrationAccessLevel`\n- Account-wide monitoring + selective management: set `accessLevel: monitor` and use `integrationAccessLevel`\n  to grant `manage` access for specific integrations\n- Full account access: set `accessLevel: manage` or `accessLevel: administrator` and leave\n  `integrationAccessLevel` undefined/empty\n\nIf per-integration level permissions are needed, omit `accessLevel` and instead populate `integrationAccessLevel`.\n\nOn update (`PUT /v1/ashares/{_id}`) the body replaces the access settings: `accessLevel`,\n`integrationAccessLevel` and `accountMFARequired` are cleared when omitted, so resend them to keep\nthem. `accountSSORequired`, `allowToEditRetryData`, `allowIntegrationWorkspaceCreation`,\n`mcpServerAccessLevel` and `allMcpServerAccess` are different — each changes only when the body\ncarries it. An update never writes `allowAccessToAPIM`.\n\n`none` is written by SCIM provisioning for a user who has no account-wide grant; do not send it\nyourself — omit `accessLevel` and use `integrationAccessLevel` for integration-only access.","enum":["monitor","manage","administrator","none"]},"integrationAccessLevel":{"type":"array","description":"Per-integration access levels for the user.\n\nUse this for granting access to specific integrations.\n\n- If `accessLevel` is omitted, this creates **integration-only** access.\n- If `accessLevel` is `monitor`, this grants **elevated access** (typically `manage`) for specific integrations.\n- If `accessLevel` is `manage` or `administrator`, do not set `integrationAccessLevel`.\n\nCleared when omitted on update — send `[]` explicitly only when you mean no per-integration grants.","items":{"type":"object","properties":{"_integrationId":{"type":"string","format":"objectId","description":"Integration ID the user should have access to."},"accessLevel":{"type":"string","description":"Access level for this integration.","enum":["monitor","manage"]}}}},"accountSSORequired":{"type":"boolean","description":"When true, the user must sign in through SSO to access this account. Written\nonly when present in the update body — omitting it on `PUT /v1/ashares/{_id}`\nleaves the stored value unchanged. While the account enforces SSO for every\nuser, the value sent is ignored and the stored value is kept until that\nenforcement is turned off.\n\nWhile SSO applies to the user (here or account-wide) and the account's SSO\nprovider is enabled, requests made through the user's access record — signed in\nto the UI, or with a personal access token, which acts through its creator's\nrecord — are refused with 403 `access_restricted` (\"You are required to sign in\nvia SSO configured for the account to access it.\") when the user's login isn't\nlinked to that provider. Account API tokens don't act through a user's access\nrecord, so SSO settings don't affect them."},"accountMFARequired":{"type":"boolean","description":"When true, MFA is required for this user in this account. Cleared when\nomitted on update — resend it with every `PUT /v1/ashares/{_id}`."},"allowAccessToAPIM":{"type":"boolean","readOnly":true,"description":"When true, the user has been set up in API Management (APIM) for this account. The platform\nsets it the first time an administrator opens API Management; `PUT /v1/ashares/{_id}` never\nwrites it."},"allowToEditRetryData":{"type":"boolean","description":"When true, the user can edit retry data when troubleshooting flow run errors (Error Management).\n\nAll users with **Monitor** access can view, retry, and resolve errant records. This flag controls whether they\ncan also **edit the retry data payload**. If set to false, the user cannot edit retry data for flow runs in any\nintegration workspace where they only have **Monitor** access.\n\nThis setting only applies when:\n- `accessLevel` is `monitor`, or\n- an entry in `integrationAccessLevel` grants `monitor` access for a specific integration.\n\nOn update it changes only when the body carries it, only for such a user, and only when the\nowner or an administrator sends it; omitted, the stored value is kept."},"allowIntegrationWorkspaceCreation":{"type":"boolean","description":"When true, a monitor or integration-level user can create integration workspaces, which\nincludes installing templates. Written on update only when the body carries it, by the\nowner or an administrator; omitted, the stored value is kept."}}},"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."}}}},"GroupMembership":{"type":"object","description":"An end user's membership in a group, with the source that created it.","properties":{"_groupId":{"type":"string","format":"objectId","description":"Group the end user belongs to."},"source":{"type":"string","enum":["manual","idp"],"description":"How the membership was created. IdP-synced memberships cannot be\nremoved through the group members API — change the person's group in\nthe identity provider instead (its group mapping, or the SCIM group\nassignment, whichever created the membership)."}}},"ResourceResponse":{"type":"object","description":"Response","properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Unique identifier for the resource. Format is a 24-character hexadecimal string."},"createdAt":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the resource was created. Set automatically and cannot be modified."},"lastModified":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the resource was last updated. Changes whenever any property is modified."},"deletedAt":{"type":["string","null"],"format":"date-time","readOnly":true,"description":"Timestamp when the resource was soft-deleted. When null or absent, the resource is active."}},"required":["_id"]},"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":{"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"]}}}}}},"paths":{"/v1/ashares":{"get":{"summary":"List users","description":"Returns all users with access to the account. The account owner is\nnot included — only invited users appear. Without `userType` the list\nholds workspace records only; end-user records (MCP-only consumers\nmanaged through the End Users API) are included only when asked for.","operationId":"listUsers","tags":["Users"],"parameters":[{"name":"userType","in":"query","required":false,"schema":{"type":"string","enum":["workspace","end-user","workspace,end-user"]},"description":"Filter by access-record type. `end-user` returns the same records as\n`GET /v1/endusers`, in this API's shape (`sharedWithUser` instead of the\njoined `email` and `name`). Any other value is rejected with 400."}],"responses":{"200":{"description":"All users with access to the account.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/User"}}}}},"204":{"description":"No users exist in the account"},"400":{"description":"`userType` is not one of the accepted values.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/401-unauthorized"}}}}}}
```

## Get a user

> Retrieve a single user's access record by its id. Returns the bare record:\
> the user is identified by \`\_sharedWithUserId\` rather than the expanded\
> \`sharedWithUser\` the list returns, and \`isProductionAdmin\` is not computed.\
> Returns workspace records only — an end-user access-record id is not found\
> here; read those from \`GET /v1/endusers\`.

```json
{"openapi":"3.2.0","info":{"title":"Users","version":"1.0.0"},"tags":[{"name":"Users","description":"Manage user access to a Celigo account. Each record represents a user's\naccess grant, including their access level and invitation status.\n\nAccess is controlled at two levels:\n- **accessLevel** — account-wide role (administrator, manage, monitor, etc.)\n- **integrationAccessLevel** — per-integration overrides for finer control.\n\nThe account owner is not included — only invited users appear, plus any\nthe identity provider provisioned through SCIM (`provisionedBy: scim`).\nUsers can be disabled (reversible) or permanently removed. The license\nsets no user or seat limit.\n\n## User schema\n\n{% openapi-schemas spec=\"user\" schemas=\"User\" 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":{"User":{"type":"object","required":["_id","createdAt","lastModified"],"if":{"properties":{"userType":{"const":"workspace"}}},"then":{"required":["integrationAccessLevel"]},"description":"A user's access record in the account. Each user who has been invited\n(or shared access), or whom the identity provider provisioned through\nSCIM, gets one record per account they belong to. The\n`_id` is the access-record id, not the user's own id — the user's\nidentity is in `sharedWithUser._id` on list and invite responses, and\nin `_sharedWithUserId` on `GET /v1/ashares/{_id}`. The account owner\ndoes not appear in this list.","allOf":[{"$ref":"#/components/schemas/UserBase"},{"type":"object","properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Access-record id for this user in the account."},"_sharedWithUserId":{"type":"string","format":"objectId","readOnly":true,"description":"The user's own account id. Present on `GET /v1/ashares/{_id}`, which\nreturns the bare record; the list and invite responses expand it into\n`sharedWithUser` instead."},"accepted":{"type":"boolean","readOnly":true,"description":"When true, the user has accepted the invitation to join the account."},"disabled":{"type":"boolean","readOnly":true,"description":"When true, the user's access to the account is suspended. Changed\nonly by `PUT /v1/ashares/{_userId}/disable` — a value sent on the\nupdate operation is accepted but not applied."},"userType":{"type":"string","readOnly":true,"enum":["workspace","end-user"],"description":"Discriminates workspace users from end users on the underlying\naccess-record model. An unfiltered list and `GET /v1/ashares/{_id}`\nreturn `workspace` records only; `end-user` records appear in the\nlist only when it is filtered with `userType=end-user` (or\n`workspace,end-user`) and are otherwise managed through the End\nUsers API, which shares the update and disable routes. Sending it\nback on update is rejected."},"lastSignIn":{"type":"string","format":"date-time","readOnly":true,"description":"When the user last signed in to this account."},"dismissed":{"type":"boolean","readOnly":true,"description":"When true, the invitation has been declined by the user."},"isProductionAdmin":{"type":"boolean","readOnly":true,"description":"When true, the user has production-admin privileges in this account."},"createdVia":{"type":"string","readOnly":true,"description":"How this user's access record was created.","enum":["existing_account_invite","existing_account_share_request","invited_during_signup","new_account_auto_join"]},"ssoSetupPending":{"type":"boolean","readOnly":true,"description":"When true, the user must complete SSO setup for this account\nbefore their SSO-required access is fully active. Set by the\nserver during SSO enrollment; cleared by removing the field, so\nit is never `false`."},"provisionedBy":{"type":"string","readOnly":true,"enum":["invite","jit","scim"],"description":"On workspace records, present only when the identity provider\nmanages the user through SCIM; every other workspace record omits\nthe field, so an invited workspace user has no value here rather\nthan `invite`. End-user records (`userType=end-user`) always carry\nit. The identity provider owns a SCIM-managed user's account-wide\naccess level and active state: `PUT /v1/ashares/{_id}` still accepts\na new `accessLevel` and `PUT /v1/ashares/{_userId}/disable` still\ntoggles `disabled`, but the identity provider's next push overwrites\nboth — change them in the IdP. SCIM never sets\n`integrationAccessLevel`, so integration-level grants made here stay."},"externalId":{"type":"string","readOnly":true,"description":"Identifier the identity provider uses for this person in its own\ndirectory, stored when the record is provisioned through SCIM.\nPresent only when `provisionedBy` is `scim`. SCIM matches people by\nemail, not by this value."},"_scimSsoClientId":{"type":"string","format":"objectId","readOnly":true,"description":"SSO client whose SCIM configuration provisioned this record. Present\nonly when `provisionedBy` is `scim`."},"resourceGrants":{"type":"array","readOnly":true,"description":"Present only on end-user records (`userType=end-user`): the MCP\nserver grants held directly by the end user, in addition to any\ngroup- or role-derived access. Replace them with the End Users\nbody on `PUT /v1/ashares/{_ashareId}`.","items":{"$ref":"#/components/schemas/ResourceGrant"}},"groupMemberships":{"type":"array","readOnly":true,"description":"Present only on end-user records that belong to at least one\ngroup. Each entry names the group and whether an administrator or\nthe identity provider created the membership.","items":{"$ref":"#/components/schemas/GroupMembership"}},"_groupIds":{"type":"array","readOnly":true,"description":"Group ids from `groupMemberships`, flattened for quick filtering.\nPresent exactly when `groupMemberships` is.","items":{"type":"string","format":"objectId"}},"sharedWithUser":{"type":"object","readOnly":true,"description":"Identity details of the invited/shared user. Present on the list and\ninvite responses; `GET /v1/ashares/{_id}` returns `_sharedWithUserId`\nin its place.","properties":{"_id":{"type":"string","format":"objectId","description":"The user's own account id."},"email":{"type":"string","format":"email","description":"Email address of the user."},"name":{"type":"string","description":"Display name of the user."},"lastSignIn":{"type":"string","format":"date-time","description":"When the user last signed in (across any account)."},"allowedToResetMFA":{"type":"boolean","description":"When true, the current requester can reset MFA for this user."},"accountSSOLinked":{"type":"string","description":"SSO linkage status for the user in this account.\n`this_account` means SSO is linked to the current account.\n`other_account` means SSO is linked to a different account.","enum":["not_linked","this_account","other_account"]}}}}},{"$ref":"#/components/schemas/ResourceResponse"}]},"UserBase":{"type":"object","description":"Writable fields shared by the request and response schemas.","properties":{"accessLevel":{"type":"string","description":"Account-level access for the user.\n\n**CRITICAL**: This controls account-wide access. Choose your strategy:\n\n- Integration-only access: omit `accessLevel` and specify integrations in `integrationAccessLevel`\n- Account-wide monitoring + selective management: set `accessLevel: monitor` and use `integrationAccessLevel`\n  to grant `manage` access for specific integrations\n- Full account access: set `accessLevel: manage` or `accessLevel: administrator` and leave\n  `integrationAccessLevel` undefined/empty\n\nIf per-integration level permissions are needed, omit `accessLevel` and instead populate `integrationAccessLevel`.\n\nOn update (`PUT /v1/ashares/{_id}`) the body replaces the access settings: `accessLevel`,\n`integrationAccessLevel` and `accountMFARequired` are cleared when omitted, so resend them to keep\nthem. `accountSSORequired`, `allowToEditRetryData`, `allowIntegrationWorkspaceCreation`,\n`mcpServerAccessLevel` and `allMcpServerAccess` are different — each changes only when the body\ncarries it. An update never writes `allowAccessToAPIM`.\n\n`none` is written by SCIM provisioning for a user who has no account-wide grant; do not send it\nyourself — omit `accessLevel` and use `integrationAccessLevel` for integration-only access.","enum":["monitor","manage","administrator","none"]},"integrationAccessLevel":{"type":"array","description":"Per-integration access levels for the user.\n\nUse this for granting access to specific integrations.\n\n- If `accessLevel` is omitted, this creates **integration-only** access.\n- If `accessLevel` is `monitor`, this grants **elevated access** (typically `manage`) for specific integrations.\n- If `accessLevel` is `manage` or `administrator`, do not set `integrationAccessLevel`.\n\nCleared when omitted on update — send `[]` explicitly only when you mean no per-integration grants.","items":{"type":"object","properties":{"_integrationId":{"type":"string","format":"objectId","description":"Integration ID the user should have access to."},"accessLevel":{"type":"string","description":"Access level for this integration.","enum":["monitor","manage"]}}}},"accountSSORequired":{"type":"boolean","description":"When true, the user must sign in through SSO to access this account. Written\nonly when present in the update body — omitting it on `PUT /v1/ashares/{_id}`\nleaves the stored value unchanged. While the account enforces SSO for every\nuser, the value sent is ignored and the stored value is kept until that\nenforcement is turned off.\n\nWhile SSO applies to the user (here or account-wide) and the account's SSO\nprovider is enabled, requests made through the user's access record — signed in\nto the UI, or with a personal access token, which acts through its creator's\nrecord — are refused with 403 `access_restricted` (\"You are required to sign in\nvia SSO configured for the account to access it.\") when the user's login isn't\nlinked to that provider. Account API tokens don't act through a user's access\nrecord, so SSO settings don't affect them."},"accountMFARequired":{"type":"boolean","description":"When true, MFA is required for this user in this account. Cleared when\nomitted on update — resend it with every `PUT /v1/ashares/{_id}`."},"allowAccessToAPIM":{"type":"boolean","readOnly":true,"description":"When true, the user has been set up in API Management (APIM) for this account. The platform\nsets it the first time an administrator opens API Management; `PUT /v1/ashares/{_id}` never\nwrites it."},"allowToEditRetryData":{"type":"boolean","description":"When true, the user can edit retry data when troubleshooting flow run errors (Error Management).\n\nAll users with **Monitor** access can view, retry, and resolve errant records. This flag controls whether they\ncan also **edit the retry data payload**. If set to false, the user cannot edit retry data for flow runs in any\nintegration workspace where they only have **Monitor** access.\n\nThis setting only applies when:\n- `accessLevel` is `monitor`, or\n- an entry in `integrationAccessLevel` grants `monitor` access for a specific integration.\n\nOn update it changes only when the body carries it, only for such a user, and only when the\nowner or an administrator sends it; omitted, the stored value is kept."},"allowIntegrationWorkspaceCreation":{"type":"boolean","description":"When true, a monitor or integration-level user can create integration workspaces, which\nincludes installing templates. Written on update only when the body carries it, by the\nowner or an administrator; omitted, the stored value is kept."}}},"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."}}}},"GroupMembership":{"type":"object","description":"An end user's membership in a group, with the source that created it.","properties":{"_groupId":{"type":"string","format":"objectId","description":"Group the end user belongs to."},"source":{"type":"string","enum":["manual","idp"],"description":"How the membership was created. IdP-synced memberships cannot be\nremoved through the group members API — change the person's group in\nthe identity provider instead (its group mapping, or the SCIM group\nassignment, whichever created the membership)."}}},"ResourceResponse":{"type":"object","description":"Response","properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Unique identifier for the resource. Format is a 24-character hexadecimal string."},"createdAt":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the resource was created. Set automatically and cannot be modified."},"lastModified":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the resource was last updated. Changes whenever any property is modified."},"deletedAt":{"type":["string","null"],"format":"date-time","readOnly":true,"description":"Timestamp when the resource was soft-deleted. When null or absent, the resource is active."}},"required":["_id"]},"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":{"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"]}}}},"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/ashares/{_id}":{"get":{"summary":"Get a user","operationId":"getUser","tags":["Users"],"description":"Retrieve a single user's access record by its id. Returns the bare record:\nthe user is identified by `_sharedWithUserId` rather than the expanded\n`sharedWithUser` the list returns, and `isProductionAdmin` is not computed.\nReturns workspace records only — an end-user access-record id is not found\nhere; read those from `GET /v1/endusers`.","parameters":[{"name":"_id","in":"path","required":true,"description":"User access-record id.","schema":{"type":"string","format":"objectId"}}],"responses":{"200":{"description":"The user record.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/User"}}}},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
```

## Update a user

> Replaces a workspace user's access settings. The body must grant access\
> through \`accessLevel\` or a non-empty \`integrationAccessLevel\`, and\
> \`accessLevel\`, \`integrationAccessLevel\` and \`accountMFARequired\` are\
> cleared when omitted — send every value to keep. The other settings\
> change only when the body carries them and keep their stored values\
> when omitted: \`accountSSORequired\` (also ignored while the account\
> enforces SSO for every user), \`allowToEditRetryData\`,\
> \`allowIntegrationWorkspaceCreation\` (both applied only to monitor and\
> integration-level users, and only when the owner or an administrator\
> sends them), \`mcpServerAccessLevel\` (send \`\[]\` to clear it) and\
> \`allMcpServerAccess\`. \`allowAccessToAPIM\` isn't changed here at all.\
> \`disabled\` is not applied here; toggle it with\
> \`PUT /v1/ashares/{\_userId}/disable\`. Read-only fields echoed from the\
> GET response are ignored, except \`userType\`, which is rejected. The\
> user's email cannot be changed after invite. A production\
> administrator's record can be changed only from production.\
> \
> End-user access records share this route with a different body — see\
> the End Users API.

```json
{"openapi":"3.2.0","info":{"title":"Users","version":"1.0.0"},"tags":[{"name":"Users","description":"Manage user access to a Celigo account. Each record represents a user's\naccess grant, including their access level and invitation status.\n\nAccess is controlled at two levels:\n- **accessLevel** — account-wide role (administrator, manage, monitor, etc.)\n- **integrationAccessLevel** — per-integration overrides for finer control.\n\nThe account owner is not included — only invited users appear, plus any\nthe identity provider provisioned through SCIM (`provisionedBy: scim`).\nUsers can be disabled (reversible) or permanently removed. The license\nsets no user or seat limit.\n\n## User schema\n\n{% openapi-schemas spec=\"user\" schemas=\"User\" 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":{"Request":{"type":"object","description":"Fields that can be sent when inviting or updating an account user.","allOf":[{"$ref":"#/components/schemas/UserBase"}]},"UserBase":{"type":"object","description":"Writable fields shared by the request and response schemas.","properties":{"accessLevel":{"type":"string","description":"Account-level access for the user.\n\n**CRITICAL**: This controls account-wide access. Choose your strategy:\n\n- Integration-only access: omit `accessLevel` and specify integrations in `integrationAccessLevel`\n- Account-wide monitoring + selective management: set `accessLevel: monitor` and use `integrationAccessLevel`\n  to grant `manage` access for specific integrations\n- Full account access: set `accessLevel: manage` or `accessLevel: administrator` and leave\n  `integrationAccessLevel` undefined/empty\n\nIf per-integration level permissions are needed, omit `accessLevel` and instead populate `integrationAccessLevel`.\n\nOn update (`PUT /v1/ashares/{_id}`) the body replaces the access settings: `accessLevel`,\n`integrationAccessLevel` and `accountMFARequired` are cleared when omitted, so resend them to keep\nthem. `accountSSORequired`, `allowToEditRetryData`, `allowIntegrationWorkspaceCreation`,\n`mcpServerAccessLevel` and `allMcpServerAccess` are different — each changes only when the body\ncarries it. An update never writes `allowAccessToAPIM`.\n\n`none` is written by SCIM provisioning for a user who has no account-wide grant; do not send it\nyourself — omit `accessLevel` and use `integrationAccessLevel` for integration-only access.","enum":["monitor","manage","administrator","none"]},"integrationAccessLevel":{"type":"array","description":"Per-integration access levels for the user.\n\nUse this for granting access to specific integrations.\n\n- If `accessLevel` is omitted, this creates **integration-only** access.\n- If `accessLevel` is `monitor`, this grants **elevated access** (typically `manage`) for specific integrations.\n- If `accessLevel` is `manage` or `administrator`, do not set `integrationAccessLevel`.\n\nCleared when omitted on update — send `[]` explicitly only when you mean no per-integration grants.","items":{"type":"object","properties":{"_integrationId":{"type":"string","format":"objectId","description":"Integration ID the user should have access to."},"accessLevel":{"type":"string","description":"Access level for this integration.","enum":["monitor","manage"]}}}},"accountSSORequired":{"type":"boolean","description":"When true, the user must sign in through SSO to access this account. Written\nonly when present in the update body — omitting it on `PUT /v1/ashares/{_id}`\nleaves the stored value unchanged. While the account enforces SSO for every\nuser, the value sent is ignored and the stored value is kept until that\nenforcement is turned off.\n\nWhile SSO applies to the user (here or account-wide) and the account's SSO\nprovider is enabled, requests made through the user's access record — signed in\nto the UI, or with a personal access token, which acts through its creator's\nrecord — are refused with 403 `access_restricted` (\"You are required to sign in\nvia SSO configured for the account to access it.\") when the user's login isn't\nlinked to that provider. Account API tokens don't act through a user's access\nrecord, so SSO settings don't affect them."},"accountMFARequired":{"type":"boolean","description":"When true, MFA is required for this user in this account. Cleared when\nomitted on update — resend it with every `PUT /v1/ashares/{_id}`."},"allowAccessToAPIM":{"type":"boolean","readOnly":true,"description":"When true, the user has been set up in API Management (APIM) for this account. The platform\nsets it the first time an administrator opens API Management; `PUT /v1/ashares/{_id}` never\nwrites it."},"allowToEditRetryData":{"type":"boolean","description":"When true, the user can edit retry data when troubleshooting flow run errors (Error Management).\n\nAll users with **Monitor** access can view, retry, and resolve errant records. This flag controls whether they\ncan also **edit the retry data payload**. If set to false, the user cannot edit retry data for flow runs in any\nintegration workspace where they only have **Monitor** access.\n\nThis setting only applies when:\n- `accessLevel` is `monitor`, or\n- an entry in `integrationAccessLevel` grants `monitor` access for a specific integration.\n\nOn update it changes only when the body carries it, only for such a user, and only when the\nowner or an administrator sends it; omitted, the stored value is kept."},"allowIntegrationWorkspaceCreation":{"type":"boolean","description":"When true, a monitor or integration-level user can create integration workspaces, which\nincludes installing templates. Written on update only when the body carries it, by the\nowner or an administrator; omitted, the stored value is kept."}}},"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":{"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-production-administrator":{"description":"The user is an administrator of the production environment, whose access record is\nrepeated in every environment, and the request came from a non-production environment.\nChange, disable, re-invite or remove a production administrator from production.","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/ashares/{_id}":{"put":{"summary":"Update a user","operationId":"updateUser","tags":["Users"],"description":"Replaces a workspace user's access settings. The body must grant access\nthrough `accessLevel` or a non-empty `integrationAccessLevel`, and\n`accessLevel`, `integrationAccessLevel` and `accountMFARequired` are\ncleared when omitted — send every value to keep. The other settings\nchange only when the body carries them and keep their stored values\nwhen omitted: `accountSSORequired` (also ignored while the account\nenforces SSO for every user), `allowToEditRetryData`,\n`allowIntegrationWorkspaceCreation` (both applied only to monitor and\nintegration-level users, and only when the owner or an administrator\nsends them), `mcpServerAccessLevel` (send `[]` to clear it) and\n`allMcpServerAccess`. `allowAccessToAPIM` isn't changed here at all.\n`disabled` is not applied here; toggle it with\n`PUT /v1/ashares/{_userId}/disable`. Read-only fields echoed from the\nGET response are ignored, except `userType`, which is rejected. The\nuser's email cannot be changed after invite. A production\nadministrator's record can be changed only from production.\n\nEnd-user access records share this route with a different body — see\nthe End Users API.","parameters":[{"name":"_id","in":"path","required":true,"description":"User access-record id.","schema":{"type":"string","format":"objectId"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Request"}}}},"responses":{"204":{"description":"User updated."},"400":{"description":"The body grants no access, or echoes the read-only `userType`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/401-unauthorized"},"403":{"$ref":"#/components/responses/403-production-administrator"},"404":{"$ref":"#/components/responses/404-not-found"},"422":{"description":"`integrationAccessLevel` is empty and no `accessLevel` was sent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

## Delete a user

> Remove a user from the current account. This is irreversible — for a\
> reversible alternative, use \`PUT /v1/ashares/{\_id}/disable\`. Works\
> on both accepted and pending invites.

```json
{"openapi":"3.2.0","info":{"title":"Users","version":"1.0.0"},"tags":[{"name":"Users","description":"Manage user access to a Celigo account. Each record represents a user's\naccess grant, including their access level and invitation status.\n\nAccess is controlled at two levels:\n- **accessLevel** — account-wide role (administrator, manage, monitor, etc.)\n- **integrationAccessLevel** — per-integration overrides for finer control.\n\nThe account owner is not included — only invited users appear, plus any\nthe identity provider provisioned through SCIM (`provisionedBy: scim`).\nUsers can be disabled (reversible) or permanently removed. The license\nsets no user or seat limit.\n\n## User schema\n\n{% openapi-schemas spec=\"user\" schemas=\"User\" 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":{"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-production-administrator":{"description":"The user is an administrator of the production environment, whose access record is\nrepeated in every environment, and the request came from a non-production environment.\nChange, disable, re-invite or remove a production administrator from production.","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/ashares/{_id}":{"delete":{"summary":"Delete a user","operationId":"deleteUser","tags":["Users"],"description":"Remove a user from the current account. This is irreversible — for a\nreversible alternative, use `PUT /v1/ashares/{_id}/disable`. Works\non both accepted and pending invites.","parameters":[{"name":"_id","in":"path","required":true,"description":"User access-record id.","schema":{"type":"string","format":"objectId"}}],"responses":{"204":{"description":"User removed from the account."},"401":{"$ref":"#/components/responses/401-unauthorized"},"403":{"$ref":"#/components/responses/403-production-administrator"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
```

## Toggle a user's account access (disable or re-enable)

> Toggles the \`disabled\` flag on a user's access record. Call again to\
> re-enable — there is no separate \`/enable\` path, and this is the only\
> way to change \`disabled\` (the update operation does not apply it). Only\
> an accepted workspace invitation toggles: a pending one is refused with\
> 400, and a declined one (\`dismissed: true\`) answers 204 without changing\
> anything — delete it, or re-send it with\
> \`PUT /v1/ashares/{\_id}/reinvite\`. The\
> user is emailed on every toggle. Disabling a production administrator\
> also disables their records in the other environments, and only\
> production can toggle one.\
> \
> End-user access records share this route — see the End Users API.

```json
{"openapi":"3.2.0","info":{"title":"Users","version":"1.0.0"},"tags":[{"name":"Users","description":"Manage user access to a Celigo account. Each record represents a user's\naccess grant, including their access level and invitation status.\n\nAccess is controlled at two levels:\n- **accessLevel** — account-wide role (administrator, manage, monitor, etc.)\n- **integrationAccessLevel** — per-integration overrides for finer control.\n\nThe account owner is not included — only invited users appear, plus any\nthe identity provider provisioned through SCIM (`provisionedBy: scim`).\nUsers can be disabled (reversible) or permanently removed. The license\nsets no user or seat limit.\n\n## User schema\n\n{% openapi-schemas spec=\"user\" schemas=\"User\" 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":{"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":{"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-production-administrator":{"description":"The user is an administrator of the production environment, whose access record is\nrepeated in every environment, and the request came from a non-production environment.\nChange, disable, re-invite or remove a production administrator from production.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v1/ashares/{_userId}/disable":{"put":{"operationId":"toggleUserDisabled","tags":["Users"],"summary":"Toggle a user's account access (disable or re-enable)","description":"Toggles the `disabled` flag on a user's access record. Call again to\nre-enable — there is no separate `/enable` path, and this is the only\nway to change `disabled` (the update operation does not apply it). Only\nan accepted workspace invitation toggles: a pending one is refused with\n400, and a declined one (`dismissed: true`) answers 204 without changing\nanything — delete it, or re-send it with\n`PUT /v1/ashares/{_id}/reinvite`. The\nuser is emailed on every toggle. Disabling a production administrator\nalso disables their records in the other environments, and only\nproduction can toggle one.\n\nEnd-user access records share this route — see the End Users API.","parameters":[{"name":"_userId","in":"path","required":true,"description":"The ashare record `_id` from `GET /v1/ashares` — despite the\nparameter name, this is NOT `sharedWithUser._id`.","schema":{"type":"string","format":"objectId"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","description":"Empty body — the target is identified by the path parameter alone."}}}},"responses":{"204":{"description":"User access toggled, or the invitation was declined and nothing changed."},"400":{"description":"The invitation is still pending.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/401-unauthorized"},"403":{"$ref":"#/components/responses/403-production-administrator"},"404":{"description":"User not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

## Reinvite a user who dismissed their invite

> Re-sends the invitation to a user who previously dismissed it. Only\
> works on users with \`dismissed: true\` in the user record. After\
> reinviting, the user returns to a pending state awaiting acceptance.\
> \
> There is no re-send for an invitation that is still pending: this\
> route refuses it, and inviting the address again answers\
> \`invalid\_invite\`. Delete the pending record and invite the address\
> again with the same access settings.

```json
{"openapi":"3.2.0","info":{"title":"Users","version":"1.0.0"},"tags":[{"name":"Users","description":"Manage user access to a Celigo account. Each record represents a user's\naccess grant, including their access level and invitation status.\n\nAccess is controlled at two levels:\n- **accessLevel** — account-wide role (administrator, manage, monitor, etc.)\n- **integrationAccessLevel** — per-integration overrides for finer control.\n\nThe account owner is not included — only invited users appear, plus any\nthe identity provider provisioned through SCIM (`provisionedBy: scim`).\nUsers can be disabled (reversible) or permanently removed. The license\nsets no user or seat limit.\n\n## User schema\n\n{% openapi-schemas spec=\"user\" schemas=\"User\" 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":{"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":{"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-production-administrator":{"description":"The user is an administrator of the production environment, whose access record is\nrepeated in every environment, and the request came from a non-production environment.\nChange, disable, re-invite or remove a production administrator from production.","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/ashares/{_id}/reinvite":{"put":{"summary":"Reinvite a user who dismissed their invite","description":"Re-sends the invitation to a user who previously dismissed it. Only\nworks on users with `dismissed: true` in the user record. After\nreinviting, the user returns to a pending state awaiting acceptance.\n\nThere is no re-send for an invitation that is still pending: this\nroute refuses it, and inviting the address again answers\n`invalid_invite`. Delete the pending record and invite the address\nagain with the same access settings.","operationId":"reinviteUser","tags":["Users"],"parameters":[{"name":"_id","in":"path","required":true,"description":"User access-record id.","schema":{"type":"string","format":"objectId"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","description":"Empty body."}}}},"responses":{"204":{"description":"Reinvitation sent."},"400":{"description":"User has not dismissed the invite.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/401-unauthorized"},"403":{"$ref":"#/components/responses/403-production-administrator"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
```

## Accept an account invitation

> Accepts an invitation to another user's account on behalf of the caller.\
> The \`\_id\` is a share record addressed \*to\* the caller — take it from\
> \`GET /v1/shared/ashares\`, not from \`GET /v1/ashares\`. Pending invitations\
> from the same owner's other environments are accepted with it, and the\
> owner is notified by email. Accepting an invitation that is already\
> accepted changes nothing. A user who still owns integrations, flows, or\
> syncs must transfer or delete them before they can join another account.

```json
{"openapi":"3.2.0","info":{"title":"Users","version":"1.0.0"},"tags":[{"name":"Users","description":"Manage user access to a Celigo account. Each record represents a user's\naccess grant, including their access level and invitation status.\n\nAccess is controlled at two levels:\n- **accessLevel** — account-wide role (administrator, manage, monitor, etc.)\n- **integrationAccessLevel** — per-integration overrides for finer control.\n\nThe account owner is not included — only invited users appear, plus any\nthe identity provider provisioned through SCIM (`provisionedBy: scim`).\nUsers can be disabled (reversible) or permanently removed. The license\nsets no user or seat limit.\n\n## User schema\n\n{% openapi-schemas spec=\"user\" schemas=\"User\" 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":{"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"]}}}}},"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/ashares/{_id}/accept":{"put":{"summary":"Accept an account invitation","operationId":"acceptAccountInvitation","tags":["Users"],"description":"Accepts an invitation to another user's account on behalf of the caller.\nThe `_id` is a share record addressed *to* the caller — take it from\n`GET /v1/shared/ashares`, not from `GET /v1/ashares`. Pending invitations\nfrom the same owner's other environments are accepted with it, and the\nowner is notified by email. Accepting an invitation that is already\naccepted changes nothing. A user who still owns integrations, flows, or\nsyncs must transfer or delete them before they can join another account.","parameters":[{"name":"_id","in":"path","required":true,"description":"Share record id from `GET /v1/shared/ashares`.","schema":{"type":"string","format":"objectId"}}],"responses":{"204":{"description":"Invitation accepted (or already accepted)."},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"description":"No share with this id is addressed to the caller.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

## Dismiss an account invitation

> Declines an invitation to another user's account on behalf of the caller.\
> The \`\_id\` is a share record addressed \*to\* the caller — take it from\
> \`GET /v1/shared/ashares\`. Pending invitations from the same owner's other\
> environments are dismissed with it, and the owner is notified by email;\
> they can send it again with \`PUT /v1/ashares/{\_id}/reinvite\`. Dismissing\
> an invitation that is already dismissed changes nothing. To leave an\
> account whose invitation you accepted, use \`DELETE /v1/shared/ashares/{\_id}\`.

```json
{"openapi":"3.2.0","info":{"title":"Users","version":"1.0.0"},"tags":[{"name":"Users","description":"Manage user access to a Celigo account. Each record represents a user's\naccess grant, including their access level and invitation status.\n\nAccess is controlled at two levels:\n- **accessLevel** — account-wide role (administrator, manage, monitor, etc.)\n- **integrationAccessLevel** — per-integration overrides for finer control.\n\nThe account owner is not included — only invited users appear, plus any\nthe identity provider provisioned through SCIM (`provisionedBy: scim`).\nUsers can be disabled (reversible) or permanently removed. The license\nsets no user or seat limit.\n\n## User schema\n\n{% openapi-schemas spec=\"user\" schemas=\"User\" 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":{"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"]}}}}},"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/ashares/{_id}/dismiss":{"put":{"summary":"Dismiss an account invitation","operationId":"dismissAccountInvitation","tags":["Users"],"description":"Declines an invitation to another user's account on behalf of the caller.\nThe `_id` is a share record addressed *to* the caller — take it from\n`GET /v1/shared/ashares`. Pending invitations from the same owner's other\nenvironments are dismissed with it, and the owner is notified by email;\nthey can send it again with `PUT /v1/ashares/{_id}/reinvite`. Dismissing\nan invitation that is already dismissed changes nothing. To leave an\naccount whose invitation you accepted, use `DELETE /v1/shared/ashares/{_id}`.","parameters":[{"name":"_id","in":"path","required":true,"description":"Share record id from `GET /v1/shared/ashares`.","schema":{"type":"string","format":"objectId"}}],"responses":{"204":{"description":"Invitation dismissed (or already dismissed)."},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"description":"No share with this id is addressed to the caller.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

## Invite users to the account

> Invite one or more users by email. Each entry in the response array\
> corresponds to the email at the same index — check \`statusCode\` per\
> entry for partial failures.\
> \
> An address that already has an access record in this environment —\
> accepted, still pending, or declined — fails in its entry with 400\
> \`invalid\_invite\`: nothing changes and no email is sent. Change an\
> existing user with \`PUT /v1/ashares/{\_id}\`, and re-send a declined\
> invitation with \`PUT /v1/ashares/{\_id}/reinvite\`. A pending\
> invitation has no re-send: delete it and invite the address again.\
> \
> Each call takes at most five addresses; the account itself has no user\
> limit.

```json
{"openapi":"3.2.0","info":{"title":"Users","version":"1.0.0"},"tags":[{"name":"Users","description":"Manage user access to a Celigo account. Each record represents a user's\naccess grant, including their access level and invitation status.\n\nAccess is controlled at two levels:\n- **accessLevel** — account-wide role (administrator, manage, monitor, etc.)\n- **integrationAccessLevel** — per-integration overrides for finer control.\n\nThe account owner is not included — only invited users appear, plus any\nthe identity provider provisioned through SCIM (`provisionedBy: scim`).\nUsers can be disabled (reversible) or permanently removed. The license\nsets no user or seat limit.\n\n## User schema\n\n{% openapi-schemas spec=\"user\" schemas=\"User\" 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":{"InviteRequest":{"description":"Request body for inviting users to the account. Extends the base\nuser request with email fields. Access settings apply uniformly\nto all emails in a batch invite.","allOf":[{"$ref":"#/components/schemas/Request"},{"type":"object","properties":{"email":{"type":"string","format":"email","description":"Single email address to invite (use with `POST /v1/invite`)."},"emails":{"type":"array","minItems":1,"maxItems":5,"uniqueItems":true,"description":"Email addresses to invite (use with `POST /v1/invite/multiple`): one to five\ndistinct addresses. An empty list, more than five, or a repeated address refuses\nthe whole request with 403 (`no_emails`, `limit_exceeded`, `duplicate_emails`).","items":{"type":"string","format":"email"}}}}]},"Request":{"type":"object","description":"Fields that can be sent when inviting or updating an account user.","allOf":[{"$ref":"#/components/schemas/UserBase"}]},"UserBase":{"type":"object","description":"Writable fields shared by the request and response schemas.","properties":{"accessLevel":{"type":"string","description":"Account-level access for the user.\n\n**CRITICAL**: This controls account-wide access. Choose your strategy:\n\n- Integration-only access: omit `accessLevel` and specify integrations in `integrationAccessLevel`\n- Account-wide monitoring + selective management: set `accessLevel: monitor` and use `integrationAccessLevel`\n  to grant `manage` access for specific integrations\n- Full account access: set `accessLevel: manage` or `accessLevel: administrator` and leave\n  `integrationAccessLevel` undefined/empty\n\nIf per-integration level permissions are needed, omit `accessLevel` and instead populate `integrationAccessLevel`.\n\nOn update (`PUT /v1/ashares/{_id}`) the body replaces the access settings: `accessLevel`,\n`integrationAccessLevel` and `accountMFARequired` are cleared when omitted, so resend them to keep\nthem. `accountSSORequired`, `allowToEditRetryData`, `allowIntegrationWorkspaceCreation`,\n`mcpServerAccessLevel` and `allMcpServerAccess` are different — each changes only when the body\ncarries it. An update never writes `allowAccessToAPIM`.\n\n`none` is written by SCIM provisioning for a user who has no account-wide grant; do not send it\nyourself — omit `accessLevel` and use `integrationAccessLevel` for integration-only access.","enum":["monitor","manage","administrator","none"]},"integrationAccessLevel":{"type":"array","description":"Per-integration access levels for the user.\n\nUse this for granting access to specific integrations.\n\n- If `accessLevel` is omitted, this creates **integration-only** access.\n- If `accessLevel` is `monitor`, this grants **elevated access** (typically `manage`) for specific integrations.\n- If `accessLevel` is `manage` or `administrator`, do not set `integrationAccessLevel`.\n\nCleared when omitted on update — send `[]` explicitly only when you mean no per-integration grants.","items":{"type":"object","properties":{"_integrationId":{"type":"string","format":"objectId","description":"Integration ID the user should have access to."},"accessLevel":{"type":"string","description":"Access level for this integration.","enum":["monitor","manage"]}}}},"accountSSORequired":{"type":"boolean","description":"When true, the user must sign in through SSO to access this account. Written\nonly when present in the update body — omitting it on `PUT /v1/ashares/{_id}`\nleaves the stored value unchanged. While the account enforces SSO for every\nuser, the value sent is ignored and the stored value is kept until that\nenforcement is turned off.\n\nWhile SSO applies to the user (here or account-wide) and the account's SSO\nprovider is enabled, requests made through the user's access record — signed in\nto the UI, or with a personal access token, which acts through its creator's\nrecord — are refused with 403 `access_restricted` (\"You are required to sign in\nvia SSO configured for the account to access it.\") when the user's login isn't\nlinked to that provider. Account API tokens don't act through a user's access\nrecord, so SSO settings don't affect them."},"accountMFARequired":{"type":"boolean","description":"When true, MFA is required for this user in this account. Cleared when\nomitted on update — resend it with every `PUT /v1/ashares/{_id}`."},"allowAccessToAPIM":{"type":"boolean","readOnly":true,"description":"When true, the user has been set up in API Management (APIM) for this account. The platform\nsets it the first time an administrator opens API Management; `PUT /v1/ashares/{_id}` never\nwrites it."},"allowToEditRetryData":{"type":"boolean","description":"When true, the user can edit retry data when troubleshooting flow run errors (Error Management).\n\nAll users with **Monitor** access can view, retry, and resolve errant records. This flag controls whether they\ncan also **edit the retry data payload**. If set to false, the user cannot edit retry data for flow runs in any\nintegration workspace where they only have **Monitor** access.\n\nThis setting only applies when:\n- `accessLevel` is `monitor`, or\n- an entry in `integrationAccessLevel` grants `monitor` access for a specific integration.\n\nOn update it changes only when the body carries it, only for such a user, and only when the\nowner or an administrator sends it; omitted, the stored value is kept."},"allowIntegrationWorkspaceCreation":{"type":"boolean","description":"When true, a monitor or integration-level user can create integration workspaces, which\nincludes installing templates. Written on update only when the body carries it, by the\nowner or an administrator; omitted, the stored value is kept."}}},"User":{"type":"object","required":["_id","createdAt","lastModified"],"if":{"properties":{"userType":{"const":"workspace"}}},"then":{"required":["integrationAccessLevel"]},"description":"A user's access record in the account. Each user who has been invited\n(or shared access), or whom the identity provider provisioned through\nSCIM, gets one record per account they belong to. The\n`_id` is the access-record id, not the user's own id — the user's\nidentity is in `sharedWithUser._id` on list and invite responses, and\nin `_sharedWithUserId` on `GET /v1/ashares/{_id}`. The account owner\ndoes not appear in this list.","allOf":[{"$ref":"#/components/schemas/UserBase"},{"type":"object","properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Access-record id for this user in the account."},"_sharedWithUserId":{"type":"string","format":"objectId","readOnly":true,"description":"The user's own account id. Present on `GET /v1/ashares/{_id}`, which\nreturns the bare record; the list and invite responses expand it into\n`sharedWithUser` instead."},"accepted":{"type":"boolean","readOnly":true,"description":"When true, the user has accepted the invitation to join the account."},"disabled":{"type":"boolean","readOnly":true,"description":"When true, the user's access to the account is suspended. Changed\nonly by `PUT /v1/ashares/{_userId}/disable` — a value sent on the\nupdate operation is accepted but not applied."},"userType":{"type":"string","readOnly":true,"enum":["workspace","end-user"],"description":"Discriminates workspace users from end users on the underlying\naccess-record model. An unfiltered list and `GET /v1/ashares/{_id}`\nreturn `workspace` records only; `end-user` records appear in the\nlist only when it is filtered with `userType=end-user` (or\n`workspace,end-user`) and are otherwise managed through the End\nUsers API, which shares the update and disable routes. Sending it\nback on update is rejected."},"lastSignIn":{"type":"string","format":"date-time","readOnly":true,"description":"When the user last signed in to this account."},"dismissed":{"type":"boolean","readOnly":true,"description":"When true, the invitation has been declined by the user."},"isProductionAdmin":{"type":"boolean","readOnly":true,"description":"When true, the user has production-admin privileges in this account."},"createdVia":{"type":"string","readOnly":true,"description":"How this user's access record was created.","enum":["existing_account_invite","existing_account_share_request","invited_during_signup","new_account_auto_join"]},"ssoSetupPending":{"type":"boolean","readOnly":true,"description":"When true, the user must complete SSO setup for this account\nbefore their SSO-required access is fully active. Set by the\nserver during SSO enrollment; cleared by removing the field, so\nit is never `false`."},"provisionedBy":{"type":"string","readOnly":true,"enum":["invite","jit","scim"],"description":"On workspace records, present only when the identity provider\nmanages the user through SCIM; every other workspace record omits\nthe field, so an invited workspace user has no value here rather\nthan `invite`. End-user records (`userType=end-user`) always carry\nit. The identity provider owns a SCIM-managed user's account-wide\naccess level and active state: `PUT /v1/ashares/{_id}` still accepts\na new `accessLevel` and `PUT /v1/ashares/{_userId}/disable` still\ntoggles `disabled`, but the identity provider's next push overwrites\nboth — change them in the IdP. SCIM never sets\n`integrationAccessLevel`, so integration-level grants made here stay."},"externalId":{"type":"string","readOnly":true,"description":"Identifier the identity provider uses for this person in its own\ndirectory, stored when the record is provisioned through SCIM.\nPresent only when `provisionedBy` is `scim`. SCIM matches people by\nemail, not by this value."},"_scimSsoClientId":{"type":"string","format":"objectId","readOnly":true,"description":"SSO client whose SCIM configuration provisioned this record. Present\nonly when `provisionedBy` is `scim`."},"resourceGrants":{"type":"array","readOnly":true,"description":"Present only on end-user records (`userType=end-user`): the MCP\nserver grants held directly by the end user, in addition to any\ngroup- or role-derived access. Replace them with the End Users\nbody on `PUT /v1/ashares/{_ashareId}`.","items":{"$ref":"#/components/schemas/ResourceGrant"}},"groupMemberships":{"type":"array","readOnly":true,"description":"Present only on end-user records that belong to at least one\ngroup. Each entry names the group and whether an administrator or\nthe identity provider created the membership.","items":{"$ref":"#/components/schemas/GroupMembership"}},"_groupIds":{"type":"array","readOnly":true,"description":"Group ids from `groupMemberships`, flattened for quick filtering.\nPresent exactly when `groupMemberships` is.","items":{"type":"string","format":"objectId"}},"sharedWithUser":{"type":"object","readOnly":true,"description":"Identity details of the invited/shared user. Present on the list and\ninvite responses; `GET /v1/ashares/{_id}` returns `_sharedWithUserId`\nin its place.","properties":{"_id":{"type":"string","format":"objectId","description":"The user's own account id."},"email":{"type":"string","format":"email","description":"Email address of the user."},"name":{"type":"string","description":"Display name of the user."},"lastSignIn":{"type":"string","format":"date-time","description":"When the user last signed in (across any account)."},"allowedToResetMFA":{"type":"boolean","description":"When true, the current requester can reset MFA for this user."},"accountSSOLinked":{"type":"string","description":"SSO linkage status for the user in this account.\n`this_account` means SSO is linked to the current account.\n`other_account` means SSO is linked to a different account.","enum":["not_linked","this_account","other_account"]}}}}},{"$ref":"#/components/schemas/ResourceResponse"}]},"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."}}}},"GroupMembership":{"type":"object","description":"An end user's membership in a group, with the source that created it.","properties":{"_groupId":{"type":"string","format":"objectId","description":"Group the end user belongs to."},"source":{"type":"string","enum":["manual","idp"],"description":"How the membership was created. IdP-synced memberships cannot be\nremoved through the group members API — change the person's group in\nthe identity provider instead (its group mapping, or the SCIM group\nassignment, whichever created the membership)."}}},"ResourceResponse":{"type":"object","description":"Response","properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Unique identifier for the resource. Format is a 24-character hexadecimal string."},"createdAt":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the resource was created. Set automatically and cannot be modified."},"lastModified":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the resource was last updated. Changes whenever any property is modified."},"deletedAt":{"type":["string","null"],"format":"date-time","readOnly":true,"description":"Timestamp when the resource was soft-deleted. When null or absent, the resource is active."}},"required":["_id"]},"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"]}}}}}},"paths":{"/v1/invite/multiple":{"post":{"summary":"Invite users to the account","description":"Invite one or more users by email. Each entry in the response array\ncorresponds to the email at the same index — check `statusCode` per\nentry for partial failures.\n\nAn address that already has an access record in this environment —\naccepted, still pending, or declined — fails in its entry with 400\n`invalid_invite`: nothing changes and no email is sent. Change an\nexisting user with `PUT /v1/ashares/{_id}`, and re-send a declined\ninvitation with `PUT /v1/ashares/{_id}/reinvite`. A pending\ninvitation has no re-send: delete it and invite the address again.\n\nEach call takes at most five addresses; the account itself has no user\nlimit.","operationId":"inviteUsers","tags":["Users"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InviteRequest"}}}},"responses":{"200":{"description":"Array of results, one per email.","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"statusCode":{"type":"integer","description":"Per-entry result code. `201` on success; `400`\n(`invalid_invite`) if the address already has an access\nrecord in this environment. For an accepted user, change\naccess with `PUT /v1/ashares/{_id}`; re-send a declined\ninvitation with `PUT /v1/ashares/{_id}/reinvite`; a\npending invitation can't be re-sent (delete it and invite\nagain)."},"doc":{"$ref":"#/components/schemas/User"},"errors":{"type":"array","description":"Why this address failed. Present instead of `doc` when `statusCode` isn't `201`.","items":{"type":"object","properties":{"code":{"type":"string","description":"Machine-readable error code, such as `invalid_invite`."},"message":{"type":"string","description":"Human-readable description of the error."}}}}}}}}}},"400":{"$ref":"#/components/responses/400-bad-request"},"401":{"$ref":"#/components/responses/401-unauthorized"},"403":{"description":"`emails` is empty, holds more than five addresses, or repeats one; nothing is\ninvited. Also returned when the caller may not invite users.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```
