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

# Business Search query syntax

> Business Search structured query reference: seven operators, and, or, not, equals, in, range and text, plus nesting and text matching rules.

A Bright Data Business Search structured query is the JSON object passed as `query` when `mode` is `ludicrous`. The query uses seven operators. `equals`, `in`, `range` and `text` each take a field name and a value and produce one condition. `and`, `or` and `not` take conditions and combine them.

This page describes each operator's value shape, how operators nest, which operators each field type accepts and the validation errors a malformed query returns. Field names are listed on [Company search](/products/business-search/company-search#searchable-fields) and [People search](/products/business-search/people-search#searchable-fields).

## Which operators does a structured query accept?

| Operator | Value shape                                                            | Meaning                                        | Example                                                                          |
| -------- | ---------------------------------------------------------------------- | ---------------------------------------------- | -------------------------------------------------------------------------------- |
| `and`    | Array of conditions                                                    | All child conditions must match                | `{ "and": [ ... ] }`                                                             |
| `or`     | Array of conditions                                                    | At least one child condition must match        | `{ "or": [ ... ] }`                                                              |
| `not`    | One condition                                                          | Exclude records that match the child condition | `{ "not": { "equals": { "organization_type": "Educational" } } }`                |
| `equals` | Field name and one scalar                                              | Match an exact value on a typed field          | `{ "equals": { "headquarters_country_code": "US" } }`                            |
| `in`     | Field name and an array                                                | Match any value in the list on a typed field   | `{ "in": { "headquarters_country_code": ["US", "GB"] } }`                        |
| `range`  | Field name and an object with `>`, `>=`, `<` or `<=`                   | Match numeric bounds on a typed field          | `{ "range": { "employees_in_linkedin": { ">=": 50, "<=": 500 } } }`              |
| `text`   | Field name and a string, or an object with `value`, `mode` and `top-k` | Match words in a text field                    | `{ "text": { "current_title": { "value": "product manager", "mode": "all" } } }` |

`and`, `or` and `not` take conditions as children. `equals`, `in`, `range` and `text` take a field name and a value. The `text` example uses `current_title`, a people field. The other examples use company fields.

## How do you combine conditions?

Logical operators nest. In the request below, an `or` condition is a child of `and`. This company request matches software or technology companies in the US or GB, excluding records whose organization type is `Educational`. The highlighted lines are the `query` object:

<CodeGroup>
  ```bash cURL highlight={6-17} theme={null}
  curl --request POST "https://api.brightdata.com/search/company" \
    --header "Authorization: Bearer $BRIGHTDATA_API_KEY" \
    --header "Content-Type: application/json" \
    --data '{
      "mode": "ludicrous",
      "query": {
        "and": [
          {
            "or": [
              { "text": { "industry": "software" } },
              { "text": { "industry": "technology" } }
            ]
          },
          { "in": { "headquarters_country_code": ["US", "GB"] } },
          { "not": { "equals": { "organization_type": "Educational" } } }
        ]
      },
      "limit": 3,
      "view": "summary"
    }'
  ```

  ```python Python highlight={12-23} theme={null}
  import os
  import requests

  response = requests.post(
      "https://api.brightdata.com/search/company",
      headers={
          "Authorization": f"Bearer {os.environ['BRIGHTDATA_API_KEY']}",
          "Content-Type": "application/json",
      },
      json={
        "mode": "ludicrous",
        "query": {
          "and": [
            {
              "or": [
                { "text": { "industry": "software" } },
                { "text": { "industry": "technology" } }
              ]
            },
            { "in": { "headquarters_country_code": ["US", "GB"] } },
            { "not": { "equals": { "organization_type": "Educational" } } }
          ]
        },
        "limit": 3,
        "view": "summary"
      },
  )
  print(response.text)
  ```

  ```javascript Node.js highlight={9-20} theme={null}
  const response = await fetch("https://api.brightdata.com/search/company", {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${process.env.BRIGHTDATA_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      "mode": "ludicrous",
      "query": {
        "and": [
          {
            "or": [
              { "text": { "industry": "software" } },
              { "text": { "industry": "technology" } }
            ]
          },
          { "in": { "headquarters_country_code": ["US", "GB"] } },
          { "not": { "equals": { "organization_type": "Educational" } } }
        ]
      },
      "limit": 3,
      "view": "summary"
    }),
  });
  console.log(await response.text());
  ```
</CodeGroup>

`in` on one field matches the same records as an `or` of `equals` conditions on that field.

## How does text matching work?

A `text` condition contains a string, as in the company request above, or an object with `value` and `mode`. `mode: "all"` requires every word in `value` to appear in the field, in any order and position. This people request matches titles containing all of `machine`, `learning` and `engineer`:

<CodeGroup>
  ```bash cURL highlight={6-13} theme={null}
  curl --request POST "https://api.brightdata.com/search/people" \
    --header "Authorization: Bearer $BRIGHTDATA_API_KEY" \
    --header "Content-Type: application/json" \
    --data '{
      "mode": "ludicrous",
      "query": {
        "text": {
          "current_title": {
            "value": "machine learning engineer",
            "mode": "all"
          }
        }
      },
      "limit": 3,
      "view": "summary"
    }'
  ```

  ```python Python highlight={12-19} theme={null}
  import os
  import requests

  response = requests.post(
      "https://api.brightdata.com/search/people",
      headers={
          "Authorization": f"Bearer {os.environ['BRIGHTDATA_API_KEY']}",
          "Content-Type": "application/json",
      },
      json={
        "mode": "ludicrous",
        "query": {
          "text": {
            "current_title": {
              "value": "machine learning engineer",
              "mode": "all"
            }
          }
        },
        "limit": 3,
        "view": "summary"
      },
  )
  print(response.text)
  ```

  ```javascript Node.js highlight={9-16} theme={null}
  const response = await fetch("https://api.brightdata.com/search/people", {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${process.env.BRIGHTDATA_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      "mode": "ludicrous",
      "query": {
        "text": {
          "current_title": {
            "value": "machine learning engineer",
            "mode": "all"
          }
        }
      },
      "limit": 3,
      "view": "summary"
    }),
  });
  console.log(await response.text());
  ```
