---
type: api
title: Run multiple templated searches
description: **All methods and paths for this operation:**
url: https://www.elastic.co/elastic/docs-builder/docs/4371/api/doc/elasticsearch/v8/operation/operation-msearch-template
resource: https://www.elastic.co/elastic/docs-builder/docs/4371/api/doc/elasticsearch/v8/operation/operation-msearch-template
products:
  - Elasticsearch
---

# Run multiple templated searches


Availability: 5.0+

## Paths

- `POST` (also `GET`) `/{index}/_msearch/template`
- `POST` (also `GET`) `/_msearch/template`

- [Api key auth](/elastic/docs-builder/docs/4371/api/doc/elasticsearch/v8/authentication#apikeyauth)
- [Basic auth](/elastic/docs-builder/docs/4371/api/doc/elasticsearch/v8/authentication#basicauth)
- [Bearer auth](/elastic/docs-builder/docs/4371/api/doc/elasticsearch/v8/authentication#bearerauth)

#### Path Parameters

- `index` (union IndexName | [] IndexName) — optional, leave it out to use `/_msearch/template`
  A comma-separated list of data streams, indices, and aliases to search.
It supports wildcards (`*`).
To search all data streams and indices, omit this parameter or use `*`.

## Description

Run multiple templated searches with a single request.
If you are providing a text file or text input to `curl`, use the `--data-binary` flag instead of `-d` to preserve newlines.
For example:

```
$ cat requests
{ "index": "my-index" }
{ "id": "my-search-template", "params": { "query_string": "hello world", "from": 0, "size": 10 }}
{ "index": "my-other-index" }
{ "id": "my-other-search-template", "params": { "query_type": "match_all" }}

$ curl -H "Content-Type: application/x-ndjson" -XGET localhost:9200/_msearch/template --data-binary "@requests"; echo
```

## Required authorization

* Index privileges: `read`

[Read the reference documentation](https://www.elastic.co/guide/en/elasticsearch/reference/8.19/search-template.html)

## Query String Parameters

- `ccs_minimize_roundtrips` (boolean · default: true)
  If `true`, network round-trips are minimized for cross-cluster search requests.
- `max_concurrent_searches` (number)
  The maximum number of concurrent searches the API can run.
- `search_type` (enum SearchType)
  The type of the search operation.

Supported values include:
  - `query_then_fetch`: Documents are scored using local term and document frequencies for the shard. This is usually faster but less accurate.
  - `dfs_query_then_fetch`: Documents are scored using global term and document frequencies across all shards. This is usually slower but more accurate.
  Values: `query_then_fetch`, `dfs_query_then_fetch`
- `rest_total_hits_as_int` (boolean · default: false)
  If `true`, the response returns `hits.total` as an integer.
If `false`, it returns `hits.total` as an object.
- `typed_keys` (boolean · default: false)
  If `true`, the response prefixes aggregation and suggester names with their respective types.

## Request Body

`application/json`

An array; each item is one of:
- **MultisearchHeader**
  Contains parameters used to limit or change the subsequent search body request.
  - `allow_no_indices` (boolean) — optional
  - `expand_wildcards` (string ExpandWildcards) — optional
    

Supported values include:
  - `all`: Match any data stream or index, including hidden ones.
  - `open`: Match open, non-hidden indices. Also matches any non-hidden data stream.
  - `closed`: Match closed, non-hidden indices. Also matches any non-hidden data stream. Data streams cannot be closed.
  - `hidden`: Match hidden data streams and hidden indices. Must be combined with `open`, `closed`, or `both`.
  - `none`: Wildcard expressions are not accepted.
    Values: `all`, `open`, `closed`, `hidden`, `none`
  - `ignore_unavailable` (boolean) — optional
  - `index` (string Indices) — optional
  - `preference` (string) — optional
  - `request_cache` (boolean) — optional
  - `routing` (string Routing) — optional
  - `search_type` (enum SearchType) — optional
    

Supported values include:
  - `query_then_fetch`: Documents are scored using local term and document frequencies for the shard. This is usually faster but less accurate.
  - `dfs_query_then_fetch`: Documents are scored using global term and document frequencies across all shards. This is usually slower but more accurate.
    Values: `query_then_fetch`, `dfs_query_then_fetch`
  - `ccs_minimize_roundtrips` (boolean) — optional
  - `allow_partial_search_results` (boolean) — optional
  - `ignore_throttled` (boolean) — optional
- **TemplateConfig**
  - `explain` (boolean · default: false) — optional
    If `true`, returns detailed information about score calculation as part of each hit.
  - `id` (string Id) — optional
    The ID of the search template to use. If no `source` is specified,
this parameter is required.
  - `params` (map string to object) — optional
    Key-value pairs used to replace Mustache variables in the template.
The key is the variable name.
The value is the variable value.
  - `profile` (boolean · default: false) — optional
    If `true`, the query execution is profiled.
  - `source` (string) — optional
    An inline search template. Supports the same parameters as the search API's
request body. It also supports Mustache variables. If no `id` is specified, this
parameter is required.

## Response

`application/json`

- `took` (number)
- `responses` ([] union ResponseItem)
  - **MultiSearchItem**
    - `took` (number)
      The number of milliseconds it took Elasticsearch to run the request.
This value is calculated by measuring the time elapsed between receipt of a request on the coordinating node and the time at which the coordinating node is ready to send the response.
It includes:

* Communication time between the coordinating node and data nodes
* Time the request spends in the search thread pool, queued for execution
* Actual run time

It does not include:

* Time needed to send the request to Elasticsearch
* Time needed to serialize the JSON response
* Time needed to send the response to a client
    - `timed_out` (boolean)
      If `true`, the request timed out before completion; returned results may be partial or empty.
    - `_shards` ({} ShardStatistics)
      A count of shards used for the request.
      - `failed` (number uint)
        The number of shards the operation or search attempted to run on but failed.
      - `successful` (number uint)
        The number of shards the operation or search succeeded on.
      - `total` (number uint)
        The number of shards the operation or search will run on overall.
      - `failures` ([] ShardFailure)
        - `index` (string IndexName)
        - `node` (string)
        - `reason` ({} ErrorCause)
          - `type` (string)
            The type of error
          - `reason` (union string) — nullable
            A human-readable explanation of the error, in English.
            One of: `string`
          - `stack_trace` (string)
            The server stack trace. Present only if the `error_trace=true` parameter was sent with the request.
          - `caused_by` ({} ErrorCause) — recursive
            Same fields as `reason` in `failures`
          - `root_cause` ([] ErrorCause) — recursive
            Same fields as `reason` in `failures`
          - `suppressed` ([] ErrorCause) — recursive
            Same fields as `reason` in `failures`
        - `shard` (number)
        - `status` (string)
        - `primary` (boolean)
      - `skipped` (number uint)
    - `hits` ({} HitsMetadata)
      The returned documents and metadata.
      - `total` (union oneOf)
        Total hit count information, present only if `track_total_hits` wasn't `false` in the search request.
        - **TotalHits**
          - `relation` (enum TotalHitsRelation)
            

Supported values include:
  - `eq`: Accurate
  - `gte`: Lower bound, including returned events or sequences
            Values: `eq`, `gte`
          - `value` (number)
        - **number**
      - `hits` ([] Hit)
        - `_index` (string IndexName)
        - `_id` (string Id)
        - `_score` (union number | string) — nullable
        - `_explanation` ({} Explanation)
          - `description` (string)
          - `details` ([] ExplanationDetail)
            - `description` (string)
            - `details` ([] ExplanationDetail) — recursive
              Same fields as `details` in `_explanation`
            - `value` (number)
          - `value` (number)
        - `fields` (map string to object)
        - `highlight` (map string to string)
        - `inner_hits` (map string to InnerHitsResult)
          Map values ({} InnerHitsResult)
          - `hits` ({} HitsMetadata) — recursive
            Same fields as `hits` in `MultiSearchItem`
        - `matched_queries` (union oneOf)
          One of: `string[]` or `string to number`
        - `_nested` ({} NestedIdentity)
          - `field` (string Field)
          - `offset` (number)
          - `_nested` ({} NestedIdentity) — recursive
            Same fields as `_nested` in `hits`
        - `_ignored` ([] string)
        - `ignored_field_values` (map string to FieldValue)
        - `_shard` (string)
        - `_node` (string)
        - `_routing` (string)
        - `_source` (object)
        - `_rank` (number)
        - `_seq_no` (number SequenceNumber)
        - `_primary_term` (number)
        - `_version` (number VersionNumber)
        - `sort` (SortResults)
      - `max_score` (union number | string) — nullable
    - `aggregations` (map string to {} Aggregate)
      See [Aggregate](https://www.elastic.co/elastic/docs-builder/docs/4371/api/doc/elasticsearch/v8/types/_types-aggregations-aggregate)
    - `_clusters` ({} ClusterStatistics)
      - `skipped` (number)
      - `successful` (number)
      - `total` (number)
      - `running` (number)
      - `partial` (number)
      - `failed` (number)
      - `details` (map string to ClusterDetails)
        Map values ({} ClusterDetails)
        - `status` (enum ClusterSearchStatus)
          Values: `running`, `successful`, `partial`, `skipped`, `failed`
        - `indices` (string)
        - `took` (DurationValueUnitMillis)
        - `timed_out` (boolean)
        - `_shards` ({} ShardStatistics)
          Same fields as `_shards` in `MultiSearchItem`
        - `failures` ([] ShardFailure)
          Same fields as `failures` in `_shards`
    - `fields` (map string to object)
    - `max_score` (number)
    - `num_reduce_phases` (number)
    - `profile` ({} Profile)
      - `shards` ([] ShardProfile)
        - `aggregations` ([] AggregationProfile)
          - `breakdown` ({} AggregationBreakdown)
            - `build_aggregation` (number)
            - `build_aggregation_count` (number)
            - `build_leaf_collector` (number)
            - `build_leaf_collector_count` (number)
            - `collect` (number)
            - `collect_count` (number)
            - `initialize` (number)
            - `initialize_count` (number)
            - `post_collection` (number)
            - `post_collection_count` (number)
            - `reduce` (number)
            - `reduce_count` (number)
          - `description` (string)
          - `time_in_nanos` (DurationValueUnitNanos)
          - `type` (string)
          - `debug` ({} AggregationProfileDebug)
            - `segments_with_multi_valued_ords` (number)
            - `collection_strategy` (string)
            - `segments_with_single_valued_ords` (number)
            - `total_buckets` (number)
            - `built_buckets` (number)
            - `result_strategy` (string)
            - `has_filter` (boolean)
            - `delegate` (string)
            - `delegate_debug` ({} AggregationProfileDebug) — recursive
              Same fields as `debug` in `aggregations`
            - `chars_fetched` (number)
            - `extract_count` (number)
            - `extract_ns` (number)
            - `values_fetched` (number)
            - `collect_analyzed_ns` (number)
            - `collect_analyzed_count` (number)
            - `surviving_buckets` (number)
            - `ordinals_collectors_used` (number)
            - `ordinals_collectors_overhead_too_high` (number)
            - `string_hashing_collectors_used` (number)
            - `numeric_collectors_used` (number)
            - `empty_collectors_used` (number)
            - `deferred_aggregators` ([] string)
            - `segments_with_doc_count_field` (number)
            - `segments_with_deleted_docs` (number)
            - `filters` ([] AggregationProfileDelegateDebugFilter)
              - `results_from_metadata` (number)
              - `query` (string)
              - `specialized_for` (string)
              - `segments_counted_in_constant_time` (number)
            - `segments_counted` (number)
            - `segments_collected` (number)
            - `map_reducer` (string)
            - `brute_force_used` (number)
            - `dynamic_pruning_attempted` (number)
            - `dynamic_pruning_used` (number)
            - `skipped_due_to_no_data` (number)
          - `children` ([] AggregationProfile) — recursive
            Same fields as `aggregations` in `shards`
        - `cluster` (string)
        - `dfs` ({} DfsProfile)
          - `statistics` ({} DfsStatisticsProfile)
            - `type` (string)
            - `description` (string)
            - `time` (string Duration)
            - `time_in_nanos` (DurationValueUnitNanos)
            - `breakdown` ({} DfsStatisticsBreakdown)
              - `collection_statistics` (number)
              - `collection_statistics_count` (number)
              - `create_weight` (number)
              - `create_weight_count` (number)
              - `rewrite` (number)
              - `rewrite_count` (number)
              - `term_statistics` (number)
              - `term_statistics_count` (number)
            - `debug` (map string to object)
            - `children` ([] DfsStatisticsProfile) — recursive
              Same fields as `statistics` in `dfs`
          - `knn` ([] DfsKnnProfile)
            - `vector_operations_count` (number)
            - `query` ([] KnnQueryProfileResult)
              - `type` (string)
              - `description` (string)
              - `time` (string Duration)
              - `time_in_nanos` (DurationValueUnitNanos)
              - `breakdown` ({} KnnQueryProfileBreakdown)
                - `advance` (number)
                - `advance_count` (number)
                - `build_scorer` (number)
                - `build_scorer_count` (number)
                - `compute_max_score` (number)
                - `compute_max_score_count` (number)
                - `count_weight` (number)
                - `count_weight_count` (number)
                - `create_weight` (number)
                - `create_weight_count` (number)
                - `match` (number)
                - `match_count` (number)
                - `next_doc` (number)
                - `next_doc_count` (number)
                - `score` (number)
                - `score_count` (number)
                - `set_min_competitive_score` (number)
                - `set_min_competitive_score_count` (number)
                - `shallow_advance` (number)
                - `shallow_advance_count` (number)
              - `debug` (map string to object)
              - `children` ([] KnnQueryProfileResult) — recursive
                Same fields as `query` in `knn`
            - `rewrite_time` (number)
            - `collector` ([] KnnCollectorResult)
              - `name` (string)
              - `reason` (string)
              - `time` (string Duration)
              - `time_in_nanos` (DurationValueUnitNanos)
              - `children` ([] KnnCollectorResult) — recursive
                Same fields as `collector` in `knn`
        - `fetch` ({} FetchProfile)
          - `type` (string)
          - `description` (string)
          - `time_in_nanos` (DurationValueUnitNanos)
          - `breakdown` ({} FetchProfileBreakdown)
            - `load_source` (number)
            - `load_source_count` (number)
            - `load_stored_fields` (number)
            - `load_stored_fields_count` (number)
            - `next_reader` (number)
            - `next_reader_count` (number)
            - `process_count` (number)
            - `process` (number)
          - `debug` ({} FetchProfileDebug)
            - `stored_fields` ([] string)
            - `fast_path` (number)
          - `children` ([] FetchProfile) — recursive
            Same fields as `fetch` in `shards`
        - `id` (string)
        - `index` (string IndexName)
        - `node_id` (string)
        - `searches` ([] SearchProfile)
          - `collector` ([] Collector)
            - `name` (string)
            - `reason` (string)
            - `time_in_nanos` (DurationValueUnitNanos)
            - `children` ([] Collector) — recursive
              Same fields as `collector` in `searches`
          - `query` ([] QueryProfile)
            - `breakdown` ({} QueryBreakdown)
              - `advance` (number)
              - `advance_count` (number)
              - `build_scorer` (number)
              - `build_scorer_count` (number)
              - `create_weight` (number)
              - `create_weight_count` (number)
              - `match` (number)
              - `match_count` (number)
              - `shallow_advance` (number)
              - `shallow_advance_count` (number)
              - `next_doc` (number)
              - `next_doc_count` (number)
              - `score` (number)
              - `score_count` (number)
              - `compute_max_score` (number)
              - `compute_max_score_count` (number)
              - `count_weight` (number)
              - `count_weight_count` (number)
              - `set_min_competitive_score` (number)
              - `set_min_competitive_score_count` (number)
            - `description` (string)
            - `time_in_nanos` (DurationValueUnitNanos)
            - `type` (string)
            - `children` ([] QueryProfile) — recursive
              Same fields as `query` in `searches`
          - `rewrite_time` (number)
        - `shard_id` (number)
    - `pit_id` (string Id)
    - `_scroll_id` (string ScrollId)
      The identifier for the search and its search context.
You can use this scroll ID with the scroll API to retrieve the next batch of search results for the request.
This property is returned only if the `scroll` query parameter is specified in the request.
    - `suggest` (map string to Suggest)
    - `terminated_early` (boolean)
    - `status` (number)
  - **ErrorResponseBase**
    The response returned by Elasticsearch when request execution did not succeed.
    - `error` ({} ErrorCause)
      - `type` (string)
        The type of error
      - `reason` (union string) — nullable
        A human-readable explanation of the error, in English.
        One of: `string`
      - `stack_trace` (string)
        The server stack trace. Present only if the `error_trace=true` parameter was sent with the request.
      - `caused_by` ({} ErrorCause) — recursive
        Same fields as `error` in `ErrorResponseBase`
      - `root_cause` ([] ErrorCause) — recursive
        Same fields as `error` in `ErrorResponseBase`
      - `suppressed` ([] ErrorCause) — recursive
        Same fields as `error` in `ErrorResponseBase`
    - `status` (number)
## Code Examples

#### Console

```console
POST my-index/_msearch/template
{ }
{ "id": "my-search-template", "params": { "query_string": "hello world", "from": 0, "size": 10 }}
{ }
{ "id": "my-other-search-template", "params": { "query_type": "match_all" }}
```

#### JavaScript

```javascript
const response = await client.msearchTemplate({
  index: "my-index",
  search_templates: [
    {},
    {
      id: "my-search-template",
      params: {
        query_string: "hello world",
        from: 0,
        size: 10,
      },
    },
    {},
    {
      id: "my-other-search-template",
      params: {
        query_type: "match_all",
      },
    },
  ],
});
```

#### Python

```python
resp = client.msearch_template(
    index="my-index",
    search_templates=[
        {},
        {
            "id": "my-search-template",
            "params": {
                "query_string": "hello world",
                "from": 0,
                "size": 10
            }
        },
        {},
        {
            "id": "my-other-search-template",
            "params": {
                "query_type": "match_all"
            }
        }
    ],
)
```

#### curl

```curl
curl -X POST "$ELASTICSEARCH_URL/my-index/_msearch/template" \
  -H "Authorization: ApiKey $ELASTIC_API_KEY" \
  -H "Content-Type: application/x-ndjson" \
  -d $'{}\n{"id":"my-search-template","params":{"query_string":"hello \
  world","from":0,"size":10}}\n{}\n{"id":"my-other-search-template","params":{"query_type":"match_all"}}\n'
```

#### C#

```c#
var response = await client
    .MultiSearchTemplateAsync<MyDocument>(d1 => d1
        .Indices(new[] { "my-index" })
        .SearchTemplates([new SearchTemplateRequestItem(new MultisearchHeader(), new TemplateConfig()
        {
            Id = "my-search-template",
            Params = new Dictionary<string, object>()
            {
                { "query_string", "hello world" },
                { "from", 0 },
                { "size", 10 }
            }
        }), new SearchTemplateRequestItem(new MultisearchHeader(), new TemplateConfig()
        {
            Id = "my-other-search-template",
            Params = new Dictionary<string, object>()
            {
                { "query_type", "match_all" }
            }
        })])
    );
```

#### PHP

```php
$resp = $client->msearchTemplate([
    "index" => "my-index",
    "body" => array(
        new ArrayObject([]),
        [
            "id" => "my-search-template",
            "params" => [
                "query_string" => "hello world",
                "from" => 0,
                "size" => 10,
            ],
        ],
        new ArrayObject([]),
        [
            "id" => "my-other-search-template",
            "params" => [
                "query_type" => "match_all",
            ],
        ],
    ),
]);
```

#### Ruby

```ruby
response = client.msearch_template(
  index: "my-index",
  body: [
    {},
    {
      "id": "my-search-template",
      "params": {
        "query_string": "hello world",
        "from": 0,
        "size": 10
      }
    },
    {},
    {
      "id": "my-other-search-template",
      "params": {
        "query_type": "match_all"
      }
    }
  ]
)
```

