> ## Documentation Index
> Fetch the complete documentation index at: https://auth0-docs-user-search.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# How to List and Search Users with Search Queries

> Retrieve a list of all user profiles and filter results with Lucene search query strings.

export const AuthCodeGroup = ({children, dropdown}) => {
  const [processedChildren, setProcessedChildren] = useState(children);
  useEffect(() => {
    let unsubscribe = null;
    function init() {
      unsubscribe = window.autorun(() => {
        const processChildren = node => {
          if (typeof node === "string") {
            let processedNode = node;
            for (const [key, value] of window.rootStore.variableStore.values.entries()) {
              const escapedKey = key.replaceAll(/[.*+?^${}()|[\]\\]/g, (String.raw)`\$&`);
              processedNode = processedNode.replaceAll(new RegExp(escapedKey, "g"), value);
            }
            return processedNode;
          } else if (Array.isArray(node)) {
            return node.map(processChildren);
          } else if (node && node.props && node.props.children) {
            return {
              ...node,
              props: {
                ...node.props,
                children: processChildren(node.props.children)
              }
            };
          }
          return node;
        };
        setProcessedChildren(processChildren(children));
      });
    }
    if (window.rootStore) {
      init();
    } else {
      window.addEventListener("adu:storeReady", init);
    }
    return () => {
      window.removeEventListener("adu:storeReady", init);
      unsubscribe?.();
    };
  }, [children]);
  return <CodeGroup dropdown={dropdown}>{processedChildren}</CodeGroup>;
};

export const AuthCodeBlock = ({filename, icon, language, highlight, children}) => {
  const [displayText, setDisplayText] = useState(children);
  const [copyText, setCopyText] = useState(children);
  const wrapperRef = React.useRef(null);
  useEffect(() => {
    let unsubscribe = null;
    function init() {
      if (!window.autorun || !window.rootStore) {
        return;
      }
      unsubscribe = window.autorun(() => {
        let processedChildrenForDisplay = children;
        let processedChildrenForCopy = children;
        for (const [key, value] of window.rootStore.variableStore.values.entries()) {
          const escapedKey = key.replaceAll(/[.*+?^${}()|[\]\\]/g, (String.raw)`\$&`);
          let displayValue = value;
          if (key === "{yourClientSecret}" && value !== "{yourClientSecret}") {
            displayValue = value.substring(0, 3) + "*****MASKED*****";
          }
          processedChildrenForDisplay = processedChildrenForDisplay.replaceAll(new RegExp(escapedKey, "g"), displayValue);
          processedChildrenForCopy = processedChildrenForCopy.replaceAll(new RegExp(escapedKey, "g"), value);
        }
        setDisplayText(processedChildrenForDisplay);
        setCopyText(processedChildrenForCopy);
      });
    }
    if (window.rootStore) {
      init();
    } else {
      window.addEventListener("adu:storeReady", init);
    }
    return () => {
      window.removeEventListener("adu:storeReady", init);
      unsubscribe?.();
    };
  }, [children]);
  useEffect(() => {
    if (!wrapperRef.current) return;
    const originalWriteText = navigator.clipboard.writeText.bind(navigator.clipboard);
    let isOverriding = false;
    const handleClick = e => {
      const button = e.target.closest('[data-testid="copy-code-button"]');
      if (!button || !wrapperRef.current.contains(button)) return;
      isOverriding = true;
      navigator.clipboard.writeText = text => {
        if (isOverriding) {
          isOverriding = false;
          navigator.clipboard.writeText = originalWriteText;
          return originalWriteText(copyText);
        }
        return originalWriteText(text);
      };
      setTimeout(() => {
        if (isOverriding) {
          isOverriding = false;
          navigator.clipboard.writeText = originalWriteText;
        }
      }, 100);
    };
    const wrapper = wrapperRef.current;
    wrapper.addEventListener('click', handleClick, true);
    return () => {
      wrapper.removeEventListener('click', handleClick, true);
      if (navigator.clipboard.writeText !== originalWriteText) {
        navigator.clipboard.writeText = originalWriteText;
      }
    };
  }, [copyText]);
  return <div ref={wrapperRef}>
      <CodeBlock filename={filename} icon={icon} language={language} lines highlight={highlight}>
        {displayText}
      </CodeBlock>
    </div>;
};

