Search

The Search service is Stage 1 of the Studio API pipeline. It generates candidate items from Elasticsearch using structured filters, relevance boosting, or semantic similarity.

Base URL: https://api.mbd.xyz/v3/studio Auth: Authorization: Bearer <your-console-api-key> — get your key from the Embed Console


Search Endpoints

MethodEndpointPurpose
POST/search/filter_and_sortStructured queries with filters + field-based sorting
POST/search/boostSoft relevance tuning with boost multipliers
POST/search/semanticText or vector similarity search
GET/search/frequent_values/{index}/{field}Discover field values before filtering

Searchable Indices

IndexContentPrimary Use Case
polymarket-itemsPrediction marketsMarket discovery, trading feeds
polymarket-walletsTrader profilesWallet lookup, leaderboards
farcaster-itemsSocial postsSocial feeds, content discovery
zora-coinsNFT coins/tokensCreator economy, minting feeds

filter_and_sort

The primary search endpoint. Returns items matching your filters, sorted by any numeric or date field.

Request

curl -X POST https://api.mbd.xyz/v3/studio/search/filter_and_sort \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{
    "index": "polymarket-items",
    "size": 20,
    "sort_by": { "field": "volume_24hr", "order": "desc" },
    "include": [
      { "filter": "term", "field": "active", "value": true },
      { "filter": "numeric", "field": "liquidity_num", "operator": ">", "value": 10000 }
    ],
    "exclude": [
      { "filter": "term", "field": "closed", "value": true },
      { "filter": "term", "field": "archived", "value": true },
      { "filter": "term", "field": "price_0_or_1", "value": true }
    ],
    "select_fields": ["question", "liquidity_num", "volume_24hr", "best_ask", "end_date", "ai_labels_med", "slug", "tags"]
  }'

Request Parameters

ParameterTypeRequiredDescription
indexstringYesOne of: polymarket-items, polymarket-wallets, farcaster-items, zora-coins
sizenumberNoNumber of results (default 100, max 10000)
sort_byobjectNo{ field, order } — sort by any numeric or date field
includeFilter[]NoAND logic — all must match
excludeFilter[]NoNOT logic — any match removes
only_idsbooleanNoReturn only item IDs (faster)
select_fieldsstring[]NoReturn only these fields from _source. Recommended — Polymarket documents have 50+ fields; only fetch what you need
include_vectorbooleanNoInclude embedding vectors in results

Response

{
  "query": { "...": "the ES query executed (useful for debugging)" },
  "result": {
    "took_es": 45,
    "took_es_roundtrip": 52,
    "total_hits": 834,
    "max_score": null,
    "hits": [
      {
        "_index": "polymarket-items-v20251024",
        "_id": "1289113",
        "_score": null,
        "_source": {
          "item_id": "1289113",
          "question": "Will Bitcoin reach $150K by June 2026?",
          "active": true,
          "liquidity": 245000.50,
          "volume_24hr": 1520340.00,
          "best_ask": 0.62
        }
      }
    ]
  },
  "error": null
}

Key fields to extract for later pipeline stages:

  • _id — the item ID to pass to Features and Scoring
  • _source — metadata for display and ranking

boost

Same filter interface as filter_and_sort, but adds a boost array for soft relevance tuning. Items matching boost filters get score multipliers without being hard-filtered.

Does not support sort_by — results are ordered by relevance score.

Request

curl -X POST https://api.mbd.xyz/v3/studio/search/boost \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{
    "index": "polymarket-items",
    "size": 30,
    "include": [
      { "filter": "term", "field": "active", "value": true }
    ],
    "boost": [
      { "filter": "numeric", "field": "liquidity_num", "operator": ">", "value": 50000, "boost": 3.0 },
      { "filter": "term", "field": "featured", "value": true, "boost": 1.5 }
    ],
    "exclude": []
  }'

The boost array accepts the same filter types as include/exclude, plus a boost multiplier (number). Higher values = stronger preference.

Wallet Personalization with group_boost

The group_boost filter dynamically looks up a wallet's preferences and boosts matching items. It reads {group}_01, {group}_02, …, {group}_N from the wallet document and applies linearly decreasing boosts (first match = max_boost, last = min_boost).

curl -X POST https://api.mbd.xyz/v3/studio/search/boost \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{
    "index": "polymarket-items",
    "size": 50,
    "include": [
      { "filter": "term", "field": "active", "value": true },
      { "filter": "numeric", "field": "liquidity_num", "operator": ">", "value": 5000 }
    ],
    "exclude": [
      { "filter": "term", "field": "closed", "value": true },
      { "filter": "term", "field": "price_0_or_1", "value": true }
    ],
    "boost": [
      {
        "filter": "group_boost",
        "field": "ai_labels_med",
        "value": "0xf68a281980f8c13828e84e147e3822381d6e5b1b",
        "lookup_index": "polymarket-wallets",
        "group": "label",
        "min_boost": 1,
        "max_boost": 5,
        "n": 5
      },
      {
        "filter": "group_boost",
        "field": "tags",
        "value": "0xf68a281980f8c13828e84e147e3822381d6e5b1b",
        "lookup_index": "polymarket-wallets",
        "group": "tag",
        "min_boost": 1,
        "max_boost": 3,
        "n": 5
      }
    ],
    "select_fields": ["question", "liquidity_num", "volume_24hr", "best_ask", "end_date", "ai_labels_med", "slug", "tags"]
  }'

Use group: "label" to match the wallet's label_01label_N fields against item ai_labels_med, and group: "tag" to match tag_01tag_N against item tags. The user's top interests get the strongest boost.


semantic

Text or vector similarity search using embeddings. Returns items ranked by semantic closeness to your query.

Does not support include/exclude filters or sort_by.

