Summary and recommendation
The Mend REST API v2.0 (base: https://api.mend.io/api/v2.0) supports full user lifecycle management: invite, read, update, and delete.
Authentication is a two-step exchange - POST userKey and orgToken to /login to receive a short-lived JWT (~30 min), then pass it as a Bearer token on every subsequent request.
A critical distinction: the orgToken used for login is not the same as the orgUuid used in API path parameters;
retrieve orgUuid from org settings or the login response.
Response payloads use a non-standard envelope where actual data is nested under the retVal field, not the root object - parsers must account for this.
SCIM is not natively supported, making this REST API the primary integration surface for identity graph synchronization across your provisioning pipeline.
API quick reference
| Has user API | Yes |
| Auth method | JWT Bearer Token obtained by exchanging an API key (userKey + orgToken) via a login endpoint |
| Base URL | Official docs |
| SCIM available | No |
| SCIM plan required | Enterprise |
Authentication
Auth method: JWT Bearer Token obtained by exchanging an API key (userKey + orgToken) via a login endpoint
Setup steps
- Log in to the Mend (WhiteSource) portal and navigate to your profile to retrieve your userKey.
- Obtain the orgToken (also called productToken or organizationUuid) from the organization settings.
- POST to https://api.mend.io/api/v2.0/login with {userKey, orgToken} in the request body to receive a JWT.
- Include the JWT as a Bearer token in the Authorization header for all subsequent API requests: 'Authorization: Bearer
'. - JWTs are short-lived; re-authenticate when the token expires (typically 30 minutes).
Required scopes
| Scope | Description | Required for |
|---|---|---|
| Admin role | Full access to user management operations including create, update, deactivate users. | POST /users, PUT /users/{uuid}, DELETE /users/{uuid} |
| Organization Admin | Required to list and manage users at the organization level. | GET /users |
User object / data model
| Field | Type | Description | On create | On update | Notes |
|---|---|---|---|---|---|
| uuid | string | Unique identifier for the user. | system-generated | immutable | Used as path parameter for user-specific operations. |
| string | User's email address; used as login identifier. | required | optional | Must be unique within the organization. | |
| name | string | Full display name of the user. | required | optional | |
| role | string (enum) | User role within the organization (e.g., Admin, User). | optional | optional | Roles control access to organization-level features. |
| status | string (enum) | Account status: ACTIVE or INACTIVE. | defaults to ACTIVE | optional | Setting to INACTIVE deactivates the user without deletion. |
| invitationStatus | string | Whether the user has accepted their invitation. | system-set | read-only | Values include PENDING, ACCEPTED. |
| userKey | string | API key associated with the user for authentication. | system-generated | read-only | Returned only for the authenticated user's own profile. |
| groups | array of strings | Group memberships for the user. | optional | optional | Group names must already exist in the organization. |
Core endpoints
Authenticate / Get JWT
- Method: POST
- URL:
https://api.mend.io/api/v2.0/login - Watch out for: JWT expires in ~30 minutes. Automate re-authentication in long-running scripts.
Request example
POST /api/v2.0/login
Content-Type: application/json
{
"userKey": "<userKey>",
"orgToken": "<orgToken>"
}
Response example
{
"retVal": {
"jwtToken": "eyJ...",
"jwtTTL": 1800
}
}
List Users
- Method: GET
- URL:
https://api.mend.io/api/v2.0/orgs/{orgUuid}/users - Watch out for: Requires Organization Admin role. Use orgUuid (not orgToken) in the path.
Request example
GET /api/v2.0/orgs/{orgUuid}/users?page=0&pageSize=25
Authorization: Bearer <jwt>
Response example
{
"retVal": [
{"uuid":"abc123","email":"user@example.com","name":"Jane Doe","role":"User","status":"ACTIVE"}
],
"additionalData": {"totalItems": 1}
}
Get User by UUID
- Method: GET
- URL:
https://api.mend.io/api/v2.0/orgs/{orgUuid}/users/{userUuid} - Watch out for: Returns 404 if the user UUID does not belong to the specified org.
Request example
GET /api/v2.0/orgs/{orgUuid}/users/{userUuid}
Authorization: Bearer <jwt>
Response example
{
"retVal": {
"uuid": "abc123",
"email": "user@example.com",
"name": "Jane Doe",
"role": "User",
"status": "ACTIVE"
}
}
Invite / Create User
- Method: POST
- URL:
https://api.mend.io/api/v2.0/orgs/{orgUuid}/users - Watch out for: Creates user via invitation email. User must accept invite before becoming ACTIVE. Duplicate email returns an error.
Request example
POST /api/v2.0/orgs/{orgUuid}/users
Authorization: Bearer <jwt>
Content-Type: application/json
{
"email": "newuser@example.com",
"name": "New User",
"role": "User"
}
Response example
{
"retVal": {
"uuid": "def456",
"email": "newuser@example.com",
"invitationStatus": "PENDING"
}
}
Update User
- Method: PUT
- URL:
https://api.mend.io/api/v2.0/orgs/{orgUuid}/users/{userUuid} - Watch out for: Full PUT semantics; omitting optional fields may reset them. Verify field behavior in the API reference.
Request example
PUT /api/v2.0/orgs/{orgUuid}/users/{userUuid}
Authorization: Bearer <jwt>
Content-Type: application/json
{
"role": "Admin",
"status": "ACTIVE"
}
Response example
{
"retVal": {
"uuid": "def456",
"role": "Admin",
"status": "ACTIVE"
}
}
Deactivate / Delete User
- Method: DELETE
- URL:
https://api.mend.io/api/v2.0/orgs/{orgUuid}/users/{userUuid} - Watch out for: Removes the user from the organization. This action may be irreversible; confirm before automating bulk deletes.
Request example
DELETE /api/v2.0/orgs/{orgUuid}/users/{userUuid}
Authorization: Bearer <jwt>
Response example
{
"retVal": "User successfully removed."
}
List Groups
- Method: GET
- URL:
https://api.mend.io/api/v2.0/orgs/{orgUuid}/groups - Watch out for: Groups are used for policy assignment. Group membership is managed separately from user creation.
Request example
GET /api/v2.0/orgs/{orgUuid}/groups
Authorization: Bearer <jwt>
Response example
{
"retVal": [
{"uuid": "grp001", "name": "developers", "memberCount": 12}
]
}
Add User to Group
- Method: POST
- URL:
https://api.mend.io/api/v2.0/orgs/{orgUuid}/groups/{groupUuid}/users - Watch out for: User must already exist in the org (ACTIVE or PENDING) before being added to a group.
Request example
POST /api/v2.0/orgs/{orgUuid}/groups/{groupUuid}/users
Authorization: Bearer <jwt>
Content-Type: application/json
{
"userUuids": ["def456"]
}
Response example
{
"retVal": "Users successfully added to group."
}
Rate limits, pagination, and events
Rate limits: Official rate limit specifics are not publicly documented in the Mend API reference as of the policy date.
Rate-limit headers: No
Retry-After header: No
Rate-limit notes: No explicit rate limit values or headers are documented in official sources. Contact Mend support for enterprise rate limit details.
Pagination method: offset
Default page size: 25
Max page size: 100
Pagination pointer: pageSize / page
Webhooks available: No
Webhook notes: Mend/WhiteSource does not document outbound webhooks for user lifecycle events in official sources.
Alternative event strategy: Poll the GET /orgs/{orgUuid}/users endpoint to detect user status changes, or use SCIM provisioning with a supported IdP for automated lifecycle events.
SCIM API status
- SCIM available: No
- SCIM version: Not documented
- Plan required: Enterprise
- Endpoint: Not documented
Limitations:
- SCIM provisioning is not natively available in WhiteSource/Mend as of the policy date per the context reference.
- SSO (SAML) is a prerequisite for any IdP-based provisioning.
- Enterprise plan required for SSO and advanced provisioning features.
- Okta and Entra ID (Azure AD) are supported IdPs for SSO; SCIM connector availability should be confirmed directly with Mend support.
Common scenarios
Three automation scenarios cover the core lifecycle.
For onboarding: POST to /orgs/{orgUuid}/users to trigger an invitation email, then poll GET /orgs/{orgUuid}/users/{userUuid} until invitationStatus is ACCEPTED before executing POST /orgs/{orgUuid}/groups/{groupUuid}/users - group policy enforcement does not activate on PENDING users.
For offboarding: resolve the user's UUID by paginating GET /orgs/{orgUuid}/users filtered by email, then DELETE /orgs/{orgUuid}/users/{userUuid};
deletion is a permanent org removal, so consider a PUT to set status=INACTIVE first if audit retention is required.
For bulk role audits: paginate GET /orgs/{orgUuid}/users with pageSize=100 (default is 25), collect uuid, email, role, status, and invitationStatus per record, and flag Admin-role or INACTIVE accounts for review.
No rate limit headers are documented;
add conservative inter-request delays on paginated loops.
Onboard a new developer and assign to a group
- POST /api/v2.0/login with userKey and orgToken to obtain JWT.
- POST /api/v2.0/orgs/{orgUuid}/users with email, name, and role to send invitation.
- Poll GET /api/v2.0/orgs/{orgUuid}/users/{userUuid} until invitationStatus is ACCEPTED.
- POST /api/v2.0/orgs/{orgUuid}/groups/{groupUuid}/users with the new user's UUID to assign group membership.
Watch out for: User must accept the invitation email before group assignment takes effect for policy enforcement. Automate the polling step with a timeout and alerting.
Offboard a departing employee
- POST /api/v2.0/login to obtain a fresh JWT.
- GET /api/v2.0/orgs/{orgUuid}/users?page=0&pageSize=100 and filter by email to find the user's UUID.
- DELETE /api/v2.0/orgs/{orgUuid}/users/{userUuid} to remove the user from the organization.
Watch out for: Deletion is permanent removal from the org. If audit trail retention is required, consider setting status to INACTIVE via PUT before deletion, if supported.
Bulk audit of user roles and statuses
- POST /api/v2.0/login to obtain JWT.
- Paginate through GET /api/v2.0/orgs/{orgUuid}/users using page and pageSize parameters until totalItems is exhausted.
- For each user, record uuid, email, role, status, and invitationStatus.
- Flag users with role=Admin or status=INACTIVE for review.
Watch out for: Default page size is 25; set pageSize=100 to reduce request count. No rate limit headers are documented, so add conservative delays between paginated requests.
Why building this yourself is a trap
The invitation-based user creation model is the most common automation trap: POST /orgs/{orgUuid}/users does not produce an ACTIVE user - it produces a PENDING one. Any downstream step that depends on an active identity (group assignment, policy enforcement, identity graph node creation) will silently fail or produce inconsistent state until the human accepts the email.
Automate the polling step with a timeout and alerting rather than assuming synchronous activation. A second trap is JWT expiry: at approximately 30 minutes, long-running scripts that do not implement token refresh will begin returning 401s mid-execution.
A third: the DELETE endpoint is documented as permanent removal with no explicit restore path - bulk offboarding scripts must include a dry-run or confirmation gate before execution.
Automate WhiteSource 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.