Summary and recommendation
BeyondTrust exposes a REST API at `https://<hostname>/api/public/v3` using OAuth 2.0 client credentials (POST to `/oauth2/token` with `client_id` + `client_secret`). A critical caveat: BeyondTrust is not a single API surface.
Privileged Remote Access, Remote Support, Password Safe, and BeyondInsight each have separate API bases and separate documentation; confirm which product you are targeting before writing any integration code. There is no shared SaaS API gateway - every call resolves against your specific appliance or cloud hostname.
For teams building identity automation at scale, Stitchflow's MCP server with ~100 deep IT/identity integrations handles BeyondTrust alongside the rest of your stack, normalizing auth flows and pagination differences across products.
API quick reference
| Has user API | Yes |
| Auth method | OAuth 2.0 client credentials (client_id + client_secret exchanged for Bearer token); some endpoints use HTTP Basic for initial token acquisition |
| Base URL | Official docs |
| SCIM available | Yes |
| SCIM plan required | Enterprise |
Authentication
Auth method: OAuth 2.0 client credentials (client_id + client_secret exchanged for Bearer token); some endpoints use HTTP Basic for initial token acquisition
Setup steps
- Log in to the BeyondTrust admin console (e.g., /login).
- Navigate to Management > API Configuration and create an API account with appropriate permissions.
- Note the client_id and client_secret generated for the API account.
- POST to /oauth2/token with grant_type=client_credentials, client_id, and client_secret to obtain a Bearer access token.
- Include the Bearer token in the Authorization header for all subsequent API requests.
- Tokens expire; implement refresh logic by re-requesting a new token before expiry.
Required scopes
| Scope | Description | Required for |
|---|---|---|
| full_access | Full read/write access to all API resources including user management | Creating, updating, and deleting users |
| read_only | Read-only access to API resources | Listing and retrieving user details |
User object / data model
| Field | Type | Description | On create | On update | Notes |
|---|---|---|---|---|---|
| id | integer | Unique internal user identifier | auto-generated | read-only | Used as path parameter for user-specific operations |
| username | string | Login username | required | optional | Must be unique within the deployment |
| password | string | User password (write-only) | required for local accounts | optional | Never returned in responses |
| display_name | string | Full display name of the user | required | optional | |
| email_address | string | User email address | optional | optional | Used for notifications |
| enabled | boolean | Whether the user account is active | optional (default true) | optional | Set to false to disable without deleting |
| account_type | string | Type of account: local, LDAP, SAML, etc. | required | read-only | Determines authentication method |
| group_memberships | array | List of group IDs the user belongs to | optional | optional | Controls permissions via group policy |
| public_key | string | SSH public key for key-based auth | optional | optional | Applicable to certain access scenarios |
| last_login | datetime | Timestamp of last successful login | auto | read-only | ISO 8601 format |
| created_at | datetime | Account creation timestamp | auto | read-only | ISO 8601 format |
| locale | string | User interface locale/language preference | optional | optional |
Core endpoints
List Users
- Method: GET
- URL:
https://<hostname>/api/public/v3/users - Watch out for: Pagination uses offset/limit; no cursor. Large deployments may require multiple requests.
Request example
GET /api/public/v3/users?offset=0&limit=100
Authorization: Bearer <token>
Response example
{
"users": [
{"id": 1, "username": "jdoe", "display_name": "Jane Doe", "enabled": true}
],
"total": 1
}
Get User
- Method: GET
- URL:
https://<hostname>/api/public/v3/users/{user_id} - Watch out for: user_id is the internal integer ID, not the username.
Request example
GET /api/public/v3/users/42
Authorization: Bearer <token>
Response example
{
"id": 42,
"username": "jdoe",
"display_name": "Jane Doe",
"email_address": "jdoe@example.com",
"enabled": true
}
Create User
- Method: POST
- URL:
https://<hostname>/api/public/v3/users - Watch out for: password is required for local account_type. LDAP/SAML accounts do not require a password field.
Request example
POST /api/public/v3/users
Authorization: Bearer <token>
Content-Type: application/json
{"username":"jdoe","display_name":"Jane Doe","password":"S3cur3!","account_type":"local"}
Response example
{
"id": 42,
"username": "jdoe",
"display_name": "Jane Doe",
"enabled": true
}
Update User
- Method: PUT
- URL:
https://<hostname>/api/public/v3/users/{user_id} - Watch out for: Some products use PUT (full replace) rather than PATCH; omitting fields may reset them to defaults.
Request example
PUT /api/public/v3/users/42
Authorization: Bearer <token>
Content-Type: application/json
{"display_name":"Jane A. Doe","enabled":false}
Response example
{
"id": 42,
"username": "jdoe",
"display_name": "Jane A. Doe",
"enabled": false
}
Delete User
- Method: DELETE
- URL:
https://<hostname>/api/public/v3/users/{user_id} - Watch out for: Deletion is permanent. Consider disabling (enabled=false) instead for audit trail preservation.
Request example
DELETE /api/public/v3/users/42
Authorization: Bearer <token>
Response example
HTTP 204 No Content
List Groups
- Method: GET
- URL:
https://<hostname>/api/public/v3/groups - Watch out for: Group membership controls permissions; always verify group IDs before assigning users.
Request example
GET /api/public/v3/groups
Authorization: Bearer <token>
Response example
{
"groups": [
{"id": 5, "name": "Admins", "description": "Admin group"}
]
}
Add User to Group
- Method: POST
- URL:
https://<hostname>/api/public/v3/groups/{group_id}/members - Watch out for: Group membership changes take effect immediately; no confirmation step.
Request example
POST /api/public/v3/groups/5/members
Authorization: Bearer <token>
Content-Type: application/json
{"user_id": 42}
Response example
HTTP 200 OK
{"group_id": 5, "user_id": 42}
Obtain OAuth Token
- Method: POST
- URL:
https://<hostname>/oauth2/token - Watch out for: Tokens expire (typically 3600s). Cache and refresh proactively; do not request a new token per API call.
Request example
POST /oauth2/token
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials&client_id=<id>&client_secret=<secret>
Response example
{
"access_token": "eyJ...",
"token_type": "Bearer",
"expires_in": 3600
}
Rate limits, pagination, and events
Rate limits: BeyondTrust does not publicly document specific rate limit thresholds. Rate limiting behavior is deployment-dependent (on-premises vs. cloud-hosted).
Rate-limit headers: Unknown
Retry-After header: Unknown
Rate-limit notes: No publicly documented rate limits found in official docs. Contact BeyondTrust support for deployment-specific limits.
Pagination method: offset
Default page size: 100
Max page size: Not documented
Pagination pointer: offset / limit
Webhooks available: No
Webhook notes: BeyondTrust does not publicly document outbound webhook support for user management events in its REST API. Event-driven integrations are typically handled via Syslog, SIEM connectors, or the BeyondInsight reporting API.
Alternative event strategy: Use BeyondInsight's reporting/audit API or Syslog/SIEM integration for event-driven workflows.
SCIM API status
SCIM available: Yes
SCIM version: 2.0
Plan required: Enterprise
Endpoint: https://
/scim/v2 Supported operations: GET /Users, GET /Users/{id}, POST /Users, PUT /Users/{id}, PATCH /Users/{id}, DELETE /Users/{id}, GET /Groups, POST /Groups, PATCH /Groups/{id}
Limitations:
- Requires SSO (SAML or OIDC) to be configured as a prerequisite.
- SCIM provisioning is configured through the IdP (Okta, Entra ID); BeyondTrust acts as the SCIM service provider.
- Available only on Enterprise tier; not available on lower-tier or standalone Remote Support licenses.
- Group push support may vary by IdP connector version.
- Password sync is not supported via SCIM (SSO handles authentication).
Common scenarios
Three scenarios cover the majority of lifecycle automation needs:
- Provision a local user and assign to a group: POST to
/userswithaccount_type=local, capture the returnedid, then POST to/groups/{group_id}/members. Group assignment is the permission grant - skipping it leaves the user with no access. - Disable a user via REST: GET the full user object first, set
enabled=false, then PUT the full object back. BeyondTrust's PUT is full-replace semantics; omitting any field can silently reset it to default. - IdP-driven SCIM deprovisioning: Requires Enterprise tier and SSO fully configured as a prerequisite. The IdP (Okta or Entra ID) sends either
PATCH active=falseorDELETEto/scim/v2/Users/{id}- which operation fires depends on IdP configuration, not BeyondTrust. Verify this behavior in a non-production environment before enabling in production to avoid accidental hard-deletes.
Pagination is offset/limit-based with a default page size of 100; no cursor support. Large deployments require explicit iteration.
Provision a new local user and assign to a group
- POST /oauth2/token with client_credentials to obtain Bearer token.
- POST /api/public/v3/users with username, display_name, password, account_type=local to create the user; capture returned id.
- GET /api/public/v3/groups to find the target group_id.
- POST /api/public/v3/groups/{group_id}/members with {user_id:
} to assign group membership.
Watch out for: Group assignment controls all permissions; a user without group membership has no access to managed resources.
Deprovision a user via SCIM (IdP-driven)
- Ensure SCIM 2.0 is configured in BeyondTrust Enterprise with your IdP (Okta or Entra ID).
- Deactivate or remove the user from the BeyondTrust application assignment in the IdP.
- The IdP sends a PATCH /scim/v2/Users/{id} with active=false or DELETE /scim/v2/Users/{id} to BeyondTrust.
- BeyondTrust disables or removes the user account automatically.
Watch out for: SCIM DELETE vs. PATCH active=false behavior depends on IdP configuration; verify whether the IdP sends a soft-disable or hard-delete to avoid accidental permanent deletion.
Disable a user account via REST API
- POST /oauth2/token to obtain Bearer token.
- GET /api/public/v3/users?username=jdoe to find the user's internal id.
- PUT /api/public/v3/users/{id} with full user object including enabled=false to disable the account.
Watch out for: Because PUT is full-replace, retrieve the full user object first and modify only the enabled field before sending the PUT to avoid resetting other fields.
Why building this yourself is a trap
The most dangerous API behavior is the PUT full-replace pattern on user objects. Developers who retrieve a user, modify one field, and PUT only that field will silently wipe all other attributes - including group memberships that control every permission the user holds. Always retrieve the complete user object and send it back in full.
Rate limits are not publicly documented and are deployment-dependent; on-premises instances may behave differently from cloud-hosted ones. OAuth tokens expire (typically 3600s) - implement proactive refresh logic rather than requesting a new token per call. On-premises deployments frequently use self-signed TLS certificates, which will cause API client failures unless the certificate is explicitly trusted.
SCIM provisioning will fail entirely if SSO is not configured first; there is no graceful fallback.
Automate BeyondTrust workflows without one-off scripts
Stitchflow builds and maintains end-to-end IT automation across your SaaS stack, including apps without APIs. Built for exactly how your company works, with human approvals where they matter.