# Manage users with SCIM

[System for Cross-domain Identity Management](https://www.rfc-editor.org/rfc/rfc7644) (SCIM) allows automating user lifecycle management across cloud apps: creating and activating a new user, updating their user attributes (e.g., email and password), and deactivating the user. For example, it allows the app’s IT system or identity provider to provision and manage users in Mosaic. Or allows integrating the app's services with Mosaic as the IDP to check if the user has been updated or deactivated.

Note
Both [Users-SCIM APIs](/openapi/user/user-scim.openapi) and [Users APIs](/openapi/user/user.openapi) are operating on the same user entities in the Mosaic identity store.

Depending on your use case, you can implement various user lifecycle management chores with the Users-SCIM APIs, e.g.:

- [Create a user](#create-a-user)
- [Enrich user data](#enrich-user-data)
- [List all users](#list-all-users)
- [Search for users](#search-for-users)
- [Fetch user updates](#fetch-user-updates)
- [Update user's profile](#update-users-profile)
- [Delete a user](#delete-a-user)


## How it works

As a REST-based protocol, SCIM describes resources as JSON objects with a standardized schema which makes it easy to provision and manage resources across multiple cloud apps. In other words, with the same object you can run queries against various independent platforms.

Mosaic exposes APIs that allow performing CRUD operations with SCIM-compatible user objects. Any user in the Mosaic identity store can be presented using the SCIM-compatible schema. Mosaic uses abbreviated [SCIM User Core schema](https://datatracker.ietf.org/doc/html/rfc7643#page-19) (`urn:ietf:params:scim:schemas:core:2.0:User`) and allows extending it with custom data using `urn:ietf:params:scim:schemas:extension:CustomAppData:2.0:User` schema.

The Users-SCIM calls are authenticated using the Bearer token generated based on the client credentials (see [Get client access tokens](/guides/user/retrieve_client_tokens)). You can only manage the users for the application used to create an access token. If an admin access token is used, you can retrieve all users in your tenant.

## User identifiers

Depending on your integration use case, you can leverage the following attributes as user identifiers when managing and authenticating users with Mosaic. The table below provides a mapping between SCIM attributes and Mosaic user identifiers.

| SCIM field | Mosaic user identifiers | Description |
|  --- | --- | --- |
| `userName` | `username` | Required attribute since Mosaic enables password authentication for the users created via SCIM APIs by default. |
| `emails.value` `emails.primary: true` | `email` | The primary email address of the user that can be used instead of their username for authentication. |
| `phoneNumbers.value ` `phoneNumbers.primary: true` | `phone_number` | The primary phone number of the user that can be used for authentication. |
| `externalId` | `external_user_id` | The attribute set outside Mosaic, it corresponds to ID in your system and allows syncing data. In WebAuthn flows can be used to register new credentials when the user is logged out. |
| `id` | `user_id` | The ID is generated by Mosaic and returned upon user creation. |


Note
Custom identifiers are returned within the `custom_user_fields` object.

## Create a user

Provision new users by sending a POST request to [/scim/users](/openapi/user/user-scim.openapi/other/scimcreateuser) endpoint with user details. For the object structure, refer to the API reference. The minimum set of attributes to create a new user includes `schemas`, `userName`, and `password`. Setting a password and a username makes a user eligible for password authentication.

Note
The user you create will be available in the Admin Portal as well as through Users APIs and journeys.

Request

```js
import fetch from 'node-fetch';

async function run() {
  const resp = await fetch(
    `https://api.transmitsecurity.io/cis/scim/Users`,
    {
      method: 'POST',
      headers: {
        Accept: 'application/scim+json',
        'Content-Type': 'application/scim+json',
        Authorization: 'Bearer [CLIENT_ACCESS_TOKEN]'
      },
      body: JSON.stringify({
        name: { // User's name
          givenName: 'John',
          familyName: 'Smith',
        },
        emails: [
          { // Unique. User's primary email address. Can be used for auth
            value: 'john.smith@example.com',
            primary: true
          }
        ],
        phoneNumbers: [
          { // Unique. User's primary phone number. Can be used for auth
            value: '+12125555555',
            primary: true
          }
        ],
        schemas: ['urn:ietf:params:scim:schemas:core:2.0:User'], // Required
        externalId: '1234567ABCDE', // Unique ID, corresponds to external system. Can be used to register new credentials in WebAuthn if the user is logged out
        userName: 'user.johnsmith', // Unique username. Required for password auth that enabled by default when creating a user with SCIM
        password: '123456' // Required for password auth that enabled by default when creating a user with SCIM
      })
    }
  );

  const data = await resp.json();
  console.log(data);
}

run();
```

Response

```shell
{
    "schemas": "urn:ietf:params:scim:schemas:core:2.0:User",
    "id": "1234abcd5678efgh9000a", // Unique ID generated by Transmit
    "externalId": "1234567",
    "userName": "JohnSmith",
    "name":
    {
        "givenName": "John",
        "familyName": "Smith"
    },
    "displayName": "John Smith",
    "active": true,
    "phoneNumbers": [
        {
            "value": '+12125555555',
            "primary": true
        }
    ],
    "emails": [
        {
            "value": 'john.smith@example.com',
            "primary": true
        }
    ],
    "meta":
    {
        "created": "2023-11-06T14:49:44.054Z",
        "lastModified": "2023-11-06T14:49:44.054Z",
        "location": "https://api.transmitsecurity.io/scim/Users/1234abcd5678efgh9000a",
        "resourceType": "User"
    },
    "urn:ietf:params:scim:schemas:extension:UserExtended:2.0:User":
    {
        "status": "Active",
        "lastAuth": "2024-11-06T14:49:44.054Z",
        "passwordInformation":
            {
                "expired": false,
                "temporary": false,
                "updated_at": "2023-11-06T14:49:44.054Z"
            }
    }
}
```

## Enrich user data

Mosaic allows extending the user object with custom data and custom attributes. For example, add app-related user information, such as a user's department or nearest branch location.

To extend the schema with custom data, include `urn:ietf:params:scim:schemas:extension:CustomAppData:2.0:User` entry in the `schemas` array in the POST or PUT call, and then specify custom attributes within the `urn:ietf:params:scim:schemas:extension:CustomAppData:2.0:User` object itself. The object is untyped, you can provide as many custom attributes as needed; nesting is supported.

Note
Correponds to user's [`custom_app_data`](/openapi/user/user.openapi/other/updateuser#other/updateuser/t=request&path=custom_app_data) managed through [Users APIs](/openapi/user/user.openapi).


```js
import fetch from 'node-fetch';

async function run() {
  const resp = await fetch(
    `https://api.transmitsecurity.io/cis/scim/Users`,
    {
      method: 'POST',
      headers: {
        Accept: 'application/scim+json',
        'Content-Type': 'application/scim+json',
        Authorization: 'Bearer [CLIENT_ACCESS_TOKEN]'
      },
      body: JSON.stringify({
        schemas: // Required
          [
            'urn:ietf:params:scim:schemas:core:2.0:User',
            'urn:ietf:params:scim:schemas:extension:CustomAppData:2.0:User'
          ],
        'urn:ietf:params:scim:schemas:extension:CustomAppData:2.0:User': { // Extends user data
            'nearestBranch': 'New York, Manhattan' // Custom data
        },
        userName: 'AnnaGreen', // Required
        password: '123456' // Required
      })
    }
  );

  const data = await resp.json();
  console.log(data);
}

run();
```

## List all users

Retrieve all users by running a GET request to [/scim/users](/openapi/user/user-scim.openapi/other/scimgetusersgetrequest) endpoint or POST to [/scim/users/.search](/openapi/user/user-scim.openapi/other/scimgetuserspostrequest). The endpoints support paging, sorting, and filtering, as well as enable you to specify which attributes to return. The examples below return 100 records per page, starting with the first record and each record includes only four attributes. The response will include a list of users with requested attributes, and metadata such as the number of records returned and SCIM schema.

Note
The call retrieves users associated with the application used to create an access token. To retrieve all users in your tenant, use the admin access token generated using management app credentials.

GET

```js
import fetch from 'node-fetch';

async function run() {
  const query = new URLSearchParams({
    startIndex: '1', // 1-based index. Controls paging. The serial number of the element to start fetching
    count: '100', // Controls paging. The number of records to return per page. If set to 0 or undefined, no records will be returned
    attributes: ['userName', 'id', 'name.familyName', 'emails'], // The attributes to return
  }).toString();

  const resp = await fetch(
    `https://api.transmitsecurity.io/cis/scim/Users?${query}`,
    {
      method: 'GET',
      headers: {
        Accept: 'application/scim+json',
        Authorization: 'Bearer [CLIENT_ACCESS_TOKEN]'
      }
    }
  );

  const data = await resp.text();
  console.log(data);
}

run();
```

POST

```js
import fetch from 'node-fetch';

async function run() {
  const resp = await fetch(
    `https://api.transmitsecurity.io/cis/scim/Users/.search`,
    {
      method: 'POST',
      headers: {
        Accept: 'application/scim+json',
        'Content-Type': 'application/scim+json',
        Authorization: 'Bearer [CLIENT_ACCESS_TOKEN]'
      },
      body: JSON.stringify({
        startIndex: 1, // 1-based index. Controls paging. The serial number of the element to start fetching
        count: '100', // Controls paging. The number of records to return per page. If set to 0 or undefined, no records will be returned
        attributes: ['userName', 'id', 'name.givenName', 'emails'], // The attributes to return
        schemas: [
            "urn:ietf:params:scim:api:messages:2.0:SearchRequest"
        ]
      })
    }
  );

  const data = await resp.json();
  console.log(data);
}

run();
```

## Search for users

Filters allow searching for users matching your search criteria as well as locating a single user record based on the unique identifier. Below are basic recipes demonstrating how to find users. For details on how filtering works, see [Search query syntax](/openapi/scim_search_syntax).

### Find a user

Find a user based on one of the unique user identifiers such as username, ID, email, phone number, or external ID.

details
summary
b
Find user by username
Locate a user by their unique `userName`. To do it, send a GET request to [/scim/users](/openapi/user/user-scim.openapi/other/scimgetusersgetrequest) endpoint or POST to [/scim/users/.search](/openapi/user/user-scim.openapi/other/scimgetuserspostrequest).

Note
The `userName` might be missing for users created with [Users APIs](/openapi/user/user.openapi).

GET

```js
import fetch from 'node-fetch';

async function run() {
  const query = new URLSearchParams({
    startIndex: '1', // 1-based index
    count: '100', // If set to 0 or undefined, no records will be returned
    filter: 'userName eq \"JohnSmith\"' // Filter expression allows locating a user with a specific username
  }).toString();

  const resp = await fetch(
    `https://api.transmitsecurity.io/cis/scim/Users?${query}`,
    {
      method: 'GET',
      headers: {
        Accept: 'application/scim+json',
        Authorization: 'Bearer [CLIENT_ACCESS_TOKEN]'
      }
    }
  );

  const data = await resp.text();
  console.log(data);
}

run();
```

POST

```js
import fetch from 'node-fetch';

async function run() {
  const resp = await fetch(
    `https://api.transmitsecurity.io/cis/scim/Users/.search`,
    {
      method: 'POST',
      headers: {
        Accept: 'application/scim+json',
        'Content-Type': 'application/scim+json',
        Authorization: 'Bearer [CLIENT_ACCESS_TOKEN]'
      },
      body: JSON.stringify({
        startIndex: 1, // 1-based index
        count: '100', // If set to 0 or undefined, no records will be returned
        filter: 'userName eq \"JohnSmith\"' // Filter expression allows locating a user with a specific username
        schemas: [
            "urn:ietf:params:scim:api:messages:2.0:SearchRequest"
        ]
      })
    }
  );

  const data = await resp.json();
  console.log(data);
}

run();
```

details
summary
b
Find user by ID
Locate a user by their unique ID. To do this, send a GET request to `/scim/users/{user_id}` endpoint with the ID of the user. Alternatively, send a POST to [/scim/users/.search](/openapi/user/user-scim.openapi/other/scimgetuserspostrequest) with a user's ID.

GET

```js
import fetch from 'node-fetch';

async function run() {
  const userId = '[ID]'; // Unique ID of the user
  const resp = await fetch(
    `https://api.transmitsecurity.io/cis/scim/Users/${userId}`,
    {
      method: 'GET',
      headers: {
        Accept: 'application/scim+json',
        Authorization: 'Bearer [CLIENT_ACCESS_TOKEN]'
      }
    }
  );

  const data = await resp.text();
  console.log(data);
}

run();
```

POST

```js
import fetch from 'node-fetch';

async function run() {
  const resp = await fetch(
    `https://api.transmitsecurity.io/cis/scim/Users/.search`,
    {
      method: 'POST',
      headers: {
        Accept: 'application/scim+json',
        'Content-Type': 'application/scim+json',
        Authorization: 'Bearer [CLIENT_ACCESS_TOKEN]'
      },
      body: JSON.stringify({
        startIndex: 1, // 1-based index
        count: '100', // If set to 0 or undefined, no records will be returned
        filter: 'id eq \"[ID]\"' // Filter expression allows locating a user by ID
        schemas: [
            "urn:ietf:params:scim:api:messages:2.0:SearchRequest"
        ]
      })
    }
  );

  const data = await resp.json();
  console.log(data);
}

run();
```

details
summary
b
Find user by email
Locate a user by their email by running a GET request to [/scim/users](/openapi/user/user-scim.openapi/other/scimgetusersgetrequest) endpoint or POST to [/scim/users/.search](/openapi/user/user-scim.openapi/other/scimgetuserspostrequest).

GET

```js
import fetch from 'node-fetch';

async function run() {
  const query = new URLSearchParams({
    startIndex: '1', // 1-based index
    count: '100', // If set to 0 or undefined, no records will be returned
    filter: 'emails eq \"john.smith@example.com\"' // Filter expression allows locating a user with a specific email
  }).toString();

  const resp = await fetch(
    `https://api.transmitsecurity.io/cis/scim/Users?${query}`,
    {
      method: 'GET',
      headers: {
        Accept: 'application/scim+json',
        Authorization: 'Bearer [CLIENT_ACCESS_TOKEN]'
      }
    }
  );

  const data = await resp.text();
  console.log(data);
}

run();
```

POST

```js
import fetch from 'node-fetch';

async function run() {
  const resp = await fetch(
    `https://api.transmitsecurity.io/cis/scim/Users/.search`,
    {
      method: 'POST',
      headers: {
        Accept: 'application/scim+json',
        'Content-Type': 'application/scim+json',
        Authorization: 'Bearer [CLIENT_ACCESS_TOKEN]'
      },
      body: JSON.stringify({
        startIndex: 1, // 1-based index
        count: '100', // If set to 0 or undefined, no records will be returned
        filter: 'emails eq \"john.smith@example.com\"' // Filter expression allows locating a user with a specific email
        schemas: [
            "urn:ietf:params:scim:api:messages:2.0:SearchRequest"
        ]
      })
    }
  );

  const data = await resp.json();
  console.log(data);
}

run();
```

details
summary
b
Find user by phone number
Locate a user by their email by running a GET request to [/scim/users](/openapi/user/user-scim.openapi/other/scimgetusersgetrequest) endpoint or POST to [/scim/users/.search](/openapi/user/user-scim.openapi/other/scimgetuserspostrequest).

GET

```js
import fetch from 'node-fetch';

async function run() {
  const query = new URLSearchParams({
    startIndex: '1', // 1-based index
    count: '100', // If set to 0 or undefined, no records will be returned
    filter: 'phoneNumbers eq \"+12125555555\"' // Filter expression allows locating a user with a specific phone number
  }).toString();

  const resp = await fetch(
    `https://api.transmitsecurity.io/cis/scim/Users?${query}`,
    {
      method: 'GET',
      headers: {
        Accept: 'application/scim+json',
        Authorization: 'Bearer [CLIENT_ACCESS_TOKEN]'
      }
    }
  );

  const data = await resp.text();
  console.log(data);
}

run();
```

POST

```js
import fetch from 'node-fetch';

async function run() {
  const resp = await fetch(
    `https://api.transmitsecurity.io/cis/scim/Users/.search`,
    {
      method: 'POST',
      headers: {
        Accept: 'application/scim+json',
        'Content-Type': 'application/scim+json',
        Authorization: 'Bearer [CLIENT_ACCESS_TOKEN]'
      },
      body: JSON.stringify({
        startIndex: 1, // 1-based index
        count: '100', // If set to 0 or undefined, no records will be returned
        filter: 'phoneNumbers eq \"+12125555555\"' // Filter expression allows locating a user with a specific phone number
        schemas: [
            "urn:ietf:params:scim:api:messages:2.0:SearchRequest"
        ]
      })
    }
  );

  const data = await resp.json();
  console.log(data);
}

run();
```

details
summary
b
Find user by external ID
Locate a user by their ID set in your system (external id for Transmit) by running a GET request to [/scim/users](/openapi/user/user-scim.openapi/other/scimgetusersgetrequest) endpoint or POST to [/scim/users/.search](/openapi/user/user-scim.openapi/other/scimgetuserspostrequest).

GET

```js
import fetch from 'node-fetch';

async function run() {
  const query = new URLSearchParams({
    startIndex: '1', // 1-based index
    count: '100', // If set to 0 or undefined, no records will be returned
    filter: 'externalID eq \"AABBCCDD\"' // Filter expression allows locating a user with a specific external ID
  }).toString();

  const resp = await fetch(
    `https://api.transmitsecurity.io/cis/scim/Users?${query}`,
    {
      method: 'GET',
      headers: {
        Accept: 'application/scim+json',
        Authorization: 'Bearer [CLIENT_ACCESS_TOKEN]'
      }
    }
  );

  const data = await resp.text();
  console.log(data);
}

run();
```

POST

```js
import fetch from 'node-fetch';

async function run() {
  const resp = await fetch(
    `https://api.transmitsecurity.io/cis/scim/Users/.search`,
    {
      method: 'POST',
      headers: {
        Accept: 'application/scim+json',
        'Content-Type': 'application/scim+json',
        Authorization: 'Bearer [CLIENT_ACCESS_TOKEN]'
      },
      body: JSON.stringify({
        startIndex: 1, // 1-based index
        count: '100', // If set to 0 or undefined, no records will be returned
        filter: 'externalId eq \"AABBCCDD\"' // Filter expression allows locating a user with a specific external ID
        schemas: [
            "urn:ietf:params:scim:api:messages:2.0:SearchRequest"
        ]
      })
    }
  );

  const data = await resp.json();
  console.log(data);
}

run();
```

### Search for users in your region

Let's assume your business is located in the United States and you're interested in finding users either located in the United States as well or speaking English. Send a GET request to [/scim/users](/openapi/user/user-scim.openapi/other/scimgetusersgetrequest) endpoint or POST to [/scim/users/.search](/openapi/user/user-scim.openapi/other/scimgetuserspostrequest) with a complex filter expression. For details on how filtering works and available operators, see [Search query syntax](/openapi/scim_search_syntax).

GET

```js
import fetch from 'node-fetch';

async function run() {
  const query = new URLSearchParams({
    startIndex: '1', // 1-based index
    count: '100', // If set to 0 or undefined, no records will be returned
    filter: '(preferredLanguage eq \"en\")or(addresses.country eq \"USA\")' // Filter expression allows fetching users who either speak English or located in the USA
  }).toString();

  const resp = await fetch(
    `https://api.transmitsecurity.io/cis/scim/Users?${query}`,
    {
      method: 'GET',
      headers: {
        Accept: 'application/scim+json',
        Authorization: 'Bearer [CLIENT_ACCESS_TOKEN]'
      }
    }
  );

  const data = await resp.text();
  console.log(data);
}

run();
```

POST

```js
import fetch from 'node-fetch';

async function run() {
  const resp = await fetch(
    `https://api.transmitsecurity.io/cis/scim/Users/.search`,
    {
      method: 'POST',
      headers: {
        Accept: 'application/scim+json',
        'Content-Type': 'application/scim+json',
        Authorization: 'Bearer [CLIENT_ACCESS_TOKEN]'
      },
      body: JSON.stringify({
        startIndex: 1, // 1-based index
        count: '100', // If set to 0 or undefined, no records will be returned
        filter: '(preferredLanguage eq \"en\")or(addresses.country eq \"USA\")"' // Filter expression allows fetching users who either speak English or located in the USA
        schemas: [
            "urn:ietf:params:scim:api:messages:2.0:SearchRequest"
        ]
      })
    }
  );

  const data = await resp.json();
  console.log(data);
}

run();
```

## Fetch user updates

For ongoing exchange of identity information, consider synchronizing data between Mosaic and other services, for example, every 24 hours. With the query below you can retrieve all user records that have been updated within the last 24 hours. Send a GET request to [/scim/users](/openapi/user/user-scim.openapi/other/scimgetusersgetrequest) endpoint or POST to [/scim/users/.search](/openapi/user/user-scim.openapi/other/scimgetuserspostrequest) with a filter expression.

GET

```js
import fetch from 'node-fetch';

async function run() {
  const query = new URLSearchParams({
    startIndex: '1', // 1-based index
    count: '100', // If set to 0 or undefined, no records will be returned
    filter: 'meta.lastModified ge \"2023-11-20T00:00:00.000Z\"' // Filter expression allows fetching user updates that occurred after November 20, 2023.
  }).toString();

  const resp = await fetch(
    `https://api.transmitsecurity.io/cis/scim/Users?${query}`,
    {
      method: 'GET',
      headers: {
        Accept: 'application/scim+json',
        Authorization: 'Bearer [CLIENT_ACCESS_TOKEN]'
      }
    }
  );

  const data = await resp.text();
  console.log(data);
}

run();
```

POST

```js
import fetch from 'node-fetch';

async function run() {
  const resp = await fetch(
    `https://api.transmitsecurity.io/cis/scim/Users/.search`,
    {
      method: 'POST',
      headers: {
        Accept: 'application/scim+json',
        'Content-Type': 'application/scim+json',
        Authorization: 'Bearer [CLIENT_ACCESS_TOKEN]'
      },
      body: JSON.stringify({
        startIndex: 1, // 1-based index
        count: '100', // If set to 0 or undefined, no records will be returned
        filter: 'meta.lastModified ge \"2023-11-20T00:00:00.000Z\"' // Filter expression allows fetching user updates that occurred after November 20, 2023.
        schemas: [
            "urn:ietf:params:scim:api:messages:2.0:SearchRequest"
        ]
      })
    }
  );

  const data = await resp.json();
  console.log(data);
}

run();
```

## Update user's profile

Modify user details such as their phone number or email address by sending a PUT request to [/scim/users](/openapi/user/user-scim.openapi/other/scimreplaceuserattributes) endpoint. Changes will be merged into the user's profile, so you can specify only the fields you want to add or update. Note that:

- Since Mosaic performs a shallow merge, object- and array-based attributes (like `name` and `addresses`) cannot be partially updated, as the new value of an object or array will just replace the current one. For example, updating a `familyName` for a user who has both a `familyName` and a `givenName` defined will override an entire `name` object and an updated user profile will only include a new family name.
- Custom data specified in `urn:ietf:params:scim:schemas:extension:CustomAppData:2.0:User` is also updated as a shallow merge.



```js
import fetch from 'node-fetch';

async function run() {
  const userId = '[USER_ID]'; // User to update
  const resp = await fetch(
    `https://api.transmitsecurity.io/cis/scim/Users/${userId}`,
    {
      method: 'PUT',
      headers: {
        Accept: 'string',
        'Content-Type': 'application/json',
        Authorization: 'Bearer [CLIENT_ACCESS_TOKEN]'
      },
      body: JSON.stringify({
        name: { // Overrides user's name. Other attributes inside this object will be overridden
          familyName: '[USER_FAMILY_NAME]'
        },
        preferredLanguage: 'LANGUAGE', // Adds preferred language to user profile
        emails: [
          {
            'value': '[NEW_USER_EMAIL]', // Overrides primary user email. Non-primary emails remain as is
            'primary': true
          }
        ],
        schemas: [
          'urn:ietf:params:scim:schemas:core:2.0:User'
        ],
        userName: '[USERNAME]'// Unique user identifier
      })
    }
  );

  const data = await resp.json();
  console.log(data);
}

run();
```

## Delete a user

As a final step in user lifecycle management, remove inactive users by sending a DELETE request to [scim/users](/openapi/user/user-scim.openapi/other/scimdeleteuserbyid) endpoint and providing the user's ID.


```js
import fetch from 'node-fetch';

async function run() {
  const userId = '[USERID]'; // The ID of the user to delete
  const resp = await fetch(
    `https://api.transmitsecurity.io/cis/scim/Users/${userId}`,
    {
      method: 'DELETE',
      headers: {
        Accept: 'string',
        Authorization: 'Bearer [CLIENT_ACCESS_TOKEN]'
      }
    }
  );

  if (resp.status === 204) {
    console.log('success');
  } else {
    const data = await resp.text();
    console.log(data);
  }
}

run();
```

style

    td:nth-child(n-2) {
      width: 280px;
    }