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.
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!
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:
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:
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%" } }
A % at the start of the pattern matches by suffix, which is how you find components that share a counter but differ by prefix:
Date Operators
Use these for createdAt and updatedAt fields:
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)
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:
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:
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
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 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:
That's it. Natural language in, components out. No two-step process, no filter syntax to learn.
Input Options
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
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
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
Complete Python Example
Paginating Large Result Sets
If totalCount exceeds your limit, use the filterInput field to paginate with component.filter.
filterWithAI returns components but no cursors, so its own response cannot be paged from. Use it once to build the filter, then read every page — including the first — through 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
Use
andoverorwhen possible. AND queries are generally faster as they narrow results.Filter by indexed fields first. Status, category, and state are highly optimized.
Paginate large results. Use
first: 50and cursor-based pagination rather than fetching everything.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
Start simple. Test one condition at a time before combining.
Check your field paths.
status.namevsstatus.mapsTovsstatus.idtarget different things.Verify IDs exist. If filtering by UUID, ensure the status/category/user actually exists in your library.
Watch for empty results. An overly specific
andquery might match nothing. Try loosening conditions.
Complete API Reference
AdvancedComponentFilterInput
ComponentFilterConditionInput
StatusFilterInput
ComponentCategoryFilterInput
LabelFilterInput
StringOperatorsInput
DateFilterInput
RevisionOperatorsInput
BooleanFilterInput
FilterWithAiInput (Recommended)
FilterWithAiOutput
BuildAiFilterInput (Two-Step Approach)
AiFilterResult
AdvancedComponentFilterOutput
The filterInput field returns this type, which mirrors AdvancedComponentFilterInput:
Next Steps
Learn about controlling access with Role-Based Access Control
Set up Webhooks to react to component changes in real-time
Explore Change Order Workflows for managing engineering changes
Skip the queries entirely — the Duro MCP Server puts this same search behind plain-language questions
Last updated
Was this helpful?