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

# Search index

> Method used for querying an index.

export const Legacy = ({title, href}) => {
  return <Note>

    This page documents an earlier version of the API client.
    For the latest version, see <a href={href}>{title}</a>.

    </Note>;
};

<Legacy title="Search an index" href="/doc/libraries/sdk/methods/search/search-single-index" />

**Required ACL:** `search`

The search query only **allows for the retrieval of up to 1,000 hits**.
If you need to retrieve more than 1,000 hits,
you can either use the [`browse`](/doc/libraries/sdk/v1/methods/browse)
method or increase the [`paginationLimitedTo`](/doc/api-reference/api-parameters/paginationLimitedTo) parameter.

## Examples

### Search

<CodeGroup>
  ```cs C# theme={"system"}
  SearchIndex index = client.SearchIndex("contacts");

  // Search for "query string" in the index "contacts"
  var result = index.Search<Contact>(new Query("query string"));

  // Perform the same search, but only retrieve 50 results
  // Return only the attributes "firstname" and "lastname"
  var result = index.Search<Contact>(new Query("query string")
  {
    AttributesToRetrieve = new List<string> { "firstname", "lastname" }
    HitsPerPage = 50
  });

  // Search asynchronously
  var result = await index.SearchAsync<Contact>(new Query("query string"));
  ```

  ```go Go theme={"system"}
  index := client.InitIndex("contacts")

  // Search for "query string" in the index "contacts"
  res, err := index.Search("query string")

  // Perform the same search, but only retrieve 50 results
  // Return only the attributes "firstname" and "lastname"
  params := []interface{}{
  	opt.AttributesToRetrieve("firstname", "lastname"),
  	opt.HitsPerPage(50),
  }
  res, err := index.Search("query string", params...)
  ```

  ```java Java theme={"system"}
  SearchIndex<Contact> index = client.initIndex("contacts", Contact.class);

  // Search for "query string" in the index "contacts"
  SearchResult<Contact> results = index.search(new Query("query string"));

  // Perform the same search, but only retrieve 50 results
  // only return the attributes "firstname" and "lastname"
  SearchResult<Contact> search2 =
    index
      .search(new Query("query string")
        .setAttributesToRetrieve(Arrays.asList("firstname", "lastname"))
        .setHitsPerPage(50)
      );

  // Search asynchronously
  CompletableFuture<SearchResult<Contact>> search1 =
    index.searchAsync(new Query("query string"));
  ```

  ```js JavaScript theme={"system"}
  const client = algoliasearch("YourApplicationID", "YourSearchOnlyAPIKey");
  const index = client.initIndex("contacts");

  // Search for "query string" in the index "contacts"
  index.search("query string").then(({ hits }) => {
    console.log(hits);
  });

  // Perform the same search, but only retrieve 50 results
  // Return only the attributes "firstname" and "lastname"
  index
    .search("query string", {
      attributesToRetrieve: ["firstname", "lastname"],
      hitsPerPage: 50,
    })
    .then(({ hits }) => {
      console.log(hits);
    });
  ```

  ```kotlin Kotlin theme={"system"}
  @Serializable
  data class Contact(
      val firstname: String,
      val lastname: String
  )

  val index = client.initIndex(IndexName("contacts"))
  // Search for "query string", retrieve up to 50 results,
  // and return only the attributes "firstname" and "lastname"
  val query = queryBuilder {
      query = "query string"
      hitsPerPage = 50
      attributesToRetrieve {
          +"firstname"
          +"lastname"
      }
  }
  val result = index.search(query)

  result.hits.deserialize(Contact.serializer())
  ```

  ```php PHP theme={"system"}
  $index = $client->initIndex('contacts');

  // Search for "query string" in the index "contacts"
  $res = $index->search('query string');

  // Perform the same search but only retrieve 50 results
  // Return only the attributes "firstname" and "lastname"
  $res = $index->search('query string', [
    'attributesToRetrieve' => [
      'firstname',
      'lastname',
    ],
    'hitsPerPage' => 50
  ]);
  ```

  ```python Python theme={"system"}
  index = client.init_index("contacts")

  # Search for "query string" in the index "contacts"
  res = index.search("query string")

  # Perform the same search, but retrieve only 50 results
  # Return only the attributes "firstname" and "lastname"
  res = index.search(
      "query string",
      {"attributesToRetrieve": ["firstname", "lastname"], "hitsPerPage": 50},
  )
  ```

  ```ruby Ruby theme={"system"}
  index = client.init_index("contacts")

  # Search for 'query string' in the index 'contacts'
  res = index.search("query string")

  # Perform the same search, but retrieve only 50 results
  # Return only the attributes "firstname" and "lastname"
  res = index.search(
    "query string",
    {
      params: {
        attributesToRetrieve: "firstname,lastname",
        hitsPerPage: 50
      }
    }
  )
  ```

  ```scala Scala theme={"system"}
  client.execute {
    // Search for "query string" in the index "contacts"
    search into "contacts" query Query(
        query = Some("query string"),
    )
  }
  client.execute {
    // Perform the same search, but retrieve only 50 results
    // Return only the attributes "firstname" and "lastname"
    attributesToRetrieve = Some(Seq("firstname", "lastname")),
    hitsPerPage = Some(50)
  }
  ```

  ```swift Swift theme={"system"}
  let index = client.index(withName: "contacts")

  // Search for "query string" in the index "contacts"
  index.search(query: "query string") { result in
    if case .success(let response) = result {
      print("Response: \(response)")
    }
  }
  // Perform the same search, but retrieve only 50 results,
  // Return only the attributes "firstname" and "lastname"
  var query = Query("query string")
  query.attributesToRetrieve = ["firstname", "lastname"]
  query.hitsPerPage = 50
  index.search(query: query) { result in
    if case .success(let response) = result {
      print("Response: \(response)")
    }
  }
  ```
