---
title: Filtering
description: Filter API results using query parameters, field operators, and complex filter expressions in TraceRTM
---

# Filtering

TraceRTM provides powerful filtering capabilities to retrieve exactly the data you need. This guide covers simple query parameters, field-specific filters, and complex filter expressions.

## Filtering Methods

| Method | Best For | Complexity |
|--------|----------|------------|
| Query Parameters | Simple equality filters | Low |
| Field Operators | Range, existence, pattern matching | Medium |
| Filter Expressions | Complex logic, nested conditions | High |

---

## Simple Query Parameter Filtering

### Basic Equality Filters

```bash
# Filter by single field
curl "https://api.tracertm.dev/v1/projects/proj_abc123/items?type=requirement" \
  -H "Authorization: Bearer rtm_live_sk_..."

# Filter by multiple fields (AND logic)
curl "https://api.tracertm.dev/v1/projects/proj_abc123/items?type=requirement&status=approved" \
  -H "Authorization: Bearer rtm_live_sk_..."

# Filter by priority
curl "https://api.tracertm.dev/v1/projects/proj_abc123/items?priority=high" \
  -H "Authorization: Bearer rtm_live_sk_..."
```

### Common Filter Parameters

| Parameter | Type | Description | Example |
|-----------|------|-------------|---------|
| `type` | string | Item type | `type=requirement` |
| `status` | string | Item status | `status=approved` |
| `priority` | string | Priority level | `priority=high` |
| `assignee` | string | Assigned user ID | `assignee=user_abc123` |
| `created_by` | string | Creator user ID | `created_by=user_def456` |
| `tags` | string | Tags (comma-separated) | `tags=mvp,security` |

### Multiple Values (OR Logic)

Use comma-separated values for OR logic within a field:

```bash
# Items with status approved OR in_review
curl "https://api.tracertm.dev/v1/projects/proj_abc123/items?status=approved,in_review" \
  -H "Authorization: Bearer rtm_live_sk_..."

# Items of type requirement OR user_story
curl "https://api.tracertm.dev/v1/projects/proj_abc123/items?type=requirement,user_story" \
  -H "Authorization: Bearer rtm_live_sk_..."
```

---

## Field Operators

For more complex filtering, use field operators with bracket notation.

### Comparison Operators

| Operator | Description | Example |
|----------|-------------|---------|
| `[eq]` | Equals (default) | `priority[eq]=high` |
| `[ne]` | Not equals | `status[ne]=deprecated` |
| `[gt]` | Greater than | `created_at[gt]=2024-01-01` |
| `[gte]` | Greater than or equal | `priority_score[gte]=5` |
| `[lt]` | Less than | `updated_at[lt]=2024-01-15` |
| `[lte]` | Less than or equal | `story_points[lte]=8` |

### Examples

```bash
# Items created after January 1, 2024
curl "https://api.tracertm.dev/v1/projects/proj_abc123/items?created_at[gt]=2024-01-01T00:00:00Z" \
  -H "Authorization: Bearer rtm_live_sk_..."

# Items NOT in deprecated status
curl "https://api.tracertm.dev/v1/projects/proj_abc123/items?status[ne]=deprecated" \
  -H "Authorization: Bearer rtm_live_sk_..."

# Items updated in the last 7 days
curl "https://api.tracertm.dev/v1/projects/proj_abc123/items?updated_at[gte]=2024-01-13T00:00:00Z" \
  -H "Authorization: Bearer rtm_live_sk_..."

# Items with story points between 3 and 8
curl "https://api.tracertm.dev/v1/projects/proj_abc123/items?story_points[gte]=3&story_points[lte]=8" \
  -H "Authorization: Bearer rtm_live_sk_..."
```

### Collection Operators

| Operator | Description | Example |
|----------|-------------|---------|
| `[in]` | Value in list | `status[in]=draft,review` |
| `[nin]` | Value not in list | `type[nin]=bug,task` |
| `[all]` | Array contains all values | `tags[all]=mvp,security` |
| `[any]` | Array contains any value | `tags[any]=urgent,blocking` |

### Examples

