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

# Filter Search

> Reference for filter capabilities, field-value discovery, and paginated filter search for people and companies.

## Use case

Search people or companies with `simple_filters` or `filters`. Discover valid fields first, inspect top values for one field, then run the paginated search.

<Card title="API Reference" icon="code" href="/api-reference/search/search-endpoints#query-search-results">
  See the full request/response schema and parameters in the API Reference.
</Card>

## Pricing

See [Credits & Pricing Guide](/guides/credits-and-pricing) for credit costs.

## Errors

For error responses (400, 403, 404, 409, 503, etc.), see [Handling Errors](/api-reference/errors).

## Rate limits

Filter-search-specific API rate limits.

| Limit                              | Value                                    |
| ---------------------------------- | ---------------------------------------- |
| `POST /search/query`               | 200 requests per minute per organization |
| `POST /search/filter-field-values` | 20 requests per minute per organization  |

## Core concepts

| Term                 | Description                                                                                                                                                                                                                                                                        |
| -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `simple_filters`     | The primary query input format for search and field-values requests. Supports Mongo-style operators such as `$eq`, `$in`, `$gte`, `$match`, and `$and`.                                                                                                                            |
| `filters`            | The DSL backup query format. The API rejects queries that exceed the field and query limits defined by `GET /search/filter-capabilities`.                                                                                                                                          |
| `exclude_entity_ids` | Excludes specific people or companies from `/search/query` results by ID. In people mode it accepts LinkedIn public IDs or profile URLs; in company mode, LinkedIn company IDs, URLs, slugs, or website domains. See [Search Exclusions](/api-reference/search/search-exclusions). |
| `exclude_list_ids`   | Excludes members of a reusable saved exclusion list. The list's entity type must match the search mode. See [Search Exclusions](/api-reference/search/search-exclusions).                                                                                                          |
| `fields`             | Unified field metadata returned by `GET /search/filter-capabilities`. Use it to discover queryable, sortable, rangeable, and top-value-capable fields.                                                                                                                             |
| `filter_snippet`     | A ready-to-use exact-match clause in `filters` format returned alongside each top value. Use it when you need `filters`.                                                                                                                                                           |
| `cursor`             | A pagination token returned as `next_cursor`. Pass it as the only field in follow-up requests to fetch the next page.                                                                                                                                                              |

## Recommended flow

<div style={{ display: "flex", justifyContent: "center" }}>
  ```mermaid theme={null}
  flowchart TD
      A["GET<br/>/search/filter-capabilities"] -->|"Discover valid fields & limits"| B["POST<br/>/search/filter-field-values"]
      B -->|"Inspect top values for a field"| C["POST<br/>/search/query"]
      C --> D{has_more?}
      D -->|"true — send {cursor} only"| C
      D -->|false| E[Done]
  ```
</div>

## Simple filters

`simple_filters` is the primary query format for this API. It supports common exact-match, range, logical, and text-search operations with concise JSON syntax.

### Top-level shape

```json theme={null}
{
  "simple_filters": {
    "hq_country_iso2": { "$eq": "US" },
    "employees_count": { "$gte": 100, "$lte": 5000 }
  }
}
```

### Supported operators

The capabilities response exposes supported simple-query operators in `simple_query_operators`.