</CodeGroup>

### Search and send an extra header

<CodeGroup>
  ```cs C# theme={"system"}
  Index index = client.InitIndex("contacts");

  RequestOptions requestOptions = new RequestOptions
  {
      Headers = new Dictionary<string,string>{ { "X-Algolia-UserToken", "user123" } }
  };

  var result = index.Search<Contact>(new Query("query string"), requestOptions);
  ```

  ```go Go theme={"system"}
  params := []interface{}{
  	opt.AttributesToRetrieve("firstname", "lastname"),
  	opt.HitsPerPage(50),
  	opt.ExtraHeader(map[string]string{"X-Algolia-UserToken", "94.228.178.246"}),
  }

  res, err := index.Search("jimmie paint", params...)
  ```

  ```java Java theme={"system"}
  //Sync version
  SearchIndex<Contact> index = client.initIndex("INDEX_NAME", Contact.class);
  SearchResult<Contact> search =
    index
      .search(
        new Query("query string"),
        new RequestOptions().addExtraHeader("X-Algolia-UserToken", "user123")
      );

  //Async version
  AsyncIndex<Contact> index = client.initIndex("INDEX_NAME", Contact.class);
  CompletableFuture<SearchResult<Contact>> search =
    index
      .search(
        new Query("query string"),
        new RequestOptions().addExtraHeader("X-Algolia-UserToken", "user123")
      );
  ```

  ```js JavaScript theme={"system"}
  const index = client.initIndex("INDEX_NAME");

  index
    .search("query string", {
      headers: { "X-Algolia-UserToken": "user123" },
    })
    .then(({ hits }) => {
      console.log(hits);
    });
  ```

  ```kotlin Kotlin theme={"system"}
  val indexName = IndexName("contacts")
  val index = client.initIndex(indexName)
  val query = Query("query")
  val requestOptions = requestOptions {
      header("X-Algolia-User-ID", "user123")
  }

  index.search(query, requestOptions)
  ```

  ```php PHP theme={"system"}
  $index = $client->initIndex('INDEX_NAME');

  $res = $index->search('query string', [
    'hitsPerPage' => 10, // search parameter
    'X-Algolia-UserToken' => 'user123' // extra header
  ]);
  ```

  ```python Python theme={"system"}
  index = client.init_index("contacts")

  res = index.search(
      "query string",
      {
          "X-Algolia-UserToken": "user123",
          "attributesToRetrieve": ["firstname", "lastname"],
          "hitsPerPage": 20,
      },
  )
  ```

  ```ruby Ruby theme={"system"}
  index = client.init_index("contacts")

  res = index.search(
    "query string",
    {
      headers: {
        :"X-Algolia-UserToken" => "user123"
      }
    }
  )
  ```

  ```scala Scala theme={"system"}
  client.execute {
    search into "INDEX_NAME" query Query(
        query = Some("query string")
    ) options RequestOptions(
        extraHeaders = Some(Map("X-Algolia-UserToken" => "user123"))
      )
  }
  ```

  ```swift Swift theme={"system"}
  let index = client.index(withName: "INDEX_NAME")
  var requestOptions = RequestOptions()
  requestOptions.headers["X-Algolia-UserToken"] = "user123"
  index.search(query: "s", requestOptions: requestOptions) { result in
    if case .success(let response) = result {
      print("Response: \(response)")
    }
  }
  ```
