> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://developer.fortresstech.io/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://developer.fortresstech.io/_mcp/server.

# Filtering with FQL

> Documentation for Fortress's filtering

Fortress Query Language (FQL) is a structured syntax for finding the resources you need throughout the API

# How to use it

This document describes the available operators for filtering, and provides examples for each.

> **Warning**
>
> **Be Sure to Encode Your URI!**: While the documentation ignores URI encoding for clarity purposes, you should always encode them according to RFC3986
>
> Example of what **NOT** to do:
>
> ```
> /users?filter=status="ACTIVE" and name="John"  // ❌ Will break due to spaces
> ```
>
> Instead, use:
>
> ```
> status="ACTIVE"%20and%20name="John"  // ✅ Works correctly  
> ```

## Comparison Operators

| Operator     | Description                               | Example Usage                          | Status               |
| ------------ | ----------------------------------------- | -------------------------------------- | -------------------- |
| `=` or `==`  | Equal to                                  | `status = "ACTIVE"`                    | ✅ Available          |
| `!=` or `<>` | Not equal to                              | `status != "INACTIVE"`                 | ⚠️ Not Yet Available |
| `>`          | Greater than                              | `amount > 100`                         | ✅ Available          |
| `>=`         | Greater than or equal to                  | `amount >= 100`                        | ✅ Available          |
| `<`          | Less than                                 | `amount < 100`                         | ✅ Available          |
| `<=`         | Less than or equal to                     | `amount <= 100`                        | ✅ Available          |
| `~=` or `~`  | Wildcard partial match                    | `name ~= "John*"`                      | ✅ Available          |
| `matches`    | Regular expression match                  | `email matches ".*@gmail.com"`         | ✅ Available          |
| `hasAny`     | Check if array contains any of the values | `propertyIds hasAny ["uuid1","uuid2"]` | ✅ Available          |

## Logical and Special Operators

| Operator | Description                                   | Example Usage                                    | Status      |
| -------- | --------------------------------------------- | ------------------------------------------------ | ----------- |
| `and`    | Logical AND - Both conditions must be true    | `status = "ACTIVE" and createdAt > "2024-01-01"` | ✅ Available |
| `or`     | Logical OR - Either condition must be true    | `status = "ACTIVE" or status = "PENDING"`        | ✅ Available |
| `not`    | Logical NOT - Negates the following condition | `not status = "INACTIVE"`                        | ✅ Available |
| `()`     | Grouping - Group conditions for precedence    | `(status = "ACTIVE") or (status = "PENDING")`    | ✅ Available |

## Special Values

| Value    | Description                           | Example Usage      | Status      |
| -------- | ------------------------------------- | ------------------ | ----------- |
| `NULL`   | Check if field is missing or null     | `deletedAt = NULL` | ✅ Available |
| `EXISTS` | Check if field exists and has a value | `email = EXISTS`   | ✅ Available |

## Examples

### Basic Equality

```
status = "ACTIVE"
propertyId = "123e4567-e89b-12d3-a456-426614174000"
```

### Range Queries

```
amount > 100
createdAt >= "2024-01-01T00:00:00Z"
amount < 1000
```

### Wildcard Searches

```
name ~= "John*"        // Names starting with "John"
email ~= "*@gmail.com" // Emails ending with @gmail.com
```

### Regular Expressions

```
email matches ".*@(gmail|yahoo)\.com"
phoneNumber matches "\+1[0-9]{10}"
```

### Array Field Queries

The `hasAny` operator allows you to check if an array field contains any of the specified values:

```
propertyIds hasAny ["uuid1","uuid2","uuid3"]
```

This is particularly useful for fields that store multiple values, such as property assignments or tags.

### Logical Combinations

```
status = "ACTIVE" and amount > 100
status = "ACTIVE" or status = "PENDING"
not status = "DELETED"
(status = "ACTIVE" or status = "PENDING") and amount > 100
```

### Null and Existence Checks

```
deletedAt = NULL           // Records that haven't been deleted
email = EXISTS             // Records that have an email address
```

### Complex Queries

```
(status = "ACTIVE" or status = "PENDING") and createdAt > "2024-01-01" and amount < 1000
propertyIds hasAny ["uuid1","uuid2"] and status = "ACTIVE"
```

---

For more advanced usage, refer to the code or ask for help!