| Operator                      | Description                                                                                                                |
| ----------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| `$eq`, `$ne`                  | Exact match or exact exclusion.                                                                                            |
| `$gt`, `$gte`, `$lt`, `$lte`  | Numeric or date range comparisons.                                                                                         |
| `$in`, `$nin`                 | Match or exclude multiple exact values.                                                                                    |
| `$exists`                     | Match documents where a field is present or absent.                                                                        |
| `$match`, `$phrase`           | Text matching for one field.                                                                                               |
| `$and`, `$or`, `$not`, `$nor` | Logical composition.                                                                                                       |
| `$elemMatch`                  | Match nested array elements. See [Nested array matching](#nested-array-matching-elemmatch) for path and type requirements. |
| `$search`                     | Full-text search across supported fields.                                                                                  |
| `$sort`                       | Sort results in search requests.                                                                                           |
| `$limit`                      | Limit result count in search requests.                                                                                     |

### Nested array matching (\$elemMatch)

`$elemMatch` queries fields inside nested arrays. Two mistakes account for nearly all failed queries:

* Relative path — `companyData.memberId` instead of the full dotted path `currentCompanies.companyData.memberId`
* Wrong type — passing a numeric ID as a string (`"1234567"`) when the field's `value_type` is `long`

<Warning>
  A relative path or type mismatch inside `$elemMatch` returns zero results or a misleading 400 — not always a clear error. Check the full dotted path and `value_type` in `GET /search/filter-capabilities` before querying.
</Warning>

Find people currently at a specific company by LinkedIn `memberId`:

```json theme={null}
{
  "mode": "people",
  "simple_filters": {
    "currentCompanies": {
      "$elemMatch": {
        "currentCompanies.companyData.memberId": 1234567
      }
    }
  }
}
```

The common wrong form — same request shape, but relative path and string ID:

```json theme={null}
{
  "mode": "people",
  "simple_filters": {
    "currentCompanies": {
      "$elemMatch": {
        "companyData.memberId": "1234567"
      }
    }
  }
}
```

Both the relative path (`companyData.memberId` instead of `currentCompanies.companyData.memberId`) and the string ID (`"1234567"` instead of `1234567`) cause this query to fail.

`$elemMatch` must be keyed on the field's `nested_path` from capabilities — not always the outermost array. `currentCompanies.companyData.memberId` has `nested_path: "currentCompanies"`, so `$elemMatch` keys on `currentCompanies`. `currentCompanies.positions.title` has `nested_path: "currentCompanies.positions"`, so `$elemMatch` on `currentCompanies` cannot reference a positions field.

### Excluding results

There are two ways to exclude records:

* Use `simple_filters` operators such as `$ne`, `$nin`, `$not`, and `$nor` to exclude records that match field conditions.
* Use the top-level exclusion fields — `exclude_entity_ids` or `exclude_list_ids` — to suppress specific people or companies by ID. See [Search Exclusions](/api-reference/search/search-exclusions) for identifier formats, saved lists, and limits.

Operator-based exclusions affect matching, pagination, and result counts. ID-based exclusions are applied after matching, so pages can return fewer rows than `page_size`. Don't rely on `total_available` to count excluded records or size pagination — page until `next_cursor` is `null`.

<Note>
  Cursor requests must send only `{"cursor": "..."}`. You cannot add or change exclusions while paging through an existing cursor. Include exclusions in the first `/search/query` request.
</Note>

### Query examples

Find US-based companies:

```json theme={null}
{
  "mode": "company",
  "simple_filters": {
    "hq_country_iso2": { "$eq": "US" }
  }
}
```

Find US-based companies with at least 4 employees:

```json theme={null}
{
  "mode": "company",
  "simple_filters": {
    "hq_country_iso2": { "$eq": "US" },
    "employees_count": { "$gte": 4 }
  }
}
```

Exclude companies in specific industries:

```json theme={null}
{
  "mode": "company",
  "simple_filters": {
    "industry": { "$nin": ["Staffing", "Recruiting"] }
  }
}
```

Find US-based companies while excluding public companies:

```json theme={null}
{
  "mode": "company",
  "simple_filters": {
    "hq_country_iso2": { "$eq": "US" },
    "is_public": { "$ne": true }
  }
}
```

Exclude records using logical negation:

```json theme={null}
{
  "mode": "company",
  "simple_filters": {
    "$and": [
      { "hq_country_iso2": { "$eq": "US" } },
      {
        "$not": {
          "categories_and_keywords": { "$match": "staffing" }
        }
      }
    ]
  }
}
```

Exclude records that match any disallowed condition:

```json theme={null}
{
  "mode": "company",
  "simple_filters": {
    "$nor": [
      { "industry": { "$eq": "Staffing" } },
      { "categories_and_keywords": { "$match": "recruiting" } }
    ]
  }
}
```

Find US-based companies with at least 4 employees where a post mentions YC X25:

```json theme={null}
{
  "mode": "company",
  "simple_filters": {
    "$and": [
      { "hq_country_iso2": { "$eq": "US" } },
      { "employees_count": { "$gte": 4 } },
      { "company_updates.description": { "$match": "(YC X25)" } }
    ]
  }
}
```

Find US-based companies sorted by employee count descending, capped to 8 total results:

```json theme={null}
{
  "mode": "company",
  "simple_filters": {
    "hq_country_iso2": { "$eq": "US" },
    "$sort": [{ "employees_count": "desc" }],
    "$limit": 8
  }
}
```

Find Canadian companies that have raised any amount and mention technology in categories or keywords:

```json theme={null}
{
  "mode": "company",
  "simple_filters": {
    "$and": [
      { "hq_country_iso2": { "$eq": "CA" } },
      { "last_funding_round_amount_raised": { "$gt": 0 } },
      { "categories_and_keywords": { "$match": "technology" } }
    ]
  }
}
```

Full-text search across specific fields:

```json theme={null}
{
  "mode": "company",
  "simple_filters": {
    "$search": {
      "query": "cloud security",
      "fields": ["description", "categories_and_keywords"]
    }
  }
}
```

Find people whose headline matches "engineer":

```json theme={null}
{
  "mode": "people",
  "simple_filters": {
    "headline": { "$match": "engineer" }
  }
}
```

Find people by current job title:

```json theme={null}
{
  "mode": "people",
  "simple_filters": {
    "currentCompanies.positions.title": { "$match": "engineering manager" }
  }
}
```

Fields with a doubly nested path accept `$elemMatch` on the inner nested path:

```json theme={null}
{
  "mode": "people",
  "simple_filters": {
    "currentCompanies.positions": {
      "$elemMatch": {
        "currentCompanies.positions.title": { "$match": "engineering manager" }
      }
    }
  }
}
```

Find people currently at a specific company by LinkedIn `memberId` — see the full example and path/type requirements in [Nested array matching (\$elemMatch)](#nested-array-matching-elemmatch).

## DSL filters

`filters` accepts a constrained DSL subset for cases where `simple_filters` is not expressive enough. For DSL syntax and clause behavior, see the [OpenSearch Query DSL docs](https://opensearch.org/docs/latest/query-dsl/).

### Top-level shape

```json theme={null}
{
  "filters": {
    "query": { ... },
    "sort": [ ... ],
    "size": 100
  }
}
```

### Supported query clauses

| Clause         | Description                                                         |
| -------------- | ------------------------------------------------------------------- |
| `bool`         | Combine conditions with `must`, `filter`, `should`, and `must_not`. |
| `term`         | Exact-match query for a single value.                               |
| `terms`        | Exact-match query for multiple values.                              |
| `range`        | Numeric or date range with `gt`, `gte`, `lt`, `lte`.                |
| `exists`       | Match documents where a field is present.                           |
| `match`        | Full-text match query.                                              |
| `match_phrase` | Phrase query.                                                       |
| `multi_match`  | Search the same value across multiple fields.                       |
| `nested`       | Query nested arrays and nested objects.                             |
| `match_all`    | Match all records in the selected mode.                             |

### Query examples

Exact match:

```json theme={null}
{
  "term": {
    "website_domain": "stripe.com"
  }
}
```

Range filter:

```json theme={null}
{
  "range": {
    "employees_count": {
      "gte": 100,
      "lte": 5000
    }
  }
}
```

Multi-field full-text search:

```json theme={null}
{
  "multi_match": {
    "query": "cloud security",
    "fields": [
      "description",
      "categories_and_keywords"
    ],
    "type": "best_fields",
    "operator": "and"
  }
}
```

Nested query:

```json theme={null}
{
  "nested": {
    "path": "funding_rounds",
    "query": {
      "match_phrase": {
        "funding_rounds.name": "Series B"
      }
    }
  }
}
```

Exclude with `must_not`:

```json theme={null}
{
  "bool": {
    "must": [
      { "term": { "hq_country_iso2": "US" } }
    ],
    "must_not": [
      { "term": { "industry": "Staffing" } }
    ]
  }
}
```

## Filter capabilities

```http theme={null}
GET https://api.sixtyfour.ai/search/filter-capabilities
```

Returns all available fields for filter search — the complete list of fields you can query, sort, range, or aggregate against, plus the supported `simple_filters` operators and DSL limits.

<Tip>
  Call this first to discover what is filterable before constructing any `simple_filters` or `filters` request. The response is the source of truth: a field that is not in `fields` cannot be queried.
</Tip>

### Query parameters

| Parameter | Type    | Description                                                                            |
| --------- | ------- | -------------------------------------------------------------------------------------- |
| `mode`    | string  | `people` or `company`. Defaults to `company`.                                          |
| `refresh` | boolean | Force a mapping refresh instead of returning cached capabilities. Defaults to `false`. |

### Example request

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET "https://api.sixtyfour.ai/search/filter-capabilities?mode=company" \
    -H "x-api-key: YOUR_API_KEY"
  ```

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

  response = requests.get(
      "https://api.sixtyfour.ai/search/filter-capabilities",
      headers={"x-api-key": "YOUR_API_KEY"},
      params={"mode": "company"},
  )
  print(response.json())
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch(
    "https://api.sixtyfour.ai/search/filter-capabilities?mode=company",
    { headers: { "x-api-key": "YOUR_API_KEY" } },
  );
  const data = await response.json();
  console.log(data);
  ```
</CodeGroup>

### Response shape

| Field                    | Type      | Description                                                                                                                         |
| ------------------------ | --------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `fields`                 | array     | Every queryable field in the selected mode. See [Field entry](#field-entry).                                                        |
| `nested_paths`           | string\[] | Top-level paths that map to nested arrays or objects. Fields underneath these paths require a `nested` clause when using `filters`. |
| `simple_query_operators` | string\[] | Operators allowed in `simple_filters` (`$eq`, `$in`, `$gte`, `$match`, etc.).                                                       |
| `limits`                 | object    | Hard limits applied to `filters` queries. See [Limits](#limits).                                                                    |
| `cache_ttl_seconds`      | integer   | Seconds the response is cached server-side. Pass `refresh=true` to bypass.                                                          |
| `generated_at_epoch_ms`  | integer   | When the cached payload was built.                                                                                                  |
| `mapping_hash`           | string    | Hash of the underlying index mapping. Changes when fields are added or removed.                                                     |

### Limits

| Limit                  | Description                                         |
| ---------------------- | --------------------------------------------------- |
| `max_query_depth`      | Maximum nesting depth of `filters.query`.           |
| `max_clause_count`     | Maximum total clauses across a `filters` query.     |
| `max_terms_per_clause` | Maximum values in a single `terms` or `$in` clause. |
| `max_sort_clauses`     | Maximum sort fields.                                |
| `max_string_length`    | Maximum length of any string value in a query.      |

### Field entry

Each item in `fields` describes one queryable field.

| Property                        | Type           | Description                                                                                                            |
| ------------------------------- | -------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `field`                         | string         | The field path to use in `simple_filters` and `filters`.                                                               |
| `field_type`                    | string         | Underlying index type (`keyword`, `text`, `long`, `double`, `integer`, `date`, `search_as_you_type`).                  |
| `value_type`                    | string         | The value type clients should send. Matches `field_type` except for text fields, which expose `keyword` for filtering. |
| `nested_path`                   | string \| null | Set when the field lives inside a nested array. Use a `nested` clause with `path` set to this value for DSL queries.   |
| `queryable`                     | boolean        | Whether the field is valid in `simple_filters` and `filters`.                                                          |
| `sortable`                      | boolean        | Whether the field can be used in `$sort` or DSL `sort`.                                                                |
| `rangeable`                     | boolean        | Whether the field accepts `$gt`, `$gte`, `$lt`, `$lte`, or DSL `range`.                                                |
| `sort_field`                    | string \| null | Alternate path used when sorting. Text fields sort on the `.keyword` subfield.                                         |
| `aggregation_field`             | string \| null | Path used for top-value aggregation in `POST /search/filter-field-values`.                                             |
| `supports_top_values`           | boolean        | Whether the field can be passed to `POST /search/filter-field-values`.                                                 |
| `supports_exact_filter_snippet` | boolean        | Whether a `filter_snippet` is returned alongside top values for this field.                                            |
| `related_fields`                | string\[]      | Other fields that pair with this one (e.g. range pairs, currency + value).                                             |
| `preferred_for_exact_match`     | boolean        | When multiple fields describe the same concept, the preferred field for exact-match queries.                           |

### Example response

Trimmed to two representative fields — a top-level keyword and a nested numeric.

```json theme={null}
{
  "fields": [
    {
      "field": "website",
      "field_type": "keyword",
      "value_type": "keyword",
      "nested_path": null,
      "queryable": true,
      "sortable": true,
      "rangeable": false,
      "sort_field": null,
      "aggregation_field": "website",
      "supports_top_values": true,
      "supports_exact_filter_snippet": true,
      "related_fields": [],
      "preferred_for_exact_match": false
    },
    {
      "field": "stock_information.marketcap",
      "field_type": "double",
      "value_type": "double",
      "nested_path": "stock_information",
      "queryable": true,
      "sortable": true,
      "rangeable": true,
      "sort_field": null,
      "aggregation_field": "stock_information.marketcap",
      "supports_top_values": true,
      "supports_exact_filter_snippet": true,
      "related_fields": [],
      "preferred_for_exact_match": false
    }
  ],
  "nested_paths": [
    "funding_rounds",
    "stock_information",
    "technologies_used",
    "visits_breakdown_by_country"
  ],
  "simple_query_operators": [
    "$eq", "$ne", "$gt", "$gte", "$lt", "$lte",
    "$in", "$nin", "$exists", "$match", "$phrase",
    "$and", "$or", "$not", "$nor", "$elemMatch",
    "$search", "$sort", "$limit"
  ],
  "limits": {
    "max_query_depth": 12,
    "max_clause_count": 200,
    "max_terms_per_clause": 25,
    "max_sort_clauses": 2,
    "max_string_length": 200
  },
  "cache_ttl_seconds": 600,
  "generated_at_epoch_ms": 1779726915580,
  "mapping_hash": "3c507eb2e597605197fac2beb483fbbf619f628ce45b2c2c446825289347a24a0"
}
```

### Common lookups

Filter the `fields` array client-side to find what is available for a given operation.

| Goal                                                       | Property                              |
| ---------------------------------------------------------- | ------------------------------------- |
| Fields usable in `simple_filters` or `filters`             | `queryable: true`                     |
| Fields usable in `$sort` or DSL `sort`                     | `sortable: true`                      |
| Fields that accept range operators                         | `rangeable: true`                     |
| Fields that can be passed to `/search/filter-field-values` | `supports_top_values: true`           |
| Fields that require a `nested` clause in DSL               | `nested_path` is non-null             |
| Fields that return `filter_snippet` for reuse in `filters` | `supports_exact_filter_snippet: true` |

### Find specific fields

To confirm that a field exists and see what operators it accepts, filter the `fields` array by name. The examples below check `hq_country_iso2` and `employees_count` — the same fields used in the `simple_filters` examples earlier on this page.

<CodeGroup>
  ```bash cURL theme={null}
  curl -s "https://api.sixtyfour.ai/search/filter-capabilities?mode=company" \
    -H "x-api-key: YOUR_API_KEY" \
    | jq '.fields[] | select(.field == "hq_country_iso2" or .field == "employees_count")'
  ```

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

  caps = requests.get(
      "https://api.sixtyfour.ai/search/filter-capabilities",
      headers={"x-api-key": "YOUR_API_KEY"},
      params={"mode": "company"},
  ).json()

  wanted = {"hq_country_iso2", "employees_count"}
  for f in caps["fields"]:
      if f["field"] in wanted:
          print(f["field"], "queryable=", f["queryable"], "rangeable=", f["rangeable"])
  ```

  ```javascript JavaScript theme={null}
  const caps = await fetch(
    "https://api.sixtyfour.ai/search/filter-capabilities?mode=company",
    { headers: { "x-api-key": "YOUR_API_KEY" } },
  ).then(r => r.json());

  const wanted = new Set(["hq_country_iso2", "employees_count"]);
  caps.fields
    .filter(f => wanted.has(f.field))
    .forEach(f => console.log(f.field, "queryable=", f.queryable, "rangeable=", f.rangeable));
  ```
</CodeGroup>

If a field is missing from `fields`, it cannot be queried. If `queryable` is `false`, the field is exposed but reserved for sort or aggregation only. If `nested_path` is non-null, wrap the clause in a `nested` query when using `filters`.

To search by partial name (e.g. every revenue-related field):

```bash theme={null}
curl -s "https://api.sixtyfour.ai/search/filter-capabilities?mode=company" \
  -H "x-api-key: YOUR_API_KEY" \
  | jq '.fields[] | select(.field | test("revenue")) | .field'
```

<Tip>Capabilities are cached for `cache_ttl_seconds` (typically 600s). Pass `refresh=true` only when verifying schema changes — every refresh rebuilds the mapping and is slower.</Tip>

## Field values

```http theme={null}
POST https://api.sixtyfour.ai/search/filter-field-values
```

Returns top values for one field, ranked by descending scoped document count. There is no batch variant.

### Scoped query

* Omit both `simple_filters` and `filters` for global scope.
* Send either `simple_filters` or `filters` for scoped discovery.
* `filters.sort`, `filters.size`, and mixed `filters` plus `simple_filters` requests are not allowed on this endpoint.
* `simple_filters.$sort` and `simple_filters.$limit` are not supported on this endpoint.

```json theme={null}
{
  "simple_filters": {
    "hq_country_iso2": { "$eq": "US" }
  }
}
```

<Tip>
  Use `filter-field-values` with a high `top_k` to enumerate valid values for any enum-like field before filtering. This prevents querying with values that return zero results.
</Tip>

Discover all available industries:

```bash theme={null}
curl -s -X POST "https://api.sixtyfour.ai/search/filter-field-values" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"mode": "company", "field": "industry", "top_k": 100}'
```

The same pattern works for any enum-like field: `ownership_status`, `hq_country_iso2`, `funding_stage`, and so on. Check `supports_top_values: true` in the capabilities response to confirm the field supports this endpoint.

### Example request

Global:

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://api.sixtyfour.ai/search/filter-field-values" \
    -H "x-api-key: YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"mode": "company", "field": "hq_country_iso2", "top_k": 4}'
  ```

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

  response = requests.post(
      "https://api.sixtyfour.ai/search/filter-field-values",
      headers={"x-api-key": "YOUR_API_KEY"},
      json={"mode": "company", "field": "hq_country_iso2", "top_k": 4},
  )
  print(response.json())
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch("https://api.sixtyfour.ai/search/filter-field-values", {
    method: "POST",
    headers: { "x-api-key": "YOUR_API_KEY", "Content-Type": "application/json" },
    body: JSON.stringify({ mode: "company", field: "hq_country_iso2", top_k: 4 }),
  });
  const data = await response.json();
  console.log(data);
  ```
</CodeGroup>

Scoped:

```json theme={null}
{
  "mode": "company",
  "field": "industry",
  "top_k": 4,
  "simple_filters": {
    "hq_country_iso2": { "$eq": "US" },
    "employees_count": { "$gte": 200, "$lte": 5000 },
    "ownership_status": { "$eq": "private" }
  }
}
```

### Nested fields

For nested fields such as `funding_rounds.name`, counts are document counts and each `filter_snippet` is wrapped in a `nested` clause so it can be reused directly in DSL flows.

## Search query

```http theme={null}
POST https://api.sixtyfour.ai/search/query
```

Runs a paginated search. Fresh searches accept `simple_filters`, `filters`, `parsed_query`, or a `search_id` to re-run a previous search.

### Request flow

1. First request: send exactly one of `simple_filters`, `filters`, `parsed_query`, or `search_id`, plus optional `page_size`, `max_results`, and exclusions (`exclude_entity_ids`, `exclude_list_ids`).
2. Next page request: send only `{"cursor":"..."}`.
3. Requests that mix `cursor` with query or pagination fields return `400`.

### Effective result cap

* `page_size` controls rows per page. Range `1..100`. Default `10`.
* `max_results` controls the total row cap across all pages. Range `1..5000`.
* `simple_filters.$limit` and `filters.size` are optional query-level caps.
* When both `max_results` and a query-level cap are set, the smaller value applies.
* When no total cap is set, the backend default applies.

### Example request

Fresh search:

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://api.sixtyfour.ai/search/query" \
    -H "x-api-key: YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "mode": "company",
      "simple_filters": {
        "hq_country_iso2": { "$eq": "US" },
        "employees_count": { "$gte": 100, "$lte": 5000 }
      }
    }'
  ```

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

  response = requests.post(
      "https://api.sixtyfour.ai/search/query",
      headers={"x-api-key": "YOUR_API_KEY"},
      json={
          "mode": "company",
          "simple_filters": {
              "hq_country_iso2": {"$eq": "US"},
              "employees_count": {"$gte": 100, "$lte": 5000},
          },
      },
  )
  print(response.json())
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch("https://api.sixtyfour.ai/search/query", {
    method: "POST",
    headers: { "x-api-key": "YOUR_API_KEY", "Content-Type": "application/json" },
    body: JSON.stringify({
      mode: "company",
      simple_filters: {
        hq_country_iso2: { $eq: "US" },
        employees_count: { $gte: 100, $lte: 5000 },
      },
    }),
  });
  const data = await response.json();
  console.log(data);
  ```
</CodeGroup>

Exclude specific people with `exclude_entity_ids`:

```json theme={null}
{
  "mode": "people",
  "parsed_query": {
    "jobTitleExperience": {
      "titles": ["VP Engineering", "Head of Engineering"],
      "searchBoth": false
    }
  },
  "exclude_entity_ids": ["john-doe-123", "https://linkedin.com/in/jane-smith-456"]
}
```

Use exclusions when re-running or refining a search and you want to avoid returning records the user has already seen. People searches also accept `exclude_public_ids` for backward compatibility. For full details — company identifiers, saved lists, and limits — see [Search Exclusions](/api-reference/search/search-exclusions).

Re-run a previous search:

```json theme={null}
{
  "search_id": "e3b0c442-98fc-1c14-9afb-f4c8996fb924"
}
```

Next page:

```json theme={null}
{
  "cursor": "eyJpZCI6I..."
}
```

<Note>`raw_source` returns the document directly. It does not use grouped objects such as `identity`, `profile`, or `location`.</Note>

## Export search results

Export results from any search as a CSV. See [Export Search Results](/api-reference/search/search-endpoints#export-search-results) for the full endpoint reference.

## Example usage

The following examples walk through the full recommended flow: discover valid fields, inspect top values for one field, then paginate through results.

<CodeGroup>
  ```bash cURL theme={null}
  API_KEY="YOUR_API_KEY"
  BASE_URL="https://api.sixtyfour.ai"

  # 1. Get filter capabilities to discover valid fields
  curl -s "$BASE_URL/search/filter-capabilities" \
    -H "x-api-key: $API_KEY" \
    | jq '[.fields[] | select(.queryable) | .field] | .[0:5]'

  # 2. Inspect top values for a field to build a simple filter
  TOP_COUNTRY=$(curl -s -X POST "$BASE_URL/search/filter-field-values" \
    -H "x-api-key: $API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"mode": "company", "field": "hq_country_iso2", "top_k": 4}' \
    | jq -r '.values[0].value')
  echo "Top country: $TOP_COUNTRY"

  # 3. Run the paginated filter search, following cursors until has_more is false
  CURSOR=""
  while true; do
    if [ -z "$CURSOR" ]; then
      PAYLOAD=$(jq -nc --arg c "$TOP_COUNTRY" \
        '{mode:"company", simple_filters:{hq_country_iso2:{"$eq":$c}, employees_count:{"$gte":100}}}')
    else
      PAYLOAD=$(jq -nc --arg cur "$CURSOR" '{cursor:$cur}')
    fi

    RESP=$(curl -s -X POST "$BASE_URL/search/query" \
      -H "x-api-key: $API_KEY" \
      -H "Content-Type: application/json" \
      -d "$PAYLOAD")

    echo "$RESP" | jq -r '"Page \(.page_number) — \(.page_count) rows"'

    HAS_MORE=$(echo "$RESP" | jq -r '.has_more')
    [ "$HAS_MORE" != "true" ] && break
    CURSOR=$(echo "$RESP" | jq -r '.next_cursor')
  done
  ```

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

  API_KEY = "YOUR_API_KEY"
  BASE_URL = "https://api.sixtyfour.ai"
  headers = {"x-api-key": API_KEY, "Content-Type": "application/json"}

  # 1. Get filter capabilities to discover valid fields
  caps = requests.get(
      f"{BASE_URL}/search/filter-capabilities",
      headers=headers,
  ).json()
  queryable_fields = [f["field"] for f in caps["fields"] if f["queryable"]][:5]
  print(f"Available queryable fields: {queryable_fields}")
  print(f"Supported simple operators: {caps['simple_query_operators']}")

  # 2. Inspect top values for a field to build a simple filter
  values_resp = requests.post(
      f"{BASE_URL}/search/filter-field-values",
      headers=headers,
      json={"mode": "company", "field": "hq_country_iso2", "top_k": 4},
  ).json()

  top_country = values_resp["values"][0]["value"]
  print(f"Top country: {values_resp['values'][0]['value']}")

  # 3. Run the paginated filter search using simple_filters
  all_results = []
  cursor = None

  while True:
      if cursor:
          payload = {"cursor": cursor}
      else:
          payload = {
              "mode": "company",
              "simple_filters": {
                  "hq_country_iso2": {"$eq": top_country},
                  "employees_count": {"$gte": 100},
              },
          }

      resp = requests.post(
          f"{BASE_URL}/search/query",
          headers=headers,
          json=payload,
      ).json()

      all_results.extend(resp["results"])
      print(f"Page {resp['page_number']} — {resp['page_count']} rows")

      if not resp["has_more"]:
          break

      cursor = resp["next_cursor"]

  print(f"Total rows fetched: {len(all_results)}")
  ```

  ```javascript JavaScript theme={null}
  const API_KEY = "YOUR_API_KEY";
  const BASE_URL = "https://api.sixtyfour.ai";
  const headers = { "x-api-key": API_KEY, "Content-Type": "application/json" };

  // 1. Get filter capabilities to discover valid fields
  const capsResp = await fetch(`${BASE_URL}/search/filter-capabilities`, { headers });
  const caps = await capsResp.json();
  const queryableFields = caps.fields.filter(f => f.queryable).slice(0, 5).map(f => f.field);
  console.log("Available queryable fields:", queryableFields);
  console.log("Supported simple operators:", caps.simple_query_operators);

  // 2. Inspect top values for a field to build a simple filter
  const valuesResp = await fetch(`${BASE_URL}/search/filter-field-values`, {
    method: "POST",
    headers,
    body: JSON.stringify({ mode: "company", field: "hq_country_iso2", top_k: 4 }),
  });
  const valuesData = await valuesResp.json();

  const topCountry = valuesData.values[0].value;
  console.log("Top country:", valuesData.values[0].value);

  // 3. Run the paginated filter search using simple_filters
  const allResults = [];
  let cursor = null;

  while (true) {
    const payload = cursor
      ? { cursor }
      : {
          mode: "company",
          simple_filters: {
            hq_country_iso2: { $eq: topCountry },
            employees_count: { $gte: 100 },
          },
        };

    const resp = await fetch(`${BASE_URL}/search/query`, {
      method: "POST",
      headers,
      body: JSON.stringify(payload),
    });
    const data = await resp.json();

    allResults.push(...data.results);
    console.log(`Page ${data.page_number} — ${data.page_count} rows`);

    if (!data.has_more) break;
    cursor = data.next_cursor;
  }

  console.log(`Total rows fetched: ${allResults.length}`);
  ```
</CodeGroup>
