> ## Documentation Index
> Fetch the complete documentation index at: https://docs.struct.to/llms.txt
> Use this file to discover all available pages before exploring further.

# Adding search to your app

> Power typeahead, command palettes, and search bars with one endpoint that returns events, markets, traders, and builders in a single call.

`GET /v1/polymarket/search` is a single endpoint that searches across events, markets, traders, and builders at once. One query returns up to four typed result lists, each with its own pagination cursor, which makes it a natural fit for a command palette, a typeahead dropdown, or a global search bar. The `q` parameter accepts a free-text term (minimum 2 characters), a slug, or a wallet address.

## When to use this

* Building a command-palette (Cmd-K) overlay that jumps to any event, market, trader, or builder.
* Adding a typeahead dropdown that suggests results as the user types.
* Resolving a pasted wallet address to a trader profile.
* Powering a global search bar that groups hits by category.

## A basic multi-category search

Call `client.search.search` with just `q` to search all four categories. Each category comes back as its own array on the response, defaulting to 10 results per category.

<CodeGroup>
  ```typescript SDK theme={null}
  const { data } = await client.search.search({
    q: "election",
  });

  console.log(data.events);
  console.log(data.markets);
  console.log(data.traders);
  console.log(data.builders);
  ```

  ```bash cURL theme={null}
  curl "https://api.struct.to/v1/polymarket/search?q=election" \
    -H "X-API-Key: YOUR_API_KEY"
  ```

  ```python Python theme={null}
  import requests

  response = requests.get(
      "https://api.struct.to/v1/polymarket/search",
      headers={"X-API-Key": "YOUR_API_KEY"},
      params={"q": "election"},
  )

  data = response.json()["data"]
  events = data["events"]
  markets = data["markets"]
  traders = data["traders"]
  builders = data["builders"]
  ```
</CodeGroup>

The response is a `SearchResponse` with `events`, `markets`, `traders`, and `builders` arrays (each may be empty or null when a category has no hits), plus the matching `events_pagination`, `markets_pagination`, `traders_pagination`, and `builders_pagination` cursors. Event hits are `PolymarketEvent` objects (`id`, `event_slug`, `title`, `image_url`, `market_count`, ...), market hits are `MarketResponse` objects (`condition_id`, `market_slug`, `question`, `volume_usd`, ...), trader hits are `TraderWithPnl` objects (`address`, `name`, `pseudonym`, `profile_image`, ...), and builder hits are `BuilderMetadata` objects (`builder_code`, `name`, `icon_url`, ...).

## Scoping results with `type`

Searching every category costs 1 credit per category. When a surface only needs some of them, pass `type` as a comma-separated list of `events`, `markets`, `traders`, and `builders` to search just those. A markets-only autocomplete, for example, only needs `markets`.

<CodeGroup>
  ```typescript SDK theme={null}
  const { data } = await client.search.search({
    q: "fed rate",
    type: "markets,events",
  });
  ```

  ```bash cURL theme={null}
  curl "https://api.struct.to/v1/polymarket/search?q=fed%20rate&type=markets,events" \
    -H "X-API-Key: YOUR_API_KEY"
  ```

  ```python Python theme={null}
  import requests

  response = requests.get(
      "https://api.struct.to/v1/polymarket/search",
      headers={"X-API-Key": "YOUR_API_KEY"},
      params={"q": "fed rate", "type": "markets,events"},
  )

  data = response.json()["data"]
  ```
</CodeGroup>

Categories left out of `type` are omitted from the response, so a request scoped to `markets,events` returns no `traders` or `builders` lists and is billed for two categories instead of four.

## Looking up a wallet by address

Passing a `0x` address as `q` performs an exact wallet lookup against the traders category. This is the path to take when a user pastes an address into your search box and you want to resolve it straight to a trader profile. Scope to `type: "traders"` to skip the other categories.

<CodeGroup>
  ```typescript SDK theme={null}
  const { data } = await client.search.search({
    q: "0x1234567890abcdef1234567890abcdef12345678",
    type: "traders",
  });

  const trader = data.traders?.[0];
  ```

  ```bash cURL theme={null}
  curl "https://api.struct.to/v1/polymarket/search?q=0x1234567890abcdef1234567890abcdef12345678&type=traders" \
    -H "X-API-Key: YOUR_API_KEY"
  ```

  ```python Python theme={null}
  import requests

  response = requests.get(
      "https://api.struct.to/v1/polymarket/search",
      headers={"X-API-Key": "YOUR_API_KEY"},
      params={
          "q": "0x1234567890abcdef1234567890abcdef12345678",
          "type": "traders",
      },
  )

  data = response.json()["data"]
  trader = (data["traders"] or [None])[0]
  ```
</CodeGroup>

A matching address comes back as the first entry in `traders`, with the resolved `address`, `name`, `pseudonym`, and `profile_image` for the wallet.

