> For the complete documentation index, see [llms.txt](https://docs.durohub.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.durohub.com/advanced-topics/searching-and-filtering.md).

# Searching and Filtering

Build powerful, precise queries to find exactly the components you need. This guide covers both our **Advanced Filter API** for programmatic queries and our **AI-Powered Filter API** for natural language searches.

{% hint style="info" %}
**New: Structured Query Syntax** — You can also use a `key:value` search syntax in the web app's search bar and via the `buildFilterFromQuery` / `filterWithQuery` APIs. See the [Search Query Syntax Reference](/advanced-topics/search-query-syntax.md) for the complete guide.
{% endhint %}

## Quick Start

Let's jump straight in. Here's a query to find all components in "Design" status that were modified in the last 30 days:

```graphql
query FilterComponents {
  component {
    filter(
      input: {
        and: [
          { status: { name: { eq: "Design" } } }
          { updatedAt: { after: "2024-12-01" } }
        ]
      }
    ) {
      edges {
        node {
          id
          name
          cpn
          status {
            name
          }
        }
      }
      totalCount
    }
  }
}
```

Or skip writing filters entirely—let AI do the work and get components in a single call:

```graphql
query SearchWithAI {
  component {
    filterWithAI(input: { query: "parts modified by Sarah in the last week" }) {
      components {
        id
        name
        cpn
      }
      totalCount
      interpretation
      success
    }
  }
}
```

That's it—one query, natural language in, components out!

{% hint style="info" %}
**New to the Duro API?** Make sure you've set up [authentication](/getting-started/authentication.md) first. All examples assume you have a valid API token.
{% endhint %}

***

## Part 1: Advanced Filter API

The Advanced Filter API gives you precise, programmatic control over component queries using a Linear-style AND/OR logic system.

### API Structure Overview

```
AdvancedComponentFilterInput
├── and: [ComponentFilterConditionInput]  ← All conditions must match
├── or: [ComponentFilterConditionInput]   ← Any condition can match
└── pagination: PaginationInput           ← Control page size and sorting
```

Each `ComponentFilterConditionInput` can filter by one or more fields:

| Field          | Type                         | Description                                                                   |
| -------------- | ---------------------------- | ----------------------------------------------------------------------------- |
| `status`       | StatusFilterInput            | Filter by status ID, name, or type (DESIGN, PRODUCTION, etc.)                 |
| `category`     | ComponentCategoryFilterInput | Filter by category ID, name, or type (PART, ASSEMBLY, DOCUMENT)               |
| `state`        | StateFilterInput             | Filter by component state (RELEASED, MODIFIED)                                |
| `revision`     | RevisionFilterInput          | Filter by revision value with ordering support                                |
| `createdBy`    | UserFilterInput              | Filter by who created the component                                           |
| `updatedBy`    | UserFilterInput              | Filter by who last modified the component                                     |
| `labels`       | LabelFilterInput             | Filter by assigned labels                                                     |
| `isPinned`     | BooleanFilterInput           | Filter pinned/unpinned components                                             |
| `isBookmarked` | BooleanFilterInput           | Filter bookmarked components                                                  |
| `createdAt`    | DateFilterInput              | Filter by creation date                                                       |
| `updatedAt`    | DateFilterInput              | Filter by last update date                                                    |
| `name`         | StringOperators              | Filter by component name (exact via `eq`, or `like`/`notLike` for patterns)   |
| `identifier`   | IdentifierFilterInput        | Filter by CPN via `displayValue` (String Operators)                           |
| `description`  | DescriptionFilterInput       | Full-text `contains`/`doesNotContain`, plus `like`/`notLike` pattern matching |

### Operators Reference

#### String Operators

Use these for filtering text fields like status names, category names, and labels:

| Operator      | Description                                                                                             | Example                                           |
| ------------- | ------------------------------------------------------------------------------------------------------- | ------------------------------------------------- |
| `eq`          | Exact match                                                                                             | `{ name: { eq: "Design" } }`                      |
| `neq`         | Not equal                                                                                               | `{ name: { neq: "Obsolete" } }`                   |
| `in`          | Match any in list                                                                                       | `{ name: { in: ["Design", "Development"] } }`     |
| `notIn`       | Exclude all in list                                                                                     | `{ name: { notIn: ["Obsolete", "Deprecated"] } }` |
| `contains`    | Substring match (case-insensitive)                                                                      | `{ name: { contains: "resistor" } }`              |
| `notContains` | Does not contain                                                                                        | `{ name: { notContains: "test" } }`               |
| `like`        | Pattern match, case-insensitive: `%` matches any sequence of characters, `_` matches a single character | `{ name: { like: "401-%" } }`                     |
| `notLike`     | Does not match the pattern                                                                              | `{ name: { notLike: "%draft%" } }`                |

{% hint style="info" %}
`like`/`notLike` match against a pattern where `%` stands for any sequence of characters and `_` for a single character. The search bar's `*` wildcard maps to `%` here — so search-bar `cpn:401-*` is equivalent to `{ identifier: { displayValue: { like: "401-%" } } }`. See the [Search Query Syntax](/advanced-topics/search-query-syntax.md#wildcards) reference.
{% endhint %}

#### Date Operators

Use these for `createdAt` and `updatedAt` fields:

| Operator                  | Description                 | Example                                                |
| ------------------------- | --------------------------- | ------------------------------------------------------ |
| `before`                  | Date is before (exclusive)  | `{ before: "2024-06-01" }`                             |
| `after`                   | Date is after (exclusive)   | `{ after: "2024-01-01" }`                              |
| `on`                      | Exact date match (same day) | `{ on: "2024-03-15" }`                                 |
| `rangeStart` + `rangeEnd` | Date range (inclusive)      | `{ rangeStart: "2024-01-01", rangeEnd: "2024-03-31" }` |

#### Revision Operators

Revisions support ordering comparisons. The ordering follows your library's revision scheme:

* **Letter sequences**: A < B < ... < Z < AA < AB
* **Integers**: 1 < 2 < 3 < ... < 999
* **Multi-segment**: Compared segment by segment (A.1 < A.2 < B.1)

| Operator | Description  | Example                                      |
| -------- | ------------ | -------------------------------------------- |
| `eq`     | Exact match  | `{ value: { eq: "B" } }`                     |
| `neq`    | Not equal    | `{ value: { neq: "A" } }`                    |
| `in`     | Match any    | `{ value: { in: ["A", "B", "C"] } }`         |
| `notIn`  | Exclude all  | `{ value: { notIn: ["A"] } }`                |
| `lt`     | Less than    | `{ value: { lt: "C" } }` ← Matches A, B      |
| `gt`     | Greater than | `{ value: { gt: "B" } }` ← Matches C, D, ... |

#### Boolean Operators

Simple true/false matching:

| Operator    | Example                           |
| ----------- | --------------------------------- |
| `eq: true`  | `{ isPinned: { eq: true } }`      |
| `eq: false` | `{ isBookmarked: { eq: false } }` |

***

### Practical Examples

#### Example 1: Find Production-Ready Components

Find all components with a production-type status that have been released:

```graphql
query ProductionReadyComponents {
  component {
    filter(
      input: {
        and: [
          { status: { mapsTo: { eq: "PRODUCTION" } } }
          { state: { eq: RELEASED } }
        ]
      }
    ) {
      edges {
        node {
          id
          name
          cpn
          revision {
            value
          }
        }
      }
      totalCount
    }
  }
}
```

**cURL:**

```bash
curl 'https://api.durohub.com/graphql' \
  -H 'x-api-key: YOUR_API_TOKEN' \
  -H 'x-organization: @your-org-slug' \
  -H 'x-library: @your-org-slug/your-library-slug' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": "query { component { filter(input: { and: [{ status: { mapsTo: { eq: \"PRODUCTION\" } } }, { state: { eq: RELEASED } }] }) { edges { node { id name cpn } } totalCount } } }"
  }'
```

{% hint style="info" %}
**Required Headers:** All component queries require `x-organization` and `x-library` headers to scope your request to the correct library. Use either slugs (e.g., `@acme/main-library`) or UUIDs.
{% endhint %}

#### Example 2: Find Components by Category Type

Find all assemblies (not parts or documents):

```graphql
query FindAssemblies {
  component {
    filter(
      input: {
        and: [
          { category: { type: { eq: "ASSEMBLY" } } }
        ]
      }
    ) {
      edges {
        node {
          id
          name
          category {
            name
            type
          }
        }
      }
    }
  }
}
```

#### Example 3: Find Recently Modified Components by a Specific User

Find components that a specific user modified in the last 7 days:

```graphql
query RecentlyModifiedByUser {
  component {
    filter(
      input: {
        and: [
          { updatedBy: { id: { eq: "user-uuid-here" } } }
          { updatedAt: { after: "2024-12-25" } }
        ]
      }
    ) {
      edges {
        node {
          id
          name
          updatedAt
          updatedBy {
            firstName
            lastName
          }
        }
      }
    }
  }
}
```

#### Example 4: Using OR Logic

Find components that are either pinned OR have a specific label:

```graphql
query PinnedOrLabeled {
  component {
    filter(
      input: {
        or: [
          { isPinned: { eq: true } }
          { labels: { name: { eq: "Critical" } } }
        ]
      }
    ) {
      edges {
        node {
          id
          name
          labels {
            name
          }
        }
      }
    }
  }
}
```

#### Example 5: Complex Multi-Condition Query

Find components that match ALL of these criteria:

* Status is "Design" or "Development"
* Category type is "PART"
* Revision is greater than "A"
* Not bookmarked

```graphql
query ComplexFilter {
  component {
    filter(
      input: {
        and: [
          { status: { name: { in: ["Design", "Development"] } } }
          { category: { type: { eq: "PART" } } }
          { revision: { value: { gt: "A" } } }
          { isBookmarked: { eq: false } }
        ]
      }
    ) {
      edges {
        node {
          id
          name
          cpn
          status { name }
          category { name type }
          revision { value }
        }
      }
      totalCount
    }
  }
}
```

#### Example 6: Date Range Query

Find components created in Q1 2024:

```graphql
query Q1Components {
  component {
    filter(
      input: {
        and: [
          {
            createdAt: {
              rangeStart: "2024-01-01"
              rangeEnd: "2024-03-31"
            }
          }
        ]
      }
    ) {
      edges {
        node {
          id
          name
          createdAt
        }
      }
    }
  }
}
```

### Pagination and Sorting

Control result size and ordering:

```graphql
query PaginatedResults {
  component {
    filter(
      input: {
        and: [{ state: { eq: RELEASED } }]
        pagination: {
          first: 25
          after: "cursor-from-previous-page"
          orderBy: { field: CREATED_AT, direction: DESC }
        }
      }
    ) {
      edges {
        cursor
        node {
          id
          name
        }
      }
      pageInfo {
        hasNextPage
        endCursor
      }
      totalCount
    }
  }
}
```

**Available sort fields:** `CREATED_AT`, `UPDATED_AT`, `NAME`, `CPN`

**Directions:** `ASC`, `DESC`

**Default sort order:** When `orderBy` is omitted, results are sorted by `CREATED_AT DESC` (most recently created first). This default applies to `findAll`, `filter`, `componentGroups`, and `componentsInGroup`.

### Grouping

In addition to filtering and sorting, you can group components by category, lifecycle status, type, last-modified user, or label using the `componentGroups` query. Each group returns a capped preview of its components with `totalCount` and cursor pagination for loading more.

The advanced filter works with grouped queries too — pass `advancedFilter` alongside `groupBy` to scope results before grouping.

See [Component Grouping](/advanced-topics/component-grouping.md) for the full guide.

***

## Part 2: AI-Powered Search

Skip the filter syntax entirely. Describe what you're looking for in plain English, and get components back directly.

### Single-Call Search (Recommended)

The `filterWithAI` endpoint is the simplest way to search with natural language—one query, components returned directly:

```graphql
query SearchWithAI {
  component {
    filterWithAI(input: {
      query: "resistors modified by Sarah in the last 30 days"
      limit: 50
    }) {
      # The components you asked for
      components {
        id
        name
        cpn
        status { name }
        category { name }
      }
      totalCount

      # What the AI understood
      interpretation
      success

      # If you need to paginate beyond the limit
      filterInput

      # Anything that wasn't found
      notFoundEntities { type name }
    }
  }
}
```

**That's it.** Natural language in, components out. No two-step process, no filter syntax to learn.

### Input Options

| Field     | Type   | Default        | Description                               |
| --------- | ------ | -------------- | ----------------------------------------- |
| `query`   | String | Required       | Natural language query (3-500 characters) |
| `limit`   | Int    | 20             | Max components to return (1-100)          |
| `orderBy` | Object | createdAt DESC | Sort field and direction                  |

### Response Structure

| Field              | Type    | Description                                           |
| ------------------ | ------- | ----------------------------------------------------- |
| `components`       | Array   | The matching components (up to `limit`)               |
| `totalCount`       | Int     | Total matches in the library (may exceed `limit`)     |
| `interpretation`   | String  | Human-readable summary of what was understood         |
| `success`          | Boolean | Whether the AI understood your query                  |
| `filterInput`      | JSON    | The generated filter (for pagination—see below)       |
| `filterValues`     | Array   | UI-friendly format with field/comparator/displayLabel |
| `matchMode`        | String  | `"all"` (AND) or `"any"` (OR)                         |
| `notFoundEntities` | Array?  | Entities mentioned but not found                      |
| `error`            | String? | Error message if generation failed                    |

{% hint style="success" %}
**Need more than 100 results?** Use the `filterInput` field (returned as JSON) and pass it to `component.filter` for cursor-based pagination.
{% endhint %}

### cURL Example

```bash
curl 'https://api.durohub.com/graphql' \
  -H 'x-api-key: YOUR_API_TOKEN' \
  -H 'x-organization: @your-org-slug' \
  -H 'x-library: @your-org-slug/your-library-slug' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": "query { component { filterWithAI(input: { query: \"parts in production status\", limit: 25 }) { components { id name cpn } totalCount interpretation success } } }"
  }'
```

### Example Response

**Query:** `"resistors modified by Sarah in the last 30 days"`

```json
{
  "data": {
    "component": {
      "filterWithAI": {
        "components": [
          { "id": "comp-1", "name": "10K Resistor", "cpn": "RES-001" },
          { "id": "comp-2", "name": "100K Resistor", "cpn": "RES-002" }
        ],
        "totalCount": 47,
        "interpretation": "Showing Resistors modified by Sarah Chen in the last 30 days",
        "success": true,
        "filterInput": {
          "and": [
            { "category": { "id": { "eq": "cat-resistors" } } },
            { "updatedBy": { "id": { "eq": "user-sarah" } } },
            { "updatedAt": { "after": "2024-12-10T00:00:00.000Z" } }
          ]
        },
        "matchMode": "all",
        "notFoundEntities": null
      }
    }
  }
}
```

### Handling Partial Matches

If the AI can't find something you mentioned, it tells you:

**Query:** `"resistors modified by John Smith"`

```json
{
  "components": [{ "id": "...", "name": "10K Resistor" }],
  "totalCount": 23,
  "interpretation": "Showing Resistors",
  "success": true,
  "notFoundEntities": [
    { "type": "user", "name": "John Smith" }
  ]
}
```

The query still runs with the filters it *could* resolve. Check `notFoundEntities` to see what was missing.

### Best Practices

{% hint style="success" %}
**Be specific with names.** Say "Design" not "designing" or "in design phase."
{% endhint %}

{% hint style="success" %}
**Use full names for users.** "Sarah Chen" works better than just "Sarah."
{% endhint %}

{% hint style="success" %}
**Combine concepts with AND/OR.** "resistors OR capacitors modified last week" → results in OR match mode.
{% endhint %}

{% hint style="warning" %}
**Check `notFoundEntities`.** If a user or status isn't found, the AI will tell you—you may have a typo or need to use a different name.
{% endhint %}

### Complete Python Example

```python
import requests

API_URL = "https://api.durohub.com/graphql"
HEADERS = {
    "x-api-key": "YOUR_API_TOKEN",
    "x-organization": "@acme",
    "x-library": "@acme/electronics",
    "Content-Type": "application/json"
}

def search_components(query: str, limit: int = 50):
    """Search components using natural language - single API call!"""

    graphql_query = """
    query SearchWithAI($query: String!, $limit: Int) {
      component {
        filterWithAI(input: { query: $query, limit: $limit }) {
          components {
            id
            name
            cpn
            status { name }
            category { name }
          }
          totalCount
          interpretation
          success
          notFoundEntities { type name }
          filterInput
        }
      }
    }
    """

    response = requests.post(API_URL, headers=HEADERS, json={
        "query": graphql_query,
        "variables": {"query": query, "limit": limit}
    })

    result = response.json()["data"]["component"]["filterWithAI"]

    print(f"AI interpretation: {result['interpretation']}")
    print(f"Found {result['totalCount']} components (showing {len(result['components'])})")

    if result.get("notFoundEntities"):
        print(f"Warning - not found: {result['notFoundEntities']}")

    return result["components"]


# Usage
if __name__ == "__main__":
    components = search_components("resistors modified by Sarah Chen in the last 30 days")
    for comp in components:
        print(f"  - {comp['cpn']}: {comp['name']}")
```

### Paginating Large Result Sets

If `totalCount` exceeds your `limit`, use the `filterInput` field to paginate with `component.filter`:

```python
def search_all_components(query: str):
    """Search with AI, then paginate through all results."""

    # First call: get components + the filter
    result = search_with_ai(query, limit=100)

    all_components = result["components"]
    filter_input = result["filterInput"]

    # If there are more results, paginate using component.filter
    if result["totalCount"] > len(all_components):
        cursor = None
        while True:
            page = fetch_page(filter_input, after=cursor)
            all_components.extend(page["components"])
            if not page["hasNextPage"]:
                break
            cursor = page["endCursor"]

    return all_components
```

### Two-Step Approach (Advanced)

If you're building a filter UI where users need to see and edit individual filter conditions before executing, use `buildFilterWithAI` instead:

```graphql
query BuildFilter {
  component {
    buildFilterWithAI(input: { query: "parts in design" }) {
      filterValues {
        field
        comparator
        value
        displayLabel
      }
      matchMode
      interpretation
      success
    }
  }
}
```

This returns structured `filterValues` that you can display as editable filter pills. Once the user confirms, pass the filter to `component.filter`.

***

## Part 3: Tips and Best Practices

### Performance Tips

1. **Use `and` over `or` when possible.** AND queries are generally faster as they narrow results.
2. **Filter by indexed fields first.** Status, category, and state are highly optimized.
3. **Paginate large results.** Use `first: 50` and cursor-based pagination rather than fetching everything.
4. **Be specific with dates.** `{ after: "2024-01-01" }` is faster than date ranges when you only need "recent" items.

### Common Patterns

#### "Recently modified by me"

```graphql
{
  and: [
    { updatedBy: { id: { eq: "YOUR_USER_ID" } } }
    { updatedAt: { after: "2024-12-01" } }
  ]
}
```

#### "All released parts except obsolete"

```graphql
{
  and: [
    { category: { type: { eq: "PART" } } }
    { state: { eq: RELEASED } }
    { status: { mapsTo: { neq: "OBSOLETE" } } }
  ]
}
```

#### "Components with any of these labels"

```graphql
{
  or: [
    { labels: { name: { eq: "Critical" } } }
    { labels: { name: { eq: "Urgent" } } }
    { labels: { name: { eq: "Review Needed" } } }
  ]
}
```

#### "Early revisions only"

```graphql
{
  and: [
    { revision: { value: { in: ["A", "B", "1", "2"] } } }
  ]
}
```

### Debugging Filters

1. **Start simple.** Test one condition at a time before combining.
2. **Check your field paths.** `status.name` vs `status.mapsTo` vs `status.id` target different things.
3. **Verify IDs exist.** If filtering by UUID, ensure the status/category/user actually exists in your library.
4. **Watch for empty results.** An overly specific `and` query might match nothing. Try loosening conditions.

***

## Complete API Reference

### AdvancedComponentFilterInput

```graphql
input AdvancedComponentFilterInput {
  """All conditions must match (AND logic)"""
  and: [ComponentFilterConditionInput!]

  """Any condition can match (OR logic)"""
  or: [ComponentFilterConditionInput!]

  """Pagination options"""
  pagination: PaginationInput
}
```

### ComponentFilterConditionInput

```graphql
input ComponentFilterConditionInput {
  status: StatusFilterInput
  category: ComponentCategoryFilterInput
  state: StateFilterInput
  revision: RevisionFilterInput
  createdBy: UserFilterInput
  updatedBy: UserFilterInput
  labels: LabelFilterInput
  isPinned: BooleanFilterInput
  isBookmarked: BooleanFilterInput
  createdAt: DateFilterInput
  updatedAt: DateFilterInput
}
```

### StatusFilterInput

```graphql
input StatusFilterInput {
  """Filter by status UUID"""
  id: StringOperatorsInput

  """Filter by custom status name"""
  name: StringOperatorsInput

  """Filter by status type: DESIGN, DEVELOPMENT, PRODUCTION, MAINTENANCE, OBSOLETE"""
  mapsTo: StringOperatorsInput
}
```

### ComponentCategoryFilterInput

```graphql
input ComponentCategoryFilterInput {
  """Filter by category UUID"""
  id: StringOperatorsInput

  """Filter by category name"""
  name: StringOperatorsInput

  """Filter by category type: ASSEMBLY, PART, DOCUMENT"""
  type: StringOperatorsInput
}
```

### LabelFilterInput

```graphql
input LabelFilterInput {
  """Filter by label name (the unique identifier for labels)"""
  name: StringOperatorsInput
}
```

{% hint style="info" %}
**Labels filter by name, not ID.** Unlike other entities, labels are matched using their `name` field (e.g., `"Critical"`, `"High Priority"`). This is the canonical identifier for labels in the filter system.
{% endhint %}

### StringOperatorsInput

```graphql
input StringOperatorsInput {
  eq: String
  neq: String
  in: [String!]
  notIn: [String!]
  contains: String
  notContains: String
}
```

### DateFilterInput

```graphql
input DateFilterInput {
  """Date is before this value (exclusive)"""
  before: String

  """Date is after this value (exclusive)"""
  after: String

  """Date equals this value (same day)"""
  on: String

  """Start of date range (inclusive)"""
  rangeStart: String

  """End of date range (inclusive)"""
  rangeEnd: String
}
```

### RevisionOperatorsInput

```graphql
input RevisionOperatorsInput {
  eq: String
  neq: String
  in: [String!]
  notIn: [String!]
  lt: String
  gt: String
}
```

### BooleanFilterInput

```graphql
input BooleanFilterInput {
  eq: Boolean
}
```

### FilterWithAiInput (Recommended)

```graphql
input FilterWithAiInput {
  """Natural language query (3-500 characters)"""
  query: String!

  """Max components to return (default: 20, max: 100)"""
  limit: Int

  """Sort order for results"""
  orderBy: ComponentOrderInput
}
```

### FilterWithAiOutput

```graphql
type FilterWithAiOutput {
  """The matching components"""
  components: [Component!]!

  """Total count of matching components in the library"""
  totalCount: Int!

  """Match mode: 'all' (AND) or 'any' (OR)"""
  matchMode: String!

  """Whether the AI understood your query"""
  success: Boolean!

  """Human-readable interpretation of the filters"""
  interpretation: String

  """UI-friendly filter format"""
  filterValues: [FilterValueOutput!]!

  """The generated filter as JSON (for pagination with component.filter)"""
  filterInput: JSON

  """Entities mentioned but not found in the library"""
  notFoundEntities: [NotFoundEntity!]

  """Error message if generation failed"""
  error: String
}
```

### BuildAiFilterInput (Two-Step Approach)

```graphql
input BuildAiFilterInput {
  """Natural language query (3-500 characters)"""
  query: String!
}
```

### AiFilterResult

```graphql
type AiFilterResult {
  """Ready-to-use filter - pass directly to component.filter(input:)"""
  filterInput: AdvancedComponentFilterOutput

  """UI-friendly filter format with field/comparator/value/displayLabel"""
  filterValues: [FilterValueOutput!]!

  """Match mode: 'all' (AND) or 'any' (OR)"""
  matchMode: String!

  """Whether filter generation succeeded"""
  success: Boolean!

  """Error message if generation failed"""
  error: String

  """Entities mentioned but not found in the library"""
  notFoundEntities: [NotFoundEntity!]

  """Human-readable interpretation of the filters"""
  interpretation: String
}
```

### AdvancedComponentFilterOutput

The `filterInput` field returns this type, which mirrors `AdvancedComponentFilterInput`:

```graphql
type AdvancedComponentFilterOutput {
  and: [ComponentFilterConditionOutput!]
  or: [ComponentFilterConditionOutput!]
}

type ComponentFilterConditionOutput {
  status: StatusFilterOutput
  category: CategoryFilterOutput
  state: StateFilterOutput
  revision: RevisionFilterOutput
  createdBy: UserFilterOutput
  updatedBy: UserFilterOutput
  labels: LabelFilterOutput
  isPinned: BooleanFilterOutput
  isBookmarked: BooleanFilterOutput
  createdAt: DateFilterOutput
  updatedAt: DateFilterOutput
}
```

***

## Next Steps

* Learn about controlling access with [Role-Based Access Control](/advanced-topics/rbac.md)
* Set up [Webhooks](/advanced-topics/webhooks.md) to react to component changes in real-time
* Explore [Change Order Workflows](/library-configuration/change-order-workflows.md) for managing engineering changes


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.durohub.com/advanced-topics/searching-and-filtering.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
