---
editLink: false
lastUpdated: false
outline: [2, 3]
---

<!-- Generated by python/b2c-tooling-sdk/scripts/generate_api_docs.py. Do not edit. -->

# b2c_tooling_sdk.operations.bm_users

Business Manager user operations for B2C Commerce instances.

Mirrors `src/operations/bm-users/index.ts`. Provides functions for querying
and managing instance-level users via the OCAPI Data API. These are distinct
from Account Manager users managed via `operations/users`.

Create-or-replace is supported via the backend's `create_or_replace_user`
method (PUT), obtained from [`create_users_backend`](/python/api/operations/bm_users#create-users-backend). On instances using
SSO with Account Manager (the default for production) this is rejected with
`LocalUserCreationException` -- local user creation must be enabled on the
instance for it to succeed; otherwise provision users in Account Manager and
use these operations for read/search/update/delete plus access-key
administration.

Core user functions:

- [`list_bm_users`](/python/api/operations/bm_users#list-bm-users) - List all users on an instance.
- [`get_bm_user`](/python/api/operations/bm_users#get-bm-user) - Get a user by login.
- [`whoami_bm_user`](/python/api/operations/bm_users#whoami-bm-user) - Get the currently authenticated user.
- [`search_bm_users`](/python/api/operations/bm_users#search-bm-users) - Search users with filter expressions.
- [`update_bm_user`](/python/api/operations/bm_users#update-bm-user) - Update user attributes (locale, external_id, disabled).
- [`delete_bm_user`](/python/api/operations/bm_users#delete-bm-user) - Delete a user from the instance.

Access keys (externally-managed users):

- [`get_bm_user_access_key`](/python/api/operations/bm_users#get-bm-user-access-key) - Read access key details.
- [`create_bm_user_access_key`](/python/api/operations/bm_users#create-bm-user-access-key) - Create / rotate an access key.
- [`set_bm_user_access_key_enabled`](/python/api/operations/bm_users#set-bm-user-access-key-enabled) - Enable / disable an access key.
- [`delete_bm_user_access_key`](/python/api/operations/bm_users#delete-bm-user-access-key) - Delete an access key.

## Classes

### CreateUserInput {#createuserinput}

```python
class CreateUserInput
```

Body for create/replace (PUT). `login` and `email` are required.

**Fields**

| Name | Type | Default |
| --- | --- | --- |
| `login` | `str` |  |
| `email` | `str` |  |
| `first_name` | `str \| None` | `None` |
| `last_name` | `str \| None` | `None` |
| `external_id` | `str \| None` | `None` |
| `password` | `str \| None` | `None` |
| `disabled` | `bool \| None` | `None` |
| `preferred_data_locale` | `str \| None` | `None` |
| `preferred_ui_locale` | `str \| None` | `None` |
| `roles` | `list[str] \| None` | `None` |

### ListBmUsersOptions {#listbmusersoptions}

```python
class ListBmUsersOptions
```

Options for listing BM users.

**Fields**

| Name | Type | Default |
| --- | --- | --- |
| `start` | `int \| None` | `None` |
| `count` | `int \| None` | `None` |
| `select` | `str \| None` | `None` |

### ListUsersOptions {#listusersoptions}

```python
class ListUsersOptions
```

Options for [`UsersBackend.list_users`](/python/api/clients#list-users).

**Fields**

| Name | Type | Default |
| --- | --- | --- |
| `start` | `int \| None` | `None` |
| `count` | `int \| None` | `None` |

### ListUsersResult {#listusersresult}

```python
class ListUsersResult
```

Result of listing users -- paginated.

**Fields**

| Name | Type | Default |
| --- | --- | --- |
| `total` | `int` |  |
| `start` | `int` |  |
| `count` | `int` |  |
| `hits` | `list[UserInfo]` | `field(default_factory=list)` |

### OcapiUsersBackend {#ocapiusersbackend}

```python
class OcapiUsersBackend
```

Manages BM users through the legacy OCAPI Data API `/users` resource.

**Fields**

| Name | Type |
| --- | --- |
| `name` | `Literal['ocapi']` |

### ScapiUsersBackend {#scapiusersbackend}

```python
class ScapiUsersBackend
```

Manages BM users through the SCAPI Merchant Users Admin API.

**Fields**

| Name | Type |
| --- | --- |
| `name` | `Literal['scapi']` |

### SearchBmUsersOptions {#searchbmusersoptions}

```python
class SearchBmUsersOptions
```

Options for searching BM users.

Searchable fields per the Data API spec: login, email, first_name,
last_name, external_id, last_login_date, is_locked, is_disabled.

**Fields**

| Name | Type | Default |
| --- | --- | --- |
| `query` | `Any` | `None` |
| `search_phrase` | `str \| None` | `None` |
| `login` | `str \| None` | `None` |
| `email` | `str \| None` | `None` |
| `locked` | `bool \| None` | `None` |
| `disabled` | `bool \| None` | `None` |
| `sort_by` | `str \| None` | `None` |
| `sort_order` | `Literal['asc', 'desc'] \| None` | `None` |
| `start` | `int \| None` | `None` |
| `count` | `int \| None` | `None` |
| `select` | `str \| None` | `None` |

### SearchUsersOptions {#searchusersoptions}

```python
class SearchUsersOptions(ListUsersOptions)
```

Portable user search criteria supported by both backends.

**Fields**

| Name | Type | Default |
| --- | --- | --- |
| `query` | `Any` | `None` |
| `search_phrase` | `str \| None` | `None` |
| `login` | `str \| None` | `None` |
| `email` | `str \| None` | `None` |
| `locked` | `bool \| None` | `None` |
| `disabled` | `bool \| None` | `None` |
| `sort_by` | `str \| None` | `None` |
| `sort_order` | `Literal['asc', 'desc'] \| None` | `None` |

### UpdateBmUserChanges {#updatebmuserchanges}

```python
class UpdateBmUserChanges
```

Updatable user fields for `patch` operations.

Note: `locked` and `password` cannot be modified via PATCH per the API spec.

**Fields**

| Name | Type | Default |
| --- | --- | --- |
| `disabled` | `bool \| None` | `None` |
| `email` | `str \| None` | `None` |
| `external_id` | `str \| None` | `None` |
| `first_name` | `str \| None` | `None` |
| `last_name` | `str \| None` | `None` |
| `preferred_data_locale` | `str \| None` | `None` |
| `preferred_ui_locale` | `str \| None` | `None` |

### UpdateUserChanges {#updateuserchanges}

```python
class UpdateUserChanges
```

Patch fields. SCAPI uses camelCase; the OCAPI backend translates to snake_case.

**Fields**

| Name | Type | Default |
| --- | --- | --- |
| `email` | `str \| None` | `None` |
| `first_name` | `str \| None` | `None` |
| `last_name` | `str \| None` | `None` |
| `external_id` | `str \| None` | `None` |
| `disabled` | `bool \| None` | `None` |
| `preferred_data_locale` | `str \| None` | `None` |
| `preferred_ui_locale` | `str \| None` | `None` |

### UserInfo {#userinfo}

```python
class UserInfo
```

Canonical Business Manager user.

Field names match SCAPI (camelCase in TS, snake_case here); the OCAPI
backend maps from OCAPI's own snake_case wire shape.

**Fields**

| Name | Type | Default |
| --- | --- | --- |
| `login` | `str` |  |
| `email` | `str \| None` | `None` |
| `first_name` | `str \| None` | `None` |
| `last_name` | `str \| None` | `None` |
| `external_id` | `str \| None` | `None` |
| `disabled` | `bool \| None` | `None` |
| `locked` | `bool \| None` | `None` |
| `last_login_date` | `str \| None` | `None` |
| `password_expiration_date` | `str \| None` | `None` |
| `password_modification_date` | `str \| None` | `None` |
| `preferred_data_locale` | `str \| None` | `None` |
| `preferred_ui_locale` | `str \| None` | `None` |
| `roles` | `list[str] \| None` | `None` |
| `raw` | `Any` | `None` |

### UsersBackend {#usersbackend}

```python
class UsersBackend(BackendBase, Protocol)
```

Backend contract for BM user operations.

Merchant Users has no server-side search endpoint, so the SCAPI backend
implements portable search criteria over its paginated user listing. Raw
OCAPI query DSL, access keys, and `whoami` remain OCAPI-only.

#### list_users <Badge type="info" text="method" /> {#usersbackend-list-users}

```python
async def list_users(options: ListUsersOptions | None = None) -> ListUsersResult
```

List users, paginated.

#### search_users <Badge type="info" text="method" /> {#usersbackend-search-users}

```python
async def search_users(options: SearchUsersOptions | None = None) -> ListUsersResult
```

Search users using portable criteria.

#### get_user <Badge type="info" text="method" /> {#usersbackend-get-user}

```python
async def get_user(login: str) -> UserInfo
```

Get a single user by login.

#### create_or_replace_user <Badge type="info" text="method" /> {#usersbackend-create-or-replace-user}

```python
async def create_or_replace_user(login: str, input: CreateUserInput) -> UserInfo
```

Create or fully replace a user.

#### update_user <Badge type="info" text="method" /> {#usersbackend-update-user}

```python
async def update_user(login: str, changes: UpdateUserChanges) -> UserInfo
```

Update fields on an existing user.

#### delete_user <Badge type="info" text="method" /> {#usersbackend-delete-user}

```python
async def delete_user(login: str) -> None
```

Delete a user.

## Functions

### create_bm_user_access_key {#create-bm-user-access-key}

```python
async def create_bm_user_access_key(instance: B2CInstance, login: str, scope: str) -> BmAccessKeyDetails
```

Creates a single access key for an externally-managed user.

Replaces any existing key for the same scope. The returned object includes
the newly-generated `access_key` value -- this is the only time it is
returned, so callers should record it.

**Parameters**

| Name | Type | Description |
| --- | --- | --- |
| `instance` | `B2CInstance` | B2C instance. |
| `login` | `str` | User login. |
| `scope` | `str` | Access key scope. |

**Returns:** Access key details (including the secret `access_key` value).

### create_users_backend {#create-users-backend}

```python
def create_users_backend(config: UsersBackendConfig) -> UsersBackend
```

Create a [`UsersBackend`](/python/api/operations/bm_users#usersbackend), resolving SCAPI/OCAPI per `config`.

### delete_bm_user {#delete-bm-user}

```python
async def delete_bm_user(instance: B2CInstance, login: str) -> None
```

Deletes a user from an instance.

**Parameters**

| Name | Type | Description |
| --- | --- | --- |
| `instance` | `B2CInstance` | B2C instance. |
| `login` | `str` | User login. |

### delete_bm_user_access_key {#delete-bm-user-access-key}

```python
async def delete_bm_user_access_key(instance: B2CInstance, login: str, scope: str) -> None
```

Deletes a single access key for an externally-managed user.

**Parameters**

| Name | Type | Description |
| --- | --- | --- |
| `instance` | `B2CInstance` | B2C instance. |
| `login` | `str` | User login. |
| `scope` | `str` | Access key scope. |

### get_bm_user {#get-bm-user}

```python
async def get_bm_user(instance: B2CInstance, login: str) -> BmUser
```

Gets a single user by login (email).

**Parameters**

| Name | Type | Description |
| --- | --- | --- |
| `instance` | `B2CInstance` | B2C instance. |
| `login` | `str` | User login. |

**Returns:** User details.

### get_bm_user_access_key {#get-bm-user-access-key}

```python
async def get_bm_user_access_key(instance: B2CInstance, login: str, scope: str) -> BmAccessKeyDetails
```

Gets a single access key for an externally-managed user.

**Parameters**

| Name | Type | Description |
| --- | --- | --- |
| `instance` | `B2CInstance` | B2C instance. |
| `login` | `str` | User login. |
| `scope` | `str` | Access key scope (one of [`ACCESS_KEY_SCOPES`](/python/api/operations/bm_users#access-key-scopes)). |

**Returns:** Access key details.

### list_bm_users {#list-bm-users}

```python
async def list_bm_users(instance: B2CInstance, options: ListBmUsersOptions | None = None) -> BmUsers
```

Lists all users on a B2C Commerce instance.

**Parameters**

| Name | Type | Description |
| --- | --- | --- |
| `instance` | `B2CInstance` | B2C instance to query. |
| `options` | `ListBmUsersOptions \| None` | Pagination options. |

**Returns:** Users collection with pagination info.

### search_bm_users {#search-bm-users}

```python
async def search_bm_users(instance: B2CInstance, options: SearchBmUsersOptions | None = None) -> BmUserSearchResult
```

Searches users on an instance.

Supports either a fully-formed OCAPI query (`options.query`) or
convenience flags (`search_phrase`, `login`, `email`, `locked`,
`disabled`) which are combined into a `bool_query`. If no criteria are
provided a `match_all_query` is used.

**Parameters**

| Name | Type | Description |
| --- | --- | --- |
| `instance` | `B2CInstance` | B2C instance. |
| `options` | `SearchBmUsersOptions \| None` | Search options. |

**Returns:** User search result.

### set_bm_user_access_key_enabled {#set-bm-user-access-key-enabled}

```python
async def set_bm_user_access_key_enabled(instance: B2CInstance, login: str, scope: str, enabled: bool) -> BmAccessKeyDetails
```

Enables or disables an existing access key for an externally-managed user.

**Parameters**

| Name | Type | Description |
| --- | --- | --- |
| `instance` | `B2CInstance` | B2C instance. |
| `login` | `str` | User login. |
| `scope` | `str` | Access key scope. |
| `enabled` | `bool` | Whether the access key should be enabled. |

**Returns:** Updated access key details.

### update_bm_user {#update-bm-user}

```python
async def update_bm_user(instance: B2CInstance, login: str, changes: UpdateBmUserChanges) -> BmUser
```

Updates an existing user.

The `locked` flag and the user `password` cannot be updated with this
resource.

**Parameters**

| Name | Type | Description |
| --- | --- | --- |
| `instance` | `B2CInstance` | B2C instance. |
| `login` | `str` | User login. |
| `changes` | `UpdateBmUserChanges` | Fields to update. |

**Returns:** Updated user.

### whoami_bm_user {#whoami-bm-user}

```python
async def whoami_bm_user(instance: B2CInstance) -> BmUser
```

Returns details for the currently authenticated user.

Useful for verifying which BM identity is in use on an instance.

**Parameters**

| Name | Type | Description |
| --- | --- | --- |
| `instance` | `B2CInstance` | B2C instance. |

**Returns:** Current user details (includes password expiration info).

## Attributes

### ACCESS_KEY_SCOPES {#access-key-scopes}

```python
ACCESS_KEY_SCOPES = ('WEBDAV_AND_STUDIO', 'AGENT_USER_AND_OCAPI', 'STOREFRONT')
```

### AccessKeyScope {#accesskeyscope}

```python
AccessKeyScope = Literal['WEBDAV_AND_STUDIO', 'AGENT_USER_AND_OCAPI', 'STOREFRONT']
```

### BmAccessKeyDetails {#bmaccesskeydetails}

```python
BmAccessKeyDetails = dict[str, Any]
```

### BmUser {#bmuser}

```python
BmUser = dict[str, Any]
```

### BmUserSearchResult {#bmusersearchresult}

```python
BmUserSearchResult = dict[str, Any]
```

### BmUsers {#bmusers}

```python
BmUsers = dict[str, Any]
```

### ScapiUsersBackendConfig {#scapiusersbackendconfig}

```python
ScapiUsersBackendConfig = ScapiBackendCtorConfig
```

### UsersBackendConfig {#usersbackendconfig}

```python
UsersBackendConfig = DualBackendConfig
```
