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

# Lua Query

> The common bounded Mongo-style query language used across Lua platform APIs

## Overview

Lua Query is the single filter language for every Lua platform API that exposes a `filter` parameter. It behaves the same for Data, Products, and any other Mongo-backed entity: the entity changes, but the supported syntax, validation rules, limits, and errors do not.

API implementations scope the compiled query to the entity's data and immutable ownership fields. Filter input cannot replace an agent, collection, user, or organization predicate.

<Note>
  Methods without a `filter` parameter do not interpret their input as Lua Query. For example, `User.get()` selects one record by an exact user and agent identity; custom properties stored on that record remain ordinary data.
</Note>

## Supported syntax

Comparison operands must be JSON scalars. Membership operands must be arrays of JSON scalars. Logical operators are allowed only at the root of a filter or one of its logical branches.

```typescript theme={null}
// Equality and comparison
{ status: 'active' }
{ age: { $eq: 25 } }
{ age: { $ne: 25 } }
{ age: { $gt: 25, $lte: 65 } }

// Membership and array shorthand
{ tags: { $in: ['urgent', 'important'] } }
{ tags: { $nin: ['spam', 'archived'] } }
{ tags: ['urgent', 'important'] } // Shorthand for $in

// Existence
{ email: { $exists: true } }

// Root logical operators
{ $and: [{ age: { $gte: 18 } }, { age: { $lte: 65 } }] }
{ $or: [{ status: 'active' }, { status: 'pending' }] }

// Nested fields
{ 'metadata.brand': 'Lua' }
{ metadata: { brand: 'Lua' } }
```

The complete operator set is `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$in`, `$nin`, `$exists`, root `$and`, and root `$or`.

## Security and errors

Lua Query is deliberately smaller than the complete MongoDB query language. Unknown or dangerous operators—including `$where`, `$expr`, `$function`, `$regex`, `$text`, and geospatial operators—are rejected with a `400` error and a stable `FILTER_*` code. They are never executed, silently removed, or allowed to widen the query.

Field paths cannot contain `$` segments, null bytes, empty segments, or prototype-related names. Invalid operands and misplaced operators also fail closed.

```text theme={null}
API request failed with status 400
(FILTER_UNSUPPORTED_OPERATOR at $.name.$regex):
Invalid filter: $regex is not supported
```

## Resource limits

The same limits apply on every API surface:

| Limit                           |       Maximum |
| ------------------------------- | ------------: |
| Encoded filter size             |         8 KiB |
| Nesting depth                   |      8 levels |
| Total nodes                     |           128 |
| Branches per logical operator   |            20 |
| Values per `$in` or `$nin` list |           100 |
| Field path size                 |     256 bytes |
| String operand size             |         4 KiB |
| Page size                       |     100 items |
| Pagination offset               | 100,000 items |
| Database execution time         |     5 seconds |

These limits protect shared database capacity while keeping common application queries expressive and predictable.
