> For the complete documentation index, see [llms.txt](https://cortex-docs.paloaltonetworks.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://cortex-docs.paloaltonetworks.com/xsoar-6-administrator-guide/6.13/learn-about-cortex-xsoar/customize-and-configure-cortex-xsoar/lists/work-with-lists.md).

# Work With Lists

A list is a data container where you can globally store data within Cortex XSOAR. Despite the name lists, the data can be in any text format, and can even store files. You can use lists to manage important users in your organization, sensitive endpoints, SOC shifts, and more. These lists can be used dynamically within different investigations to provide global context to each relevant incident type.

The data within lists can be accessed in automations, playbooks, or any other place where the context button appears (double-curly brackets). In a playbook, you can access the data in a list via the context button under **Lists**, or by using the path **`${lists.<list_name>}`**. You can use a list in a playbook to modify, filter, or transform parts of a list and then update the list with the changes or use the changed data in subsequent playbook tasks. You can also use a playbook task to iterate over list items.

{% hint style="info" %}

### Note

The maximum list size is 209715 characters.
{% endhint %}

* Create a list

  When [creating a list](/xsoar-6-administrator-guide/6.13/learn-about-cortex-xsoar/customize-and-configure-cortex-xsoar/lists/create-a-list.md), you can select the content type (Text, [Markdown](/xsoar-6-administrator-guide/6.13/learn-about-cortex-xsoar/get-started-in-cortex-xsoar/how-to-use-markdown.md), HTML, JSON or CSS) and whether you want to limit permissions for read and write or read only.

  <div data-gb-custom-block data-tag="hint" data-style="info" class="hint hint-info"><h3>Note</h3><p>You can change the content type without editing the list. You cannot edit truncated lists that are too large to display, but you can download a truncated list.</p></div>

  If a valid JSON is stored within a list, it will automatically be parsed as a JSON object when you access it from within a playbook. Depending on how you store the data, you may need to [transform a list into an array](/xsoar-6-administrator-guide/6.13/learn-about-cortex-xsoar/customize-and-configure-cortex-xsoar/lists/transform-a-list-into-an-array.md).

  When you access a list using the built-in list or base pack commands, the data is considered to be comma-separated unless you specifically [define a custom separator for the list](/xsoar-6-administrator-guide/6.13/learn-about-cortex-xsoar/customize-and-configure-cortex-xsoar/lists/set-the-list-separator-character.md). When using built-in commands, you do not need to split the list. However, if you want to use non built-in commands, such as in an automation or to loop over list items, you need to [split the list using a transformer](/xsoar-6-administrator-guide/6.13/learn-about-cortex-xsoar/customize-and-configure-cortex-xsoar/lists/transform-a-list-into-an-array.md).
* Upload/download a list.
* In a remote repository, lists can be pushed to a production environment. When the list is pushed to production, you cannot edit the list in the production environment. If a list has been pushed to production that already exists with the same name, you can resolve the conflict. You can still create lists in production.
* (Multi-tenant) You can propagate lists from the Main Account to tenants.

Lists can be included in a content pack and be installed from the Marketplace.

**Use cases**

These are some common use cases for creating and using lists in Cortex XSOAR.

* A list of allowed executable files against which to check potentially malicious executable files.
* An HTML template that you can define to use as part of a Communication task.
* Store data object, for example JSON, that you can call as inputs for scripts and playbooks.
* Use the getList or addToList commands in a script to take action based on the list data, for example, **`res = demisto.executeCommand("getList", {"listName": demisto.args()["listName"]})`** will return all list entries in the script.

**List commands**

You can use the following list commands in scripts and playbook tasks.

| Command              | Description                                                                                                                                                                               | Arguments                                                                                                                                                                                                                                                   |
| -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`getList`**        | Retrieves the contents of the specified list.                                                                                                                                             | **`listName`**: The name of the list for which to retrieve the contents.                                                                                                                                                                                    |
| **`createList`**     | Creates a list with the supplied data and overwrites existing list data..                                                                                                                 | <ul><li><strong><code>listName</code></strong>: The name of the list to which to add items.</li><li><strong><code>listData</code></strong>: The data to add to the new list overwrites existing list data.</li></ul>                                        |
| **`addToList`**      | Appends the supplied items to the specified list. If you add multiple items, make sure you use the same list separator that the list currently uses, for example, a comma or a semicolon. | <ul><li><strong><code>listName</code></strong>: The name of the list to which to append items.</li><li><strong><code>listData</code></strong>: The data to add to the specified list. The data will be appended to the existing data in the list.</li></ul> |
| **`setList`**        | Adds the supplied data to the specified list and overwrites existing list data.                                                                                                           | <ul><li><strong><code>listName</code></strong>: The name of the list to which to add items.</li><li><strong><code>listData</code></strong>: The data to add to the specified list. The data overwrites the existing data in the list.</li></ul>             |
| **`removeFromList`** | Removes a single item from the specified list.                                                                                                                                            | <ul><li><strong><code>listName</code></strong>: The name of the list from which to remove an item.</li><li><strong><code>listData</code></strong>: The item to remove from the specified list.</li></ul>                                                    |

**Example**

For example, the ManageOOOUsers script uses the **`getList`**, **`createList`**, and **`setList`** commands.

register\_module\_line('ManageOOOusers', 'start', **line**())

def \_get\_current\_user(): current\_username = demisto.executeCommand("getUsers", {"current": True}) if isError(current\_username): demisto.debug(f"failed to get current username - {get\_error(current\_username)}") return else: return current\_username\[0]\["Contents"]\[0]\['username']

def main(): # get current time now = datetime.now()

```
# args
list_name = demisto.getArg("listname")
username = demisto.getArg("username")

option = demisto.getArg("option")
days_off = now + timedelta(days=int(demisto.getArg("daysoff")))
off_until = days_off.strftime("%Y-%m-%d")

# update list name to start with 'OOO', so we can't overwrite other lists with this
if not list_name.startswith("OOO"):
    list_name = f"OOO {list_name}"

current_user = _get_current_user()
if not current_user and not username:
    return_error('Failed to get current user. Please set the username argument in the script.')

if not username:
    # Current user was found, running script on it.
    username = current_user
else:
    # check if provided username is a valid xsoar user
    users = demisto.executeCommand("getUsers", {})
    if isError(users):
        return_error(f'Failed to get users: {str(get_error(users))}')
    users = users[0]['Contents']

    users = [x['username'] for x in users]
    if username not in users:
        return_error(message=f"{username} is not a valid user")

# get the out of office list, check if the list exists, if not create it:
ooo_list = demisto.executeCommand("getList", {"listName": list_name})[0]["Contents"]
if isError(ooo_list):
    return_error(f'Failed to get users out of office: {str(get_error(ooo_list))}')

if "Item not found" in ooo_list:
    demisto.results(demisto.executeCommand("createList", {"listName": list_name, "listData": []}))
    ooo_list = demisto.executeCommand("getList", {"listName": list_name})[0]["Contents"]

# check status of the list, and add/remove the user from it.
if not ooo_list:
    list_data = []
else:
    list_data = json.loads(ooo_list)
if option == "add":
    # check if user is already in the list, and remove, to allow updating
    list_data = [i for i in list_data if not (i['user'] == username)]
    list_data.append({"user": username,
                      "offuntil": off_until,
                      "addedby": current_user if current_user else 'DBot'})
else:
    # remove the user from the list.
    list_data = [i for i in list_data if not (i['user'] == username)]

set_list_res = demisto.executeCommand("setList", {"listName": list_name, "listData": json.dumps(list_data)})
if isError(set_list_res):
    return_error(f'Failed to update the list {list_name}: {str(get_error(set_list_res))}')

# welcome back, or see ya later!
if option == "add":
    demisto.results(f"Vacation mode engaged until {off_until}, enjoy the time off {username}")
else:
    demisto.results(f"Welcome back {username}, it's like you never left!")
if name in ('builtin', 'builtins', 'main'): main()
register_module_line('ManageOOOusers', 'end', line())    
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://cortex-docs.paloaltonetworks.com/xsoar-6-administrator-guide/6.13/learn-about-cortex-xsoar/customize-and-configure-cortex-xsoar/lists/work-with-lists.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
