magnifying-glass-waveformSearching 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.

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:

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:

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

circle-info

New to the Duro API? Make sure you've set up authentication first. All examples assume you have a valid API token.


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

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

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" } }

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:

cURL:

circle-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.

Example 2: Find Components by Category Type

Find all assemblies (not parts or documents):

Example 3: Find Recently Modified Components by a Specific User

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

Example 4: Using OR Logic

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

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

Example 6: Date Range Query

Find components created in Q1 2024:

Pagination and Sorting

Control result size and ordering:

Available sort fields: CREATED_AT, UPDATED_AT, NAME, CPN

Directions: ASC, DESC


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

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

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

circle-check

cURL Example

Example Response

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

Handling Partial Matches

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

Query: "resistors modified by John Smith"

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

Best Practices

circle-check
circle-check
circle-check
circle-exclamation

Complete Python Example

Paginating Large Result Sets

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

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:

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"

"All released parts except obsolete"

"Components with any of these labels"

"Early revisions only"

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

ComponentFilterConditionInput

StatusFilterInput

ComponentCategoryFilterInput

LabelFilterInput

circle-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.

StringOperatorsInput

DateFilterInput

RevisionOperatorsInput

BooleanFilterInput

FilterWithAiOutput

BuildAiFilterInput (Two-Step Approach)

AiFilterResult

AdvancedComponentFilterOutput

The filterInput field returns this type, which mirrors AdvancedComponentFilterInput:


Next Steps

Last updated

Was this helpful?