diff --git a/README.md b/README.md
index c5533ed6..360b8b09 100755
--- a/README.md
+++ b/README.md
@@ -122,9 +122,15 @@ curl -X POST http://localhost:8000/api/hyperfleet/v1/clusters \
 
 # Search clusters
 curl -G http://localhost:8000/api/hyperfleet/v1/clusters \
-  --data-urlencode "search=labels.env='production'" | jq
+  --data-urlencode "search=labels.environment='production'" | jq
+
+# Search ready clusters in a specific region
+curl -G http://localhost:8000/api/hyperfleet/v1/clusters \
+  --data-urlencode "search=status.conditions.Ready='True' and labels.region='us-east'" | jq
 ```
 
+See [docs/search.md](docs/search.md) for search and filtering documentation.
+
 ## Development
 
 ### Common Commands
@@ -161,6 +167,7 @@ This project uses [pre-commit](https://pre-commit.io/) for code quality checks.
 ### Additional Resources
 
 - **[PREREQUISITES.md](PREREQUISITES.md)** - Prerequisite installation
+- **[Search and Filtering](docs/search.md)** - Guide to TSL query syntax, operators, and examples
 - **[docs/continuous-delivery-migration.md](docs/continuous-delivery-migration.md)** - CD migration guide
 - **[docs/dao.md](docs/dao.md)** - Data access patterns
 - **[docs/testcontainers.md](docs/testcontainers.md)** - Testcontainers usage
diff --git a/docs/api-resources.md b/docs/api-resources.md
index c0b16665..fa83ebff 100644
--- a/docs/api-resources.md
+++ b/docs/api-resources.md
@@ -408,40 +408,14 @@ GET /api/hyperfleet/v1/clusters?page=1&pageSize=10
 
 ### Search
 
-Search using TSL (Tree Search Language) query syntax:
+All list endpoints support filtering using TSL (Tree Search Language) query syntax. Example:
 
 ```bash
-# Simple equality
-curl -G http://localhost:8000/api/hyperfleet/v1/clusters \
-  --data-urlencode "search=name='my-cluster'"
-
-# AND query with condition-based status
 curl -G http://localhost:8000/api/hyperfleet/v1/clusters \
   --data-urlencode "search=status.conditions.Ready='True' and labels.environment='production'"
