# Using Auth0 filtering capabilities through API

Users will find in this page a comprehensive guide to interacting with the Auth0 Management API using the `q` parameter for user search and filtering, based on Auth0's official query syntax and best practices.

## A Comprehensive Guide to Auth0 API User Search and Filtering

Auth0's Management API provides a robust way to search and filter through your user base. Under the hood, the API uses **Lucene Query Syntax** (version 3) to parse the search string passed via the `q` parameter. This allows you to construct precise queries using logical operators, exact matches, wildcards, and more.

## 1. Prerequisites

Before performing search requests, ensure that you have:

- **An Access Token:** You need a valid Management API access token.
- **The Right Scopes:** Your token must include the `read:users` scope to perform user search operations.

## 2. Understanding the `q` Parameter & Lucene Syntax

When calling the `/api/v2/users` endpoint, you pass your search string into the `q` parameter.

### Basic Terms and Exact Matches

- **Single terms:** A single word like `jane` or `smith`.
- **Exact Matches:** To find an exact phrase matching multiple words, wrap the string in double quotes.
  - _Example:_ `q=name:"jane smith"`
- **Escaping Spaces:** To improve performance, especially when not using double quotes, you can escape the space character using a backslash.
  - _Example:_ `q=name:John\ Doe`

### Logical Operators

You can combine multiple search terms to form complex sub-queries using logical operators.

- **Supported Operators:** `AND`, `OR`, `NOT`
- **Important:** Operators **must** always be capitalized. They work across all normalized user fields and root metadata fields.

### Case Sensitivity

- **Case-Insensitive:** Search values for normalized user fields (`email`, `name`, `given_name`, `family_name`, and `nickname`).
- **Case-Sensitive:** All other fields, including any custom fields inside `app_metadata` or `user_metadata`.

## 3. Searchable Built-in Fields

Aside from the standard profile fields, Auth0 indexes a variety of specific data points you can filter on:

| **Field**                   | **Data Type** | **Description**                                                    |
| --------------------------- | ------------- | ------------------------------------------------------------------ |
| `phone_number`              | text          | The user's phone number (for SMS connections).                     |
| `phone_verified`            | boolean       | `true`/`false` indicating if the phone is verified.                |
| `logins_count`              | integer       | Total number of times the user has logged in.                      |
| `created_at` / `updated_at` | date time     | Timestamps of when the profile was created or modified.            |
| `last_login`                | date time     | Timestamp of the user's last login.                                |
| `last_ip`                   | text          | The valid IP address from the user's last login.                   |
| `blocked`                   | boolean       | Filters users blocked via Admin Dashboard or API (`true`/`false`). |
| `email.domain`              | text          | The domain portion of the user's email address.                    |
| `organization_id`           | text          | The organization ID the user belongs to.                           |

## 4. Searching Custom Metadata

Auth0 allows you to attach custom data to users via `user_metadata` (user-editable) and `app_metadata` (admin/app-controlled). You can easily filter by these properties using dot notation.

_Supported Data Types:_ boolean, numeric (integer/double), and text.

- **Filter by existence:** To find users who simply have a specific metadata attribute:
  - `q=_exists_:user_metadata.favorite_color`
- **Filter by value:** \* `q=user_metadata.favorite_color:"blue"`
- **Nested Objects:** Use the exact path to query a nested scalar value:
  - `q=user_metadata.preferences.fontSize:13`
- **Nested Arrays:** To search inside nested arrays, use the path and ignore the array level itself:
  - `q=user_metadata.addresses.city:"Seattle"`

## (Note: Metadata fields containing empty arrays, empty objects, or null values are not indexed and cannot be searched)

## 5. Advanced Filtering: Wildcards and Ranges

### Wildcards ()

You can use the asterisk `*` to replace zero or more characters.

- **Prefix matching:** `q=name:john*` returns users with names starting with "john".
- **Suffix matching:** `q=name:*usa`. _Note: The literal before a suffix wildcard must be at least 3 characters long (e.g., `usa` is valid, `sa` is not)._
- **Limitation:** Wildcards **cannot** be used on `user_metadata` or `app_metadata` fields.

### Ranges

Range filters are highly useful for numerical values (like `logins_count`) or date times (like `created_at`).

- **Inclusive ranges:** Use square brackets `[min TO max]`
- **Exclusive ranges:** Use curly brackets `{min TO max}`
- **Combinations:** `q=logins_count:[100 TO 200}` (Inclusive 100, exclusive 200).
- **Open-ended ranges:** Combine ranges with wildcards. `q=logins_count:{100 TO *]` finds all users with more than 100 logins.
- **Limitation:** Range searches **cannot** be used on metadata fields.

## 6. Performance Best Practices

To ensure your queries resolve quickly and do not run into Auth0's strict **2-second timeout** window (which results in a `503 Service Unavailable` error), follow these guidelines:

1. **Leverage non-deterministic search:** If you don't care about the specific order of the returned list, append `&primary_order=false` to your API call. This significantly improves database query performance.
2. **Avoid prefix wildcards where possible:** Suffix wildcards perform much better than prefixing wildcards to search terms.
3. **Optimize your metadata schema:**
   - Keep data types consistent across user profiles.
   - Avoid deep nesting structures and dynamic property names.
   - Keep metadata fields small (Auth0 recommends 2 KB or less per field).
4. **Avoid "Existence" Queries on large datasets:** Asking the API to return _"all users with this property, regardless of value"_ is a highly expensive operation.
5. **Escape Spaces:** As mentioned earlier, `q=name:John\ Doe` parses much faster than unescaped strings.

## 7. Operational Limitations & Anti-Patterns

Auth0 explicitly warns against a few anti-patterns when using the User Search APIs:

- **Don't use User Search for authentication flows:** Search endpoints are eventually consistent. If you need immediately consistent data during a login process (e.g., checking if a user exists), use the **Get Users by ID** or **Get Users by Email** endpoints instead.
- **No critical operations:** Never rely on the list or search users endpoint for mission-critical operations or post-login Actions/Rules.
- **Pagination Limits:** Do not attempt to use `q` search criteria that yields massive datasets. The search APIs strictly limit returns to **1,000 results maximum** (10 pages of 100 records). If you need more data, you should be using the Auth0 User Import/Export extensions.
- **Do not poll the API:** Repeatedly querying the search API on a timer can quickly exhaust rate limits and result in blocked requests.