```bash
# Items with any of these statuses
curl "https://api.tracertm.dev/v1/projects/proj_abc123/items?status[in]=draft,in_review,approved" \
  -H "Authorization: Bearer rtm_live_sk_..."

# Items NOT of these types
curl "https://api.tracertm.dev/v1/projects/proj_abc123/items?type[nin]=bug,task" \
  -H "Authorization: Bearer rtm_live_sk_..."

# Items tagged with BOTH mvp AND security
curl "https://api.tracertm.dev/v1/projects/proj_abc123/items?tags[all]=mvp,security" \
  -H "Authorization: Bearer rtm_live_sk_..."

# Items tagged with EITHER urgent OR blocking
curl "https://api.tracertm.dev/v1/projects/proj_abc123/items?tags[any]=urgent,blocking" \
  -H "Authorization: Bearer rtm_live_sk_..."
```

### Text Operators

| Operator | Description | Example |
|----------|-------------|---------|
| `[contains]` | Contains substring (case-insensitive) | `title[contains]=auth` |
| `[startswith]` | Starts with string | `key[startswith]=REQ-` |
| `[endswith]` | Ends with string | `title[endswith]=feature` |
| `[regex]` | Matches regex pattern | `key[regex]=^REQ-[0-9]+$` |

### Examples

```bash
# Items with "authentication" in title
curl "https://api.tracertm.dev/v1/projects/proj_abc123/items?title[contains]=authentication" \
  -H "Authorization: Bearer rtm_live_sk_..."

# Items with keys starting with "REQ-"
curl "https://api.tracertm.dev/v1/projects/proj_abc123/items?key[startswith]=REQ-" \
  -H "Authorization: Bearer rtm_live_sk_..."

# Items matching regex pattern
curl "https://api.tracertm.dev/v1/projects/proj_abc123/items?key[regex]=^(REQ|TC)-[0-9]{3}$" \
  -H "Authorization: Bearer rtm_live_sk_..."
```

### Existence Operators

| Operator | Description | Example |
|----------|-------------|---------|
| `[exists]` | Field exists | `assignee[exists]=true` |
| `[null]` | Field is null | `due_date[null]=true` |
| `[empty]` | Field is empty | `description[empty]=false` |

### Examples

```bash
# Items with an assignee
curl "https://api.tracertm.dev/v1/projects/proj_abc123/items?assignee[exists]=true" \
  -H "Authorization: Bearer rtm_live_sk_..."

# Items without a due date
curl "https://api.tracertm.dev/v1/projects/proj_abc123/items?due_date[null]=true" \
  -H "Authorization: Bearer rtm_live_sk_..."

# Items with non-empty descriptions
curl "https://api.tracertm.dev/v1/projects/proj_abc123/items?description[empty]=false" \
  -H "Authorization: Bearer rtm_live_sk_..."
```

---

## Custom Field Filtering

Filter by custom fields using the `custom.` prefix:

```bash
# Filter by custom field value
curl "https://api.tracertm.dev/v1/projects/proj_abc123/items?custom.risk_level=high" \
  -H "Authorization: Bearer rtm_live_sk_..."

# Custom field with operator
curl "https://api.tracertm.dev/v1/projects/proj_abc123/items?custom.compliance_required[eq]=true" \
  -H "Authorization: Bearer rtm_live_sk_..."

# Custom field range
curl "https://api.tracertm.dev/v1/projects/proj_abc123/items?custom.estimated_hours[gte]=10&custom.estimated_hours[lte]=40" \
  -H "Authorization: Bearer rtm_live_sk_..."

# Custom field contains
curl "https://api.tracertm.dev/v1/projects/proj_abc123/items?custom.affected_modules[any]=auth,payments" \
  -H "Authorization: Bearer rtm_live_sk_..."
```

---

## Complex Filter Expressions

For advanced filtering logic, use the `filter` parameter with JSON:

### POST with Filter Body

```bash
curl -X POST "https://api.tracertm.dev/v1/projects/proj_abc123/items/query" \
  -H "Authorization: Bearer rtm_live_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
    "filter": {
      "and": [
        {"field": "type", "op": "eq", "value": "requirement"},
        {
          "or": [
            {"field": "status", "op": "eq", "value": "approved"},
            {"field": "priority", "op": "eq", "value": "critical"}
          ]
        },
        {"field": "created_at", "op": "gte", "value": "2024-01-01T00:00:00Z"}
      ]
    }
  }'
```

### Filter Expression Structure

```json
{
  "filter": {
    "and": [
      {"field": "field_name", "op": "operator", "value": "value"},
      {
        "or": [
          {"field": "field_name", "op": "operator", "value": "value"},
          {"field": "field_name", "op": "operator", "value": "value"}
        ]
      }
    ]
  }
}
```

