[role="xpack"]
[[put-search-application]]
=== Put Search Application
++++
<titleabbrev>Put Search Application</titleabbrev>
++++

.New API reference
[sidebar]
--
For the most up-to-date API details, refer to {api-es}/group/endpoint-search_application[Search application APIs].
--

beta::[]

Creates or updates a Search Application.

[[put-search-application-request]]
==== {api-request-title}

`PUT _application/search_application/<name>`

[[put-search-application-prereqs]]
==== {api-prereq-title}

Requires the `manage_search_application` cluster privilege.
Also requires <<privileges-list-indices,manage privileges>> on all indices that are added to the Search Application.

[[put-search-application-path-params]]
==== {api-path-parms-title}


`create`::
(Optional, Boolean) If `true`, this request cannot replace or update existing Search Applications.
Defaults to `false`.

`<body>`::
(Required, object)
Contains parameters for a search application:
+
.Properties of `<body>` objects
[%collapsible%open]
====
`indices`::
(Required, array of strings)
The <<indices,indices>> associated with this search application. All indices need to exist in order to be added to a search application.

`template`::
(Optional, object)
The <<search-template,search template>> associated with this search application. The search application's template is only stored and accessible through the search application.

- This search template must be a Mustache template.
- The template must contain a Mustache script and script source.
- The template may be modified with subsequent <<put-search-application,put search application>> requests.
- If no template is specified when creating a search application, or if a template is removed from a search application, we use the <<query-string-query-ex-request,query_string>> defined in the template examples as a default.
- This template will be used by the <<search-application-search,search application search>> API to execute searches.
- The template accepts an optional `dictionary` parameter which defines a https://json-schema.org[JSON schema] used for validating parameters sent to the <<search-application-search,search application search>> API.

.Properties of `<template>`
[%collapsible%open]
=====

`script`::
(Required, object)
The associated mustache template.

[[put-search-application-dictionary-param]]
`dictionary`::
(Optional, object)
The dictionary used to validate the parameters used with the <<search-application-search, search application search>> API. The dictionary must be a valid JSON schema.
If `dictionary` is not specified, then the parameters will not be validated before being applied in the template.
=====
====


[[put-search-application-response-codes]]
==== {api-response-codes-title}

`404`::
Search Application `<name>` does not exist.

`409`::
Search Application `<name>` exists and `create` is `true`.

[[put-search-application-example]]
==== {api-examples-title}

The following example creates or updates a new Search Application called `my-app`:

////
[source,console]
----
PUT /index1

PUT /index2

PUT _application/search_application/my-app
{
  "indices": [ "index1", "index2" ],
  "template": {
    "script": {
      "source": {
        "query": {
          "query_string": {
            "query": "{{query_string}}",
            "default_field": "{{default_field}}"
          }
        }
      },
      "params": {
        "query_string": "*",
        "default_field": "*"
      }
    },
    "dictionary": {
      "properties": {
        "query_string": {
          "type": "string"
        },
        "default_field": {
          "type": "string",
          "enum": [
            "title",
            "description"
          ]
        },
        "additionalProperties": false
      },
      "required": [
        "query_string"
      ]
    }
  }
}
----
// TESTSETUP

//////////////////////////

[source,console]
--------------------------------------------------
DELETE _application/search_application/my-app

DELETE /index1

DELETE /index2
--------------------------------------------------
// TEARDOWN

////

[source,console]
----
PUT _application/search_application/my-app
{
  "indices": [ "index1", "index2" ],
  "template": {
    "script": {
      "source": {
        "query": {
          "query_string": {
            "query": "{{query_string}}",
            "default_field": "{{default_field}}"
          }
        }
      },
      "params": {
        "query_string": "*",
        "default_field": "*"
      }
    },
    "dictionary": {
      "properties": {
        "query_string": {
          "type": "string"
        },
        "default_field": {
          "type": "string",
          "enum": [
            "title",
            "description"
          ]
        },
        "additionalProperties": false
      },
      "required": [
        "query_string"
      ]
    }
  }
}
----

When the above `dictionary` parameter is specified, the <<search-application-search, search application search>> API will perform the following parameter validation:

* It accepts only the `query_string` and `default_field` parameters
* It verifies that `query_string` and `default_field` are both strings
* It accepts `default_field` only if it takes the values `title` or `description`

If the parameters are not valid, the <<search-application-search, search application search>> API will return an error.
[source,console]
----
POST _application/search_application/my-app/_search
{
  "params": {
    "default_field": "author",
    "query_string": "Jane"
  }
}
----
// TEST[catch:bad_request]

In the above example, the value of the `default_field` parameter is not valid, therefore Elasticsearch will return an error:

[source,JSON]
----
{
  "error": {
    "root_cause": [
      {
        "type": "validation_exception",
        "reason": 'Validation Failed: 1: $.default_field: does not have a value in the enumeration [title, description];',
        "stack_trace": ...
      }
    ],
    "type": "validation_exception",
    "reason": 'Validation Failed: 1: $.default_field: does not have a value in the enumeration [title, description];',
    "stack_trace": ...
  },
  "status": 400
}
----
// TESTRESPONSE[s/"stack_trace": \.\.\./"stack_trace": $body.$_path/]
// Need to use source,JSON above instead console-result, as $ fields are replaced in console-result snippets
