Stitchflow
Bitwarden logo

Bitwarden User Management API Guide

API workflow

How to automate user lifecycle operations through APIs with caveats that matter in production.

UpdatedMar 4, 2026

Summary and recommendation

Bitwarden's Public API uses OAuth 2.0 client credentials (scope: api.organization) issued per organization from the web vault. The token endpoint (https://identity.bitwarden.com/connect/token) and the API base URL (https://api.bitwarden.com) are separate hosts - a common misconfiguration point. Access tokens expire; implement refresh logic on 401 responses rather than assuming token longevity.

Self-hosted deployments replace both URLs with custom domain equivalents, so any integration must make base URLs configurable. Bitwarden does not publish numeric rate limits; no rate-limit headers are returned, so implement conservative retry logic with exponential backoff.

API quick reference

Has user APIYes
Auth methodOAuth 2.0 client credentials (organization API key)
Base URLOfficial docs
SCIM availableYes
SCIM plan requiredTeams or Enterprise

Authentication

Auth method: OAuth 2.0 client credentials (organization API key)

Setup steps

  1. Log in to the Bitwarden web vault as an organization owner.
  2. Navigate to Organization Settings > My Organization.
  3. Scroll to API Key section and click View API Key.
  4. Note the client_id (format: organization.{uuid}) and client_secret.
  5. POST to https://identity.bitwarden.com/connect/token with grant_type=client_credentials, scope=api.organization, client_id, and client_secret.
  6. Use the returned access_token as a Bearer token in the Authorization header for all Public API requests.

Required scopes

Scope Description Required for
api.organization Grants access to the Bitwarden Public API for organization management operations. All Public API endpoints including member, group, collection, and event management.

User object / data model

Field Type Description On create On update Notes
id string (UUID) Unique identifier for the organization member. system-generated read-only Used as path parameter for member operations.
userId string (UUID) Bitwarden user account UUID. system-generated read-only Distinct from the organization membership id.
email string User's email address. required not updatable via API Used to invite members.
name string Display name of the user. optional read-only Set by the user on their account.
status integer (enum) Membership status: 0=Invited, 1=Accepted, 2=Confirmed, -1=Revoked. auto-set to 0 via confirm/revoke endpoints Revoked members retain their account but lose org access.
type integer (enum) Organization role: 0=Owner, 1=Admin, 2=User, 3=Manager, 4=Custom. required updatable Custom role requires Enterprise plan.
accessAll boolean Whether the member has access to all collections. optional updatable If true, collections array is ignored.
externalId string External identifier for directory sync. optional updatable Used by Directory Connector and SCIM.
resetPasswordEnrolled boolean Whether the member is enrolled in admin password reset. read-only read-only Enrollment is user-initiated or policy-enforced.
collections array of objects Collections the member has access to, with readOnly and hidePasswords flags. optional updatable Ignored if accessAll is true.
groups array of strings (UUIDs) Group IDs the member belongs to. optional updatable via group endpoints Groups available on Teams and Enterprise plans.
twoFactorEnabled boolean Whether the user has two-step login enabled. read-only read-only Informational only.
permissions object Granular permissions for Custom role members. optional updatable Only applicable when type=4 (Custom).

Core endpoints

List organization members

  • Method: GET
  • URL: https://api.bitwarden.com/public/members
  • Watch out for: Returns all members regardless of status (invited, accepted, confirmed, revoked). No pagination; all members returned in one response.

Request example

GET /public/members
Authorization: Bearer {access_token}

Response example

{
  "data": [
    {"id":"uuid","email":"user@example.com","status":2,"type":2,"accessAll":false}
  ],
  "object": "list"
}

Get a member

  • Method: GET
  • URL: https://api.bitwarden.com/public/members/{id}
  • Watch out for: The {id} is the organization membership UUID, not the user's global Bitwarden userId.

Request example

GET /public/members/member-uuid
Authorization: Bearer {access_token}

Response example

{
  "id": "member-uuid",
  "email": "user@example.com",
  "status": 2,
  "type": 2,
  "accessAll": false,
  "object": "member"
}

Invite a member

  • Method: POST
  • URL: https://api.bitwarden.com/public/members
  • Watch out for: Invitation email is sent automatically. Member status is 0 (Invited) until they accept. Cannot invite an email already in the organization.

Request example

POST /public/members
Content-Type: application/json
{
  "email": "newuser@example.com",
  "type": 2,
  "accessAll": false,
  "collections": [{"id":"col-uuid","readOnly":false}]
}

Response example

{
  "id": "new-member-uuid",
  "email": "newuser@example.com",
  "status": 0,
  "type": 2,
  "object": "member"
}