</CodeGroup>

## Parameters

<ParamField body="query" type="string" required>
  The query used to search.
  Accepts every character, and every character entered will be used in the search.
  There's a hard limit of 512 characters per query. If a search query is longer, the API will return an error.

  An empty query can be used to fetch all records.
</ParamField>

<ParamField body="requestOptions" type="object">
  A mapping of request options when using this method.
</ParamField>

<ParamField body="searchParameters" type="object">
  [Search parameters](/doc/api-reference/search-api-parameters) to send with the query.
</ParamField>

## Response

<ResponseField name="abTestID" type="integer">
  If a search encounters an index that is being A/B tested, `abTestID` reports the ongoing A/B test ID.

  Returned only if [`getRankingInfo`](/doc/api-reference/api-parameters/getRankingInfo) is set to `true`.
</ResponseField>

<ResponseField name="abTestVariantID" type="integer">
  If a search encounters an index that is being A/B tested, `abTestVariantID` reports the variant ID of the index used (note, this is the ID not the name).
  The variant ID is the position in the array of variants (starting at 1).

  For example, `abTestVariantID=1` is variant A (the main index), `abTestVariantID=2` is variant B (the replica you chose when creating the A/B test, or the queries with the changed query parameters if the A/B test is based on query parameters).

  Returned only if [`getRankingInfo`](/doc/api-reference/api-parameters/getRankingInfo) is set to `true`.
</ResponseField>

<ResponseField name="aroundLatLng" type="string">
  The computed geo location. **Warning: for legacy reasons, this parameter is a string and not an object.**
  Format: `${lat},${lng}`, where the latitude and longitude are expressed as decimal floating point numbers.

  Only returned when [`aroundLatLngViaIP`](/doc/api-reference/api-parameters/aroundLatLngViaIP) or [`aroundLatLng`](/doc/api-reference/api-parameters/aroundLatLng) is set.
</ResponseField>

<ResponseField name="automaticRadius" type="string">
  The automatically computed radius. For legacy reasons, this parameter is a string and not an integer.

  Only returned for geo queries without an explicitly specified radius (see `aroundRadius`).
</ResponseField>