-
-# OR query
-curl -G http://localhost:8000/api/hyperfleet/v1/clusters \
-  --data-urlencode "search=labels.environment='dev' or labels.environment='staging'"
-
-# Query for available resources
-curl -G http://localhost:8000/api/hyperfleet/v1/clusters \
-  --data-urlencode "search=status.conditions.Available='True'"
 ```
 
-**Supported fields:**
-
-- `name` - Resource name
-- `status.conditions.<Type>` - Condition status (True, False). Examples:
-  - `status.conditions.Ready='True'` - Resources that are ready
-  - `status.conditions.Available='True'` - Resources that are available
-- `labels.<key>` - Label values
-
-**Supported operators:**
-
-- `=` - Equality
-- `in` - In list
-- `and` - Logical AND
-- `or` - Logical OR
+See **[search.md](search.md)** for complete documentation.
 
 ## Field Descriptions
 
diff --git a/docs/search.md b/docs/search.md
new file mode 100644
index 00000000..15eac4ec
--- /dev/null
+++ b/docs/search.md
@@ -0,0 +1,167 @@
+# API Search and Filtering
+
+This document describes how to search and filter resources in the HyperFleet API using TSL (Tree Search Language) queries.
+
+## Overview
+
+The HyperFleet API supports search and filtering capabilities through the `search` query parameter. All list endpoints (`GET /clusters`, `GET /nodepools`, etc.) accept TSL (Tree Search Language) queries that allow you to filter results using field comparisons, logical operators, and complex nested conditions.
+
+## TSL Language Reference
+
+The HyperFleet API uses the [Tree Search Language (TSL)](https://github.com/yaacov/tree-search-language) library for parsing search queries.
+
+### Supported Operators
+
+| Operator | Description | Example |
+|----------|-------------|---------|
+| `=` | Equal | `name='test'` |
+| `!=` | Not equal | `name!='old'` |
+| `<` | Less than | `generation<10` |
+| `<=` | Less than or equal | `generation<=5` |
+| `>` | Greater than | `generation>1` |
+| `>=` | Greater than or equal | `generation>=1` |
+| `in` | In list | `name in ('c1','c2')` |
+| `and` | Logical AND | `a='1' and b='2'` |
+| `or` | Logical OR | `a='1' or a='2'` |
+| `not` | Logical NOT | `not name='test'` |
+
+### Query Value Syntax
+
+- **String values**: Must be enclosed in single quotes: `name='my-cluster'`
+- **Numeric values**: No quotes required: `generation>5`
+- **Lists**: Comma-separated values in parentheses: `id in ('2abc123', '2def456')`
+
+## Searchable Fields
+
+### Clusters
+
+| Field | Type | Description | Example |
+|-------|------|-------------|---------|
+| `id` | string | Cluster ID | `id='2abc123'` |
+| `name` | string | Cluster name | `name='my-cluster'` |
+| `generation` | integer | Spec version counter | `generation>1` |
+| `created_by` | string | Creator email | `created_by='user@example.com'` |
+| `updated_by` | string | Last updater email | `updated_by='user@example.com'` |
+| `labels.<key>` | string | Label value | `labels.environment='production'` |
+| `status.conditions.<Type>` | string | Condition status | `status.conditions.Ready='True'` |
+
+```bash
+# Find cluster by name
+curl -G "http://localhost:8000/api/hyperfleet/v1/clusters" \
+  --data-urlencode "search=name='my-cluster'"
+
+# Find clusters by multiple names
+curl -G "http://localhost:8000/api/hyperfleet/v1/clusters" \
+  --data-urlencode "search=name in ('cluster1', 'cluster2', 'cluster3')"
+```
+
+### NodePools
+
+NodePools support the same searchable fields as Clusters, plus:
+
+| Field | Type | Description | Example |
+|-------|------|-------------|---------|
+| `owner_id` | string | Parent cluster ID | `owner_id='2abc123'` |
+
+```bash
+# Find nodepools by parent cluster ID
+curl -G "http://localhost:8000/api/hyperfleet/v1/nodepools" \
+  --data-urlencode "search=owner_id='2abc123'"
+
+# Find ready nodepools
+curl -G "http://localhost:8000/api/hyperfleet/v1/nodepools" \
+  --data-urlencode "search=status.conditions.Ready='True'"
+
+# Find nodepools by label
+curl -G "http://localhost:8000/api/hyperfleet/v1/nodepools" \
+  --data-urlencode "search=labels.role='worker'"
+```
+
+## Labels Queries
+
+Use `labels.<key>` syntax to filter by label values:
+
+```bash
+# Find production clusters
+curl -G "http://localhost:8000/api/hyperfleet/v1/clusters" \
+  --data-urlencode "search=labels.environment='production'"
+
+# Find clusters in a specific region
+curl -G "http://localhost:8000/api/hyperfleet/v1/clusters" \
+  --data-urlencode "search=labels.region='us-east'"
+```
+
+Label keys must contain only lowercase letters (a-z), digits (0-9), and underscores (_).
+
+## Status Condition Queries
+
+Query resources by status conditions: `status.conditions.<Type>='<Status>'`
+
+Condition types must be PascalCase (`Ready`, `Available`) and status must be `True` or `False` for resource conditions.
+
+**Note:** Only the `=` operator is supported for condition queries. Other  operators (`!=`, `<`, `>`, `in`, etc.) will return an error. Use `not` with  conditions cautiously — `not status.conditions.Ready='True'` does not work as expected.
+
+```bash
+# Find available clusters
+curl -G "http://localhost:8000/api/hyperfleet/v1/clusters" \
+  --data-urlencode "search=status.conditions.Available='True'"
+
+# Find clusters that are not ready
+curl -G "http://localhost:8000/api/hyperfleet/v1/clusters" \
+  --data-urlencode "search=status.conditions.Ready='False'"
+```
+
+## Complex Queries
+
+Combine multiple conditions using `and`, `or`, `not`, and parentheses `()`:
+
+```bash
+# Find ready production clusters
+curl -G "http://localhost:8000/api/hyperfleet/v1/clusters" \
+  --data-urlencode "search=status.conditions.Ready='True' and labels.environment='production'"
+
+# Find clusters in dev or staging
+curl -G "http://localhost:8000/api/hyperfleet/v1/clusters" \
+  --data-urlencode "search=labels.environment in ('dev', 'staging')"
+
+# Find ready clusters in production or staging
+curl -G "http://localhost:8000/api/hyperfleet/v1/clusters" \
+  --data-urlencode "search=status.conditions.Ready='True' and (labels.environment='production' or labels.environment='staging')"
+
+# Find clusters that are not in production
+curl -G "http://localhost:8000/api/hyperfleet/v1/clusters" \
+  --data-urlencode "search=not labels.environment='production'"
+```
+
+Operator precedence: `()` > comparisons > `not` > `and` > `or`
+
+## Other Common Use Cases
+
+```bash
+# Find non-production clusters
+curl -G "http://localhost:8000/api/hyperfleet/v1/clusters" \
+  --data-urlencode "search=labels.environment in ('dev', 'staging', 'test')"
+
+# Find clusters created by specific user
+curl -G "http://localhost:8000/api/hyperfleet/v1/clusters" \
+  --data-urlencode "search=created_by='user@example.com'"
+
+# Find clusters by multiple IDs
+curl -G "http://localhost:8000/api/hyperfleet/v1/clusters" \
+  --data-urlencode "search=id in ('2abc123', '2def456', '2ghi789')"
+```
+
+## Error Handling
+
+Invalid queries return `400 Bad Request` with error details:
+
+```json
+{
+  "type": "https://api.hyperfleet.io/errors/bad-request",
+  "title": "Bad Request",
+  "status": 400,
+  "detail": "Failed to parse search query: invalid-query",
+  "code": "HYPERFLEET-VAL-005",
+  "timestamp": "2025-01-15T10:30:00Z"
+}
+```