Update a member

  • Method: PUT
  • URL: https://api.bitwarden.com/public/members/{id}
  • Watch out for: Full replacement (PUT), not partial update. Omitting fields may reset them. Use GET first to preserve existing values.

Request example

PUT /public/members/member-uuid
Content-Type: application/json
{
  "type": 1,
  "accessAll": true,
  "collections": []
}

Response example

{
  "id": "member-uuid",
  "type": 1,
  "accessAll": true,
  "status": 2,
  "object": "member"
}

Delete (remove) a member

  • Method: DELETE
  • URL: https://api.bitwarden.com/public/members/{id}
  • Watch out for: Permanently removes the member from the organization. Their personal Bitwarden account is not deleted. Consider using revoke instead to preserve audit history.

Request example

DELETE /public/members/member-uuid
Authorization: Bearer {access_token}

Response example

HTTP 200 OK (empty body)

Revoke a member

  • Method: PUT
  • URL: https://api.bitwarden.com/public/members/{id}/revoke
  • Watch out for: Sets member status to -1 (Revoked). Member loses org access but remains in the member list. Can be restored via the restore endpoint.

Request example

PUT /public/members/member-uuid/revoke
Authorization: Bearer {access_token}

Response example

HTTP 200 OK (empty body)

Restore a member

  • Method: PUT
  • URL: https://api.bitwarden.com/public/members/{id}/restore
  • Watch out for: Restores a previously revoked member. Member must re-confirm if they had not previously confirmed.

Request example

PUT /public/members/member-uuid/restore
Authorization: Bearer {access_token}

Response example

HTTP 200 OK (empty body)

List groups

  • Method: GET
  • URL: https://api.bitwarden.com/public/groups
  • Watch out for: Groups are only available on Teams and Enterprise plans. Returns 404 or empty on Free/Families plans.

Request example

GET /public/groups
Authorization: Bearer {access_token}

Response example

{
  "data": [
    {"id":"group-uuid","name":"Engineering","accessAll":false}
  ],
  "object": "list"
}

Rate limits, pagination, and events

  • Rate limits: Bitwarden does not publish explicit numeric rate limits for the Public API in official documentation.

  • Rate-limit headers: No

  • Retry-After header: No

  • Rate-limit notes: No documented rate limit tiers or headers found in official docs. Standard fair-use limits likely apply server-side.

  • Pagination method: none

  • Default page size: 0

  • Max page size: 0

  • Pagination pointer: Not documented

  • Webhooks available: No

  • Webhook notes: Bitwarden does not offer outbound webhooks from the Public API. Event logs are available via the /public/events endpoint (GET, poll-based).

  • Alternative event strategy: Poll GET https://api.bitwarden.com/public/events with date range filters (start, end query params) to retrieve audit events including user actions.

SCIM API status

  • SCIM available: Yes

  • SCIM version: 2.0

  • Plan required: Teams or Enterprise

  • Endpoint: https://scim.bitwarden.com/{organizationId}/v2

  • Supported operations: GET /Users, GET /Users/{id}, POST /Users, PUT /Users/{id}, PATCH /Users/{id}, DELETE /Users/{id}, GET /Groups, GET /Groups/{id}, POST /Groups, PUT /Groups/{id}, PATCH /Groups/{id}, DELETE /Groups/{id}

Limitations:

  • SCIM token is generated in Organization Settings > SCIM Provisioning; it is a static bearer token, not OAuth.
  • SSO (Login with SSO) must be configured and enabled before SCIM provisioning is activated.
  • Self-hosted Bitwarden uses a different SCIM endpoint: https://{your-domain}/scim/{organizationId}/v2.
  • Deprovisioning via SCIM DELETE revokes the member (status=-1), it does not delete their Bitwarden account.
  • Supported IdPs with native SCIM connectors: Okta, Azure AD (Entra ID), OneLogin, JumpCloud, Ping Identity.
  • Google Workspace does not have a native SCIM connector; use Bitwarden Directory Connector instead.
  • SCIM and Directory Connector should not be used simultaneously for the same organization.

Common scenarios

The Public API covers member invite, update (PUT, full replacement only), revoke, restore, and delete - plus group and collection management on Teams and Enterprise. The critical gap: member confirmation after acceptance cannot be automated via the Public API and requires a vault admin action.

For fully automated provisioning, SCIM is the correct path - it bypasses the confirmation step entirely and auto-confirms provisioned users.

Stitchflow connects to Bitwarden through an MCP server with ~100 deep IT/identity integrations, enabling provisioning workflows to be orchestrated across Bitwarden and adjacent systems - IdP, HRIS, ticketing - without building point-to-point API logic for each.

