APIs
Search
Full-text search over your catalog and, on the back office, over your users and registrations.
Basta provides full-text search over your catalog and, on the back office, over your users and registrations. Search is available on both APIs:
- Client API — public search across items, for storefront discovery
- Management API — search across items, sale items, sales, users, and registrations, for back-office tooling
Search runs against an index that is eventually consistent. Results update in near real-time, but very recent changes may take a moment to appear.
Basic search (Client API)
query SearchItems {
search(
accountId: "ACCOUNT_ID"
type: ITEM
query: "vintage watch"
first: 20
) {
resultCount
edges {
node {
__typename
... on Item {
id
title
}
}
}
pageInfo {
currentPage
totalPages
totalCount
}
}
}What you can search
| Type | Available on | Typical use |
|---|---|---|
ITEM | Client + Management | Storefront catalog discovery |
SALE_ITEM | Management | Find items within sales |
SALE | Management | Find sales |
USER | Management | Look up bidders by name or email |
SALE_REGISTRATION | Management | Find registrations |
Refining results
The search query supports a few optional refinements:
| Argument | Description |
|---|---|
query | The free-text search string |
queryBy | Which fields to search in (e.g. title, description, tags). Defaults to sensible fields per type |
orderBy | Sort by a field and direction, e.g. "title:asc". Defaults to relevance |
filterBy | Additional conditions, combinable with && |
first / page | Page size and 1-based page number |
Example: filtered & sorted
query SearchOpenItems {
search(
accountId: "ACCOUNT_ID"
type: ITEM
query: "ceramic"
queryBy: ["title", "description", "tags"]
filterBy: "currentBid:>= 10000 && reserveMet:true"
orderBy: "currentBid:desc"
first: 20
page: 1
) {
resultCount
edges { node { __typename ... on Item { id title } } }
}
}How to filter
filterBy is a filter expression evaluated against the search index. Combine conditions on indexed fields to narrow results — your account scope is always applied automatically, so you only filter on the data itself.
Operators
| Operator | Meaning | Example |
|---|---|---|
field:value | Matches (contains / token) | status:ITEM_OPEN |
field:=value | Exact match | itemType:=Painting |
field:!=value | Not equal | status:!=ITEM_CLOSED |
field:> :>= :< :<= | Numeric comparison | currentBid:>= 10000 |
field:[min..max] | Numeric range | lowEstimate:[5000..20000] |
field:[a, b] | Any of these values | tags:[rare, vintage] |
| backticks | Quote values with spaces | location:=`New York` |
Combining conditions
Join conditions with && (AND). For advanced filters you can group with parentheses and use || (OR) — for example status:=ITEM_OPEN && (tags:=rare || tags:=vintage).
Filtering on dates
Filter time-based fields using their epoch (Unix seconds) counterparts, such as dates.closingEndEpoch or closingDateEpoch. Nested fields use dot notation: dates.closingEndEpoch, price.startingBid, metafields.<key>.
Common filterable fields
Items (ITEM): status, currentBid, startingBid, lowEstimate, highEstimate, reserveMet, itemType, itemResult, tags, categoryPaths, creatorPaths, location, highlighted, buyNowEnabled, offerEnabled, saleId, dates.closingEndEpoch, metafields.<key>.
Sales (SALE): status (LIVE, PUBLISHED, OPENED, CLOSING, CLOSED, PAUSED, PROCESSING), saleType, currency, closing_method, categoryPaths, departmentIds, location, closingDateEpoch, metafields.<key>.
Management-only types expose their own fields — for example USER: email, name, trustLevel, idVerificationStatus, blocked.
Not filterable
Account scoping is automatic, and internal fields — hidden, reserve, and individual bid details — can't be filtered on. On the public Client API, only published, visible records are ever returned.
# Open lots over $100 (amounts are integers in minor units), most-bid first
query OpenLots {
search(
accountId: "ACCOUNT_ID"
type: ITEM
query: "*"
filterBy: "status:=ITEM_OPEN && currentBid:>= 10000"
orderBy: "totalBids:desc"
first: 24
) {
resultCount
edges { node { __typename ... on Item { id title } } }
}
}More filter expressions:
# Estimate range, in a category, tagged rare OR vintage
lowEstimate:[5000..20000] && categoryPaths:=Watches && (tags:=rare || tags:=vintage)
# Sales that are open and close after a given time (Unix seconds)
status:=OPENED && closingDateEpoch:> 1735689600
# Match any of several statuses
status:[ITEM_OPEN, ITEM_CLOSING]Facets
Search results can include facet counts— distributions of values across the result set — which are ideal for building filter sidebars (e.g. "show me how many results fall into each bracket"). Facets include value counts and, for numeric fields, basic statistics (min, max, average).
query SearchWithFacets {
search(accountId: "ACCOUNT_ID", type: USER, query: "john") {
resultCount
facets {
fieldName
counts { value count }
}
}
}Pagination
Search uses page-based pagination (page + first), unlike the cursor-based connections used elsewhere in the API. The pageInfo block returns currentPage, perPage, totalPages, and totalCount so you can render page controls.
Best practices
- Debounce input — search as the user types, but throttle requests
- Cache common queries on your side to reduce load
- Expect slight lag— the index is eventually consistent; don't rely on it for authoritative, up-to-the-millisecond state
For live bid data, use Subscriptions rather than polling search.