### Nested Conditions

```json
{
  "filter": {
    "and": [
      {"field": "type", "op": "in", "value": ["requirement", "user_story"]},
      {
        "or": [
          {
            "and": [
              {"field": "status", "op": "eq", "value": "approved"},
              {"field": "priority", "op": "in", "value": ["high", "critical"]}
            ]
          },
          {
            "and": [
              {"field": "status", "op": "eq", "value": "in_review"},
              {"field": "tags", "op": "any", "value": ["urgent", "blocking"]}
            ]
          }
        ]
      }
    ]
  }
}
```

### NOT Conditions

```json
{
  "filter": {
    "and": [
      {"field": "type", "op": "eq", "value": "requirement"},
      {
        "not": {
          "or": [
            {"field": "status", "op": "eq", "value": "deprecated"},
            {"field": "status", "op": "eq", "value": "rejected"}
          ]
        }
      }
    ]
  }
}
```

---

## SDK Examples

### Python

```python
from tracertm import TraceRTMClient
from tracertm.filters import Filter, And, Or, Not

client = TraceRTMClient(api_key="rtm_live_sk_...")

# Simple filters
items = client.items.list(
    project_id="proj_abc123",
    type="requirement",
    status="approved"
)

# Field operators
items = client.items.list(
    project_id="proj_abc123",
    filters={
        "status__ne": "deprecated",
        "created_at__gte": "2024-01-01T00:00:00Z",
        "priority__in": ["high", "critical"]
    }
)

# Complex filter expressions
filter_expr = And([
    Filter("type", "eq", "requirement"),
    Or([
        Filter("status", "eq", "approved"),
        And([
            Filter("priority", "eq", "critical"),
            Filter("tags", "any", ["urgent", "blocking"])
        ])
    ]),
    Not(Filter("assignee", "null", True))
])

items = client.items.query(
    project_id="proj_abc123",
    filter=filter_expr
)

# Filter builder pattern
items = client.items.list(
    project_id="proj_abc123"
).filter(
    type="requirement"
).filter(
    status__in=["approved", "in_review"]
).filter(
    created_at__gte="2024-01-01"
).filter(
    tags__any=["mvp", "priority"]
).execute()

# Custom field filters
items = client.items.list(
    project_id="proj_abc123",
    filters={
        "custom.risk_level": "high",
        "custom.compliance_required": True,
        "custom.estimated_hours__lte": 40
    }
)
```

### TypeScript

```typescript
import { TraceRTMClient, Filter, And, Or, Not } from '@tracertm/sdk';

const client = new TraceRTMClient({ apiKey: 'rtm_live_sk_...' });

// Simple filters
const items = await client.items.list({
  projectId: 'proj_abc123',
  type: 'requirement',
  status: 'approved'
});

// Field operators
const filtered = await client.items.list({
  projectId: 'proj_abc123',
  filters: {
    'status[ne]': 'deprecated',
    'created_at[gte]': '2024-01-01T00:00:00Z',
    'priority[in]': ['high', 'critical']
  }
});

// Complex filter expressions
const complexFilter = And([
  Filter.eq('type', 'requirement'),
  Or([
    Filter.eq('status', 'approved'),
    And([
      Filter.eq('priority', 'critical'),
      Filter.any('tags', ['urgent', 'blocking'])
    ])
  ]),
  Not(Filter.isNull('assignee'))
]);

const results = await client.items.query({
  projectId: 'proj_abc123',
  filter: complexFilter
});

// Fluent filter builder
const fluentResults = await client.items
  .filter({ type: 'requirement' })
  .filter({ status: { in: ['approved', 'in_review'] } })
  .filter({ created_at: { gte: '2024-01-01' } })
  .filter({ tags: { any: ['mvp', 'priority'] } })
  .list({ projectId: 'proj_abc123' });

// Custom fields
const customFiltered = await client.items.list({
  projectId: 'proj_abc123',
  filters: {
    'custom.risk_level': 'high',
    'custom.compliance_required': true,
    'custom.estimated_hours[lte]': 40
  }
});
```

### Go