For event data, Bitwarden has no outbound webhooks; poll GET /public/events with start and end date filters to retrieve audit events.

Invite and confirm a new organization member

  1. Obtain an access token: POST https://identity.bitwarden.com/connect/token with client_id, client_secret, grant_type=client_credentials, scope=api.organization.
  2. Invite the user: POST https://api.bitwarden.com/public/members with {email, type, accessAll, collections}. Response returns member with status=0 (Invited).
  3. User receives invitation email and accepts it (status becomes 1=Accepted). This step is user-driven and cannot be automated via API.
  4. Confirm the member via the Bitwarden web vault (Admin Console > Members > Confirm). Note: there is no Public API endpoint to programmatically confirm a member; confirmation requires a vault action.

Watch out for: Member confirmation cannot be automated via the Public API - it requires a vault admin action. SCIM provisioning bypasses this limitation by auto-confirming provisioned users.

Deprovision a member when they leave the organization

  1. Obtain access token via client credentials flow.
  2. List members: GET https://api.bitwarden.com/public/members to find the member's organization membership id by email.
  3. Revoke the member: PUT https://api.bitwarden.com/public/members/{id}/revoke. This sets status=-1 and removes org access immediately.
  4. Optionally, permanently remove: DELETE https://api.bitwarden.com/public/members/{id} if you do not need to restore them later.

Watch out for: Revoke is reversible; DELETE is permanent. Neither action deletes the user's personal Bitwarden account or their personal vault data.

Set up SCIM provisioning with Okta

  1. Ensure the organization is on Teams or Enterprise plan.
  2. Configure Login with SSO in Bitwarden Admin Console (SSO must be active before enabling SCIM).
  3. In Bitwarden Admin Console, go to Settings > SCIM Provisioning, enable SCIM, and copy the SCIM URL and API token.
  4. In Okta, add the Bitwarden application from the Okta Integration Network.
  5. In the Bitwarden Okta app, navigate to Provisioning > Integration, enter the SCIM base URL (https://scim.bitwarden.com/{orgId}/v2) and the SCIM token as the API token.
  6. Enable provisioning features: Push New Users, Push Profile Updates, Push Groups, Deactivate Users.
  7. Assign users/groups in Okta; Bitwarden will auto-provision and confirm them via SCIM.

Watch out for: The SCIM token is a static long-lived token - rotate it in Bitwarden Admin Console if compromised. Okta SCIM DELETE maps to Bitwarden member revocation, not account deletion.

Why building this yourself is a trap

PUT /members/{id} is a full replacement - omitting any field (collections, permissions, accessAll) silently resets it. Always GET the current member state before any update. The member {id} in the Public API is the organization membership UUID, not the user's global Bitwarden userId - using the wrong identifier returns a 404 with no descriptive error.

SCIM requires SSO to be configured and active before provisioning is enabled; enabling SCIM without SSO produces provisioning errors that surface in the IdP, not in Bitwarden. The SCIM token is a static long-lived bearer token with no rotation schedule enforced by Bitwarden, so token hygiene is entirely the operator's responsibility.

Groups and SCIM endpoints return errors or empty results on plans below Teams; plan-gate your API calls accordingly.

Automate Bitwarden 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.

Every app coverage, including apps without APIs
60+ app integrations plus browser automation for apps without APIs
IT graph reconciliation across apps and your IdP
Less than a week to launch, maintained as APIs and admin consoles change
SOC 2 Type II. ~2 hours of your team's time

UpdatedMar 4, 2026

* Details sourced from official product documentation and admin references.

Keep exploring

Related apps

15Five logo

15Five

Full API + SCIM
AutomationAPI + SCIM
Last updatedFeb 2026

15Five uses a fixed role-based permission model with six predefined roles: Account Admin, HR Admin, Billing Admin, Group Admin, Manager, and Employee. No custom roles can be constructed. User management lives at Settings gear → People → Manage people p

1Password logo

1Password

Full API + SCIM
AutomationAPI + SCIM
Last updatedFeb 2026

1Password's admin console at my.1password.com covers the full user lifecycle — invitations, group assignments, vault access, suspension, and deletion — without any third-party tooling. Like every app that mixes role-based and resource-level permissions

8x8 logo

8x8

Full API + SCIM
AutomationAPI + SCIM
Last updatedFeb 2026

8x8 Admin Console supports full lifecycle user management — create, deactivate, and delete — across its X Series unified communications platform. Every app a user can access (8x8 Work desktop, mobile, web, Agent Workspace) is gated by license assignmen