> ## Documentation Index
> Fetch the complete documentation index at: https://docs.verisoul.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Account

> Account object structure and behavior

# Account Type

The Account object represents a user in the Verisoul system. Each account has a unique identifier, optional identity attributes (email, phone, name, username), and customizable metadata.

## Structure

| Field                | Type   | Required | Description                                                                                                                                                  |
| -------------------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `id`                 | string | Yes      | Unique identifier for the account                                                                                                                            |
| `email`              | string | No       | Email address associated with the account                                                                                                                    |
| `phone`              | string | No       | Phone number on file for the account, in E.164 format (e.g. `+14155550123`). Used for [multi-accounting phone matching](/signals-scores/multi-accounting).   |
| `first_name`         | string | No       | Account holder's first name. Combined with `last_name` for multi-accounting name matching.                                                                   |
| `last_name`          | string | No       | Account holder's last name. Combined with `first_name` for multi-accounting name matching.                                                                   |
| `username`           | string | No       | Username associated with the account. Used for multi-accounting username matching.                                                                           |
| `expected_countries` | array  | No       | Countries the account is expected to legitimately operate from, as ISO 3166-1 alpha-2 codes (e.g. `["US", "CA"]`).                                           |
| `metadata`           | object | No       | Key-value pairs of custom data associated with the account                                                                                                   |
| `group`              | string | No       | Groups must be enabled for the project to use this field. See [Multi Accounting Groups](/integration/advanced/multi-accounting-groups) for more information. |
| `lists`              | array  | No       | Array of list names to add the account to during authentication. See [Lists](/action/lists) for more information.                                            |

## Email Address

An Account can have have a string email address. Verisoul stores only one email address per Account. When updating an account with a new email address, the previous email address is replaced.

## Phone Number

An Account can have one phone number, provided in E.164 format (e.g. `+14155550123`). Like email, Verisoul stores one phone number per Account — updating an account with a new phone number replaces the previous one, and omitting the field keeps the stored value.

Before matching, the number is normalized: formatting characters (spaces, dashes, parentheses, dots) are stripped, and the result must be a valid E.164 number (`+` followed by 8–15 digits). Two accounts sharing a normalized phone number are linked with the full-strength `phone` match type. See [Multi-Accounting](/signals-scores/multi-accounting) for details.

## Username

An Account can have one username. Updating an account with a new username replaces the previous one, and omitting the field keeps the stored value.

Before matching, the username is lowercased and only letters, digits, `.`, `_`, and `-` are kept — so `Jane.Doe` and `jane.doe` match, while `jane.doe` and `janedoe` remain distinct. Two accounts sharing a normalized username are linked with the full-strength `username` match type.

## Name

An Account can have a first and last name, passed as separate `first_name` and `last_name` fields. Each field is updated independently — a call that includes only `first_name` keeps the stored `last_name`.

For matching, the available parts are combined into a single name and normalized: lowercased, with punctuation and diacritics removed (so `Jane O'Brien` and `JANE obrien` match). Providing either part enables name matching. Because names are far less distinctive than phone numbers or usernames, a name match is moderate strength: a name match alone never fully links two accounts, but name plus another match (device, network, email) does.

## Expected Countries

The `expected_countries` field is a declaration of where the account should legitimately operate from. Sending a **non-empty** list replaces the entire stored array (so a country can be removed by sending a new list without it). Omitting the field or sending an empty list `[]` leaves the stored declaration unchanged.

Once declared, sessions outside the expected countries carry the `outside_expected_countries` risk signal and raise the [location spoofing score](/signals-scores/location#location-spoofing-score) in proportion to how far outside they are. See [Expected Countries](/signals-scores/expected-countries) for how both work.

## Metadata

The metadata object allows you to store custom data with each account. When updating metadata:

1. New fields are added to the existing metadata
2. Existing fields are overwritten with new values
3. Other existing fields are preserved

### Example: Metadata Updates

Starting metadata state:

```json theme={null}
{
  "id": "acc_123456789",
  "email": "user@example.com",
  "metadata": {
    "plan": "free",
    "signup_date": "2023-01-15"
  }
}
```

**Update 1: Overwrite an existing field**

```json theme={null}
// Request
{
  "metadata": {
    "plan": "premium"
  }
}

// Resulting account state
{
  "id": "acc_123456789",
  "email": "user@example.com",
  "metadata": {
    "plan": "premium", // Updated
    "signup_date": "2023-01-15" // Preserved
  }
}
```

**Update 2: Add a new field**

```json theme={null}
// Request
{
  "metadata": {
    "referral_code": "FRIEND50"
  }
}

// Resulting account state
{
  "id": "acc_123456789",
  "email": "user@example.com",
  "metadata": {
    "plan": "premium", // Preserved
    "signup_date": "2023-01-15", // Preserved
    "referral_code": "FRIEND50" // Added
  }
}
```

## Lists

The `lists` field allows you to specify which lists an account should be added to. This field is available in both:

* **Server-side API**: During authentication via `/session/authenticate`
* **Client-side SDK**: Using the `Verisoul.account()` method

This is useful for automatically categorizing accounts based on certain criteria.

### Example: Adding Account to Lists

**Server-side (Authenticate API):**

```json theme={null}
{
  "account": {
    "id": "niel-test-08-11-2025",
    "email": "niel30@beeble.com",
    "lists": ["custom-list", "allow"]
  },
  "session_id": "00000000-0000-0000-0000-000000000001"
}
```

**Client-side (Browser SDK):**

```javascript theme={null}
await window.Verisoul.account({
  id: "niel-test-08-11-2025",
  email: "niel30@beeble.com",
  lists: ["custom-list", "allow"]
});
```

**Important Notes:**

* The account will be added to all specified lists during processing
* If a list does not exist, it will be automatically created (this will not cause the API to fail)
* Use good naming conventions: lowercase with dashes or underscores, no special characters or whitespace
* Standard lists (allow, block, main\_account) follow the [list hierarchy rules](/action/lists#list-hierarchy-and-movement)
* Custom lists can be used for flexible account categorization

```
```