<ResponseField name="exhaustive" type="object">
  Whether certain properties of the search response are calculated exhaustive (exact) or approximated.

  List of fields:

  * `facetsCount`: Whether the facet count is exhaustive (`true`) or approximate (`false`).
    See the [related discussion](https://support.algolia.com/hc/en-us/articles/4406975248145-Why-are-my-facet-and-hit-counts-not-accurate-).
  * `facetValues`: The value is `false` if not all facet values are retrieved.
  * `nbHits`: Whether the `nbHits` is exhaustive (`true`) or approximate (`false`).
  * When the query takes more than 50ms to be processed, the engine makes an approximation.
    This can happen when using complex filters on millions of records, when typo-tolerance was not exhaustive, or when enough hits have been retrieved (for example, after the engine finds 10,000 exact matches).
    `nbHits` is reported as non-exhaustive whenever an approximation is made,
    even if the approximation didn't, in the end, impact the exhaustivity of the query.
  * `rulesMatch`: Rules matching exhaustivity.
    The value is `false` if rules were enable for this query, and could not be fully processed due a timeout.
    This is generally caused by the number of alternatives (such as typos) which is too large.
  * `typo`: Whether the typo search was exhaustive (`true`) or approximate (`false`).
    An approximation is done when the typo search query part takes more than 10% of the query budget (ie. 5ms by default) to be processed\n    (this can happen when a lot of typo alternatives exist for the query).\n    This field will not be included when typo-tolerance is entirely disabled.
</ResponseField>

<ResponseField name="exhaustiveFacetsCount" type="boolean" deprecated>
  See the `facetsCount` field of the [`exhaustive`](/doc/libraries/sdk/v1/methods/search#exhaustive) object in the response.
</ResponseField>

<ResponseField name="exhaustiveNbHits" type="boolean" deprecated>
  See the `nbHits` field of the [`exhaustive`](/doc/libraries/sdk/v1/methods/search#exhaustive) object in the response.
</ResponseField>

<ResponseField name="exhaustiveTypo" type="boolean" deprecated>
  See the `typo` field of the [`exhaustive`](/doc/libraries/sdk/v1/methods/search#exhaustive) object in the response.
</ResponseField>

<ResponseField name="facets" type="object">
  A mapping of each facet name to the corresponding facet counts.

  Returned only if [`facets`](/doc/api-reference/api-parameters/facets) is non-empty.
</ResponseField>

<ResponseField name="facets_stats" type="object">
  Statistics for numerical facets.

  `${facet_name}` (object): The statistics for a given facet:

  * `min` (`number`): The minimum value in the result set.
  * `max` (`number`): The maximum value in the result set.
  * `avg` (`number`): The average facet value in the result set.
  * `sum` (`number`): The sum of all values in the result set.

  Regardless of the number of requested facet values (as per [`maxValuesPerFacet`](/doc/api-reference/api-parameters/maxValuesPerFacet)),
  statistics are always computed on at most 1,000 distinct values (starting with the most frequent ones).
  If there are more than 1,000 distinct values, statistics may therefore not be 100% accurate.

  Returned only if [`facets`](/doc/api-reference/api-parameters/facets) is non-empty and at least one of the returned facets contains numerical values.
</ResponseField>

<ResponseField name="hits" type="hit[]">
  The hits returned by the search.

  Hits are ordered according to the ranking
  or sorting of the index being queried.

  Hits are made of the **schemaless** JSON objects that you stored in the index.

  However, Algolia does enrich them with a few additional fields,
  such as `_highlightResult`, `_snippetResult`, `_rankingInfo`, and `_distinctSeqID`.

  **Example:**

  ```jsonc JSON icon=braces theme={"system"}
  hits: [
    {
      field1 : "",
      field2 : "",
      // [...],

      _highlightResult: {
        // [...]
      },
      _snippetResult: {
        // [...]
      },
      _rankingInfo: {
        // [...]
      },
      _distinctSeqID:
    },
    // [...]
  ]
  ```

  <Expandable>
    <ResponseField name="_distinctSeqID" type="integer">
      When two consecutive results have the same value for the attribute
      used for "distinct", this field is used to distinguish between them.
      Only returned when [`distinct`](/doc/api-reference/api-parameters/distinct) is non-zero.
    </ResponseField>

    <ResponseField name="filters" type="integer">
      This field is reserved for advanced usage. It will be zero in most cases.
    </ResponseField>

    <ResponseField name="firstMatchedWord" type="integer">
      Position of the most important matched attribute in the attributes to index list.
      Corresponds to the `attribute` ranking criterion in the ranking formula.
    </ResponseField>

    <ResponseField name="fullyHighlighted" type="boolean">
      Whether the entire attribute value is highlighted.
    </ResponseField>

    <ResponseField name="geoDistance" type="integer">
      Distance between the geo location in the search query and the best matching
      geo location in the record,
      divided by the geo precision (in meters).
    </ResponseField>

    <ResponseField name="geoPrecision" type="integer">
      Precision used when computing the geo distance, in meters.
      All distances will be floored to a multiple of this precision.
    </ResponseField>

    <ResponseField name="matchedGeoLocation" type="object">
      Geo location that matched the query.

      * lat: Latitude of the matched location.
      * lng: Longitude of the matched location.
      * distance: Distance between the matched location and the search location (in meters).
        Contrary to `geoDistance`, this value is *not* divided by the geo precision.

      Only returned if [`aroundRadius`](/doc/api-reference/api-parameters/aroundRadius) is used.

      **Example:**

      ```jsonc JSON icon=braces theme={"system"}
      {
        "lat": 51.148056,
        "lng": -0.190278,
        "distance": 35
      }
      ```
    </ResponseField>

    <ResponseField name="matchedWords" type="string[]">
      List of words *from the query* that matched the object.
    </ResponseField>

    <ResponseField name="matchLevel" type="string">
      Indicates how well the attribute matched the search query.
      Can be: `none` or `partial` or `full`.
      See [highlightResult matchLevel](/doc/libraries/sdk/v1/methods/search#match-level) for more details.
    </ResponseField>

    <ResponseField name="nbExactWords" type="integer">
      Number of exactly matched words.
      If `alternativesAsExact` is set, it may include plurals, synonyms, or both.
    </ResponseField>

    <ResponseField name="nbTypos" type="integer">
      Number of typos encountered when matching the record.
      Corresponds to the `typos` ranking criterion in the ranking formula
    </ResponseField>

    <ResponseField name="promoted" type="boolean">
      Present and set to `true` if a Rule promoted the hit.
    </ResponseField>

    <ResponseField name="proximityDistance" type="integer">
      When the query contains more than one word, the sum of the distances
      between matched words (in meters).
      Corresponds to the `proximity` criterion in the ranking formula.
    </ResponseField>

    <ResponseField name="userScore" type="integer">
      Custom ranking for the object, expressed as a single integer value.
      This field is internal to Algolia and shouldn't be relied upon.
    </ResponseField>

    <ResponseField name="value" type="string">
      Markup text with occurrences highlighted.
      The tags used for highlighting are specified
      via [`highlightPreTag`](/doc/api-reference/api-parameters/highlightPreTag) and [`highlightPostTag`](/doc/api-reference/api-parameters/highlightPostTag).
      The text used to indicate ellipsis is specified via [`snippetEllipsisText`](/doc/api-reference/api-parameters/snippetEllipsisText).
    </ResponseField>

    <ResponseField name="words" type="integer">
      Number of matched words, including prefixes and typos.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="hitsPerPage" type="integer">
  The maximum number of hits returned per page.
  See the [`hitsPerPage`](/doc/api-reference/api-parameters/hitsPerPage) search parameter.

  Not returned if you use `offset` and `length` for pagination.
</ResponseField>

<ResponseField name="indexUsed" type="string">
  Index name used for the query.
  In the case of an A/B test, the targeted index isn't always the index used by the query.

  Returned only if [`getRankingInfo`](/doc/api-reference/api-parameters/getRankingInfo) is set to `true`.
</ResponseField>

<ResponseField name="message" type="string">
  Used to return warnings about the query.
</ResponseField>

<ResponseField name="nbHits" type="integer">
  The number of hits matched by the query.
</ResponseField>

<ResponseField name="nbPages" type="integer">
  The number of returned pages. Calculation is based on the total number of hits (`nbHits`)
  divided by the number of hits per page (`hitsPerPage`), rounded up to the nearest integer.

  Not returned if you use `offset` and `length` for pagination.
</ResponseField>

<ResponseField name="nbSortedHits" type="integer">
  The number of hits selected and sorted by the [relevant sort](/doc/guides/managing-results/refine-results/sorting/in-depth/relevant-sort) algorithm.

  Only returned when searching on a virtual replica.
</ResponseField>

<ResponseField name="page" type="integer">
  Index of the current page (zero-based). See the [`page`](/doc/api-reference/api-parameters/page) search parameter.

  Not returned if you use `offset`/`length` for pagination.
</ResponseField>

<ResponseField name="params" type="string">
  A url-encoded string of all search parameters.
</ResponseField>

<ResponseField name="parsedQuery" type="string">
  The query string that will be searched, after [normalization](/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/normalization#what-is-normalization).
  Normalization includes removing stop words (if [`removeStopWords`](/doc/api-reference/api-parameters/removeStopWords) is enabled),
  and transforming portions of the query string into phrase queries (see [`advancedSyntax`](/doc/api-reference/api-parameters/advancedSyntax)).

  Returned only if [`getRankingInfo`](/doc/api-reference/api-parameters/getRankingInfo) is set to `true`.
</ResponseField>

<ResponseField name="processingTimeMS" type="integer">
  Time the server took to process the search request, in milliseconds.
  This doesn't include network time.
</ResponseField>

<ResponseField name="processingTimingsMS" type="object">
  List of processing steps and their times, in milliseconds. You can use this list to investigate performance issues.

  <Info>
    This parameter is **experimental**.
    Fields may change without further notice and may be different for different Algolia servers.
    The list of steps is not exhaustive.
  </Info>
</ResponseField>

<ResponseField name="query" type="string">
  An echo of the query text. See the [`query`](/doc/api-reference/api-parameters/query) search parameter.
</ResponseField>

<ResponseField name="queryAfterRemoval" type="string">
  A markup text indicating which parts of the original query have been removed
  in order to retrieve a non-empty result set.

  The removed parts are surrounded by `<em>` tags.

  Only returned when [`removeWordsIfNoResults`](/doc/api-reference/api-parameters/removeWordsIfNoResults)
  is set to `lastWords` or `firstWords`.
</ResponseField>

<ResponseField name="queryID" type="string">
  Unique identifier of the search query,
  for [sending events to the Insights API](/doc/guides/sending-events/getting-started).

  Returned only if [`clickAnalytics`](/doc/api-reference/api-parameters/clickAnalytics) is `true`.
</ResponseField>

<ResponseField name="serverTimeMS" type="integer">
  Time the server took to process the complete request, in milliseconds.
  This does not include network time.
</ResponseField>

<ResponseField name="serverUsed" type="string">
  Actual host name of the server that processed the request.
  The DNS supports automatic failover and load balancing,
  so this may differ from the host name used in the request.

  Returned only if [`getRankingInfo`](/doc/api-reference/api-parameters/getRankingInfo) is set to `true`.
</ResponseField>

<ResponseField name="timeoutCounts" type="boolean" deprecated>
  Use the `facetsCount` field of the [`exhaustive`](/doc/libraries/sdk/v1/methods/search#exhaustive) object in the response.

  Returned only if [`getRankingInfo`](/doc/api-reference/api-parameters/getRankingInfo) is set to `true`.
</ResponseField>

<ResponseField name="timeoutHits" type="boolean" deprecated>
  Please use `exhaustiveHitsCount` instead.

  Returned only if [`getRankingInfo`](/doc/api-reference/api-parameters/getRankingInfo) is set to `true`.
</ResponseField>

<ResponseField name="userData" type="object[]">
  Array of [`userData`](/doc/libraries/sdk/v1/methods/save-rule#param-user-data)
  objects.

  Only returned if at least one rule containing a custom [`userData`](/doc/libraries/sdk/v1/methods/save-rule#param-user-data)
  consequence was applied.
</ResponseField>

### Response as JSON

This section shows the JSON response returned by the API.
Each API client wraps this response in language-specific objects, so the structure may vary.
To view the response, use the `getLogs` method.
Don't rely on the order of properties—JSON objects don't preserve key order.

```jsonc JSON icon=braces theme={"system"}
{
  "hits": [
    {
      "firstname": "Jimmie",
      "lastname": "Barninger",
      "objectID": "433",
      "_highlightResult": {
        "firstname": {
          "value": "<em>Jimmie</em>",
          "matchLevel": "partial"
        },
        "lastname": {
          "value": "Barninger",
          "matchLevel": "none"
        },
        "company": {
          "value": "California <em>Paint</em> & Wlpaper Str",
          "matchLevel": "partial"
        }
      }
    }
  ],
  "page": 0,
  "nbHits": 1,
  "nbPages": 1,
  "hitsPerPage": 20,
  "processingTimeMS": 1,
  "query": "jimmie paint",
  "params": "query=jimmie+paint&attributesToRetrieve=firstname,lastname&hitsPerPage=50"
}
```
