From 2bdcb413f0d3d2306ecd0bebd12189a7fd3270cb Mon Sep 17 00:00:00 2001 From: ajkamen Date: Wed, 27 May 2026 10:26:33 -0700 Subject: [PATCH 1/9] gitignore update --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 8f60e1e..70da55e 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,4 @@ code-samples/**/obj/* *.sln .idea/ *.iml +engage-voice-api-docs.code-workspace From 2362c2278454cabbababbbc5208ed1873a39bf45 Mon Sep 17 00:00:00 2001 From: ajkamen Date: Wed, 27 May 2026 10:47:34 -0700 Subject: [PATCH 2/9] docs: add admin users and permissions guide Document user, role, rights document, and auth utility APIs with reference entries. --- docs/users/admin-users-and-permissions.md | 70 + mkdocs.yml | 1 + specs/engage-voice_openapi3.json | 3216 ++++++++++++++++++++- 3 files changed, 3142 insertions(+), 145 deletions(-) create mode 100644 docs/users/admin-users-and-permissions.md diff --git a/docs/users/admin-users-and-permissions.md b/docs/users/admin-users-and-permissions.md new file mode 100644 index 0000000..8713089 --- /dev/null +++ b/docs/users/admin-users-and-permissions.md @@ -0,0 +1,70 @@ +# Admin User and Permission APIs + +The Admin User and Permission APIs let you manage RingCX administrative users, role assignments, rights documents, API tokens, and account-level authentication checks. Use them when user and permission changes are driven by an external identity or governance process. + +## Strategic Overview + +Agents and administrators are related but not identical. Agent APIs manage contact-center users who handle interactions. Admin user and permission APIs manage access to the Admin portal and administrative API capabilities. + +### Key Use Cases + +* **User Governance:** List users and inspect effective permissions for audits. +* **Role Automation:** Add or remove platform roles during onboarding and offboarding. +* **Rights Document Management:** Create or update rights documents that define administrative access. +* **Auth Utilities:** Validate tokens and support password reset workflows. + +### Required Permissions & Scopes + +Your application needs the `ReadAccounts` OAuth scope. The authenticating user must have sufficient platform permissions to read users and update roles or rights documents. + +## Users + +| Operation | Method and Path | API Reference | +| --- | --- | --- | +| List users | `GET /voice/api/v1/admin/users` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/getUserList) | +| Create user | `POST /voice/api/v1/admin/users` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/createUser) | +| Get user | `GET /voice/api/v1/admin/users/{userId}` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/getUser) | +| Update user | `PUT /voice/api/v1/admin/users/{userId}` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/updateUser) | +| Delete user | `DELETE /voice/api/v1/admin/users/{userId}` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/deleteUser) | + +## Roles + +Roles are coarse-grained access assignments. Use role endpoints for straightforward role membership changes. + +| Operation | Method and Path | API Reference | +| --- | --- | --- | +| List user roles | `GET /voice/api/v1/admin/users/{userId}/roles` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/getRoles) | +| Add role | `POST /voice/api/v1/admin/users/{userId}/roles/{roleType}` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/addRole) | +| Remove role | `DELETE /voice/api/v1/admin/users/{userId}/roles/{roleType}` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/removeRole) | + +## Rights Documents + +Rights documents provide detailed administrative permissions. Use these endpoints for advanced permission management or audit tooling. + +| Operation | Method and Path | API Reference | +| --- | --- | --- | +| List rights docs | `GET /voice/api/v1/admin/users/{userId}/rightsDocs` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/getRightsDocs) | +| Create rights doc | `POST /voice/api/v1/admin/users/{userId}/rightsDocs` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/createRightsDoc) | +| Update rights doc | `PUT /voice/api/v1/admin/users/{userId}/rightsDocs/{rightsDocId}` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/updateRightsDoc) | +| Delete rights doc | `DELETE /voice/api/v1/admin/users/{userId}/rightsDocs/{rightsDocId}` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/deleteRightsDoc) | +| Assign rights doc | `POST /voice/api/v1/admin/rightsDocs/{rightsDocId}/assignments` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/assignRightsDoc) | +| Delete assignment | `DELETE /voice/api/v1/admin/rightsDocs/{rightsDocId}/assignments/{assignedUserId}` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/deleteRightsDocAssignment) | + +## Auth Utilities + +| Operation | Method and Path | API Reference | +| --- | --- | --- | +| Validate token | `GET /voice/api/v1/auth/isTokenValid` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/isTokenValid) | +| Reset password | `POST /voice/api/v1/auth/passwordReset` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/passwordReset) | +| Request password reset | `POST /voice/api/v1/auth/passwordResetRequest` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/passwordResetRequest) | + +## Recommended Workflow + +1. List or create the user. +2. Apply required roles for broad access. +3. Create or assign rights documents for detailed access. +4. Verify effective access by reading assigned and aggregated rights documents. +5. Remove roles and rights document assignments during offboarding. + +!!! warning + Permission changes can grant administrative access to customer data and configuration. Apply least privilege and log all automated changes for audit review. diff --git a/mkdocs.yml b/mkdocs.yml index e455d6b..5bdc8c9 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -69,6 +69,7 @@ nav: - 'Active Calls': dialing/active-calls/index.md - 'Users': - 'Overview': users/agents/index.md + - 'Admin Users and Permissions': users/admin-users-and-permissions.md - 'Agents': - 'Agents': users/agents/agents.md - 'Agent Groups': users/agents/agent-groups.md diff --git a/specs/engage-voice_openapi3.json b/specs/engage-voice_openapi3.json index 4d0eb35..d5bf910 100644 --- a/specs/engage-voice_openapi3.json +++ b/specs/engage-voice_openapi3.json @@ -14446,34 +14446,91 @@ "WEMDialogSegmentMetaData": { "type": "object", "properties": { - "subAccountId": { "type": "string" }, - "dialogId": { "type": "string" }, - "interactionId": { "type": "string" }, - "channelId": { "type": "string" }, - "channelType": { "type": "string" }, - "channelClass": { "type": "string" }, - "channelEndpointAddress": { "type": "string" }, - "contactEndpointAddress": { "type": "string" }, - "dialogOrigination": { "type": "string" }, - "dialogStartTimeMs": { "type": "string", "format": "date-time" }, - "dialogEndTimeMs": { "type": "string", "format": "date-time" }, - "dialogDurationMs": { "type": "integer" }, - "segmentId": { "type": "string" }, - "segmentType": { "type": "string" }, - "segmentParticipantId": { "type": "string" }, - "segmentParticipantRcExtensionId": { "type": "string" }, - "segmentStartTimeMs": { "type": "string", "format": "date-time" }, - "segmentEndTimeMs": { "type": "string", "format": "date-time" }, - "segmentDurationMs": { "type": "integer" }, - "segmentAgentGroupId": { "type": "string" }, - "systemDisposition": { "type": "string", "nullable": true }, - "agentDisposition": { "type": "string" }, - "agentNotes": { "type": "string" }, - "hasRecording": { "type": "boolean" }, - "hasTranscript": { "type": "boolean" }, + "subAccountId": { + "type": "string" + }, + "dialogId": { + "type": "string" + }, + "interactionId": { + "type": "string" + }, + "channelId": { + "type": "string" + }, + "channelType": { + "type": "string" + }, + "channelClass": { + "type": "string" + }, + "channelEndpointAddress": { + "type": "string" + }, + "contactEndpointAddress": { + "type": "string" + }, + "dialogOrigination": { + "type": "string" + }, + "dialogStartTimeMs": { + "type": "string", + "format": "date-time" + }, + "dialogEndTimeMs": { + "type": "string", + "format": "date-time" + }, + "dialogDurationMs": { + "type": "integer" + }, + "segmentId": { + "type": "string" + }, + "segmentType": { + "type": "string" + }, + "segmentParticipantId": { + "type": "string" + }, + "segmentParticipantRcExtensionId": { + "type": "string" + }, + "segmentStartTimeMs": { + "type": "string", + "format": "date-time" + }, + "segmentEndTimeMs": { + "type": "string", + "format": "date-time" + }, + "segmentDurationMs": { + "type": "integer" + }, + "segmentAgentGroupId": { + "type": "string" + }, + "systemDisposition": { + "type": "string", + "nullable": true + }, + "agentDisposition": { + "type": "string" + }, + "agentNotes": { + "type": "string" + }, + "hasRecording": { + "type": "boolean" + }, + "hasTranscript": { + "type": "boolean" + }, "segmentEvents": { "type": "array", - "items": { "$ref": "#/components/schemas/InteractionSegmentEvent" }, + "items": { + "$ref": "#/components/schemas/InteractionSegmentEvent" + }, "nullable": true } } @@ -14522,60 +14579,185 @@ "AggregatedAgentStats": { "type": "object", "properties": { - "interval": { "type": "integer", "format": "int32" }, - "dateTimeFrom": { "type": "string" }, - "agentId": { "type": "integer", "format": "int32" }, - "agentName": { "type": "string" }, - "availDur": { "type": "integer", "format": "int32" }, - "totWorkDur": { "type": "integer", "format": "int32" }, - "pauseDur": { "type": "integer", "format": "int32" }, - "waitDur": { "type": "integer", "format": "int32" }, - "adminDur": { "type": "integer", "format": "int32" }, - "directOutIxnCnt": { "type": "integer", "format": "int32" }, - "directOutIxnDur": { "type": "integer", "format": "int32" }, - "directInIxnCnt": { "type": "integer", "format": "int32" }, - "directInIxnDur": { "type": "integer", "format": "int32" } + "interval": { + "type": "integer", + "format": "int32" + }, + "dateTimeFrom": { + "type": "string" + }, + "agentId": { + "type": "integer", + "format": "int32" + }, + "agentName": { + "type": "string" + }, + "availDur": { + "type": "integer", + "format": "int32" + }, + "totWorkDur": { + "type": "integer", + "format": "int32" + }, + "pauseDur": { + "type": "integer", + "format": "int32" + }, + "waitDur": { + "type": "integer", + "format": "int32" + }, + "adminDur": { + "type": "integer", + "format": "int32" + }, + "directOutIxnCnt": { + "type": "integer", + "format": "int32" + }, + "directOutIxnDur": { + "type": "integer", + "format": "int32" + }, + "directInIxnCnt": { + "type": "integer", + "format": "int32" + }, + "directInIxnDur": { + "type": "integer", + "format": "int32" + } } }, "AggregatedQueueStats": { "type": "object", "properties": { - "dateTimeFrom": { "type": "string" }, - "interval": { "type": "integer", "format": "int32" }, - "queue": { "type": "integer", "format": "int32" }, - "queueName": { "type": "string" }, - "offdDirectIxnCnt": { "type": "integer", "format": "int32" }, - "answIxnCnt": { "type": "integer", "format": "int32" }, - "abandIxnCnt": { "type": "integer", "format": "int32" }, - "abandShortIxnCnt": { "type": "integer", "format": "int32" }, - "abandWithinSlCnt": { "type": "integer", "format": "int32" }, - "ansServicelevelCnt": { "type": "integer", "format": "int32" }, - "completedContacts": { "type": "integer", "format": "int32" }, - "queuedAndAnswIxnDur": { "type": "integer", "format": "int32" }, - "queuedAndAbandIxnDur": { "type": "integer", "format": "int32" }, - "queuedAnswLongestQueDur": { "type": "integer", "format": "int32" }, - "queuedAbandLongestQueDur": { "type": "integer", "format": "int32" }, - "talkingIxnDur": { "type": "integer", "format": "int32" }, - "wrapUpDur": { "type": "integer", "format": "int32" }, - "waitDur": { "type": "integer", "format": "int32" }, - "segmentHoldTime": { "type": "integer", "format": "int32" }, - "overflowInIxnCnt": { "type": "integer", "format": "int32" }, - "overflowOutIxnCnt": { "type": "integer", "format": "int32" } + "dateTimeFrom": { + "type": "string" + }, + "interval": { + "type": "integer", + "format": "int32" + }, + "queue": { + "type": "integer", + "format": "int32" + }, + "queueName": { + "type": "string" + }, + "offdDirectIxnCnt": { + "type": "integer", + "format": "int32" + }, + "answIxnCnt": { + "type": "integer", + "format": "int32" + }, + "abandIxnCnt": { + "type": "integer", + "format": "int32" + }, + "abandShortIxnCnt": { + "type": "integer", + "format": "int32" + }, + "abandWithinSlCnt": { + "type": "integer", + "format": "int32" + }, + "ansServicelevelCnt": { + "type": "integer", + "format": "int32" + }, + "completedContacts": { + "type": "integer", + "format": "int32" + }, + "queuedAndAnswIxnDur": { + "type": "integer", + "format": "int32" + }, + "queuedAndAbandIxnDur": { + "type": "integer", + "format": "int32" + }, + "queuedAnswLongestQueDur": { + "type": "integer", + "format": "int32" + }, + "queuedAbandLongestQueDur": { + "type": "integer", + "format": "int32" + }, + "talkingIxnDur": { + "type": "integer", + "format": "int32" + }, + "wrapUpDur": { + "type": "integer", + "format": "int32" + }, + "waitDur": { + "type": "integer", + "format": "int32" + }, + "segmentHoldTime": { + "type": "integer", + "format": "int32" + }, + "overflowInIxnCnt": { + "type": "integer", + "format": "int32" + }, + "overflowOutIxnCnt": { + "type": "integer", + "format": "int32" + } } }, "ExtendedAggregatedQueueStats": { "type": "object", "properties": { - "interval": { "type": "integer", "format": "int32" }, - "dateTimeFrom": { "type": "string" }, - "agentId": { "type": "integer", "format": "int32" }, - "agentName": { "type": "string" }, - "queue": { "type": "integer", "format": "int32" }, - "queueName": { "type": "string" }, - "talkingIxnDur": { "type": "integer", "format": "int32" }, - "wrapUpDur": { "type": "integer", "format": "int32" }, - "answIxnCnt": { "type": "integer", "format": "int32" }, - "transferOutIxnCnt": { "type": "integer", "format": "int32" } + "interval": { + "type": "integer", + "format": "int32" + }, + "dateTimeFrom": { + "type": "string" + }, + "agentId": { + "type": "integer", + "format": "int32" + }, + "agentName": { + "type": "string" + }, + "queue": { + "type": "integer", + "format": "int32" + }, + "queueName": { + "type": "string" + }, + "talkingIxnDur": { + "type": "integer", + "format": "int32" + }, + "wrapUpDur": { + "type": "integer", + "format": "int32" + }, + "answIxnCnt": { + "type": "integer", + "format": "int32" + }, + "transferOutIxnCnt": { + "type": "integer", + "format": "int32" + } } }, "CXQueueWithAgents": { @@ -24000,41 +24182,47 @@ }, "/voice/api/v1/admin/users": { "get": { + "tags": [ + "Admin Users and Permissions" + ], + "summary": "Returns a listing of all users that a user has access to", "description": "Permissions: MANAGE_USERS or SUPER_USER role", "operationId": "listAllUsers", "parameters": [ { - "description": "activeOnly", - "in": "query", "name": "activeOnly", + "in": "query", + "description": "activeOnly", + "required": false, "schema": { - "default": false, - "type": "boolean" + "type": "boolean", + "default": false } }, { - "description": "flatten", - "in": "query", "name": "flatten", + "in": "query", + "description": "flatten", + "required": false, "schema": { - "default": false, - "type": "boolean" + "type": "boolean", + "default": false } } ], "responses": { "200": { + "description": "OK", "content": { "application/json": { "schema": { + "type": "array", "items": { "$ref": "#/components/schemas/User" - }, - "type": "array" + } } } - }, - "description": "OK" + } }, "401": { "description": "Unauthorized" @@ -24047,49 +24235,47 @@ } }, "security": [ - { - "BearerAuth": [] - }, - { - "BearerAuth": [] - }, { "BearerAuth": [] } - ], - "summary": "Returns a listing of all users that a user has access to", - "tags": [ - "Users" ] }, "post": { + "tags": [ + "Admin Users and Permissions" + ], + "summary": "Creates a single new user", "description": "Permissions: MANAGE_USERS or SUPER_USER role", "operationId": "createUser", "parameters": [ { - "description": "parentUserId", - "in": "query", "name": "parentUserId", + "in": "query", + "description": "parentUserId", + "required": false, "schema": { - "format": "int32", - "type": "integer" + "type": "integer", + "format": "int32" } }, { - "description": "returnUri", - "in": "query", "name": "returnUri", + "in": "query", + "description": "returnUri", + "required": false, "schema": { - "type": "string" + "type": "string", + "format": "uri" } }, { - "description": "isSSO", - "in": "query", "name": "isSSO", + "in": "query", + "description": "isSSO", + "required": false, "schema": { - "default": false, - "type": "boolean" + "type": "boolean", + "default": false } } ], @@ -24101,18 +24287,20 @@ } } }, - "description": "userRequest", - "required": true + "required": false }, "responses": { - "201": { + "200": { + "description": "OK", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/User" } } - }, + } + }, + "201": { "description": "Created" }, "401": { @@ -24126,69 +24314,60 @@ } }, "security": [ - { - "BearerAuth": [] - }, - { - "BearerAuth": [] - }, { "BearerAuth": [] } - ], - "summary": "Creates a single new user", - "tags": [ - "Users" - ], - "x-codegen-request-body-name": "userRequest" + ] } }, "/voice/api/v1/auth/login": { "post": { + "tags": [ + "Admin Users and Permissions" + ], + "summary": "Application login to authenticate and receive an X-Auth-Token", "description": "Permissions: Anonymous User", "operationId": "doLogin", "parameters": [ { - "description": "username", - "in": "query", "name": "username", - "required": true, + "in": "query", + "description": "username", + "required": false, "schema": { "type": "string" } }, { - "description": "password", - "in": "query", "name": "password", - "required": true, + "in": "query", + "description": "password", + "required": false, "schema": { "type": "string" } }, { - "description": "stayLoggedIn", - "in": "query", "name": "stayLoggedIn", + "in": "query", + "description": "stayLoggedIn", + "required": false, "schema": { - "default": false, - "type": "boolean" + "type": "boolean", + "default": false } } ], "responses": { "200": { + "description": "OK", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UserLoginView" } } - }, - "description": "OK" - }, - "201": { - "description": "Created" + } }, "401": { "description": "Unauthorized" @@ -24201,19 +24380,9 @@ } }, "security": [ - { - "BearerAuth": [] - }, - { - "BearerAuth": [] - }, { "BearerAuth": [] } - ], - "summary": "Application login to authenticate and receive an X-Auth-Token", - "tags": [ - "Legacy Auth" ] } }, @@ -26529,6 +26698,2763 @@ } } } + }, + "/voice/api/v1/admin/auth": { + "get": { + "tags": [ + "Admin Users and Permissions" + ], + "summary": "Returns information provided by /v1/auth/login for users who are already authenticated. Additionally, we return the host name of this platform.", + "description": "", + "operationId": "getUserLoginView", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UserLoginView" + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + } + }, + "/voice/api/v1/admin/rightsDocs/assignments/{userId}": { + "post": { + "tags": [ + "Admin Users and Permissions" + ], + "summary": "Assigns a user to a rights document", + "description": "Permissions: MANAGE_RIGHTS or SUPER_USER roles", + "operationId": "assignUserToRightsDocs", + "parameters": [ + { + "name": "userId", + "in": "path", + "description": "userId", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "rightsDocIds", + "in": "query", + "description": "rightsDocIds", + "required": true, + "schema": { + "type": "array" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "boolean" + } + } + } + }, + "201": { + "description": "Created" + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + } + }, + "/voice/api/v1/admin/rightsDocs/{rightsDocId}/assignments": { + "get": { + "tags": [ + "Admin Users and Permissions" + ], + "summary": "Returns a listing of users assigned to a rights document", + "description": "Permissions: MANAGE_RIGHTS or SUPER_USER roles", + "operationId": "getRightsDocAssignments", + "parameters": [ + { + "name": "rightsDocId", + "in": "path", + "description": "rightsDocId", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/User" + } + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + }, + "post": { + "tags": [ + "Admin Users and Permissions" + ], + "summary": "Assigns a rights document to a user", + "description": "Permissions: MANAGE_RIGHTS or SUPER_USER roles", + "operationId": "assignRightsDocsToUsers", + "parameters": [ + { + "name": "rightsDocId", + "in": "path", + "description": "rightsDocId", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "userIds", + "in": "query", + "description": "userIds", + "required": true, + "schema": { + "type": "array" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "boolean" + } + } + } + }, + "201": { + "description": "Created" + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + } + }, + "/voice/api/v1/admin/rightsDocs/{rightsDocId}/assignments/{assignedUserId}": { + "delete": { + "tags": [ + "Admin Users and Permissions" + ], + "summary": "Deletes a rights document from a user", + "description": "Permissions: MANAGE_RIGHTS or SUPER_USER roles", + "operationId": "deleteRightsDocAssignment", + "parameters": [ + { + "name": "assignedUserId", + "in": "path", + "description": "assignedUserId", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "rightsDocId", + "in": "path", + "description": "rightsDocId", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "default": { + "description": "successful operation" + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + } + }, + "/voice/api/v1/admin/users/availableUserNames": { + "get": { + "tags": [ + "Admin Users and Permissions" + ], + "summary": "Checks if username is available", + "description": "Permissions: Authenticated User", + "operationId": "isUserNameTaken", + "parameters": [ + { + "name": "userName", + "in": "query", + "description": "userName", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object" + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + } + }, + "/voice/api/v1/admin/users/duplicateAuthenticatedUser": { + "post": { + "tags": [ + "Admin Users and Permissions" + ], + "summary": "Duplicates this authenticated user's session and returns a new auth token", + "description": "Permissions: Authenticated User", + "operationId": "duplicateAuthenticatedUsers", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuthenticatedUser" + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + } + }, + "/voice/api/v1/admin/users/passwordReset": { + "post": { + "tags": [ + "Admin Users and Permissions" + ], + "summary": "Resets a user's password", + "description": "Permissions: Authenticated User", + "operationId": "securedPasswordRequestRequest", + "parameters": [ + { + "name": "currentPassword", + "in": "query", + "description": "currentPassword", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "newPassword", + "in": "query", + "description": "newPassword", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "boolean" + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + } + }, + "/voice/api/v1/admin/users/reassign": { + "put": { + "tags": [ + "Admin Users and Permissions" + ], + "summary": "Reassigns all existing child users to a new parent user", + "description": "Permissions: MANAGE_USERS or SUPER_USER role", + "operationId": "reassignUsers", + "parameters": [ + { + "name": "oldUserId", + "in": "query", + "description": "oldUserId", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "reassignUserId", + "in": "query", + "description": "reassignUserId", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "201": { + "description": "Created" + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + } + }, + "/voice/api/v1/admin/users/root": { + "post": { + "tags": [ + "Admin Users and Permissions" + ], + "summary": "Creates a single root user", + "description": "Permissions: SUPER_USER role", + "operationId": "createRootUser", + "parameters": [ + { + "name": "returnUri", + "in": "query", + "description": "returnUri", + "required": false, + "schema": { + "type": "string", + "format": "uri" + } + }, + { + "name": "isSSO", + "in": "query", + "description": "isSSO", + "required": false, + "schema": { + "type": "boolean", + "default": false + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AdminUserRequest" + } + } + }, + "required": false + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/User" + } + } + } + }, + "201": { + "description": "Created" + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + } + }, + "/voice/api/v1/admin/users/root/{userId}/assignAccount": { + "post": { + "tags": [ + "Admin Users and Permissions" + ], + "summary": "Assigns an account to a root user", + "description": "Permissions: SUPER_USER role", + "operationId": "assignAccountToRootUser", + "parameters": [ + { + "name": "userId", + "in": "path", + "description": "userId", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "accountId", + "in": "query", + "description": "accountId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "isMaster", + "in": "query", + "description": "isMaster", + "required": false, + "schema": { + "type": "boolean", + "default": false + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "boolean" + } + } + } + }, + "201": { + "description": "Created" + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + } + }, + "/voice/api/v1/admin/users/{targetUpdateUserId}": { + "put": { + "tags": [ + "Admin Users and Permissions" + ], + "summary": "Updates a user", + "description": "Permissions: MANAGE_USERS or SUPER_USER role", + "operationId": "updateUser", + "parameters": [ + { + "name": "targetUpdateUserId", + "in": "path", + "description": "targetUpdateUserId", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AdminUserRequest" + } + } + }, + "required": false + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/User" + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + } + }, + "/voice/api/v1/admin/users/{userId}": { + "get": { + "tags": [ + "Admin Users and Permissions" + ], + "summary": "Returns a user", + "description": "Permissions: MANAGE_USERS or SUPER_USER role", + "operationId": "getUserDetails", + "parameters": [ + { + "name": "userId", + "in": "path", + "description": "userId", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/User" + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + }, + "delete": { + "tags": [ + "Admin Users and Permissions" + ], + "summary": "Deletes a user", + "description": "Permissions: MANAGE_USERS or SUPER_USER role", + "operationId": "deleteUser", + "parameters": [ + { + "name": "userId", + "in": "path", + "description": "userId", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "reassignUserId", + "in": "query", + "description": "reassignUserId", + "required": false, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "cascadeDelete", + "in": "query", + "description": "cascadeDelete", + "required": false, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "default": { + "description": "successful operation" + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + } + }, + "/voice/api/v1/admin/users/{userId}/aggregatedRightsDocs": { + "get": { + "tags": [ + "Admin Users and Permissions" + ], + "summary": "Returns a map of aggregated rights documents for a user", + "description": "Permissions: MANAGE_RIGHTS or SUPER_USER roles", + "operationId": "getAggregatedRightsDocForAllAccounts", + "parameters": [ + { + "name": "userId", + "in": "path", + "description": "userId", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/RightsDocument" + } + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + } + }, + "/voice/api/v1/admin/users/{userId}/assignAccountToAnyUser": { + "post": { + "tags": [ + "Admin Users and Permissions" + ], + "summary": "Assigns an account to any user", + "description": "Permissions: hasRole('MANAGE_RIGHTS') or hasRole('SUPER_USER')", + "operationId": "assignAccountToAnyUser", + "parameters": [ + { + "name": "userId", + "in": "path", + "description": "userId", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "accountId", + "in": "query", + "description": "accountId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "isMaster", + "in": "query", + "description": "isMaster", + "required": false, + "schema": { + "type": "boolean", + "default": false + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "boolean" + } + } + } + }, + "201": { + "description": "Created" + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + } + }, + "/voice/api/v1/admin/users/{userId}/assignedMasterRightsDocs": { + "get": { + "tags": [ + "Admin Users and Permissions" + ], + "summary": "Returns a map of assigned master rights documents for a user", + "description": "Permissions: MANAGE_RIGHTS or SUPER_USER roles", + "operationId": "getUsersAssignedRightsDocs", + "parameters": [ + { + "name": "userId", + "in": "path", + "description": "userId", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "$ref": "#/components/schemas/RightsDocument" + } + } + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + } + }, + "/voice/api/v1/admin/users/{userId}/assignedRightsDocs": { + "get": { + "tags": [ + "Admin Users and Permissions" + ], + "summary": "Returns a map of assigned rights documents for a user", + "description": "Permissions: MANAGE_RIGHTS or SUPER_USER roles", + "operationId": "getUsersAssignedRightsDocs2", + "parameters": [ + { + "name": "userId", + "in": "path", + "description": "userId", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "$ref": "#/components/schemas/RightsDocument" + } + } + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + } + }, + "/voice/api/v1/admin/users/{userId}/bulkAssignAccountToAnyUser": { + "post": { + "tags": [ + "Admin Users and Permissions" + ], + "summary": "Assigns an account to any user", + "description": "Permissions: hasRole('MANAGE_RIGHTS') or hasRole('SUPER_USER')", + "operationId": "assignAccountToAnyUser2", + "parameters": [ + { + "name": "userId", + "in": "path", + "description": "userId", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "required": false + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/RightsDocTable" + } + } + } + } + }, + "201": { + "description": "Created" + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + } + }, + "/voice/api/v1/admin/users/{userId}/children": { + "get": { + "tags": [ + "Admin Users and Permissions" + ], + "summary": "Returns a hierarchical listing of all users that a user has access to", + "description": "Permissions: MANAGE_USERS or SUPER_USER role", + "operationId": "listAllUsersChildren", + "parameters": [ + { + "name": "userId", + "in": "path", + "description": "userId", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/User" + } + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + } + }, + "/voice/api/v1/admin/users/{userId}/dashboards": { + "get": { + "tags": [ + "Admin Users and Permissions" + ], + "summary": "Returns a listing of a dashboards for a user", + "description": "Permissions: Authenticated User", + "operationId": "getDashboardList", + "parameters": [ + { + "name": "userId", + "in": "path", + "description": "userId", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Dashboard" + } + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + }, + "post": { + "tags": [ + "Admin Users and Permissions" + ], + "summary": "Creates a new dashboard for a user", + "description": "Permissions: Authenticated User", + "operationId": "createDashboard", + "parameters": [ + { + "name": "userId", + "in": "path", + "description": "userId", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Dashboard" + } + } + }, + "required": false + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Dashboard" + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + } + }, + "/voice/api/v1/admin/users/{userId}/dashboards/{dashboardId}": { + "get": { + "tags": [ + "Admin Users and Permissions" + ], + "summary": "Returns a dashboard for a user", + "description": "Permissions: Authenticated User", + "operationId": "getDashboardDetail", + "parameters": [ + { + "name": "userId", + "in": "path", + "description": "userId", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "dashboardId", + "in": "path", + "description": "dashboardId", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Dashboard" + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + }, + "put": { + "tags": [ + "Admin Users and Permissions" + ], + "summary": "Updates an existing dashboard for a user", + "description": "Permissions: Authenticated User", + "operationId": "updateDashboard", + "parameters": [ + { + "name": "userId", + "in": "path", + "description": "userId", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "dashboardId", + "in": "path", + "description": "dashboardId", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Dashboard" + } + } + }, + "required": false + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Dashboard" + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + }, + "delete": { + "tags": [ + "Admin Users and Permissions" + ], + "summary": "Deletes a dashboard for a user", + "description": "Permissions: Authenticated User", + "operationId": "deleteDashboard", + "parameters": [ + { + "name": "userId", + "in": "path", + "description": "userId", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "dashboardId", + "in": "path", + "description": "dashboardId", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "boolean" + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + } + }, + "/voice/api/v1/admin/users/{userId}/dashboards/{dashboardId}/share": { + "put": { + "tags": [ + "Admin Users and Permissions" + ], + "summary": "Creates a copy of the dashboard for each admin id supplied", + "description": "Permissions: Authenticated User", + "operationId": "shareDashboard", + "parameters": [ + { + "name": "userId", + "in": "path", + "description": "userId", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "dashboardId", + "in": "path", + "description": "dashboardId", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "userIds", + "in": "query", + "description": "userIds", + "required": true, + "schema": { + "type": "array" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "integer", + "format": "int32" + } + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + } + }, + "/voice/api/v1/admin/users/{userId}/effectiveAssignedRightsDocs": { + "get": { + "tags": [ + "Admin Users and Permissions" + ], + "summary": "Returns a map of merged (master and regular) and aggregated assigned rights documents for a user", + "description": "Permissions: MANAGE_RIGHTS or SUPER_USER roles", + "operationId": "getEffectiveAssignedRightsDocForAllAccounts", + "parameters": [ + { + "name": "userId", + "in": "path", + "description": "userId", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/RightsDocument" + } + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + } + }, + "/voice/api/v1/admin/users/{userId}/masterRightsDocs": { + "get": { + "tags": [ + "Admin Users and Permissions" + ], + "summary": "Returns a map of master rights documents for a user", + "description": "Permissions: MANAGE_RIGHTS or SUPER_USER roles", + "operationId": "getUsersRightsDocs", + "parameters": [ + { + "name": "userId", + "in": "path", + "description": "userId", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "$ref": "#/components/schemas/RightsDocument" + } + } + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + }, + "post": { + "tags": [ + "Admin Users and Permissions" + ], + "summary": "Creates a new master rights document for a user", + "description": "Permissions: SUPER_USER roles", + "operationId": "createRightsDoc", + "parameters": [ + { + "name": "userId", + "in": "path", + "description": "userId", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RightsDocument" + } + } + }, + "required": false + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RightsDocument" + } + } + } + }, + "201": { + "description": "Created" + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + } + }, + "/voice/api/v1/admin/users/{userId}/masterRightsDocs/{rightsDocId}": { + "get": { + "tags": [ + "Admin Users and Permissions" + ], + "summary": "Returns a single master rights document for a user", + "description": "Permissions: SUPER_USER roles", + "operationId": "getRightsDoc", + "parameters": [ + { + "name": "userId", + "in": "path", + "description": "userId", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "rightsDocId", + "in": "path", + "description": "rightsDocId", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RightsDocument" + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + }, + "put": { + "tags": [ + "Admin Users and Permissions" + ], + "summary": "Updates an existing master rights document for a user", + "description": "Permissions: SUPER_USER roles", + "operationId": "updateRightsDoc", + "parameters": [ + { + "name": "userId", + "in": "path", + "description": "userId", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "rightsDocId", + "in": "path", + "description": "rightsDocId", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RightsDocument" + } + } + }, + "required": false + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RightsDocument" + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + }, + "delete": { + "tags": [ + "Admin Users and Permissions" + ], + "summary": "Deletes an existing master rights document for a user", + "description": "Permissions: SUPER_USER roles", + "operationId": "deleteRightsDoc", + "parameters": [ + { + "name": "userId", + "in": "path", + "description": "userId", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "rightsDocId", + "in": "path", + "description": "rightsDocId", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "default": { + "description": "successful operation" + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + } + }, + "/voice/api/v1/admin/users/{userId}/ownedMasterRightsDocs": { + "get": { + "tags": [ + "Admin Users and Permissions" + ], + "summary": "Returns a map of owned master rights documents for a user", + "description": "Permissions: MANAGE_RIGHTS or SUPER_USER roles", + "operationId": "getUsersOwnedRightsDocs", + "parameters": [ + { + "name": "userId", + "in": "path", + "description": "userId", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "$ref": "#/components/schemas/RightsDocument" + } + } + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + } + }, + "/voice/api/v1/admin/users/{userId}/ownedRightsDocs": { + "get": { + "tags": [ + "Admin Users and Permissions" + ], + "summary": "Returns a map of owned rights documents for a user", + "description": "Permissions: MANAGE_RIGHTS or SUPER_USER roles", + "operationId": "getUsersOwnedRightsDocs2", + "parameters": [ + { + "name": "userId", + "in": "path", + "description": "userId", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "$ref": "#/components/schemas/RightsDocument" + } + } + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + } + }, + "/voice/api/v1/admin/users/{userId}/passwordReset": { + "post": { + "tags": [ + "Admin Users and Permissions" + ], + "summary": "Resets a user's password and sends reset password email", + "description": "Permissions: Authenticated User", + "operationId": "securePasswordRequestResetForUse", + "parameters": [ + { + "name": "userId", + "in": "path", + "description": "userId", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "returnPath", + "in": "query", + "description": "returnPath", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "resetViaEngageAuth", + "in": "query", + "description": "resetViaEngageAuth", + "required": false, + "schema": { + "type": "boolean", + "default": false + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "boolean" + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + } + }, + "/voice/api/v1/admin/users/{userId}/rightsDocs": { + "get": { + "tags": [ + "Admin Users and Permissions" + ], + "summary": "Returns a map of rights documents for a user", + "description": "Permissions: MANAGE_RIGHTS or SUPER_USER roles", + "operationId": "getUsersRightsDocs2", + "parameters": [ + { + "name": "userId", + "in": "path", + "description": "userId", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "$ref": "#/components/schemas/RightsDocument" + } + } + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + }, + "post": { + "tags": [ + "Admin Users and Permissions" + ], + "summary": "Creates a new rights document for a user", + "description": "Permissions: MANAGE_RIGHTS or SUPER_USER roles", + "operationId": "createRightsDoc2", + "parameters": [ + { + "name": "userId", + "in": "path", + "description": "userId", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RightsDocument" + } + } + }, + "required": false + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RightsDocument" + } + } + } + }, + "201": { + "description": "Created" + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + } + }, + "/voice/api/v1/admin/users/{userId}/rightsDocs/{rightsDocId}": { + "get": { + "tags": [ + "Admin Users and Permissions" + ], + "summary": "Returns a single rights document for a user", + "description": "Permissions: MANAGE_RIGHTS or SUPER_USER roles", + "operationId": "getRightsDoc2", + "parameters": [ + { + "name": "userId", + "in": "path", + "description": "userId", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "rightsDocId", + "in": "path", + "description": "rightsDocId", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RightsDocument" + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + }, + "put": { + "tags": [ + "Admin Users and Permissions" + ], + "summary": "Updates an existing rights document for a user", + "description": "Permissions: MANAGE_RIGHTS or SUPER_USER roles", + "operationId": "updateRightsDoc2", + "parameters": [ + { + "name": "userId", + "in": "path", + "description": "userId", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "rightsDocId", + "in": "path", + "description": "rightsDocId", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RightsDocument" + } + } + }, + "required": false + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RightsDocument" + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + }, + "delete": { + "tags": [ + "Admin Users and Permissions" + ], + "summary": "Deletes an existing rights document for a user", + "description": "Permissions: MANAGE_RIGHTS or SUPER_USER roles", + "operationId": "deleteRightsDoc2", + "parameters": [ + { + "name": "userId", + "in": "path", + "description": "userId", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "rightsDocId", + "in": "path", + "description": "rightsDocId", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "default": { + "description": "successful operation" + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + } + }, + "/voice/api/v1/admin/users/{userId}/rightsDocsWithSubAccounts": { + "get": { + "tags": [ + "Admin Users and Permissions" + ], + "summary": "Returns a map of rights documents for a user", + "description": "Permissions: MANAGE_RIGHTS or SUPER_USER roles", + "operationId": "getUsersRightsDocsByMasterDoc", + "parameters": [ + { + "name": "userId", + "in": "path", + "description": "userId", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "enablePreBuiltRoles", + "in": "query", + "description": "enablePreBuiltRoles", + "required": false, + "schema": { + "type": "boolean", + "default": false + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "$ref": "#/components/schemas/RightsDocument" + } + } + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + } + }, + "/voice/api/v1/admin/users/{userId}/roles": { + "get": { + "tags": [ + "Admin Users and Permissions" + ], + "summary": "Returns a listing of roles for a user", + "description": "Permissions: MANAGE_USERS or SUPER_USER roles", + "operationId": "getUserRoles", + "parameters": [ + { + "name": "userId", + "in": "path", + "description": "userId", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "SUPER_USER", + "USER", + "MANAGE_USERS", + "MANAGE_RIGHTS", + "ACCESS_SIBLINGS", + "ACCESS_AUDIT_LOG", + "ASSUME_USERS", + "REPORT_ADMINISTRATIVE_USER", + "WFO_ACCESS", + "ACCESS_GOODDATA_EDITOR", + "ACCESS_GOODDATA_ANALYST", + "ACCESS_GOODDATA_VIEWER", + "NO_ACCESS" + ] + } + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + } + }, + "/voice/api/v1/admin/users/{userId}/roles/{roleType}": { + "post": { + "tags": [ + "Admin Users and Permissions" + ], + "summary": "Adds a role to a user", + "description": "Permissions: MANAGE_USERS or SUPER_USER roles", + "operationId": "addUserRole", + "parameters": [ + { + "name": "userId", + "in": "path", + "description": "userId", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "roleType", + "in": "path", + "description": "roleType", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "boolean" + } + } + } + }, + "201": { + "description": "Created" + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + }, + "delete": { + "tags": [ + "Admin Users and Permissions" + ], + "summary": "Removes a role from a user", + "description": "Permissions: MANAGE_USERS or SUPER_USER roles", + "operationId": "removeUserRole", + "parameters": [ + { + "name": "userId", + "in": "path", + "description": "userId", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "roleType", + "in": "path", + "description": "roleType", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "boolean" + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + } + }, + "/voice/api/v1/admin/users/{userId}/setIsActive": { + "put": { + "tags": [ + "Admin Users and Permissions" + ], + "summary": "Set user is active", + "description": "Permissions: Authenticated User", + "operationId": "setUserIsActive", + "parameters": [ + { + "name": "userId", + "in": "path", + "description": "userId", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ActiveStateBoolean" + } + } + }, + "required": false + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "boolean" + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + } + }, + "/voice/api/v1/auth/isTokenValid": { + "get": { + "tags": [ + "Admin Users and Permissions" + ], + "summary": "Checks to see if a given token is valid", + "description": "Permissions: NONE", + "operationId": "isTokenValid", + "parameters": [ + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "boolean" + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + } + }, + "/voice/api/v1/auth/passwordReset": { + "post": { + "tags": [ + "Admin Users and Permissions" + ], + "summary": "Used to reset a users password", + "description": "Permissions: NONE", + "operationId": "unsecuredPasswordReset", + "parameters": [ + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "password", + "in": "query", + "description": "password", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "boolean" + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + } + }, + "/voice/api/v1/auth/passwordResetRequest": { + "post": { + "tags": [ + "Admin Users and Permissions" + ], + "summary": "Resets a password if a user is locked out, an email will be sent to the user", + "description": "Permissions: NONE", + "operationId": "unsecuredPasswordResetRequest", + "parameters": [ + { + "name": "userName", + "in": "query", + "description": "userName", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "returnPath", + "in": "query", + "description": "returnPath", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "boolean" + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + } + }, + "/voice/api/v1/auth/smsGateway/messages/callbacks/": { + "post": { + "tags": [ + "Admin Users and Permissions" + ], + "summary": "incomingMessageCallback", + "description": "", + "operationId": "incomingMessageCallback", + "parameters": [ + { + "name": "message", + "in": "query", + "description": "message", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "default": { + "description": "successful operation" + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + } } }, "servers": [ @@ -26697,4 +29623,4 @@ ] } ] -} \ No newline at end of file +} From 4fe0b6d45aa0632173da9e073fafc52828ccd778 Mon Sep 17 00:00:00 2001 From: ajkamen Date: Wed, 27 May 2026 10:49:26 -0700 Subject: [PATCH 3/9] docs: align admin-users-permissions-api reference links --- specs/engage-voice_openapi3.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/specs/engage-voice_openapi3.json b/specs/engage-voice_openapi3.json index d5bf910..49d3f5c 100644 --- a/specs/engage-voice_openapi3.json +++ b/specs/engage-voice_openapi3.json @@ -26851,7 +26851,7 @@ ], "summary": "Assigns a rights document to a user", "description": "Permissions: MANAGE_RIGHTS or SUPER_USER roles", - "operationId": "assignRightsDocsToUsers", + "operationId": "assignRightsDoc", "parameters": [ { "name": "rightsDocId", @@ -27351,7 +27351,7 @@ ], "summary": "Returns a user", "description": "Permissions: MANAGE_USERS or SUPER_USER role", - "operationId": "getUserDetails", + "operationId": "getUser", "parameters": [ { "name": "userId", @@ -28675,7 +28675,7 @@ ], "summary": "Returns a map of rights documents for a user", "description": "Permissions: MANAGE_RIGHTS or SUPER_USER roles", - "operationId": "getUsersRightsDocs2", + "operationId": "getRightsDocs", "parameters": [ { "name": "userId", @@ -29025,7 +29025,7 @@ ], "summary": "Returns a listing of roles for a user", "description": "Permissions: MANAGE_USERS or SUPER_USER roles", - "operationId": "getUserRoles", + "operationId": "getRoles", "parameters": [ { "name": "userId", @@ -29091,7 +29091,7 @@ ], "summary": "Adds a role to a user", "description": "Permissions: MANAGE_USERS or SUPER_USER roles", - "operationId": "addUserRole", + "operationId": "addRole", "parameters": [ { "name": "userId", @@ -29149,7 +29149,7 @@ ], "summary": "Removes a role from a user", "description": "Permissions: MANAGE_USERS or SUPER_USER roles", - "operationId": "removeUserRole", + "operationId": "removeRole", "parameters": [ { "name": "userId", @@ -29311,7 +29311,7 @@ ], "summary": "Used to reset a users password", "description": "Permissions: NONE", - "operationId": "unsecuredPasswordReset", + "operationId": "passwordReset", "parameters": [ { "name": "token", @@ -29367,7 +29367,7 @@ ], "summary": "Resets a password if a user is locked out, an email will be sent to the user", "description": "Permissions: NONE", - "operationId": "unsecuredPasswordResetRequest", + "operationId": "passwordResetRequest", "parameters": [ { "name": "userName", From d5c9aae7240d8bb1f4b6ee7ac8cd67b2b0d5719d Mon Sep 17 00:00:00 2001 From: ajkamen Date: Wed, 27 May 2026 11:08:10 -0700 Subject: [PATCH 4/9] docs: expand admin users guide Add permissions detail, absolute endpoints, request examples, schemas, errors, and onboarding sample code. Co-authored-by: Cursor --- docs/users/admin-users-and-permissions.md | 102 +++++++++++++++++++++- 1 file changed, 101 insertions(+), 1 deletion(-) diff --git a/docs/users/admin-users-and-permissions.md b/docs/users/admin-users-and-permissions.md index 8713089..da22f0d 100644 --- a/docs/users/admin-users-and-permissions.md +++ b/docs/users/admin-users-and-permissions.md @@ -15,7 +15,13 @@ Agents and administrators are related but not identical. Agent APIs manage conta ### Required Permissions & Scopes -Your application needs the `ReadAccounts` OAuth scope. The authenticating user must have sufficient platform permissions to read users and update roles or rights documents. +#### 1. Configure OAuth Scopes + +Your application needs the `ReadAccounts` OAuth scope. + +#### 2. Enable RingCX Admin Access + +The authenticating user must have sufficient Admin portal permissions to read users and update roles or rights documents. Use least privilege for automation accounts, and separate read-only audit automation from onboarding/offboarding automation. ## Users @@ -68,3 +74,97 @@ Rights documents provide detailed administrative permissions. Use these endpoint !!! warning Permission changes can grant administrative access to customer data and configuration. Apply least privilege and log all automated changes for audit review. + +!!! important "Rate Limiting & Stability" + User and permission changes should be serialized per user. Avoid parallel role and rights document updates for the same user because the final effective permission set can be difficult to audit. + +## Absolute Endpoint Examples + +| Workflow | Endpoint | +| --- | --- | +| Create user | `POST https://ringcx.ringcentral.com/voice/api/v1/admin/users` | +| Add role | `POST https://ringcx.ringcentral.com/voice/api/v1/admin/users/{userId}/roles/{roleType}` | +| Create rights document | `POST https://ringcx.ringcentral.com/voice/api/v1/admin/users/{userId}/rightsDocs` | +| Assign rights document | `POST https://ringcx.ringcentral.com/voice/api/v1/admin/rightsDocs/{rightsDocId}/assignments` | + +## Request Examples + +### Create a User + +```json +{ + "email": "alex.admin@example.com", + "firstName": "Alex", + "lastName": "Admin", + "active": true, + "timezone": "America/Denver" +} +``` + +### Assign a Role + +`POST https://ringcx.ringcentral.com/voice/api/v1/admin/users/{userId}/roles/{roleType}` + +Use the `roleType` path parameter for the role being assigned. + +### Create a Rights Document + +```json +{ + "rightsDocName": "Reporting audit access", + "description": "Read-only analytics and reporting permissions", + "active": true +} +``` + +### Assign a Rights Document + +```json +{ + "assignedUserId": 987654, + "accountIds": [123456] +} +``` + +## Response and Schema Notes + +| Resource | Key Fields | Notes | +| --- | --- | --- | +| User | `userId`, `email`, `firstName`, `lastName`, `active`, `timezone` | Admin portal identity and lifecycle state. | +| Role | `roleType`, `userId`, `createdOn` | Coarse access grant. Role names are controlled by the platform. | +| Rights document | `rightsDocId`, `rightsDocName`, `description`, `active`, `permissions` | Fine-grained administrative permissions. | +| Assignment | `rightsDocId`, `assignedUserId`, `accountIds` | Grants rights document access to a user/account context. | + +## Common Errors + +| Status | Cause | Resolution | +| --- | --- | --- | +| `400 Bad Request` | Missing user fields, invalid role type, or malformed rights document. | Validate against the generated API reference before submitting. | +| `403 Forbidden` | Caller cannot manage users, roles, or rights docs. | Grant appropriate Admin portal permission to the automation user. | +| `404 Not Found` | User, role, or rights document ID does not exist. | List the target resource before updating or deleting. | +| `409 Conflict` | Email, role, or assignment already exists. | Treat create operations as idempotent by reading current state first. | + +## Sample Implementation (Python) + +```python +import requests + +BASE_URL = "https://ringcx.ringcentral.com/voice/api" + +def onboard_admin_user(token, email, role_type): + headers = {"Authorization": f"Bearer {token}"} + user = requests.post( + f"{BASE_URL}/v1/admin/users", + headers=headers, + json={"email": email, "firstName": "Alex", "lastName": "Admin", "active": True}, + ) + user.raise_for_status() + user_id = user.json()["userId"] + + role = requests.post( + f"{BASE_URL}/v1/admin/users/{user_id}/roles/{role_type}", + headers=headers, + ) + role.raise_for_status() + return user.json() +``` From 562231b5305fdc6325821eaffa254782795ebe86 Mon Sep 17 00:00:00 2001 From: ajkamen Date: Wed, 27 May 2026 11:20:52 -0700 Subject: [PATCH 5/9] docs: polish admin users guide Add authorization error detail, full endpoint URLs, and a compact user response example. Co-authored-by: Cursor --- docs/users/admin-users-and-permissions.md | 57 ++++++++++++++++------- 1 file changed, 40 insertions(+), 17 deletions(-) diff --git a/docs/users/admin-users-and-permissions.md b/docs/users/admin-users-and-permissions.md index da22f0d..b287445 100644 --- a/docs/users/admin-users-and-permissions.md +++ b/docs/users/admin-users-and-permissions.md @@ -23,15 +23,25 @@ Your application needs the `ReadAccounts` OAuth scope. The authenticating user must have sufficient Admin portal permissions to read users and update roles or rights documents. Use least privilege for automation accounts, and separate read-only audit automation from onboarding/offboarding automation. +!!! warning "Common Authorization Errors" + If the OAuth token is valid but the user cannot manage users, roles, or rights documents, the API returns an error similar to: + ```json + { + "errorCode": "access.denied.exception", + "generalMessage": "You do not have permission to access this resource", + "timestamp": 1611847650696 + } + ``` + ## Users | Operation | Method and Path | API Reference | | --- | --- | --- | -| List users | `GET /voice/api/v1/admin/users` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/getUserList) | -| Create user | `POST /voice/api/v1/admin/users` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/createUser) | -| Get user | `GET /voice/api/v1/admin/users/{userId}` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/getUser) | -| Update user | `PUT /voice/api/v1/admin/users/{userId}` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/updateUser) | -| Delete user | `DELETE /voice/api/v1/admin/users/{userId}` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/deleteUser) | +| List users | `GET https://ringcx.ringcentral.com/voice/api/v1/admin/users` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/getUserList) | +| Create user | `POST https://ringcx.ringcentral.com/voice/api/v1/admin/users` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/createUser) | +| Get user | `GET https://ringcx.ringcentral.com/voice/api/v1/admin/users/{userId}` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/getUser) | +| Update user | `PUT https://ringcx.ringcentral.com/voice/api/v1/admin/users/{userId}` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/updateUser) | +| Delete user | `DELETE https://ringcx.ringcentral.com/voice/api/v1/admin/users/{userId}` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/deleteUser) | ## Roles @@ -39,9 +49,9 @@ Roles are coarse-grained access assignments. Use role endpoints for straightforw | Operation | Method and Path | API Reference | | --- | --- | --- | -| List user roles | `GET /voice/api/v1/admin/users/{userId}/roles` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/getRoles) | -| Add role | `POST /voice/api/v1/admin/users/{userId}/roles/{roleType}` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/addRole) | -| Remove role | `DELETE /voice/api/v1/admin/users/{userId}/roles/{roleType}` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/removeRole) | +| List user roles | `GET https://ringcx.ringcentral.com/voice/api/v1/admin/users/{userId}/roles` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/getRoles) | +| Add role | `POST https://ringcx.ringcentral.com/voice/api/v1/admin/users/{userId}/roles/{roleType}` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/addRole) | +| Remove role | `DELETE https://ringcx.ringcentral.com/voice/api/v1/admin/users/{userId}/roles/{roleType}` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/removeRole) | ## Rights Documents @@ -49,20 +59,20 @@ Rights documents provide detailed administrative permissions. Use these endpoint | Operation | Method and Path | API Reference | | --- | --- | --- | -| List rights docs | `GET /voice/api/v1/admin/users/{userId}/rightsDocs` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/getRightsDocs) | -| Create rights doc | `POST /voice/api/v1/admin/users/{userId}/rightsDocs` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/createRightsDoc) | -| Update rights doc | `PUT /voice/api/v1/admin/users/{userId}/rightsDocs/{rightsDocId}` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/updateRightsDoc) | -| Delete rights doc | `DELETE /voice/api/v1/admin/users/{userId}/rightsDocs/{rightsDocId}` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/deleteRightsDoc) | -| Assign rights doc | `POST /voice/api/v1/admin/rightsDocs/{rightsDocId}/assignments` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/assignRightsDoc) | -| Delete assignment | `DELETE /voice/api/v1/admin/rightsDocs/{rightsDocId}/assignments/{assignedUserId}` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/deleteRightsDocAssignment) | +| List rights docs | `GET https://ringcx.ringcentral.com/voice/api/v1/admin/users/{userId}/rightsDocs` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/getRightsDocs) | +| Create rights doc | `POST https://ringcx.ringcentral.com/voice/api/v1/admin/users/{userId}/rightsDocs` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/createRightsDoc) | +| Update rights doc | `PUT https://ringcx.ringcentral.com/voice/api/v1/admin/users/{userId}/rightsDocs/{rightsDocId}` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/updateRightsDoc) | +| Delete rights doc | `DELETE https://ringcx.ringcentral.com/voice/api/v1/admin/users/{userId}/rightsDocs/{rightsDocId}` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/deleteRightsDoc) | +| Assign rights doc | `POST https://ringcx.ringcentral.com/voice/api/v1/admin/rightsDocs/{rightsDocId}/assignments` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/assignRightsDoc) | +| Delete assignment | `DELETE https://ringcx.ringcentral.com/voice/api/v1/admin/rightsDocs/{rightsDocId}/assignments/{assignedUserId}` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/deleteRightsDocAssignment) | ## Auth Utilities | Operation | Method and Path | API Reference | | --- | --- | --- | -| Validate token | `GET /voice/api/v1/auth/isTokenValid` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/isTokenValid) | -| Reset password | `POST /voice/api/v1/auth/passwordReset` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/passwordReset) | -| Request password reset | `POST /voice/api/v1/auth/passwordResetRequest` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/passwordResetRequest) | +| Validate token | `GET https://ringcx.ringcentral.com/voice/api/v1/auth/isTokenValid` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/isTokenValid) | +| Reset password | `POST https://ringcx.ringcentral.com/voice/api/v1/auth/passwordReset` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/passwordReset) | +| Request password reset | `POST https://ringcx.ringcentral.com/voice/api/v1/auth/passwordResetRequest` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/passwordResetRequest) | ## Recommended Workflow @@ -126,6 +136,19 @@ Use the `roleType` path parameter for the role being assigned. } ``` +### Example User Response + +```json +{ + "userId": 987654, + "email": "alex.admin@example.com", + "firstName": "Alex", + "lastName": "Admin", + "active": true, + "timezone": "America/Denver" +} +``` + ## Response and Schema Notes | Resource | Key Fields | Notes | From 28c71c98db280f4c691a7a95f1a7b9b10a371fb5 Mon Sep 17 00:00:00 2001 From: ajkamen Date: Mon, 1 Jun 2026 10:59:59 -0700 Subject: [PATCH 6/9] docs: correct admin user schema accuracy --- docs/users/admin-users-and-permissions.md | 72 ++++++++++++-------- specs/engage-voice_openapi3.json | 82 ++++++++--------------- 2 files changed, 71 insertions(+), 83 deletions(-) diff --git a/docs/users/admin-users-and-permissions.md b/docs/users/admin-users-and-permissions.md index b287445..2942e6a 100644 --- a/docs/users/admin-users-and-permissions.md +++ b/docs/users/admin-users-and-permissions.md @@ -21,7 +21,7 @@ Your application needs the `ReadAccounts` OAuth scope. #### 2. Enable RingCX Admin Access -The authenticating user must have sufficient Admin portal permissions to read users and update roles or rights documents. Use least privilege for automation accounts, and separate read-only audit automation from onboarding/offboarding automation. +The authenticating user must have sufficient Admin portal permissions to read users and update roles or rights documents. User create/list operations require `MANAGE_USERS` or `SUPER_USER`; rights document assignment requires `MANAGE_RIGHTS` or `SUPER_USER`. Use least privilege for automation accounts, and separate read-only audit automation from onboarding/offboarding automation. !!! warning "Common Authorization Errors" If the OAuth token is valid but the user cannot manage users, roles, or rights documents, the API returns an error similar to: @@ -88,26 +88,23 @@ Rights documents provide detailed administrative permissions. Use these endpoint !!! important "Rate Limiting & Stability" User and permission changes should be serialized per user. Avoid parallel role and rights document updates for the same user because the final effective permission set can be difficult to audit. -## Absolute Endpoint Examples - -| Workflow | Endpoint | -| --- | --- | -| Create user | `POST https://ringcx.ringcentral.com/voice/api/v1/admin/users` | -| Add role | `POST https://ringcx.ringcentral.com/voice/api/v1/admin/users/{userId}/roles/{roleType}` | -| Create rights document | `POST https://ringcx.ringcentral.com/voice/api/v1/admin/users/{userId}/rightsDocs` | -| Assign rights document | `POST https://ringcx.ringcentral.com/voice/api/v1/admin/rightsDocs/{rightsDocId}/assignments` | - ## Request Examples ### Create a User ```json { - "email": "alex.admin@example.com", + "userName": "alex.admin@example.com", "firstName": "Alex", "lastName": "Admin", - "active": true, - "timezone": "America/Denver" + "enabled": true, + "roles": [ + "USER", + "MANAGE_USERS" + ], + "regionalSettings": { + "timezoneName": "America/Denver" + } } ``` @@ -129,23 +126,26 @@ Use the `roleType` path parameter for the role being assigned. ### Assign a Rights Document -```json -{ - "assignedUserId": 987654, - "accountIds": [123456] -} -``` +`POST https://ringcx.ringcentral.com/voice/api/v1/admin/rightsDocs/{rightsDocId}/assignments?userIds=987654&userIds=987655` + +The assignment endpoint takes one or more `userIds` query parameters. It does not accept a JSON request body. ### Example User Response ```json { "userId": 987654, - "email": "alex.admin@example.com", + "userName": "alex.admin@example.com", "firstName": "Alex", "lastName": "Admin", - "active": true, - "timezone": "America/Denver" + "enabled": true, + "roles": [ + "USER", + "MANAGE_USERS" + ], + "regionalSettings": { + "timezoneName": "America/Denver" + } } ``` @@ -153,10 +153,10 @@ Use the `roleType` path parameter for the role being assigned. | Resource | Key Fields | Notes | | --- | --- | --- | -| User | `userId`, `email`, `firstName`, `lastName`, `active`, `timezone` | Admin portal identity and lifecycle state. | -| Role | `roleType`, `userId`, `createdOn` | Coarse access grant. Role names are controlled by the platform. | +| User | `userId`, `userName`, `firstName`, `lastName`, `enabled`, `regionalSettings`, `roles` | Admin portal identity and lifecycle state. | +| Role | `roleType`, `userId`, `createdOn` | Coarse access grant. Supported role values include `SUPER_USER`, `USER`, `MANAGE_USERS`, `MANAGE_RIGHTS`, `ACCESS_SIBLINGS`, `ACCESS_AUDIT_LOG`, `ASSUME_USERS`, `REPORT_ADMINISTRATIVE_USER`, `WFO_ACCESS`, `ACCESS_GOODDATA_EDITOR`, `ACCESS_GOODDATA_ANALYST`, `ACCESS_GOODDATA_VIEWER`, and `NO_ACCESS`. | | Rights document | `rightsDocId`, `rightsDocName`, `description`, `active`, `permissions` | Fine-grained administrative permissions. | -| Assignment | `rightsDocId`, `assignedUserId`, `accountIds` | Grants rights document access to a user/account context. | +| Assignment | `rightsDocId`, `userIds`, `rightsDocIds` | Grants rights document access to one or more users. Assignment create operations use query parameters rather than a JSON body. | ## Common Errors @@ -165,7 +165,7 @@ Use the `roleType` path parameter for the role being assigned. | `400 Bad Request` | Missing user fields, invalid role type, or malformed rights document. | Validate against the generated API reference before submitting. | | `403 Forbidden` | Caller cannot manage users, roles, or rights docs. | Grant appropriate Admin portal permission to the automation user. | | `404 Not Found` | User, role, or rights document ID does not exist. | List the target resource before updating or deleting. | -| `409 Conflict` | Email, role, or assignment already exists. | Treat create operations as idempotent by reading current state first. | +| `409 Conflict` | Username, role, or assignment already exists. | Treat create operations as idempotent by reading current state first. | ## Sample Implementation (Python) @@ -174,12 +174,19 @@ import requests BASE_URL = "https://ringcx.ringcentral.com/voice/api" -def onboard_admin_user(token, email, role_type): +def onboard_admin_user(token, user_name, role_type, rights_doc_id=None): headers = {"Authorization": f"Bearer {token}"} user = requests.post( f"{BASE_URL}/v1/admin/users", headers=headers, - json={"email": email, "firstName": "Alex", "lastName": "Admin", "active": True}, + json={ + "userName": user_name, + "firstName": "Alex", + "lastName": "Admin", + "enabled": True, + "roles": ["USER"], + "regionalSettings": {"timezoneName": "America/Denver"}, + }, ) user.raise_for_status() user_id = user.json()["userId"] @@ -189,5 +196,14 @@ def onboard_admin_user(token, email, role_type): headers=headers, ) role.raise_for_status() + + if rights_doc_id is not None: + assignment = requests.post( + f"{BASE_URL}/v1/admin/rightsDocs/{rights_doc_id}/assignments", + headers=headers, + params={"userIds": [user_id]}, + ) + assignment.raise_for_status() + return user.json() ``` diff --git a/specs/engage-voice_openapi3.json b/specs/engage-voice_openapi3.json index 49d3f5c..3d5de08 100644 --- a/specs/engage-voice_openapi3.json +++ b/specs/engage-voice_openapi3.json @@ -26760,7 +26760,11 @@ "description": "rightsDocIds", "required": true, "schema": { - "type": "array" + "type": "array", + "items": { + "type": "integer", + "format": "int32" + } } } ], @@ -26869,7 +26873,11 @@ "description": "userIds", "required": true, "schema": { - "type": "array" + "type": "array", + "items": { + "type": "integer", + "format": "int32" + } } } ], @@ -26935,9 +26943,6 @@ } ], "responses": { - "default": { - "description": "successful operation" - }, "401": { "description": "Unauthorized" }, @@ -26946,6 +26951,9 @@ }, "404": { "description": "Not Found" + }, + "default": { + "description": "successful operation" } }, "security": [ @@ -27431,9 +27439,6 @@ } ], "responses": { - "default": { - "description": "successful operation" - }, "401": { "description": "Unauthorized" }, @@ -27442,6 +27447,9 @@ }, "404": { "description": "Not Found" + }, + "default": { + "description": "successful operation" } }, "security": [ @@ -28120,7 +28128,11 @@ "description": "userIds", "required": true, "schema": { - "type": "array" + "type": "array", + "items": { + "type": "integer", + "format": "int32" + } } } ], @@ -28473,9 +28485,6 @@ } ], "responses": { - "default": { - "description": "successful operation" - }, "401": { "description": "Unauthorized" }, @@ -28484,6 +28493,9 @@ }, "404": { "description": "Not Found" + }, + "default": { + "description": "successful operation" } }, "security": [ @@ -28934,9 +28946,6 @@ } ], "responses": { - "default": { - "description": "successful operation" - }, "401": { "description": "Unauthorized" }, @@ -28945,6 +28954,9 @@ }, "404": { "description": "Not Found" + }, + "default": { + "description": "successful operation" } }, "security": [ @@ -29415,46 +29427,6 @@ } ] } - }, - "/voice/api/v1/auth/smsGateway/messages/callbacks/": { - "post": { - "tags": [ - "Admin Users and Permissions" - ], - "summary": "incomingMessageCallback", - "description": "", - "operationId": "incomingMessageCallback", - "parameters": [ - { - "name": "message", - "in": "query", - "description": "message", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "default": { - "description": "successful operation" - }, - "401": { - "description": "Unauthorized" - }, - "403": { - "description": "Forbidden" - }, - "404": { - "description": "Not Found" - } - }, - "security": [ - { - "BearerAuth": [] - } - ] - } } }, "servers": [ From d0c72e4894f86e1b2b60f13430bbacc8d7ee09c0 Mon Sep 17 00:00:00 2001 From: ajkamen Date: Mon, 1 Jun 2026 11:32:16 -0700 Subject: [PATCH 7/9] docs: merge admin user schema fixes --- docs/users/admin-users-and-permissions.md | 13 ++++++++++--- specs/engage-voice_openapi3.json | 18 ++++++++++++------ 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/docs/users/admin-users-and-permissions.md b/docs/users/admin-users-and-permissions.md index 2942e6a..e8044a4 100644 --- a/docs/users/admin-users-and-permissions.md +++ b/docs/users/admin-users-and-permissions.md @@ -116,11 +116,18 @@ Use the `roleType` path parameter for the role being assigned. ### Create a Rights Document +The `RightsDocument` schema does not have `description` or `active`. Use `cascade` to control whether the document applies to child users and use `accountPermissions`, `productPermissions`, and `resourcePermissions` to declare what the document grants. + ```json { "rightsDocName": "Reporting audit access", - "description": "Read-only analytics and reporting permissions", - "active": true + "cascade": false, + "isMaster": false, + "accountPermissions": [ + "READ" + ], + "productPermissions": [], + "resourcePermissions": [] } ``` @@ -155,7 +162,7 @@ The assignment endpoint takes one or more `userIds` query parameters. It does no | --- | --- | --- | | User | `userId`, `userName`, `firstName`, `lastName`, `enabled`, `regionalSettings`, `roles` | Admin portal identity and lifecycle state. | | Role | `roleType`, `userId`, `createdOn` | Coarse access grant. Supported role values include `SUPER_USER`, `USER`, `MANAGE_USERS`, `MANAGE_RIGHTS`, `ACCESS_SIBLINGS`, `ACCESS_AUDIT_LOG`, `ASSUME_USERS`, `REPORT_ADMINISTRATIVE_USER`, `WFO_ACCESS`, `ACCESS_GOODDATA_EDITOR`, `ACCESS_GOODDATA_ANALYST`, `ACCESS_GOODDATA_VIEWER`, and `NO_ACCESS`. | -| Rights document | `rightsDocId`, `rightsDocName`, `description`, `active`, `permissions` | Fine-grained administrative permissions. | +| Rights document | `rightsDocId`, `rightsDocName`, `ownerId`, `cascade`, `isMaster`, `accountPermissions`, `productPermissions`, `resourcePermissions`, `roleCode`, `isSystemRole` | Fine-grained administrative permissions. There is no `description` or `active` field on this resource. | | Assignment | `rightsDocId`, `userIds`, `rightsDocIds` | Grants rights document access to one or more users. Assignment create operations use query parameters rather than a JSON body. | ## Common Errors diff --git a/specs/engage-voice_openapi3.json b/specs/engage-voice_openapi3.json index 3d5de08..7163fd9 100644 --- a/specs/engage-voice_openapi3.json +++ b/specs/engage-voice_openapi3.json @@ -26757,7 +26757,7 @@ { "name": "rightsDocIds", "in": "query", - "description": "rightsDocIds", + "description": "Repeat the parameter (e.g. ?rightsDocIds=1&rightsDocIds=2) to assign multiple rights documents to the user.", "required": true, "schema": { "type": "array", @@ -26765,7 +26765,9 @@ "type": "integer", "format": "int32" } - } + }, + "style": "form", + "explode": true } ], "responses": { @@ -26870,7 +26872,7 @@ { "name": "userIds", "in": "query", - "description": "userIds", + "description": "Repeat the parameter (e.g. ?userIds=1&userIds=2) to assign the rights document to multiple users.", "required": true, "schema": { "type": "array", @@ -26878,7 +26880,9 @@ "type": "integer", "format": "int32" } - } + }, + "style": "form", + "explode": true } ], "responses": { @@ -28125,7 +28129,7 @@ { "name": "userIds", "in": "query", - "description": "userIds", + "description": "Repeat the parameter (e.g. ?userIds=1&userIds=2) to share the dashboard with multiple users.", "required": true, "schema": { "type": "array", @@ -28133,7 +28137,9 @@ "type": "integer", "format": "int32" } - } + }, + "style": "form", + "explode": true } ], "responses": { From a96451643c21e0ebcd8f38303efac3f5b0c04d2f Mon Sep 17 00:00:00 2001 From: ajkamen Date: Mon, 1 Jun 2026 12:52:02 -0700 Subject: [PATCH 8/9] docs: strengthen admin users guide --- docs/users/admin-users-and-permissions.md | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/docs/users/admin-users-and-permissions.md b/docs/users/admin-users-and-permissions.md index e8044a4..b23c53f 100644 --- a/docs/users/admin-users-and-permissions.md +++ b/docs/users/admin-users-and-permissions.md @@ -41,8 +41,11 @@ The authenticating user must have sufficient Admin portal permissions to read us | Create user | `POST https://ringcx.ringcentral.com/voice/api/v1/admin/users` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/createUser) | | Get user | `GET https://ringcx.ringcentral.com/voice/api/v1/admin/users/{userId}` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/getUser) | | Update user | `PUT https://ringcx.ringcentral.com/voice/api/v1/admin/users/{userId}` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/updateUser) | +| Set active state | `PUT https://ringcx.ringcentral.com/voice/api/v1/admin/users/{userId}/setIsActive` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/setUserIsActive) | | Delete user | `DELETE https://ringcx.ringcentral.com/voice/api/v1/admin/users/{userId}` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/deleteUser) | +Use `activeOnly=true` to list only enabled users and `flatten=true` when you need a flat list instead of a hierarchy. + ## Roles Roles are coarse-grained access assignments. Use role endpoints for straightforward role membership changes. @@ -63,17 +66,25 @@ Rights documents provide detailed administrative permissions. Use these endpoint | Create rights doc | `POST https://ringcx.ringcentral.com/voice/api/v1/admin/users/{userId}/rightsDocs` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/createRightsDoc) | | Update rights doc | `PUT https://ringcx.ringcentral.com/voice/api/v1/admin/users/{userId}/rightsDocs/{rightsDocId}` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/updateRightsDoc) | | Delete rights doc | `DELETE https://ringcx.ringcentral.com/voice/api/v1/admin/users/{userId}/rightsDocs/{rightsDocId}` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/deleteRightsDoc) | +| List assigned rights docs | `GET https://ringcx.ringcentral.com/voice/api/v1/admin/users/{userId}/assignedRightsDocs` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/getUsersAssignedRightsDocs2) | +| List assigned master rights docs | `GET https://ringcx.ringcentral.com/voice/api/v1/admin/users/{userId}/assignedMasterRightsDocs` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/getUsersAssignedRightsDocs) | | Assign rights doc | `POST https://ringcx.ringcentral.com/voice/api/v1/admin/rightsDocs/{rightsDocId}/assignments` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/assignRightsDoc) | +| Assign user to rights docs | `POST https://ringcx.ringcentral.com/voice/api/v1/admin/rightsDocs/assignments/{userId}` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/assignUserToRightsDocs) | | Delete assignment | `DELETE https://ringcx.ringcentral.com/voice/api/v1/admin/rightsDocs/{rightsDocId}/assignments/{assignedUserId}` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/deleteRightsDocAssignment) | -## Auth Utilities +## API Tokens and Auth Utilities | Operation | Method and Path | API Reference | | --- | --- | --- | +| List API tokens | `GET https://ringcx.ringcentral.com/voice/api/v1/admin/token` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/getApiTokensForLoggedInUser) | +| Create API token | `POST https://ringcx.ringcentral.com/voice/api/v1/admin/token` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/createApiTokenForLoggedInUser) | +| Remove API token | `DELETE https://ringcx.ringcentral.com/voice/api/v1/admin/token/{token}` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/removeApiToken) | | Validate token | `GET https://ringcx.ringcentral.com/voice/api/v1/auth/isTokenValid` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/isTokenValid) | | Reset password | `POST https://ringcx.ringcentral.com/voice/api/v1/auth/passwordReset` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/passwordReset) | | Request password reset | `POST https://ringcx.ringcentral.com/voice/api/v1/auth/passwordResetRequest` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/passwordResetRequest) | +API tokens are long-lived authenticated-user tokens. Create and rotate them only for service accounts that are governed like other administrative users. + ## Recommended Workflow 1. List or create the user. @@ -92,6 +103,8 @@ Rights documents provide detailed administrative permissions. Use these endpoint ### Create a User +The create endpoint accepts optional query parameters: `parentUserId` places the new user under an existing administrator, `returnUri` supplies a callback URI for onboarding flows, and `isSSO=true` marks the user for SSO-based access. + ```json { "userName": "alex.admin@example.com", @@ -137,6 +150,8 @@ The `RightsDocument` schema does not have `description` or `active`. Use `cascad The assignment endpoint takes one or more `userIds` query parameters. It does not accept a JSON request body. +To assign multiple rights documents to one user, call `POST https://ringcx.ringcentral.com/voice/api/v1/admin/rightsDocs/assignments/{userId}?rightsDocIds=4567&rightsDocIds=4568`. + ### Example User Response ```json From c2bfbbba2110e089966d784514dd40812aff15da Mon Sep 17 00:00:00 2001 From: ajkamen Date: Mon, 1 Jun 2026 14:42:35 -0700 Subject: [PATCH 9/9] Fix docs links and spec validation --- docs/authentication/auth-engage.md | 10 ++++++++++ docs/index.md | 8 ++++---- docs/integration/admin.md | 4 ++-- docs/users/admin-users-and-permissions.md | 2 +- docs/workforce/qm/index.md | 4 ++-- mkdocs.yml | 3 +++ specs/engage-voice_openapi3.json | 14 +++++++++++--- 7 files changed, 33 insertions(+), 12 deletions(-) diff --git a/docs/authentication/auth-engage.md b/docs/authentication/auth-engage.md index 6bca027..a1f4b4f 100644 --- a/docs/authentication/auth-engage.md +++ b/docs/authentication/auth-engage.md @@ -25,6 +25,16 @@ Here is an example using cURL: In the response, you will see a very long string for an `accessToken`. You'll want to copy and save this for your next call. You will also see a shorter string for a `refreshToken`. Save this token as well to [refresh your access token](#refresh-ringcentral-engage-access-token) when the access token expires. +## Refresh RingCentral Engage Access Token + +Use the `refreshToken` returned by the Engage login response to renew the Engage access token when it expires. + +```http +POST https://engage.ringcentral.com/api/auth/token/refresh?refresh_token={refreshToken} +``` + +The response returns a new `accessToken` and `refreshToken`. Save the new refresh token for the next refresh request. + ## Generate a Permanent API Token In specific instances, a permanent API token is desired (for example, calling an API from the IVR). You can create permanent API tokens for this instance. Every time you run the method below, a new API token will be created and returned. You can also [retrieve a list](#list-all-personal-api-tokens) of permanent API tokens to see which tokens are still working. diff --git a/docs/index.md b/docs/index.md index 575aca5..0b6c254 100644 --- a/docs/index.md +++ b/docs/index.md @@ -8,7 +8,7 @@ no_breadcrumb: true

The following Quick Start Guides have been created to assist developers in getting started in each of our major APIs:

@@ -86,9 +86,9 @@ Welcome RingCentral RingCX Developer! Here you have access to all the resources
Integration & Reports API

Monitor agent activity and download recordings for agent optimization, analysis, compliance and archival.

diff --git a/docs/integration/admin.md b/docs/integration/admin.md index d276eef..1066256 100644 --- a/docs/integration/admin.md +++ b/docs/integration/admin.md @@ -4,7 +4,7 @@ The following set of APIs are for admins that need to manage their sub accounts, ## User List -The user list returns a list of admins on the account. For a list of agents, please use the [Agents](https://developers.ringcentral.com/engage/voice/api-reference/Integration-Agent-Controller/getAgentList) API. The [public user list](https://developers.ringcentral.com/engage/voice/api-reference/Users/listAllUsers) most developers will use has many details including creation date, enabled status, and roles. However, for integrations, a smaller set of user data may be all that is needed, but with the added ability to distinguish the RingCX user name from the RingEX user name and the environment ID. For this purpose, there's an [integration user list](https://developers.ringcentral.com/engage/voice/api-reference/Integration-User-Controller/getUserList) that can be used instead. +The user list returns a list of admins on the account. For a list of agents, please use the [Agents](https://developers.ringcentral.com/engage/voice/api-reference/Integration-Agent-Controller/getAgentList) API. The [public user list](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/listAllUsers) most developers will use has many details including creation date, enabled status, and roles. However, for integrations, a smaller set of user data may be all that is needed, but with the added ability to distinguish the RingCX user name from the RingEX user name and the environment ID. For this purpose, there's an [integration user list](https://developers.ringcentral.com/engage/voice/api-reference/Integration-User-Controller/getUserList) that can be used instead. ## Sub-Accounts @@ -16,7 +16,7 @@ Most developers will want a list of agents and agent groups, but for workforce m ## Queue Groups with Agents -Once known as gates, queues are inbound routing rules for customers calling in to a number. Typically, queues have agents assigned to them and each queue would have to be iterated through to find all the agents assigned to a queue group. However, the [gate group with agents](https://developers.ringcentral.com/engage/voice/api-reference/Integration-Gate-Group-Controller/getGateGroupsWithAgents) integration API allows you to get a complete list of all queues in a queue group and the agents contained in that queue in a single call. +Once known as gates, queues are inbound routing rules for customers calling in to a number. Typically, queues have agents assigned to them and each queue would have to be iterated through to find all the agents assigned to a queue group. However, the [gate group with agents](https://developers.ringcentral.com/engage/voice/api-reference/Public-Integration-API/getQueuesWithAgents) integration API allows you to get a complete list of all queues in a queue group and the agents contained in that queue in a single call. !!! info "This is not active agents in a queue" This API only returns a list of agents assigned to the queue. It does not return a list of agents actively receivng calls and chats from a queue. diff --git a/docs/users/admin-users-and-permissions.md b/docs/users/admin-users-and-permissions.md index b23c53f..2587226 100644 --- a/docs/users/admin-users-and-permissions.md +++ b/docs/users/admin-users-and-permissions.md @@ -37,7 +37,7 @@ The authenticating user must have sufficient Admin portal permissions to read us | Operation | Method and Path | API Reference | | --- | --- | --- | -| List users | `GET https://ringcx.ringcentral.com/voice/api/v1/admin/users` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/getUserList) | +| List users | `GET https://ringcx.ringcentral.com/voice/api/v1/admin/users` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/listAllUsers) | | Create user | `POST https://ringcx.ringcentral.com/voice/api/v1/admin/users` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/createUser) | | Get user | `GET https://ringcx.ringcentral.com/voice/api/v1/admin/users/{userId}` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/getUser) | | Update user | `PUT https://ringcx.ringcentral.com/voice/api/v1/admin/users/{userId}` | [Reference](https://developers.ringcentral.com/engage/voice/api-reference/Admin-Users-and-Permissions/updateUser) | diff --git a/docs/workforce/qm/index.md b/docs/workforce/qm/index.md index af34e72..1fee449 100644 --- a/docs/workforce/qm/index.md +++ b/docs/workforce/qm/index.md @@ -12,11 +12,11 @@ When a call is ended, a call event is triggered so you can know that a call is r ## Call Details and Recordings -Sometimes, you may miss an event due to server issues or connection issues. In these cases, you can reconcile your call events with the [Call Details and Recordings](../../analytics/reports/global-call-type-detail-report.md) report. All the call details are available in this historical report including the [single channel call recording](../../analytics/reports/global-call-type-detail-report.md#call-recordings). +Sometimes, you may miss an event due to server issues or connection issues. In these cases, you can reconcile your call events with the [Call Details and Recordings](../../integration/reports-orig.md#interaction-metadata-media) report. All the call details are available in this historical report including the [single channel call recording](../../integration/reports-orig.md#retrieving-agent-segment-recordings-transcripts). ## Agent Reports -Not all agent performance can be tracked via events. Some details like ring time, hold time, and talk time are all captured and report on after the call. You can find these report details in the [Agent Segment Metadata Report](../../analytics/reports/agent-segment-metadata-report.md). This report also includes the call recording, stored as a `WAV` file and can be retrieved 1-2 minutes after the call ends. To determine when a call ends, use the [Configuring Workforce Management](../../notifications/wfm/configure-wfm.md) to listen for End Call Events. +Not all agent performance can be tracked via events. Some details like ring time, hold time, and talk time are all captured and report on after the call. You can find these report details in the [Agent Segment Metadata Report](../../integration/reports-orig.md#agent-segment-metadata). This report also includes the call recording, stored as a `WAV` file and can be retrieved 1-2 minutes after the call ends. To determine when a call ends, use the [Configuring Workforce Management](../../notifications/wfm/configure-wfm.md) to listen for End Call Events. ## Call Recordings diff --git a/mkdocs.yml b/mkdocs.yml index 5bdc8c9..5c0c332 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -2,6 +2,9 @@ site_name: RingCentral RingCX Developer Guide site_url: https://engage-voice-api-docs.rtfd.org repo_url: https://github.com/ringcentral/engage-voice-api-docs docs_dir: docs +exclude_docs: | + integration/reports.md + theme: name: ringcentral product_section: engage diff --git a/specs/engage-voice_openapi3.json b/specs/engage-voice_openapi3.json index 7163fd9..e6f4adb 100644 --- a/specs/engage-voice_openapi3.json +++ b/specs/engage-voice_openapi3.json @@ -2109,6 +2109,14 @@ }, "type": "object" }, + "ActiveStateBoolean": { + "properties": { + "isActive": { + "type": "boolean" + } + }, + "type": "object" + }, "AgentAccountAccess": { "properties": { "account": { @@ -24080,7 +24088,7 @@ ], "summary": "Retrieves all Api Tokens for AuthenticatedUser", "tags": [ - "Legacy Auth" + "Admin Users and Permissions" ] }, "post": { @@ -24123,7 +24131,7 @@ ], "summary": "Creates a new 'Api Token' based AuthenticatedUser that does not expire", "tags": [ - "Legacy Auth" + "Admin Users and Permissions" ] } }, @@ -24176,7 +24184,7 @@ ], "summary": "Removes an api token", "tags": [ - "Legacy Auth" + "Admin Users and Permissions" ] } },