Request (text query)

curl -X POST https://api.mbd.xyz/v3/studio/search/semantic \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{
    "index": "polymarket-items",
    "text": "artificial intelligence regulation and policy",
    "size": 20,
    "select_fields": ["item_id", "question", "liquidity_num", "volume_24hr"]
  }'

Request Parameters

ParameterTypeRequiredDescription
indexstringYesTarget index
textstringOne of text/vectorNatural language query (min 5 chars)
vectornumber[]One of text/vector768-dimension embedding vector
sizenumberNoNumber of results
select_fieldsstring[]NoFields to return

Tip: To combine semantic search with filtering, run semantic search first, collect the item IDs, then run filter_and_sort with { "filter": "terms", "field": "item_id", "value": [...ids] } in the include array.


frequent_values

Discover what values exist in a field before building filters. Useful for exploring AI labels, categories, and other keyword fields.

Request

curl -X GET "https://api.mbd.xyz/v3/studio/search/frequent_values/polymarket-items/ai_labels_med?size=50" \
  -H "Authorization: Bearer YOUR_API_KEY"

Response

[
  { "id": "mbd2:f_neutral", "count": 8765 },
  { "id": "mbd2:f_positive", "count": 5432 },
  { "id": "mbd2:t_science_technology", "count": 3876 }
]

Filter Logic

Every filter_and_sort and boost request accepts three filter arrays:

ArrayLogicEffect
includeAND — all must matchA document must satisfy every include filter
excludeNOT — any match removesA document matching any exclude filter is removed
boostSHOULD — soft relevanceMatching documents get a score multiplier (boost endpoint only)

Combined logic: (include[0] AND include[1] AND ...) AND NOT (exclude[0] OR exclude[1] OR ...)


Quick Reference: All 12 Filter Types

TypeDescriptionKey Properties
termExact match on a single valuefield, value (string/boolean)
termsMatch any of multiple values (OR)field, value (string array)
numericRange comparison (>, >=, <, <=)field, operator, value (number)
matchFull-text keyword searchfield, value (string array)
dateDate range filteringfield, value ({ date_from?, date_to? })
geoGeographic distancefield, value (["geo:lat,lon"])
is_nullField is null/missingfield
not_nullField exists and has a valuefield
customRaw Elasticsearch query clausefield, value (ES query object)
group_boostDynamic wallet personalization — looks up {group}_01{group}_N fields from a wallet document and applies linearly decreasing boosts (boost only)lookup_index, field, value, group, min_boost, max_boost, n
terms_lookupMatch against terms from another documentlookup_index, field, value, path
console_accountMatch against console account datafield, value, path

For detailed examples, per-index filterable fields, AI label taxonomy, and ready-to-use recipes, see the Filter Cookbook.


Examples

Polymarket: Active High-Volume Markets

{
  "index": "polymarket-items",
  "size": 25,
  "sort_by": { "field": "volume_24hr", "order": "desc" },
  "include": [
    { "filter": "term", "field": "active", "value": true },
    { "filter": "numeric", "field": "liquidity_num", "operator": ">", "value": 10000 },
    { "filter": "numeric", "field": "volume_24hr", "operator": ">", "value": 100 }
  ],
  "exclude": [
    { "filter": "term", "field": "closed", "value": true },
    { "filter": "term", "field": "archived", "value": true },
    { "filter": "term", "field": "price_0_or_1", "value": true }
  ],
  "select_fields": ["question", "liquidity_num", "volume_24hr", "spread", "best_ask", "last_trade_price", "end_date", "ai_labels_med", "slug", "tags"]
}

Field name gotchas (Polymarket):

  • Use liquidity_num not liquidity for filtering — liquidity can be null and will silently miss results.
  • Use ai_labels_med not ai_labels — the field ai_labels does not exist.
  • Use slug not market_slugmarket_slug does not exist.
  • Exclude closed, archived, and price_0_or_1 markets to filter out resolved/inactive content.

Polymarket: Wallets by PnL

{
  "index": "polymarket-wallets",
  "size": 25,
  "sort_by": { "field": "pnl", "order": "desc" },
  "include": [
    { "filter": "numeric", "field": "volume", "operator": ">", "value": 100000 }
  ],
  "exclude": []
}

Farcaster: English Posts by Popularity

{
  "index": "farcaster-items",
  "size": 20,
  "sort_by": { "field": "score_popular", "order": "desc" },
  "include": [
    { "filter": "term", "field": "lang", "value": "en" },
    { "filter": "numeric", "field": "num_like", "operator": ">=", "value": 10 }
  ],
  "exclude": [
    { "filter": "numeric", "field": "user_score_spam", "operator": ">", "value": 0.5 }
  ]
}

Zora: New Coins with Market Activity

{
  "index": "zora-coins",
  "size": 30,
  "sort_by": { "field": "zora_created_at", "order": "desc" },
  "include": [
    {
      "filter": "date",
      "field": "zora_created_at",
      "value": { "date_from": "2026-02-05T00:00:00Z" }
    },
    { "filter": "numeric", "field": "zora_unique_holders", "operator": ">=", "value": 10 }
  ],
  "exclude": [
    { "filter": "numeric", "field": "score_spam", "operator": ">", "value": 0.5 }
  ]
}

What's Next

  • Filter Cookbook — All 12 filter types with per-index field tables, AI label taxonomy, and 12 ready-to-use recipes
  • Features — Stage 2: enrich items with ML features
  • Scoring & Ranking — Stage 3-4: rerank with trained models and apply diversity
  • Quickstart — Full 4-stage pipeline walkthrough with copy-paste code

Looking for the legacy Feed Builder filters? They're documented in Feed Builder 201.


What’s Next

Dive deeper with the Filter Cookbook