</CodeGroup>

`mode` takes one of these values. No mode matches an exact phrase:

| Mode       | Behavior                             |
| ---------- | ------------------------------------ |
| `top-bm25` | Default. BM25-ranked partial matches |
| `all`      | Every search word must match         |
| `any`      | Any search word may match            |

`top-k` caps how many candidate records the text condition retrieves, 100 by default.

## How do you express a numeric bound?

`range` takes a field name and one or two comparison keys. Two keys give a closed interval. This company request matches 50 to 500 employees on record:

<CodeGroup>
  ```bash cURL highlight={6-10} theme={null}
  curl --request POST "https://api.brightdata.com/search/company" \
    --header "Authorization: Bearer $BRIGHTDATA_API_KEY" \
    --header "Content-Type: application/json" \
    --data '{
      "mode": "ludicrous",
      "query": {
        "range": {
          "employees_in_linkedin": { ">=": 50, "<=": 500 }
        }
      },
      "limit": 3,
      "view": "summary"
    }'
  ```

  ```python Python highlight={12-16} theme={null}
  import os
  import requests

  response = requests.post(
      "https://api.brightdata.com/search/company",
      headers={
          "Authorization": f"Bearer {os.environ['BRIGHTDATA_API_KEY']}",
          "Content-Type": "application/json",
      },
      json={
        "mode": "ludicrous",
        "query": {
          "range": {
            "employees_in_linkedin": { ">=": 50, "<=": 500 }
          }
        },
        "limit": 3,
        "view": "summary"
      },
  )
  print(response.text)
  ```

  ```javascript Node.js highlight={9-13} theme={null}
  const response = await fetch("https://api.brightdata.com/search/company", {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${process.env.BRIGHTDATA_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      "mode": "ludicrous",
      "query": {
        "range": {
          "employees_in_linkedin": { ">=": 50, "<=": 500 }
        }
      },
      "limit": 3,
      "view": "summary"
    }),
  });
  console.log(await response.text());
  ```
</CodeGroup>

One key gives an open bound, such as `{ "followers": { ">=": 1000 } }`.

## Which operators does each field type accept?

The operator a field accepts depends on the field type. Sending an operator the type does not support returns HTTP 400 with a message naming the field, the operator and the types the operator supports.

| Field type             | Example fields                                                            | Operators accepted      | Example rejection                                                                                                    |
| ---------------------- | ------------------------------------------------------------------------- | ----------------------- | -------------------------------------------------------------------------------------------------------------------- |
| Text                   | `industry`, `current_title`                                               | `text`                  | `equals` on `industry` returns `Operator does not support field type 'text'`                                         |
| Typed (string, number) | `headquarters_country_code`, `city`, `employees_in_linkedin`, `followers` | `equals`, `in`, `range` | `text` on `headquarters_country_code` returns `Operator does not support field type 'string'. Supported types: text` |

Field names differ by category. The full lists are on [Company search](/products/business-search/company-search#searchable-fields) and [People search](/products/business-search/people-search#searchable-fields). A field that appears in `view` output is not necessarily searchable: people `connections` is returned in `summary` but cannot be used in a `range` condition.

## Which queries are rejected?

Business Search validates the request before running a search. A rejected request returns HTTP 400 with a message naming the property at fault. The request is not searched and not billed.

| Rule                                                                     | What happens                                                                               |
| ------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------ |
| `query` must be an object in Ludicrous and a string in Instant and Smart | HTTP 400: `request: "query" must be of type object` or `request: "query" must be a string` |
| `equals`, `in` and `range` work only on typed fields                     | HTTP 400: `Operator does not support field type 'text'`                                    |
| `text` works only on text fields                                         | HTTP 400: `Operator does not support field type 'string'. Supported types: text`           |
| `mode` inside `text` must be an accepted value                           | HTTP 400 listing the accepted values                                                       |

Rejections outside the `query` object, such as an invalid `limit`, an unknown `view` field or a natural-language query longer than 200 characters, are listed under [Why was a request rejected?](/products/business-search/error-codes#why-was-a-request-rejected) on the Business Search error codes page.

## Frequently asked questions

### Does the query object change between company and people searches?

The operators are identical. The field names are not. The company category uses `industry`, `headquarters_country_code` and `linkedin_followers`. The people category uses `current_title`, `country_code` and `followers`. See [Company search](/products/business-search/company-search) and [People search](/products/business-search/people-search).

### Can I use a structured query with Instant or Smart mode?

No. `ludicrous` takes a structured object, and `instant` and `smart` take a natural-language string. A mismatch is rejected with HTTP 400: an object in Instant returns `request: "query" must be a string`, and a string in Ludicrous returns `request: "query" must be of type object`. See [What is Business Search?](/products/business-search/introduction#search-modes).

## Related

* [Company search](/products/business-search/company-search)
* [People search](/products/business-search/people-search)
* [Business Search field views](/products/business-search/select-fields)
* [Business Search error codes](/products/business-search/error-codes)
* [What is Business Search?](/products/business-search/introduction)
