BOOK A DEMO

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)

GraphQL
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

TypeAvailable onTypical use
ITEMClient + ManagementStorefront catalog discovery
SALE_ITEMManagementFind items within sales
SALEManagementFind sales
USERManagementLook up bidders by name or email
SALE_REGISTRATIONManagementFind registrations

Refining results

The search query supports a few optional refinements:

ArgumentDescription
queryThe free-text search string
queryByWhich fields to search in (e.g. title, description, tags). Defaults to sensible fields per type
orderBySort by a field and direction, e.g. "title:asc". Defaults to relevance
filterByAdditional conditions, combinable with &&
first / pagePage size and 1-based page number

Example: filtered & sorted

GraphQL
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

OperatorMeaningExample
field:valueMatches (contains / token)status:ITEM_OPEN
field:=valueExact matchitemType:=Painting
field:!=valueNot equalstatus:!=ITEM_CLOSED
field:> :>= :< :<=Numeric comparisoncurrentBid:>= 10000
field:[min..max]Numeric rangelowEstimate:[5000..20000]
field:[a, b]Any of these valuestags:[rare, vintage]
backticksQuote values with spaceslocation:=`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.

GraphQL
# 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:

Text
# 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).

GraphQL
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

  1. Debounce input — search as the user types, but throttle requests
  2. Cache common queries on your side to reduce load
  3. 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.

Related documentation

Support

Questions about search? Contact us at hi@basta.app.