Using the Auth0 Dashboard or the Management API, you can retrieve a list of users and filter results by search criteria you specify.

## List and search for users

<Tabs>
  <Tab title="Auth0 Dashboard">
    To view a list of users, go to [Dashboard > User Management > Users](https://manage.auth0.com/#/users).

    <img src="https://mintlify.s3.us-west-1.amazonaws.com/auth0-docs-user-search/docs/images/user-management/users.png" alt="The Users page in the Auth0 Dashboard" />

    The search field and drop-down menu at the top of the page lets you search by the following properties:

    * User
    * Email
    * Identity provider
    * Connection
    * Organization ID
    * Login count
    * Last login
    * Phone number

    You can also choose **Lucene Syntax (Advanced)** to specify search criteria. The [search query syntax reference](./user-search-query-syntax) includes more information on supported search features and example queries.
  </Tab>

  <Tab title="Management API">
    The Management API's [List or Search Users endpoint](/docs/api/management/v2/users/get-users) (`GET /users`) is eventually consistent, so results may not immediately reflect recently-completed write operations. We recommend using this endpoint for actions that are not critically time sensitive, such as changing the display name of an existing user.

    <Warning>
      **When to use the List or Search Users endpoint**

      * Do not use this endpoint as part of an authentication process, for [account linking](/docs/manage-users/user-accounts/user-account-linking), or when immediate consistency is necessary. Instead, use the Management API endpoints to [get users by ID or email](/docs/manage-users/user-search/get-users-by-id-or-email).

      * Do not use the List or Search Users endpoint to export users. Instead, use [bulk user exports](/docs/manage-users/user-migration/bulk-user-exports).
    </Warning>

    To list all users with the Management API, call the [List or Search Users endpoint](/docs/api/management/v2/users/get-users) (`GET /users`). To search for users, specify search criteria with the [`q` query parameter](/docs/api/management/v2/users/get-users#parameter-q) and a [Lucene search query string](./user-search-query-syntax).

    For example, to search for a user whose name is exactly `example`:

    <AuthCodeGroup>
      ```bash curl theme={null}
      curl --request GET \
        --url 'https://{yourDomain}/api/v2/users?q=name%3A%22example%22&search_engine=v3' \
        --header 'authorization: Bearer {yourMgmtApiAccessToken}'
      ```

      ```csharp C# theme={null}
      var client = new RestClient("https://{yourDomain}/api/v2/users?q=name%3A%22example%22&search_engine=v3");
      var request = new RestRequest(Method.GET);
      request.AddHeader("authorization", "Bearer {yourMgmtApiAccessToken}");
      IRestResponse response = client.Execute(request);
      ```

      ```go Go theme={null}
      package main

      import (
      	"fmt"
      	"net/http"
      	"io/ioutil"
      )

      func main() {
      	url := "https://{yourDomain}/api/v2/users?q=name%3A%22example%22&search_engine=v3"
      	req, _ := http.NewRequest("GET", url, nil)
      	req.Header.Add("authorization", "Bearer {yourMgmtApiAccessToken}")

      	res, _ := http.DefaultClient.Do(req)
      	defer res.Body.Close()
      	body, _ := ioutil.ReadAll(res.Body)

      	fmt.Println(res)
      	fmt.Println(string(body))
      }
      ```

      ```java Java theme={null}
      HttpResponse<String> response = Unirest.get("https://{yourDomain}/api/v2/users?q=name%3A%22example%22&search_engine=v3")
        .header("authorization", "Bearer {yourMgmtApiAccessToken}")
        .asString();
      ```

      ```javascript Node.JS theme={null}
      var axios = require("axios").default;

      var options = {
        method: 'GET',
        url: 'https://{yourDomain}/api/v2/users',
        params: {q: 'name:"example"', search_engine: 'v3'},
        headers: {authorization: 'Bearer {yourMgmtApiAccessToken}'}
      };

      axios.request(options).then(function (response) {
        console.log(response.data);
      }).catch(function (error) {
        console.error(error);
      });
      ```

      ```php PHP theme={null}
      $curl = curl_init();

      curl_setopt_array($curl, [
        CURLOPT_URL => "https://{yourDomain}/api/v2/users?q=name%3A%22example%22&search_engine=v3",
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_ENCODING => "",
        CURLOPT_MAXREDIRS => 10,
        CURLOPT_TIMEOUT => 30,
        CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
        CURLOPT_CUSTOMREQUEST => "GET",
        CURLOPT_HTTPHEADER => [
          "authorization: Bearer {yourMgmtApiAccessToken}"
        ],
      ]);

      $response = curl_exec($curl);
      $err = curl_error($curl);
      curl_close($curl);

      if ($err) {
        echo "curl Error #:" . $err;
      } else {
        echo $response;
      }
      ```

      ```python Python theme={null}
      import http.client

      conn = http.client.HTTPSConnection("")
      headers = { 'authorization': "Bearer {yourMgmtApiAccessToken}" }
      conn.request("GET", "/{yourDomain}/api/v2/users?q=name%3A%22example%22&search_engine=v3", headers=headers)

      res = conn.getresponse()
      data = res.read()

      print(data.decode("utf-8"))
      ```

      ```ruby Ruby theme={null}
      require 'uri'
      require 'net/http'
      require 'openssl'

      url = URI("https://{yourDomain}/api/v2/users?q=name%3A%22example%22&search_engine=v3")

      http = Net::HTTP.new(url.host, url.port)
      http.use_ssl = true
      http.verify_mode = OpenSSL::SSL::VERIFY_NONE

      request = Net::HTTP::Get.new(url)
      request["authorization"] = 'Bearer {yourMgmtApiAccessToken}'

      response = http.request(request)
      puts response.read_body
      ```
    </AuthCodeGroup>

    Search queries time out (HTTP status code 503) if they don't complete in two seconds or less. If your search query times out, it may be an expensive query or it may have an error that results in it not completing in time.

    The error `414 Request-URI Too Large` means that your query string is larger than the supported length. In this case, refine your search.

    The [search query syntax reference](./user-search-query-syntax) includes more information on supported search features and example queries.
  </Tab>
</Tabs>

## Sort results

<Tabs>
  <Tab title="Auth0 Dashboard">
    In the Auth0 Dashboard, you can sort results by selecting the columns available in the table of users:

    * Name
    * User ID
    * Connection
    * Logins
    * Latest Login

    Select the column title once to sort in ascending order and again to sort in descending order. To sort results by other fields, use the Management API.
  </Tab>

  <Tab title="Management API">
    To sort user search results, set the [`sort` query parameter](/docs/api/management/v2/users/get-users#parameter-sort) to the value `field:order`, where:

    * `field` is the name of the field to sort by
    * `order` is `1` for ascending or `-1` for descending.

    For example, to sort users in ascending order by their creation time, set the `sort` parameter to `created_at:1`:

    <AuthCodeGroup>
      ```bash curl theme={null}
      curl --request GET \
        --url 'https://{yourDomain}/api/v2/users?q=logins_count%3A%5B100%20TO%20200%5D&sort=created_at%3A1&search_engine=v3' \
        --header 'authorization: Bearer {yourMgmtApiAccessToken}'
      ```

      ```csharp C# theme={null}
      var client = new RestClient("https://{yourDomain}/api/v2/users?q=logins_count%3A%5B100%20TO%20200%5D&sort=created_at%3A1&search_engine=v3");
      var request = new RestRequest(Method.GET);
      request.AddHeader("authorization", "Bearer {yourMgmtApiAccessToken}");
      IRestResponse response = client.Execute(request);
      ```

      ```go Go theme={null}
      package main

      import (
      	"fmt"
      	"net/http"
      	"io/ioutil"
      )

      func main() {
      	url := "https://{yourDomain}/api/v2/users?q=logins_count%3A%5B100%20TO%20200%5D&sort=created_at%3A1&search_engine=v3"
      	req, _ := http.NewRequest("GET", url, nil)
      	req.Header.Add("authorization", "Bearer {yourMgmtApiAccessToken}")

      	res, _ := http.DefaultClient.Do(req)
      	defer res.Body.Close()
      	body, _ := ioutil.ReadAll(res.Body)

      	fmt.Println(res)
      	fmt.Println(string(body))
      }
      ```

      ```java Java theme={null}
      HttpResponse<String> response = Unirest.get("https://{yourDomain}/api/v2/users?q=logins_count%3A%5B100%20TO%20200%5D&sort=created_at%3A1&search_engine=v3")
        .header("authorization", "Bearer {yourMgmtApiAccessToken}")
        .asString();
      ```

      ```javascript Node.JS theme={null}
      var axios = require("axios").default;

      var options = {
        method: 'GET',
        url: 'https://{yourDomain}/api/v2/users',
        params: {q: 'logins_count:[100 TO 200]', sort: 'created_at:1', search_engine: 'v3'},
        headers: {authorization: 'Bearer {yourMgmtApiAccessToken}'}
      };

      axios.request(options).then(function (response) {
        console.log(response.data);
      }).catch(function (error) {
        console.error(error);
      });
      ```

      ```php PHP theme={null}
      $curl = curl_init();

      curl_setopt_array($curl, [
        CURLOPT_URL => "https://{yourDomain}/api/v2/users?q=logins_count%3A%5B100%20TO%20200%5D&sort=created_at%3A1&search_engine=v3",
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_ENCODING => "",
        CURLOPT_MAXREDIRS => 10,
        CURLOPT_TIMEOUT => 30,
        CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
        CURLOPT_CUSTOMREQUEST => "GET",
        CURLOPT_HTTPHEADER => [
          "authorization: Bearer {yourMgmtApiAccessToken}"
        ],
      ]);

      $response = curl_exec($curl);
      $err = curl_error($curl);

      curl_close($curl);

      if ($err) {
        echo "curl Error #:" . $err;
      } else {
        echo $response;
      }
      ```

      ```python Python theme={null}
      import http.client

      conn = http.client.HTTPSConnection("")
      headers = { 'authorization': "Bearer {yourMgmtApiAccessToken}" }
      conn.request("GET", "/{yourDomain}/api/v2/users?q=logins_count%3A%5B100%20TO%20200%5D&sort=created_at%3A1&search_engine=v3", headers=headers)

      res = conn.getresponse()
      data = res.read()

      print(data.decode("utf-8"))
      ```

      ```ruby Ruby theme={null}
      require 'uri'
      require 'net/http'
      require 'openssl'

      url = URI("https://{yourDomain}/api/v2/users?q=logins_count%3A%5B100%20TO%20200%5D&sort=created_at%3A1&search_engine=v3")

      http = Net::HTTP.new(url.host, url.port)
      http.use_ssl = true
      http.verify_mode = OpenSSL::SSL::VERIFY_NONE

      request = Net::HTTP::Get.new(url)
      request["authorization"] = 'Bearer {yourMgmtApiAccessToken}'

      response = http.request(request)
      puts response.read_body
      ```
    </AuthCodeGroup>
  </Tab>
</Tabs>

## Performance recommendations

Use the following guidelines for better performance with user search:

* The Management API List or Search Users endpoint returns results in a deterministic order so the same query yields the same logically ordered results each time. Non-deterministic search is faster, so if deterministic search is not necessary for your use case, use non-deterministic search by setting `primary_order=false`.

* Escape the space character (for example, write `q=name:John Doe` as `q=name:John\ Doe`).

* Minimize use of wildcards, especially on large data sets. When using wildcards, prefer using them as suffixes to the search term rather than prefixes.

* Avoid search criteria that return data sets with more than 1,000 results.

* Avoid existence queries (for example, "give me all users with a property regardless of its value").

* For user-defined attributes in `app_metadata` and `user_metadata`:

  * Keep metadata fields to 2 KB or less.

  * Use consistent data types and static names for metadata properties.

  * Avoid large schema sizes and deep structures.

* Avoid user searches within login flow extension points like `post-login` Actions.

* Don't poll the search APIs.

## Limits

* Search returns a maximum of 1,000 users, even if more users match your query. When using the API, large results are [paginated](/docs/api/management/v2#pagination).

* When using the Management API's List or Search Users endpoint, there is a [1 MB per-user limit on user data](/docs/manage-users/user-accounts/metadata/metadata-fields-data#size-limits-and-storage) that can be indexed, queried, and returned. To retrieve all user attributes for a large user profile, [get users by ID or email](/docs/manage-users/user-search/get-users-by-id-or-email).

* The Management API's List or Search Users endpoint does not support sorting by `app_metadata` or `user_metadata`.