```go
package main

import (
    "context"
    "github.com/tracertm/tracertm-go"
)

func main() {
    client := tracertm.NewClient("rtm_live_sk_...")
    ctx := context.Background()

    // Simple filters
    items, _ := client.Items.List(ctx, &tracertm.ListItemsRequest{
        ProjectID: "proj_abc123",
        Type:      "requirement",
        Status:    "approved",
    })

    // Field operators
    filtered, _ := client.Items.List(ctx, &tracertm.ListItemsRequest{
        ProjectID: "proj_abc123",
        Filters: map[string]interface{}{
            "status[ne]":       "deprecated",
            "created_at[gte]": "2024-01-01T00:00:00Z",
            "priority[in]":    []string{"high", "critical"},
        },
    })

    // Complex filter expressions
    complexFilter := tracertm.And(
        tracertm.Filter("type", "eq", "requirement"),
        tracertm.Or(
            tracertm.Filter("status", "eq", "approved"),
            tracertm.And(
                tracertm.Filter("priority", "eq", "critical"),
                tracertm.Filter("tags", "any", []string{"urgent", "blocking"}),
            ),
        ),
        tracertm.Not(tracertm.Filter("assignee", "null", true)),
    )

    results, _ := client.Items.Query(ctx, &tracertm.QueryItemsRequest{
        ProjectID: "proj_abc123",
        Filter:    complexFilter,
    })

    // Custom fields
    customFiltered, _ := client.Items.List(ctx, &tracertm.ListItemsRequest{
        ProjectID: "proj_abc123",
        Filters: map[string]interface{}{
            "custom.risk_level":          "high",
            "custom.compliance_required": true,
            "custom.estimated_hours[lte]": 40,
        },
    })
}
```

---

## Filterable Fields by Resource

### Items

| Field | Type | Operators |
|-------|------|-----------|
| `id` | string | eq, ne, in, nin |
| `key` | string | eq, ne, in, nin, contains, startswith, regex |
| `type` | string | eq, ne, in, nin |
| `status` | string | eq, ne, in, nin |
| `priority` | string | eq, ne, in, nin, gt, gte, lt, lte |
| `title` | string | eq, ne, contains, startswith, endswith, regex |
| `description` | string | contains, empty |
| `assignee` | string | eq, ne, in, nin, exists, null |
| `created_by` | string | eq, ne, in, nin |
| `created_at` | datetime | eq, ne, gt, gte, lt, lte |
| `updated_at` | datetime | eq, ne, gt, gte, lt, lte |
| `tags` | array | all, any, empty |
| `custom.*` | varies | depends on field type |

### Links

| Field | Type | Operators |
|-------|------|-----------|
| `id` | string | eq, ne, in, nin |
| `type` | string | eq, ne, in, nin |
| `source_id` | string | eq, ne, in, nin |
| `target_id` | string | eq, ne, in, nin |
| `created_at` | datetime | eq, ne, gt, gte, lt, lte |
| `created_by` | string | eq, ne, in, nin |

### Projects

| Field | Type | Operators |
|-------|------|-----------|
| `id` | string | eq, ne, in, nin |
| `key` | string | eq, ne, contains, startswith |
| `name` | string | eq, ne, contains |
| `status` | string | eq, ne, in, nin |
| `created_at` | datetime | eq, ne, gt, gte, lt, lte |

---

## Best Practices

### 1. Use Specific Filters

```python
# Good: Specific filters reduce data transfer
items = client.items.list(
    project_id="proj_abc123",
    type="requirement",
    status="approved",
    assignee="user_abc123"
)

# Bad: Fetch all and filter client-side
all_items = client.items.list(project_id="proj_abc123")
filtered = [i for i in all_items if i.type == "requirement" and i.status == "approved"]
```

### 2. Index-Friendly Filters First

```python
# Good: Equality on indexed fields first
items = client.items.list(
    project_id="proj_abc123",
    type="requirement",  # Indexed
    status="approved",   # Indexed
    title__contains="auth"  # Full-text search last
)
```

### 3. Combine with Pagination

```python
# Always paginate filtered results
for item in client.items.iterate(
    project_id="proj_abc123",
    type="requirement",
    status__in=["approved", "in_review"],
    page_size=50
):
    process(item)
```

---

## Related Documentation

- [Filter Operators](/docs/api-reference/rest-api/filter-operators) - Complete operator reference
- [Sorting](/docs/api-reference/rest-api/sorting) - Sort filtered results
- [Pagination](/docs/api-reference/rest-api/pagination) - Paginate results
- [Search](/docs/api-reference/rest-api/search) - Full-text search