## Enriching trader hits with PnL

By default trader hits carry only profile fields. Set `include_pnl` to `true` to attach a lifetime PnL summary to each trader, which is handy when search results double as a leaderboard preview. This adds 1 credit to the request on top of the per-category cost.

<CodeGroup>
  ```typescript SDK theme={null}
  const { data } = await client.search.search({
    q: "whale",
    type: "traders",
    include_pnl: true,
  });

  const top = data.traders?.[0];
  console.log(top?.address, top?.pnl);
  ```

  ```bash cURL theme={null}
  curl "https://api.struct.to/v1/polymarket/search?q=whale&type=traders&include_pnl=true" \
    -H "X-API-Key: YOUR_API_KEY"
  ```

  ```python Python theme={null}
  import requests

  response = requests.get(
      "https://api.struct.to/v1/polymarket/search",
      headers={"X-API-Key": "YOUR_API_KEY"},
      params={"q": "whale", "type": "traders", "include_pnl": True},
  )

  data = response.json()["data"]
  ```
</CodeGroup>

With `include_pnl` enabled, each `TraderWithPnl` in `traders` gains a `pnl` field holding the wallet's lifetime PnL summary. The field is absent when `include_pnl` is not set.

## Sorting and timeframe

`sort_by` controls how events and markets are ordered. It accepts `volume` (the default), `relevance`, `liquidity`, `holders`, `txns`, `unique_traders`, and the date and time fields (`creation_date`, `start_date`, `end_date`, `start_time`, `end_time`, `created_time`). Pair it with `sort_dir` (`asc` or `desc`, default `desc`). When you sort by an activity metric such as `volume`, `txns`, or `unique_traders`, `timeframe` selects the window that metric is measured over: `1m`, `5m`, `30m`, `1h`, `6h`, `24h` (the default), `7d`, `30d`, or `lifetime`.

<CodeGroup>
  ```typescript SDK theme={null}
  const { data } = await client.search.search({
    q: "trump",
    type: "markets",
    sort_by: "volume",
    sort_dir: "desc",
    timeframe: "7d",
  });
  ```

  ```bash cURL theme={null}
  curl "https://api.struct.to/v1/polymarket/search?q=trump&type=markets&sort_by=volume&sort_dir=desc&timeframe=7d" \
    -H "X-API-Key: YOUR_API_KEY"
  ```

  ```python Python theme={null}
  import requests

  response = requests.get(
      "https://api.struct.to/v1/polymarket/search",
      headers={"X-API-Key": "YOUR_API_KEY"},
      params={
          "q": "trump",
          "type": "markets",
          "sort_by": "volume",
          "sort_dir": "desc",
          "timeframe": "7d",
      },
  )

  data = response.json()["data"]
  ```
</CodeGroup>

Ranking the markets list by 7-day volume surfaces what is busy right now, which is usually what a search-as-you-type box should show first.

## Per-category pagination

`limit` caps results per category (default 10, max 250), so a single response holds at most `limit` events, `limit` markets, and so on. Each category paginates independently through its own cursor. Read `pagination_key` from a category's pagination block (`data.events_pagination`, `data.markets_pagination`, `data.traders_pagination`, or `data.builders_pagination`) and feed it back as the matching request parameter (`events_pagination_key`, `markets_pagination_key`, `traders_pagination_key`, or `builders_pagination_key`) to fetch the next page of just that category.

<CodeGroup>
  ```typescript SDK theme={null}
  const first = await client.search.search({ q: "election", limit: 25 });

  const next = await client.search.search({
    q: "election",
    limit: 25,
    markets_pagination_key:
      first.data.markets_pagination?.pagination_key ?? undefined,
  });
  ```

  ```bash cURL theme={null}
  curl "https://api.struct.to/v1/polymarket/search?q=election&limit=25&markets_pagination_key=MARKETS_CURSOR" \
    -H "X-API-Key: YOUR_API_KEY"
  ```

  ```python Python theme={null}
  import requests

  base = {"q": "election", "limit": 25}

  first = requests.get(
      "https://api.struct.to/v1/polymarket/search",
      headers={"X-API-Key": "YOUR_API_KEY"},
      params=base,
  ).json()["data"]

  cursor = (first["markets_pagination"] or {}).get("pagination_key")

  second = requests.get(
      "https://api.struct.to/v1/polymarket/search",
      headers={"X-API-Key": "YOUR_API_KEY"},
      params={**base, "markets_pagination_key": cursor},
  ).json()["data"]
  ```
</CodeGroup>

Each `*_pagination` block is a `PaginationMeta` with `has_more` and `pagination_key`. When `has_more` is `false`, that category has no further pages, even if other categories still do. Because the cursors are independent, you can advance markets without re-fetching events, which keeps a category-grouped results panel cheap to load more on demand.
