---
type: api
title: Create a Discover session
description: Creates a Discover session and returns its ID, full state, and metadata.
url: https://www.elastic.co/docs/api/doc/kibana-serverless/operation/operation-create-discover-session
resource: https://www.elastic.co/docs/api/doc/kibana-serverless/operation/operation-create-discover-session
products:
  - Kibana
---

# Create a Discover session

Authentication: required

- Server: `https://{kibana_url}`

## Paths

- `POST` `/api/discover_sessions`
- `POST` `/s/{space_id}/api/discover_sessions`

#### Path parameters

- `space_id` (string) — optional
  An identifier for the space. If `space_id` is not provided in the URL, the default space is used. Refer to [Spaces](https://www.elastic.co/docs/deploy-manage/manage-spaces) for more information.

## Description

Creates a Discover session and returns its ID, full state, and metadata.

## Header parameters

- `kbn-xsrf` (string) — required
  A required header to protect against CSRF attacks

## Request body

`application/json`

- `description` (string · max length: 10000) — optional
  A short description of the Discover session.
- `tabs` (union anyOf[] · min items: 1 · max items: 25) — required
  Ordered list of tabs in the Discover session. Each tab requires a stable, unique ID, which other saved objects and links can reference.
  - **header_row_height: auto**
    - `breakdown_field` (string · max length: 1000) — optional
      Field name used to split chart data into series.
    - `chart_interval` (enum) — optional
      Time interval for the chart histogram on this tab.
      Values: `auto`, `ms`, `s`, `m`, `h`, `d`, `w`, `M`, `y`
    - `column_order` (string[] · max items: 100) — optional
      Ordered list of field names to display in the data table. If omitted, defaults to the `defaultColumns` advanced setting.
    - `column_settings` (map string to object) — optional
      Per-column settings keyed by field name, such as width. Keys should correspond to entries in `column_order` when both are set.
      Map values (object)
      - `width` (number · min: 0) — optional
        Optional width of the column in pixels.
    - `control_panels` (object[] · max items: 1000) — optional
      The ES|QL controls of the tab.
      - `config` (union oneOf) — required
        The ES|QL control settings, including its variable, available options, and selected values.
        - **STATIC_VALUES** (`control_type: STATIC_VALUES`)
          An ES|QL variable control with a fixed list of selectable options defined directly in `available_options`.
          - `control_type` (enum) — required
            Values: `STATIC_VALUES`
          - `available_options` (string[] · max items: 1000) — required
            A fixed list of option strings displayed in the control.
          - `display_settings` (object) — optional
            - `hide_action_bar` (boolean) — optional
              When `true`, the search bar, sorting options, and select all toggle are hidden from the control.
            - `hide_exclude` (boolean) — optional
              When `true`, the exclude mode toggle is hidden from the control.
            - `hide_exists` (boolean) — optional
              When `true`, the exists filter option is hidden from the control.
            - `hide_sort` (boolean) — optional
              When `true`, the sort selector is hidden from the control.
            - `placeholder` (string) — optional
              Placeholder text displayed in the control input when no option is selected.
          - `selected_options` (string[] · max items: 10000) — required
            The list of currently selected option values.
          - `single_select` (boolean · default: true) — optional
            When `true`, only one option can be selected at a time. Selecting a new option deselects any previously selected option. Defaults to `true`.
          - `title` (string) — optional
            A human-readable title for the control.
          - `variable_name` (string) — required
            The name of the ES|QL variable that this control populates. The variable is referenced in ES|QL queries using the `?variable_name` syntax.
          - `variable_type` (enum) — required
            The ES|QL variable type that determines how the selected value is substituted into the query. Accepts `fields`, `values`, `functions`, `time_literal`, or `multi_values`.
            Values: `fields`, `values`, `functions`, `time_literal`, `multi_values`
        - **VALUES_FROM_QUERY** (`control_type: VALUES_FROM_QUERY`)
          An ES|QL variable control whose selectable options are dynamically retrieved by running an ES|QL query.
          - `control_type` (enum) — required
            Values: `VALUES_FROM_QUERY`
          - `display_settings` (object) — optional
            - `hide_action_bar` (boolean) — optional
              When `true`, the search bar, sorting options, and select all toggle are hidden from the control.
            - `hide_exclude` (boolean) — optional
              When `true`, the exclude mode toggle is hidden from the control.
            - `hide_exists` (boolean) — optional
              When `true`, the exists filter option is hidden from the control.
            - `hide_sort` (boolean) — optional
              When `true`, the sort selector is hidden from the control.
            - `placeholder` (string) — optional
              Placeholder text displayed in the control input when no option is selected.
          - `esql_query` (string) — required
            An ES|QL query whose results populate the list of available options in the control popover.
          - `selected_options` (string[] · max items: 10000) — required
            The list of currently selected option values.
          - `single_select` (boolean · default: true) — optional
            When `true`, only one option can be selected at a time. Selecting a new option deselects any previously selected option. Defaults to `true`.
          - `title` (string) — optional
            A human-readable title for the control.
          - `variable_name` (string) — required
            The name of the ES|QL variable that this control populates. The variable is referenced in ES|QL queries using the `?variable_name` syntax.
          - `variable_type` (enum) — required
            The ES|QL variable type that determines how the selected value is substituted into the query. Accepts `fields`, `values`, `functions`, `time_literal`, or `multi_values`.
            Values: `fields`, `values`, `functions`, `time_literal`, `multi_values`
      - `grow` (boolean · default: false) — optional
        When `true`, the control expands to fill any available horizontal space.
      - `id` (string · min length: 1) — required
        The unique ID of the control.
      - `type` (enum) — required
        Values: `esql_control`
      - `width` (enum · default: medium) — optional
        The minimum width of the control.
        Values: `small`, `medium`, `large`
    - `data_source` (union oneOf) — required
      The data view used by the tab, specified by reference or defined inline.
      - **Data view reference** (`type: data_view_reference`)
        - `type` (enum) — required
          Values: `data_view_reference`
        - `ref_id` (string) — required
          The id of the Kibana data view to use as the data source. Example: "my-data-view".
      - **Data view inline spec** (`type: data_view_spec`)
        - `type` (enum) — required
          Values: `data_view_spec`
        - `allow_hidden_indices` (boolean) — optional
          When `true`, allows the data view to match hidden indices.
        - `field_filters` (string[] · max items: 10000) — optional
          Field filters can be used to exclude one or more fields when fetching a document. They may contain wildcards, such as `user*` which filters fields starting with 'user'.
        - `field_settings` (map string to anyOf) — optional
          Settings for individual fields, keyed by field name. To change how Kibana displays a field from the backing indices, set its label, description, or format. To define a runtime field, use the runtime field name and set `type`.
          Map values (union anyOf)
          Any of:
          - **Composite runtime field**
            - `fields` (map string to object) — required
              Map values (object)
              - `custom_description` (string · min length: 1) — optional
                Add a description to the field. It's displayed next to the field on the Discover, Lens, and Data View Management pages.
              - `custom_label` (string · min length: 1) — optional
                Create a label to display in place of the field name in Discover, Maps, Lens, Visualize, and TSVB. Useful for shortening a long field name. Queries and filters use the original field name.
              - `format` (union anyOf) — optional
                Set your preferred format for displaying the value. Changing the format can affect the value and prevent highlighting in Discover.
                - **Boolean field format**
                  Formats a field into a true/false value.
                  - `type` (enum) — required
                    Values: `boolean`
                - **Bytes field format**
                  Formats a field into a bytes value following the numeral.js format pattern. The default pattern is defined by the format:bytes:defaultPattern advanced setting.
                  - `params` (object) — optional
                    - `pattern` (string) — optional
                      Numeral.js format pattern. See https://www.elastic.co/docs/explore-analyze/numeral-formatting to learn more.
                  - `type` (enum) — required
                    Values: `bytes`
                - **Color field format**
                  Formats a field into a color value.
                  - `params` (union oneOf) — required
                    - **field_type: string** (`field_type: string`)
                      - `field_type` (enum) — required
                        Values: `string`
                      - `colors` (object[]) — required
                        - `background` (string) — required
                          The background color to use for the field.
                        - `regex` (string) — required
                          When the field type is a string, this regex is used to determine the color.
                        - `text` (string) — required
                          The text color to use for the field.
                    - **field_type: number** (`field_type: number`)
                      - `field_type` (enum) — required
                        Values: `number`
                      - `colors` (object[]) — required
                        - `background` (string) — required
                          The background color to use for the field.
                        - `range` (string) — required
                          When the field type is a number, this range is used to determine the color.
                        - `text` (string) — required
                          The text color to use for the field.
                      - `pattern` (string) — optional
                        Numeral.js format pattern. See https://www.elastic.co/docs/explore-analyze/numeral-formatting to learn more.
                    - **field_type: boolean** (`field_type: boolean`)
                      - `field_type` (enum) — required
                        Values: `boolean`
                      - `colors` (object[]) — required
                        - `background` (string) — required
                          The background color to use for the field.
                        - `boolean` (boolean) — required
                          When the field type is a boolean, this boolean is used to determine the color.
                        - `text` (string) — required
                          The text color to use for the field.
                  - `type` (enum) — required
                    Values: `color`
                - **Currency field format**
                  Formats a field into a currency value. The format is determined by the pattern of the format:currency:defaultPattern advanced setting.
                  - `type` (enum) — required
                    Values: `currency`
                - **Date nanos field format**
                  Formats a field into a date nanos value following the defined pattern.
                  - `params` (object) — optional
                    - `pattern` (string · default: MMM D, YYYY @ HH:mm:ss.SSSSSSSSS) — optional
                      Moment.js format pattern. See https://momentjs.com/ to learn more.
                  - `type` (enum) — required
                    Values: `date_nanos`
                - **Date field format**
                  Formats a field into a date value following the defined pattern.
                  - `params` (object) — optional
                    - `pattern` (string · default: MMM D, YYYY @ HH:mm:ss.SSS) — optional
                      Moment.js format pattern. See https://momentjs.com/ to learn more.
                  - `type` (enum) — required
                    Values: `date`
                - **Duration field format**
                  Formats a field into a duration value.
                  - `params` (object) — required
                    - `include_space_with_suffix` (boolean · default: true) — optional
                      When true or not provided, the formatted duration includes a space between the value and suffix. When false, no space is included.
                    - `input_format` (enum) — required
                      The unit of the field value before formatting.
                      Values: `picoseconds`, `nanoseconds`, `microseconds`, `milliseconds`, `seconds`, `minutes`, `hours`, `days`, `weeks`, `months`, `years`
                    - `output_format` (enum) — required
                      The unit to convert the field value into for display.
                      Values: `humanize`, `humanize_precise`, `as_milliseconds`, `as_seconds`, `as_minutes`, `as_hours`, `as_days`, `as_weeks`, `as_months`, `as_years`
                    - `output_precision` (number · default: 2) — optional
                      The number of decimal places to display in the duration value.
                    - `show_suffix` (boolean) — optional
                      When true, the formatted duration includes a suffix (such as "seconds", "milliseconds", or "years"). When false or not provided, no suffix is shown.
                    - `use_short_suffix` (boolean · default: false) — optional
                      When true, the formatted duration uses short suffixes (such as "s", "ms", or "h"). When false or not provided, full suffixes are used.
                  - `type` (enum) — required
                    Values: `duration`
                - **Geo point field format**
                  Formats a field into a geo point value.
                  - `params` (object) — optional
                    - `transform` (enum) — required
                      The transform to apply to the geo point value.
                      Values: `lat_lon_string`, `wkt`, `dms`, `mgrs`, `multi`
                  - `type` (enum) — required
                    Values: `geo_point`
                - **Histogram field format**
                  Formats a histogram field into a numeric value following the defined pattern. The default pattern is defined by format:bytes:defaultPattern, format:percent:defaultPattern or format:number:defaultPattern advanced settings depending on the selected format.
                  - `params` (object) — required
                    - `format` (enum) — required
                      Values: `bytes`, `percent`, `number`
                    - `pattern` (string) — optional
                      Numeral.js format pattern. See https://www.elastic.co/docs/explore-analyze/numeral-formatting to learn more.
                  - `type` (enum) — required
                    Values: `histogram`
                - **IP field format**
                  Formats a field into an IP address.
                  - `type` (enum) — required
                    Values: `ip`
                - **Number field format**
                  Formats a field into a numeric value following the defined pattern. The default pattern is defined by format:number:defaultPattern advanced setting.
                  - `params` (object) — optional
                    - `pattern` (string) — optional
                      Numeral.js format pattern. See https://www.elastic.co/docs/explore-analyze/numeral-formatting to learn more.
                  - `type` (enum) — required
                    Values: `number`
                - **Percent field format**
                  Formats a field into a percentage value following the defined pattern. The default pattern is defined by format:percent:defaultPattern advanced setting.
                  - `params` (object) — optional
                    - `pattern` (string) — optional
                      Numeral.js format pattern. See https://www.elastic.co/docs/explore-analyze/numeral-formatting to learn more.
                  - `type` (enum) — required
                    Values: `percent`
                - **Relative date field format**
                  Formats a field into a relative date value. For example: "1 day ago".
                  - `type` (enum) — required
                    Values: `relative_date`
                - **Static lookup field format**
                  Formats a field into a static value based on the lookup entries or the unknown key value.
                  - `params` (object) — required
                    - `lookup_entries` (object[]) — required
                      The lookup entries to use for the static lookup. The key refers to the field value, and the value refers to the new value to display.
                      - `key` (string) — required
                      - `value` (string) — required
                    - `unknown_key_value` (string) — optional
                      The value to display for unknown key values. If not provided, the field value will be displayed.
                  - `type` (enum) — required
                    Values: `static_lookup`
                - **String field format**
                  Formats a field into a string value.
                  - `params` (object) — optional
                    - `transform` (enum) — optional
                      Values: `lower`, `upper`, `title`, `short`, `base64`, `urlparam`
                  - `type` (enum) — required
                    Values: `string`
                - **Truncate field format**
                  Truncates the field value to the specified length. If the field value is longer than the specified length, it will be truncated and the remaining text will be replaced with "...".
                  - `params` (object) — optional
                    - `field_length` (number) — optional
                  - `type` (enum) — required
                    Values: `truncate`
                - **URL field format**
                  Formats a field into a link, image or audio.
                  - `params` (union oneOf) — required
                    - **type: a** (`type: a`)
                      - `type` (enum) — required
                        Displays the field value as a hyperlink.
                        Values: `a`
                      - `label_template` (string) — optional
                        The template to use for the label. The template is a string that contains the field value. The field value is replaced with the template. The available placeholders are: `{{value}}`, `{{rawValue}}` and `{{url}}`. For example: "`{{value}}`".
                      - `open_link_in_current_tab` (boolean) — optional
                        When true, the URL opens in the current tab. When false or not provided, the URL opens in a new tab.
                      - `url_template` (string) — optional
                        The template to use for the URL. The template is a string that contains the field value. The field value is replaced with the template. The available placeholders are: `{{value}}`, `{{rawValue}}` and `{{risonValue}}`. Use `{{risonValue}}` when embedding the field value inside Kibana app URL rison state (for example: query:'`{{risonValue}}`'). For example: "https://example.com/`{{value}}`".
                    - **type: img** (`type: img`)
                      - `type` (enum) — required
                        Displays the field value as an image.
                        Values: `img`
                      - `height` (number) — optional
                        The height of the image. If not provided, the image will be displayed at the original height.
                      - `label_template` (string) — optional
                        The template to use for the label. The template is a string that contains the field value. The field value is replaced with the template. The available placeholders are: `{{value}}`, `{{rawValue}}` and `{{url}}`. For example: "`{{value}}`".
                      - `url_template` (string) — optional
                        The template to use for the URL. The template is a string that contains the field value. The field value is replaced with the template. The available placeholders are: `{{value}}`, `{{rawValue}}` and `{{risonValue}}`. Use `{{risonValue}}` when embedding the field value inside Kibana app URL rison state (for example: query:'`{{risonValue}}`'). For example: "https://example.com/`{{value}}`".
                      - `width` (number) — optional
                        The width of the image. If not provided, the image will be displayed at the original width.
                    - **type: audio** (`type: audio`)
                      - `type` (enum) — required
                        Displays the field value as an audio player.
                        Values: `audio`
                      - `label_template` (string) — optional
                        The template to use for the label. The template is a string that contains the field value. The field value is replaced with the template. The available placeholders are: `{{value}}`, `{{rawValue}}` and `{{url}}`. For example: "`{{value}}`".
                      - `url_template` (string) — optional
                        The template to use for the URL. The template is a string that contains the field value. The field value is replaced with the template. The available placeholders are: `{{value}}`, `{{rawValue}}` and `{{risonValue}}`. Use `{{risonValue}}` when embedding the field value inside Kibana app URL rison state (for example: query:'`{{risonValue}}`'). For example: "https://example.com/`{{value}}`".
                  - `type` (enum) — required
                    Values: `url`
                - **Extensible format**
                  Fallback for custom formatter IDs only. Known formatter IDs must match their dedicated schema and are validated at runtime.
                  - `params` (object) — optional
                  - `type` (string) — required
              - `type` (enum) — required
                The type of the runtime field (e.g., "keyword", "long", "date").
                Values: `keyword`, `long`, `double`, `date`, `ip`, `boolean`, `geo_point`
            - `script` (string · min length: 1) — optional
              The script that defines the runtime field. This should be a painless script that computes the field value at query time. Runtime fields without a script retrieve values from _source. If the field doesn't exist in _source, a search request returns no value.
            - `type` (enum) — required
              Values: `composite`
          - **Runtime field**
            - `custom_description` (string · min length: 1) — optional
              Add a description to the field. It's displayed next to the field on the Discover, Lens, and Data View Management pages.
            - `custom_label` (string · min length: 1) — optional
              Create a label to display in place of the field name in Discover, Maps, Lens, Visualize, and TSVB. Useful for shortening a long field name. Queries and filters use the original field name.
            - `format` (union anyOf) — optional
              Set your preferred format for displaying the value. Changing the format can affect the value and prevent highlighting in Discover.
              Same options as `format` in `fields`
            - `script` (string · min length: 1) — optional
              The script that defines the runtime field. This should be a painless script that computes the field value at query time. Runtime fields without a script retrieve values from _source. If the field doesn't exist in _source, a search request returns no value.
            - `type` (enum) — required
              The type of the runtime field (e.g., "keyword", "long", "date").
              Values: `keyword`, `long`, `double`, `date`, `ip`, `boolean`, `geo_point`
          - **Field settings**
            Display overrides for a field. These settings can define a custom label, description, and format.
            - `custom_description` (string · min length: 1) — optional
              Add a description to the field. It's displayed next to the field on the Discover, Lens, and Data View Management pages.
            - `custom_label` (string · min length: 1) — optional
              Create a label to display in place of the field name in Discover, Maps, Lens, Visualize, and TSVB. Useful for shortening a long field name. Queries and filters use the original field name.
            - `format` (union anyOf) — optional
              Set your preferred format for displaying the value. Changing the format can affect the value and prevent highlighting in Discover.
              Same options as `format` in `fields`
        - `index_pattern` (string · min length: 1) — required
          The index pattern (Elasticsearch index expression) to use as the data source. Example: "my-index-*".
        - `name` (string · min length: 1 · max length: 256) — optional
          The name of the data view. Example: "Sample data view".
        - `time_field` (string) — optional
          The name of the time field in the index. Used for time-based filtering. Example: "@timestamp".
    - `default_rendered_nodes` (number · min: 10 · max: 200) — optional
      The number of nodes each JSON cell renders by default in the JSON document view.
    - `density` (enum) — optional
      The table row spacing. If omitted, Kibana determines the density from its current settings, such as the user preference.
      Values: `compact`, `expanded`, `normal`
    - `documents_display_mode` (enum) — optional
      How documents are shown: `table` for a formatted table or `json` for a raw JSON tree.
      Values: `table`, `json`
    - `filters` (union oneOf[] · max items: 100 · default: []) — optional
      List of filters to apply to the data in the tab.
      - **condition**
        A filter that evaluates a single field condition such as equality, range, or existence.
        - `type` (enum) — required
          Values: `condition`
        - `condition` (union oneOf) — required
          A filter condition with strict operator/value type matching.
          - **is** (`operator: is`)
            Matches documents where `field` equals a single specified value.
            - `operator` (enum) — required
              Values: `is`
            - `field` (string) — required
              Name of the document field the condition evaluates.
            - `negate` (boolean) — optional
              When `true`, the filter is negated and matches documents that do NOT satisfy the condition. Defaults to `false`.
            - `value` (union string | number | boolean) — required
              Single value to compare against the field.
          - **is_one_of** (`operator: is_one_of`)
            Matches documents where `field` equals any value in a provided list.
            - `operator` (enum) — required
              Values: `is_one_of`
            - `field` (string) — required
              Name of the document field the condition evaluates.
            - `negate` (boolean) — optional
              When `true`, the filter is negated and matches documents that do NOT satisfy the condition. Defaults to `false`.
            - `value` (union string[] | number[] | boolean[]) — required
              Homogeneous array of values to match against the field.
          - **range** (`operator: range`)
            Matches documents where `field` falls within a specified numeric or date range.
            - `operator` (enum) — required
              Values: `range`
            - `field` (string) — required
              Name of the document field the condition evaluates.
            - `negate` (boolean) — optional
              When `true`, the filter is negated and matches documents that do NOT satisfy the condition. Defaults to `false`.
            - `value` (object) — required
              Boundary values for a range comparison.
              - `format` (string) — optional
                Elasticsearch [date format](https://www.elastic.co/docs/reference/elasticsearch/mapping-reference/mapping-date-format) string applied when parsing date boundary values. For example, `strict_date_optional_time` or `epoch_millis`.
              - `gt` (number | string) — optional
                Greater than.
              - `gte` (number | string) — optional
                Greater than or equal to.
              - `lt` (number | string) — optional
                Less than.
              - `lte` (number | string) — optional
                Less than or equal to.
          - **exists** (`operator: exists`)
            Matches documents where `field` exists and contains a non-null value.
            - `operator` (enum) — required
              Values: `exists`
            - `field` (string) — required
              Name of the document field the condition evaluates.
            - `negate` (boolean) — optional
              When `true`, the filter is negated and matches documents that do NOT satisfy the condition. Defaults to `false`.
        - `controlled_by` (string) — optional
          Identifier of the panel that manages this filter. When set, the filter is treated as owned by that panel.
        - `data_view_id` (string) — optional
          Identifier of the data view used as context for this filter.
        - `disabled` (boolean) — optional
          When `true`, the filter is inactive and does not affect query results. Defaults to `false`.
        - `is_multi_index` (boolean) — optional
          When `true`, the filter can be applied across multiple indices. Defaults to `false`.
        - `label` (string) — optional
          Human-readable label for the filter, used for display purposes.
        - `negate` (boolean) — optional
          When `true`, the filter is negated and matches documents that do NOT satisfy the condition. Defaults to `false`.
      - **group**
        A filter that combines multiple conditions or nested groups using a logical `and` or `or` operator.
        - `type` (enum) — required
          Values: `group`
        - `controlled_by` (string) — optional
          Identifier of the panel that manages this filter. When set, the filter is treated as owned by that panel.
        - `data_view_id` (string) — optional
          Identifier of the data view used as context for this filter.
        - `disabled` (boolean) — optional
          When `true`, the filter is inactive and does not affect query results. Defaults to `false`.
        - `group` (object) — required
          Logical group that combines one or more conditions or nested groups.
          - `conditions` (union anyOf[]) — required — recursive
            Ordered list of conditions or nested groups combined by the group `operator`.
          - `operator` (enum) — required
            Logical operator applied across all entries in `conditions`. Use `and` to require all conditions, or `or` to require at least one.
            Values: `and`, `or`
        - `is_multi_index` (boolean) — optional
          When `true`, the filter can be applied across multiple indices. Defaults to `false`.
        - `label` (string) — optional
          Human-readable label for the filter, used for display purposes.
        - `negate` (boolean) — optional
          When `true`, the filter is negated and matches documents that do NOT satisfy the condition. Defaults to `false`.
      - **dsl**
        A filter expressed as a raw [Elasticsearch Query DSL](https://www.elastic.co/docs/reference/query-languages/querydsl) object, used for queries that cannot be represented by condition or group filters.
        - `type` (enum) — required
          Values: `dsl`
        - `controlled_by` (string) — optional
          Identifier of the panel that manages this filter. When set, the filter is treated as owned by that panel.
        - `data_view_id` (string) — optional
          Identifier of the data view used as context for this filter.
        - `disabled` (boolean) — optional
          When `true`, the filter is inactive and does not affect query results. Defaults to `false`.
        - `dsl` (map string to object) — required
          Elasticsearch Query DSL object passed directly to the query.
        - `field` (string) — optional
          Field name for scripted filters where the field cannot be extracted from the DSL query.
        - `is_multi_index` (boolean) — optional
          When `true`, the filter can be applied across multiple indices. Defaults to `false`.
        - `label` (string) — optional
          Human-readable label for the filter, used for display purposes.
        - `negate` (boolean) — optional
          When `true`, the filter is negated and matches documents that do NOT satisfy the condition. Defaults to `false`.
        - `params` (object) — optional
          Filter parameters metadata. May contain display values, formats, and parameters for scripted filters.
      - **spatial**
        A filter that applies an Elasticsearch geo query, used for geographic boundary and shape matching.
        - `type` (enum) — required
          Values: `spatial`
        - `controlled_by` (string) — optional
          Identifier of the panel that manages this filter. When set, the filter is treated as owned by that panel.
        - `data_view_id` (string) — optional
          Identifier of the data view used as context for this filter.
        - `disabled` (boolean) — optional
          When `true`, the filter is inactive and does not affect query results. Defaults to `false`.
        - `dsl` (map string to object) — required
          Elasticsearch geo query DSL object.
        - `is_multi_index` (boolean) — optional
          When `true`, the filter can be applied across multiple indices. Defaults to `false`.
        - `label` (string) — optional
          Human-readable label for the filter, used for display purposes.
        - `negate` (boolean) — optional
          When `true`, the filter is negated and matches documents that do NOT satisfy the condition. Defaults to `false`.
    - `header_row_height` (union number | enum) — optional
      The table header row height, as a number of lines, or `auto` to size it based on content. If omitted, Kibana determines the height from its current settings, such as the user preference.
      Values: `auto`
    - `hide_aggregated_preview` (boolean) — optional
      Applies to the field statistics view. When `true`, hides the distribution preview shown for each field. If omitted, previews are shown.
    - `hide_chart` (boolean · default: false) — optional
      When `true`, the chart is hidden.
    - `hide_nulls` (boolean) — optional
      When `true`, fields with null values are hidden in the JSON document view.
    - `hide_table` (boolean · default: false) — optional
      When `true`, the data table is hidden.
    - `id` (string · min length: 1 · max length: 250) — required
      A unique identifier. Must contain only lowercase letters, numbers, hyphens, and underscores.
    - `label` (string · max length: 120) — required
      The label of the tab.
    - `query` (object) — optional
      A search query consisting of an expression and its language. Supports KQL and Lucene syntax.
      - `expression` (string) — required
        A query expression in KQL or Lucene syntax.
      - `language` (enum) — required
        Query language. Use `kql` for Kibana Query Language (KQL) or `lucene` for Lucene query syntax.
        Values: `kql`, `lucene`
    - `refresh_interval` (object) — optional
      Specifies the auto-refresh interval for the object.
      - `pause` (boolean) — required
        When `true`, auto-refresh is paused.
      - `value` (number) — required
        The refresh interval in milliseconds.
    - `row_height` (union number | enum) — optional
      The table data row height, as a number of lines, or `auto` to size it based on content. If omitted, defaults to the `discover:rowHeightOption` advanced setting.
      Values: `auto`
    - `rows_per_page` (number · min: 1 · max: 10000) — optional
      The number of rows to display per page in the data table. If omitted, defaults to the `discover:sampleRowsPerPage` advanced setting. Has no effect on ES|QL tabs.
    - `sample_size` (number · min: 10 · max: 10000) — optional
      The number of documents to sample for the data table. If omitted, defaults to the `discover:sampleSize` advanced setting.
    - `sort` (object[] · max items: 100 · default: []) — optional
      Sort configuration for the data table (field and direction).
      - `direction` (enum) — required
        The sort direction: `asc` for ascending or `desc` for descending.
        Values: `asc`, `desc`
      - `name` (string) — required
        The name of the field to sort by.
    - `time_range` (object) — optional
      Specifies the time range for a query.
      - `from` (string) — required
        The start of the time range. Accepts Elasticsearch [date math](https://www.elastic.co/docs/reference/elasticsearch/rest-apis/common-options#date-math) expressions (for example, `now-7d`) or ISO 8601 timestamps.
      - `mode` (enum) — optional
        The time range mode. Use `absolute` for fixed start and end timestamps. Use `relative` for [date math](https://www.elastic.co/docs/reference/elasticsearch/rest-apis/common-options#date-math) expressions that are re-evaluated at query time (for example, `now-7d`).
        Values: `absolute`, `relative`
      - `to` (string) — required
        The end of the time range. Accepts Elasticsearch [date math](https://www.elastic.co/docs/reference/elasticsearch/rest-apis/common-options#date-math) expressions (for example, `now`) or ISO 8601 timestamps.
    - `type` (enum · default: default) — optional
      The tab type. `default` tabs have no type-specific settings.
      Values: `default`
    - `view_mode` (enum · default: documents) — optional
      The Discover view mode: `documents` (search hits), `patterns` (pattern analysis), or `aggregated` (field statistics).
      Values: `documents`, `patterns`, `aggregated`
    - `vis_context` (object) — optional
      The saved chart configuration. Discover reuses it when compatible with the tab’s current settings and query results; otherwise, it rebuilds the chart.
      - `attributes` (map string to object) — required
        Lens visualization attributes used to render the Discover chart.
      - `suggestion_type` (enum) — required
        Chart suggestion type used by Discover to generate this histogram configuration.
        Values: `lensSuggestion`, `histogramForESQL`, `histogramForDataView`
    - `wrap_lines` (boolean) — optional
      When `true`, long values wrap in the JSON document view. When `false`, they are truncated to a single line.
  - **header_row_height: auto**
    - `breakdown_field` (string · max length: 1000) — optional
      Field name used to split chart data into series.
    - `column_order` (string[] · max items: 100) — optional
      Ordered list of field names to display in the data table. If omitted, defaults to the `defaultColumns` advanced setting.
    - `column_settings` (map string to object) — optional
      Per-column settings keyed by field name, such as width. Keys should correspond to entries in `column_order` when both are set.
      Map values (object)
      - `width` (number · min: 0) — optional
        Optional width of the column in pixels.
    - `control_panels` (object[] · max items: 1000) — optional
      The ES|QL controls of the tab.
      Same fields as `control_panels` in `header_row_height: auto`
    - `data_source` (object) — required
      Uses an ES|QL query as the data source. The query is executed at render time; resulting columns are available as fields.
      - `query` (string) — required
        An ES|QL query that drives the data source. The query must produce a tabular result set; column names are used as field references. Example: "FROM logs-* | STATS count = COUNT(*) BY host.name".
      - `type` (enum) — required
        Values: `esql`
    - `default_rendered_nodes` (number · min: 10 · max: 200) — optional
      The number of nodes each JSON cell renders by default in the JSON document view.
    - `density` (enum) — optional
      The table row spacing. If omitted, Kibana determines the density from its current settings, such as the user preference.
      Values: `compact`, `expanded`, `normal`
    - `documents_display_mode` (enum) — optional
      How documents are shown: `table` for a formatted table or `json` for a raw JSON tree.
      Values: `table`, `json`
    - `esql_approximation` (boolean) — optional
      When `true`, ES|QL visualizations that use `STATS` run with [approximate execution](https://www.elastic.co/docs/reference/query-languages/esql/esql-query-approximation) for faster, estimated results.
    - `header_row_height` (union number | enum) — optional
      The table header row height, as a number of lines, or `auto` to size it based on content. If omitted, Kibana determines the height from its current settings, such as the user preference.
      Values: `auto`
    - `hide_chart` (boolean · default: false) — optional
      When `true`, the chart is hidden.
    - `hide_nulls` (boolean) — optional
      When `true`, fields with null values are hidden in the JSON document view.
    - `hide_table` (boolean · default: false) — optional
      When `true`, the data table is hidden.
    - `id` (string · min length: 1 · max length: 250) — required
      A unique identifier. Must contain only lowercase letters, numbers, hyphens, and underscores.
    - `label` (string · max length: 120) — required
      The label of the tab.
    - `refresh_interval` (object) — optional
      Specifies the auto-refresh interval for the object.
      - `pause` (boolean) — required
        When `true`, auto-refresh is paused.
      - `value` (number) — required
        The refresh interval in milliseconds.
    - `row_height` (union number | enum) — optional
      The table data row height, as a number of lines, or `auto` to size it based on content. If omitted, defaults to the `discover:rowHeightOption` advanced setting.
      Values: `auto`
    - `rows_per_page` (number · min: 1 · max: 10000) — optional
      The number of rows to display per page in the data table. If omitted, defaults to the `discover:sampleRowsPerPage` advanced setting. Has no effect on ES|QL tabs.
    - `sort` (object[] · max items: 100 · default: []) — optional
      Sort configuration for the data table (field and direction).
      - `direction` (enum) — required
        The sort direction: `asc` for ascending or `desc` for descending.
        Values: `asc`, `desc`
      - `name` (string) — required
        The name of the field to sort by.
    - `time_range` (object) — optional
      Specifies the time range for a query.
      - `from` (string) — required
        The start of the time range. Accepts Elasticsearch [date math](https://www.elastic.co/docs/reference/elasticsearch/rest-apis/common-options#date-math) expressions (for example, `now-7d`) or ISO 8601 timestamps.
      - `mode` (enum) — optional
        The time range mode. Use `absolute` for fixed start and end timestamps. Use `relative` for [date math](https://www.elastic.co/docs/reference/elasticsearch/rest-apis/common-options#date-math) expressions that are re-evaluated at query time (for example, `now-7d`).
        Values: `absolute`, `relative`
      - `to` (string) — required
        The end of the time range. Accepts Elasticsearch [date math](https://www.elastic.co/docs/reference/elasticsearch/rest-apis/common-options#date-math) expressions (for example, `now`) or ISO 8601 timestamps.
    - `type` (enum · default: default) — optional
      The tab type. `default` tabs have no type-specific settings.
      Values: `default`
    - `vis_context` (object) — optional
      The saved chart configuration. Discover reuses it when compatible with the tab’s current settings and query results; otherwise, it rebuilds the chart.
      - `attributes` (map string to object) — required
        Lens visualization attributes used to render the Discover chart.
      - `suggestion_type` (enum) — required
        Chart suggestion type used by Discover to generate this histogram configuration.
        Values: `lensSuggestion`, `histogramForESQL`, `histogramForDataView`
    - `wrap_lines` (boolean) — optional
      When `true`, long values wrap in the JSON document view. When `false`, they are truncated to a single line.
  - **Metrics tab**
    An ES|QL tab with saved metrics grid settings.
    - `breakdown_field` (string · max length: 1000) — optional
      Field name used to split chart data into series.
    - `column_order` (string[] · max items: 100) — optional
      Ordered list of field names to display in the data table. If omitted, defaults to the `defaultColumns` advanced setting.
    - `column_settings` (map string to object) — optional
      Per-column settings keyed by field name, such as width. Keys should correspond to entries in `column_order` when both are set.
      Map values (object)
      - `width` (number · min: 0) — optional
        Optional width of the column in pixels.
    - `control_panels` (object[] · max items: 1000) — optional
      The ES|QL controls of the tab.
      Same fields as `control_panels` in `header_row_height: auto`
    - `counter_aggregation` (enum) — required
      Aggregation applied to counter metric fields.
      Values: `avg`, `sum`, `min`, `max`
    - `data_source` (object) — required
      Uses an ES|QL query as the data source. The query is executed at render time; resulting columns are available as fields.
      - `query` (string) — required
        An ES|QL query that drives the data source. The query must produce a tabular result set; column names are used as field references. Example: "FROM logs-* | STATS count = COUNT(*) BY host.name".
      - `type` (enum) — required
        Values: `esql`
    - `default_rendered_nodes` (number · min: 10 · max: 200) — optional
      The number of nodes each JSON cell renders by default in the JSON document view.
    - `density` (enum) — optional
      The table row spacing. If omitted, Kibana determines the density from its current settings, such as the user preference.
      Values: `compact`, `expanded`, `normal`
    - `dimensions` (string[] · max items: 5) — required
      Fields used to group metrics in the metrics grid.
    - `documents_display_mode` (enum) — optional
      How documents are shown: `table` for a formatted table or `json` for a raw JSON tree.
      Values: `table`, `json`
    - `esql_approximation` (boolean) — optional
      When `true`, ES|QL visualizations that use `STATS` run with [approximate execution](https://www.elastic.co/docs/reference/query-languages/esql/esql-query-approximation) for faster, estimated results.
    - `gauge_aggregation` (enum) — required
      Aggregation applied to gauge metric fields.
      Values: `avg`, `sum`, `min`, `max`
    - `grid_sort_direction` (enum) — optional
      Direction of the metrics grid order. If omitted, defaults to ascending.
      Values: `asc`, `desc`
    - `grid_sort_field` (enum) — optional
      Criterion used to order metrics in the metrics grid. `recency` orders by the metrics the viewing user explored most recently in their own browser. If omitted, metrics are ordered alphabetically.
      Values: `alphabetically`, `recency`
    - `header_row_height` (union number | enum) — optional
      The table header row height, as a number of lines, or `auto` to size it based on content. If omitted, Kibana determines the height from its current settings, such as the user preference.
      Values: `auto`
    - `hide_chart` (boolean · default: false) — optional
      When `true`, the chart is hidden.
    - `hide_nulls` (boolean) — optional
      When `true`, fields with null values are hidden in the JSON document view.
    - `hide_table` (boolean · default: false) — optional
      When `true`, the data table is hidden.
    - `histogram_percentile` (enum) — required
      Percentile displayed for histogram metric fields.
      Values: `p50`, `p75`, `p90`, `p95`, `p99`
    - `histogram_visualization` (enum) — optional
      How histogram metrics are drawn. If omitted, Discover uses the percentile chart.
      Values: `lnsXY`
    - `id` (string · min length: 1 · max length: 250) — required
      A unique identifier. Must contain only lowercase letters, numbers, hyphens, and underscores.
    - `label` (string · max length: 120) — required
      The label of the tab.
    - `refresh_interval` (object) — optional
      Specifies the auto-refresh interval for the object.
      - `pause` (boolean) — required
        When `true`, auto-refresh is paused.
      - `value` (number) — required
        The refresh interval in milliseconds.
    - `row_height` (union number | enum) — optional
      The table data row height, as a number of lines, or `auto` to size it based on content. If omitted, defaults to the `discover:rowHeightOption` advanced setting.
      Values: `auto`
    - `rows_per_page` (number · min: 1 · max: 10000) — optional
      The number of rows to display per page in the data table. If omitted, defaults to the `discover:sampleRowsPerPage` advanced setting. Has no effect on ES|QL tabs.
    - `search_term` (string · max length: 1000) — required
      Search term used to filter metrics in the metrics grid.
    - `sort` (object[] · max items: 100 · default: []) — optional
      Sort configuration for the data table (field and direction).
      - `direction` (enum) — required
        The sort direction: `asc` for ascending or `desc` for descending.
        Values: `asc`, `desc`
      - `name` (string) — required
        The name of the field to sort by.
    - `time_range` (object) — optional
      Specifies the time range for a query.
      - `from` (string) — required
        The start of the time range. Accepts Elasticsearch [date math](https://www.elastic.co/docs/reference/elasticsearch/rest-apis/common-options#date-math) expressions (for example, `now-7d`) or ISO 8601 timestamps.
      - `mode` (enum) — optional
        The time range mode. Use `absolute` for fixed start and end timestamps. Use `relative` for [date math](https://www.elastic.co/docs/reference/elasticsearch/rest-apis/common-options#date-math) expressions that are re-evaluated at query time (for example, `now-7d`).
        Values: `absolute`, `relative`
      - `to` (string) — required
        The end of the time range. Accepts Elasticsearch [date math](https://www.elastic.co/docs/reference/elasticsearch/rest-apis/common-options#date-math) expressions (for example, `now`) or ISO 8601 timestamps.
    - `type` (enum) — required
      A tab with saved metrics grid settings. Requires an ES|QL data source. These settings are used only when the query supports the metrics experience.
      Values: `metrics`
    - `vis_context` (object) — optional
      The saved chart configuration. Discover reuses it when compatible with the tab’s current settings and query results; otherwise, it rebuilds the chart.
      - `attributes` (map string to object) — required
        Lens visualization attributes used to render the Discover chart.
      - `suggestion_type` (enum) — required
        Chart suggestion type used by Discover to generate this histogram configuration.
        Values: `lensSuggestion`, `histogramForESQL`, `histogramForDataView`
    - `wrap_lines` (boolean) — optional
      When `true`, long values wrap in the JSON document view. When `false`, they are truncated to a single line.
- `tags` (string[] · max items: 1000 · default: []) — optional
  Tag IDs to associate with this Discover session.
- `title` (string · min length: 1 · max length: 1000) — required
  The title of the Discover session.

## Responses

#### `201`

Created

`application/json`

- `data` (object)
  Configuration data for a Discover session.
  - `description` (string · max length: 10000)
    A short description of the Discover session.
  - `tabs` (union anyOf[] · min items: 1 · max items: 25)
    Ordered list of tabs in the Discover session. Each tab requires a stable, unique ID, which other saved objects and links can reference.
    Same options as `tabs`
  - `tags` (string[] · max items: 1000 · default: [])
    Tag IDs to associate with this Discover session.
  - `title` (string · min length: 1 · max length: 1000)
    The title of the Discover session.
- `id` (string)
  The Discover session ID.
- `meta` (object)
  - `created_at` (string)
    Timestamp when the object was created (ISO 8601).
  - `created_by` (string)
    User profile ID of the user who created the object.
  - `managed` (boolean)
    When `true`, the object is managed by Kibana and cannot be edited by users.
  - `owner` (string)
    Identifier of the plugin or team that owns this object.
  - `updated_at` (string)
    Timestamp when the object was last updated (ISO 8601).
  - `updated_by` (string)
    User profile ID of the user who last updated the object.
  - `version` (string)
    Internal version identifier for optimistic concurrency control.
#### `400`

Invalid request

#### `403`

Forbidden

## Code examples

#### Console

```console
POST kbn:/api/discover_sessions
{
  "title": "Requests by extension",
  "description": "",
  "tags": [],
  "tabs": [
    {
      "id": "requests",
      "label": "Requests",
      "type": "default",
      "data_source": {
        "type": "esql",
        "query": "FROM kibana_sample_data_logs | STATS requests = COUNT(*) BY extension | SORT requests DESC"
      },
      "column_order": [
        "extension",
        "requests"
      ],
      "sort": [],
      "hide_chart": false,
      "hide_table": false
    }
  ]
}
```

#### curl

```curl
curl -X POST "${KIBANA_URL}/api/discover_sessions" \
  -H "Authorization: ApiKey ${API_KEY}" \
  -H "elastic-api-version: 2023-10-31" \
  -H "kbn-xsrf: true" \
  -H "Content-Type: application/json" \
  -d '{
  "title": "Requests by extension",
  "description": "",
  "tags": [],
  "tabs": [
    {
      "id": "requests",
      "label": "Requests",
      "type": "default",
      "data_source": {
        "type": "esql",
        "query": "FROM kibana_sample_data_logs | STATS requests = COUNT(*) BY extension | SORT requests DESC"
      },
      "column_order": [
        "extension",
        "requests"
      ],
      "sort": [],
      "hide_chart": false,
      "hide_table": false
    }
  ]
}'
```

## Response examples

#### Response for the ES|QL session example

`application/json`

```json
{
  "data": {
    "description": "",
    "tabs": [
      {
        "column_order": [
          "extension",
          "requests"
        ],
        "data_source": {
          "query": "FROM kibana_sample_data_logs | STATS requests = COUNT(*) BY extension | SORT requests DESC",
          "type": "esql"
        },
        "hide_chart": false,
        "hide_table": false,
        "id": "requests",
        "label": "Requests",
        "sort": [],
        "type": "default"
      }
    ],
    "tags": [],
    "title": "Requests by extension"
  },
  "id": "web-log-requests",
  "meta": {
    "created_at": "2026-10-15T09:00:00.000Z",
    "created_by": "u_example",
    "managed": false,
    "updated_at": "2026-10-15T09:00:00.000Z",
    "updated_by": "u_example",
    "version": "WzEsMV0="
  }
}
```

