Download OpenAPI specification:
Technical preview — These APIs are available as technical preview on Elastic Cloud Serverless projects and Kibana 9.4.
Use the Kibana Dashboards and Visualizations APIs to programmatically create, retrieve, update, and delete dashboards and visualizations.
To interact with these APIs, use the following HTTP methods:
You can prepend any Kibana API endpoint with kbn: and run the request in Dev Tools → Console. For example:
GET kbn:/api/dashboards
For more information about the console, refer to Run API requests.
Note - This documentation is derived from the
mainbranch of the kibana repository and is provided under Attribution-NonCommercial-NoDerivatives 4.0 International.
A dashboard is a collection of panels arranged on a grid. Each panel can contain a visualization, a Discover session, an image, markdown text, or an interactive filter control. Use this API to create and manage dashboards programmatically.
Before you begin:
POST, PUT, DELETE) require the kbn-xsrf: true header.s/{space_id}/ to the path.Create your first dashboard right now. The following example creates a dashboard with an ES|QL line chart showing log entries over time. You can run it as-is once you have the Kibana sample logs dataset installed:
curl -X POST "${KIBANA_URL}/api/dashboards" \
-H "Authorization: ApiKey ${API_KEY}" \
-H "kbn-xsrf: true" \
-H "Content-Type: application/json" \
-d '{
"title": "My first API dashboard",
"panels": [
{
"grid": {
"x": 0,
"y": 0,
"w": 24,
"h": 10
},
"type": "vis",
"config": {
"type": "xy",
"title": "Total log entries over time",
"layers": [
{
"type": "line",
"data_source": {
"type": "esql",
"query": "FROM kibana_sample_data_logs | STATS count = COUNT() BY BUCKET(@timestamp, 75, ?_tstart, ?_tend)"
},
"x": {
"column": "BUCKET(@timestamp, 75, ?_tstart, ?_tend)"
},
"y": [
{
"column": "count"
}
]
}
],
"axis": {
"x": {
"title": {
"visible": false
}
}
}
}
}
]
}'
All examples on this page use Kibana sample datasets (kibana_sample_data_logs, kibana_sample_data_ecommerce, kibana_sample_data_flights). To use your own data, replace the FROM pattern and field references.
A dashboard is structured as follows:
title (required): the display name of the dashboard.
panels: array of items placed on a 48-column grid. Each item has a type, a grid position (x, y, w, h), and a config. Two item shapes are supported:
type field determines the panel's content and the structure of its config.grid.y position and its own nested panels array.The grid is 48 columns wide. Use w: 48 for a full-width panel, w: 24 for half-width, and so on. Height (h) and vertical position (y) are in grid rows with no fixed maximum.
pinned_panels: filter controls pinned at the top of the dashboard that apply to all panels. Filter controls placed in panels apply only to panels in the same section.
filters, query, time_range: filter the data displayed across all panels.
The type field in each panel determines what it contains and the structure of its config:
| Type | Description |
|---|---|
vis |
Visualization (bar, line, metric, and so on), supports both data view and ES|QL queries |
discover_session |
Discover session |
image |
Image |
markdown |
Markdown text |
esql_control |
ES|QL variable control |
options_list_control |
Dropdown filter by field value |
range_slider_control |
Slider filter by numeric range |
time_slider_control |
Time range slider |
Additional panel types for observability use cases:
| Type | Description |
|---|---|
slo_alerts |
SLO alerts |
slo_burn_rate |
SLO burn rate |
slo_error_budget |
SLO error budget |
slo_overview |
SLO overview |
synthetics_monitors |
Synthetics monitors |
synthetics_stats_overview |
Synthetics stats overview |
info The following panel types are supported in the Kibana UI but not yet by the REST API:
map,legacy_vis,links,field_stats_table,aiops_change_point_chart,aiops_log_rate_analysis,aiops_pattern_analysis. Write operations (POST,PUT) return a400error when these panel types are included. Read operations (GET) strip these panels from the response and include them in a list of warnings.
vis, discover_session, and markdown panels can be embedded inline (full config stored in the dashboard) or linked from library (references a library item by ID).
For the full config schema for visualization panels, including chart types, metric operations, and breakdowns, refer to the Visualizations API.
Inline: use when the panel is specific to this dashboard or must work across Kibana spaces. The panel configuration goes directly inside config:
{
"grid": {
"x": 0,
"y": 0,
"w": 12,
"h": 8
},
"type": "vis",
"config": {
"type": "metric",
"title": "Average bytes",
"data_source": {
"type": "data_view_spec",
"index_pattern": "kibana_sample_data_logs",
"time_field": "timestamp"
},
"metrics": [
{
"type": "primary",
"operation": "average",
"field": "bytes"
}
]
}
}
Linked from library: references an item in your library by its ID. Use ref_id with any supported panel type (vis, discover_session, markdown). Use the Visualizations API to create and retrieve IDs for visualization items.
{
"grid": {
"x": 0,
"y": 0,
"w": 12,
"h": 8
},
"type": "vis",
"config": {
"ref_id": "1e4f0a30-b3c5-11ef-bd7a-2b6b1a8c0f3d"
}
}
To create ES|QL-based charts, embed them inline as vis panels and set data_source.type to "esql".
metric charts: reference query result columns in metrics using column:
{
"grid": {
"x": 0,
"y": 0,
"w": 12,
"h": 6
},
"type": "vis",
"config": {
"type": "metric",
"title": "Total requests",
"data_source": {
"type": "esql",
"query": "FROM logs-* | STATS count = COUNT()"
},
"metrics": [
{
"type": "primary",
"column": "count"
}
]
}
}
xy charts: data_source goes inside each layer. Use BUCKET(@timestamp, 75, ?_tstart, ?_tend) to align time-series buckets with the dashboard's selected time range. For a complete xy chart example, see the Create a dashboard endpoint.
Spaces method and path for this operation:
Refer to Spaces for more information.
Returns a paginated list of dashboards. Each result includes title, description, tags, and metadata, but not the full panel layout. Use GET /api/dashboards/{id} to retrieve the complete state.
| page | number The page of results to return. Defaults to |
| per_page | number The number of results to return per page. Defaults to |
| query | string Filters results by |
| tags | Array of strings <= 100 items A tag ID to include. Accepts a single tag ID or multiple tag IDs. When multiple are specified, dashboards matching any of the tag IDs are included. |
| excluded_tags | Array of strings <= 100 items A tag ID to exclude. Accepts a single tag ID or multiple tag IDs. When multiple are specified, dashboards matching any of the tag IDs are excluded. |
curl -X GET "${KIBANA_URL}/api/dashboards?query=web+logs&per_page=10" \ -H "Authorization: ApiKey ${API_KEY}"
Paginated list of dashboard summaries. Each item includes the ID, a subset of dashboard state fields (title, time_range if set), and metadata. Full panel content is not included — use the GET endpoint to retrieve a specific dashboard.
{- "dashboards": [
- {
- "id": "3c4b8e10-d57a-11ef-9a52-4f3c2a8d0e1b",
- "data": {
- "title": "Web logs overview"
}, - "meta": {
- "created_at": "2026-04-13T10:00:00.000Z",
- "managed": false,
- "updated_at": "2026-04-13T10:00:00.000Z",
- "version": "WzEwMiwxXQ=="
}
}, - {
- "id": "7f2a1c40-e83b-11ef-a641-7d5b3f9e1c2a",
- "data": {
- "time_range": {
- "from": "now-7d",
- "to": "now"
}, - "title": "Operations overview"
}, - "meta": {
- "created_at": "2026-04-12T08:00:00.000Z",
- "managed": false,
- "updated_at": "2026-04-12T14:22:00.000Z",
- "version": "WzEwMSwxXQ=="
}
}
], - "page": 1,
- "total": 2
}Spaces method and path for this operation:
Refer to Spaces for more information.
Creates a new dashboard and returns its ID, full state, and metadata.
| kbn-xsrf required | string Example: true A required header to protect against CSRF attacks |
object (Access control) Access control settings for the dashboard. | |
| description | string A short description of the dashboard. |
Array of condition (object) or group (object) or dsl (object) or spatial (object) <= 500 items Filters applied across all panels, including pinned panels. | |
object (Options) Default: {"auto_apply_filters":true,"hide_panel_borders":false,"hide_panel_titles":false,"sync_colors":false,"sync_cursor":true,"sync_tooltips":false,"use_margins":true} Display and behavior settings for the dashboard. | |
Array of (APM Service map (object) or Discover session (object) or ES|QL variable control (object) or Image (object) or Markdown (object) or Options list control (object) or Range slider control (object) or SLO alerts (object) or SLO burn rate (object) or SLO error budget (object) or SLO overview (object) or Synthetics monitors (object) or Synthetics stats overview (object) or Time slider control (object) or Visualization (object)) or Section (object) <= 100 items Default: [] Panels and sections in the dashboard. Each entry is either a panel (with a | |
Array of any <= 100 items Default: [] An array of control panels and their state in the control group. | |
| project_routing | string Controls cross-project search behavior for this dashboard (Serverless only). Set to |
object (Query) A search query consisting of an expression and its language. Supports KQL and Lucene syntax. | |
object (Refresh interval) Specifies the auto-refresh interval for the object. | |
| tags | Array of strings <= 100 items Tag IDs to associate with this dashboard. |
object (Time range) Specifies the time range for a query. | |
| title required | string non-empty A human-readable title for the dashboard. |
{- "access_control": {
- "access_mode": "write_restricted"
}, - "description": "string",
- "filters": [
- {
- "condition": {
- "field": "string",
- "negate": true,
- "operator": "is",
- "value": "string"
}, - "controlled_by": "string",
- "data_view_id": "string",
- "disabled": true,
- "is_multi_index": true,
- "label": "string",
- "negate": true,
- "type": "condition"
}
], - "options": {
- "auto_apply_filters": true,
- "hide_panel_borders": false,
- "hide_panel_titles": false,
- "sync_colors": false,
- "sync_cursor": true,
- "sync_tooltips": false,
- "use_margins": true
}, - "panels": [ ],
- "pinned_panels": [ ],
- "project_routing": "string",
- "query": {
- "expression": "string",
- "language": "kql"
}, - "refresh_interval": {
- "pause": true,
- "value": 0
}, - "tags": [
- "string"
], - "time_range": {
- "from": "string",
- "mode": "absolute",
- "to": "string"
}, - "title": "string"
}Response to creating a dashboard. Returns the generated ID, the full dashboard state in data, and metadata. Default option values are always returned even when not explicitly set in the request. Panel id values are generated automatically.
{- "id": "3c4b8e10-d57a-11ef-9a52-4f3c2a8d0e1b",
- "data": {
- "options": {
- "hide_panel_titles": false,
- "hide_panel_borders": false,
- "use_margins": true,
- "auto_apply_filters": true,
- "sync_colors": false,
- "sync_cursor": true,
- "sync_tooltips": false
}, - "panels": [
- {
- "grid": {
- "x": 0,
- "y": 0,
- "w": 24,
- "h": 15
}, - "config": {
- "content": "## Web logs overview\n\n \n\nCreated with the [Dashboards API](https://www.elastic.co/docs/api/doc/kibana) using the Kibana sample web logs dataset (`kibana_sample_data_logs`). Contains:\n- This markdown panel\n- 2 metrics, showing request count and average response size\n- A line chart based on an ES|QL query\n\n \n\n \n\n[Learn more about dashboards](https://www.elastic.co/docs/explore-analyze/dashboards)"
}, - "id": "a1b2c3d4-0001-4000-8000-000000000001",
- "type": "markdown"
}, - {
- "grid": {
- "x": 24,
- "y": 0,
- "w": 12,
- "h": 5
}, - "config": {
- "title": "",
- "data_source": {
- "type": "data_view_spec",
- "index_pattern": "kibana_sample_data_logs",
- "time_field": "timestamp"
}, - "type": "metric",
- "sampling": 1,
- "ignore_global_filters": false,
- "metrics": [
- {
- "type": "primary",
- "operation": "count",
- "empty_as_null": false
}
], - "styling": {
- "primary": {
- "position": "bottom",
- "labels": {
- "alignment": "left"
}, - "value": {
- "sizing": "auto",
- "alignment": "right"
}
}
}
}, - "id": "a1b2c3d4-0001-4000-8000-000000000002",
- "type": "vis"
}, - {
- "grid": {
- "x": 36,
- "y": 0,
- "w": 12,
- "h": 5
}, - "config": {
- "title": "",
- "data_source": {
- "type": "data_view_spec",
- "index_pattern": "kibana_sample_data_logs",
- "time_field": "timestamp"
}, - "type": "metric",
- "sampling": 1,
- "ignore_global_filters": false,
- "metrics": [
- {
- "type": "primary",
- "operation": "average",
- "field": "bytes"
}
], - "styling": {
- "primary": {
- "position": "bottom",
- "labels": {
- "alignment": "left"
}, - "value": {
- "sizing": "auto",
- "alignment": "right"
}
}
}
}, - "id": "a1b2c3d4-0001-4000-8000-000000000003",
- "type": "vis"
}, - {
- "grid": {
- "x": 24,
- "y": 5,
- "w": 24,
- "h": 10
}, - "config": {
- "title": "Requests over time",
- "type": "xy",
- "layers": [
- {
- "type": "line",
- "data_source": {
- "type": "esql",
- "query": "FROM kibana_sample_data_logs | STATS count = COUNT() BY BUCKET(@timestamp, 75, ?_tstart, ?_tend)"
}, - "sampling": 1,
- "ignore_global_filters": false,
- "x": {
- "column": "BUCKET(@timestamp, 75, ?_tstart, ?_tend)"
}, - "y": [
- {
- "column": "count",
- "axis_id": "y"
}
]
}
], - "axis": {
- "x": {
- "title": {
- "visible": false
}, - "ticks": {
- "visible": true
}, - "grid": {
- "visible": true
}, - "domain": {
- "type": "fit",
- "rounding": false
}, - "labels": {
- "orientation": "horizontal"
}, - "scale": "ordinal"
}, - "y": {
- "anchor": "start",
- "title": {
- "visible": true
}, - "scale": "linear",
- "ticks": {
- "visible": true
}, - "grid": {
- "visible": true
}, - "domain": {
- "type": "full",
- "rounding": true
}, - "labels": {
- "orientation": "horizontal"
}
}
}, - "styling": {
- "overlays": {
- "partial_buckets": {
- "visible": false
}, - "current_time_marker": {
- "visible": false
}
}, - "interpolation": "linear",
- "points": {
- "visibility": "auto"
}
}, - "legend": {
- "visibility": "hidden",
- "placement": "outside",
- "position": "right",
- "layout": {
- "type": "grid",
- "truncate": {
- "max_lines": 1
}
}
}
}, - "id": "a1b2c3d4-0001-4000-8000-000000000003",
- "type": "vis"
}
], - "pinned_panels": [ ],
- "title": "Web logs overview"
}, - "meta": {
- "created_at": "2026-04-13T10:00:00.000Z",
- "managed": false,
- "updated_at": "2026-04-13T10:00:00.000Z",
- "version": "WzEwMiwxXQ=="
}
}Spaces method and path for this operation:
Refer to Spaces for more information.
Permanently deletes a dashboard by ID.
| id required | string The dashboard ID, as returned by the create or search endpoints. |
| kbn-xsrf required | string Example: true A required header to protect against CSRF attacks |
curl -X DELETE "${KIBANA_URL}/api/dashboards/3c4b8e10-d57a-11ef-9a52-4f3c2a8d0e1b" \ -H "Authorization: ApiKey ${API_KEY}" \ -H "kbn-xsrf: true"
Spaces method and path for this operation:
Refer to Spaces for more information.
Returns the complete state of a dashboard by ID.
| id required | string The dashboard ID, as returned by the create or search endpoints. |
curl -X GET "${KIBANA_URL}/api/dashboards/3c4b8e10-d57a-11ef-9a52-4f3c2a8d0e1b" \ -H "Authorization: ApiKey ${API_KEY}"
The full dashboard state including all panels, options, and metadata.
{- "id": "3c4b8e10-d57a-11ef-9a52-4f3c2a8d0e1b",
- "data": {
- "options": {
- "hide_panel_titles": false,
- "hide_panel_borders": false,
- "use_margins": true,
- "auto_apply_filters": true,
- "sync_colors": false,
- "sync_cursor": true,
- "sync_tooltips": false
}, - "title": "Web logs overview",
- "panels": [
- {
- "grid": {
- "x": 0,
- "y": 0,
- "w": 12,
- "h": 8
}, - "config": {
- "title": "Total requests",
- "data_source": {
- "type": "data_view_spec",
- "index_pattern": "kibana_sample_data_logs",
- "time_field": "timestamp"
}, - "type": "metric",
- "sampling": 1,
- "ignore_global_filters": false,
- "metrics": [
- {
- "type": "primary",
- "operation": "count",
- "empty_as_null": false
}
], - "styling": {
- "primary": {
- "position": "bottom",
- "labels": {
- "alignment": "left"
}, - "value": {
- "sizing": "auto",
- "alignment": "right"
}
}
}
}, - "id": "a1b2c3d4-0001-4000-8000-000000000001",
- "type": "vis"
}, - {
- "grid": {
- "x": 12,
- "y": 0,
- "w": 12,
- "h": 8
}, - "config": {
- "title": "Average response size",
- "data_source": {
- "type": "data_view_spec",
- "index_pattern": "kibana_sample_data_logs",
- "time_field": "timestamp"
}, - "type": "metric",
- "sampling": 1,
- "ignore_global_filters": false,
- "metrics": [
- {
- "type": "primary",
- "operation": "average",
- "field": "bytes"
}
], - "styling": {
- "primary": {
- "position": "bottom",
- "labels": {
- "alignment": "left"
}, - "value": {
- "sizing": "auto",
- "alignment": "right"
}
}
}
}, - "id": "a1b2c3d4-0001-4000-8000-000000000002",
- "type": "vis"
}, - {
- "grid": {
- "x": 0,
- "y": 15,
- "w": 24,
- "h": 10
}, - "config": {
- "title": "Requests over time",
- "type": "xy",
- "layers": [
- {
- "type": "line",
- "data_source": {
- "type": "esql",
- "query": "FROM kibana_sample_data_logs | STATS count = COUNT() BY BUCKET(@timestamp, 75, ?_tstart, ?_tend)"
}, - "sampling": 1,
- "ignore_global_filters": false,
- "x": {
- "column": "BUCKET(@timestamp, 75, ?_tstart, ?_tend)"
}, - "y": [
- {
- "column": "count",
- "axis_id": "y"
}
]
}
], - "axis": {
- "x": {
- "title": {
- "visible": false
}, - "ticks": {
- "visible": true
}, - "grid": {
- "visible": true
}, - "domain": {
- "type": "fit",
- "rounding": false
}, - "labels": {
- "orientation": "horizontal"
}, - "scale": "ordinal"
}, - "y": {
- "anchor": "start",
- "title": {
- "visible": true
}, - "scale": "linear",
- "ticks": {
- "visible": true
}, - "grid": {
- "visible": true
}, - "domain": {
- "type": "full",
- "rounding": true
}, - "labels": {
- "orientation": "horizontal"
}
}
}, - "styling": {
- "overlays": {
- "partial_buckets": {
- "visible": false
}, - "current_time_marker": {
- "visible": false
}
}, - "interpolation": "linear",
- "points": {
- "visibility": "auto"
}
}, - "legend": {
- "visibility": "hidden",
- "placement": "outside",
- "position": "right",
- "layout": {
- "type": "grid",
- "truncate": {
- "max_lines": 1
}
}
}
}, - "id": "a1b2c3d4-0001-4000-8000-000000000003",
- "type": "vis"
}
], - "pinned_panels": [ ]
}, - "meta": {
- "created_at": "2026-04-13T10:00:00.000Z",
- "managed": false,
- "updated_at": "2026-04-13T10:00:00.000Z",
- "version": "WzEwMiwxXQ=="
}
}Spaces method and path for this operation:
Refer to Spaces for more information.
Creates a new dashboard with the given ID if none exists, or replaces the complete state of an existing one.
warn This is a full replacement. Any panels not included in the request body are permanently removed. To make targeted changes, retrieve the current state first with GET /api/dashboards/{id}, apply your changes, and submit the full updated object.
| id required | string |
| kbn-xsrf required | string Example: true A required header to protect against CSRF attacks |
| description | string A short description of the dashboard. |
Array of condition (object) or group (object) or dsl (object) or spatial (object) <= 500 items Filters applied across all panels, including pinned panels. | |
object (Options) Default: {"auto_apply_filters":true,"hide_panel_borders":false,"hide_panel_titles":false,"sync_colors":false,"sync_cursor":true,"sync_tooltips":false,"use_margins":true} Display and behavior settings for the dashboard. | |
Array of (APM Service map (object) or Discover session (object) or ES|QL variable control (object) or Image (object) or Markdown (object) or Options list control (object) or Range slider control (object) or SLO alerts (object) or SLO burn rate (object) or SLO error budget (object) or SLO overview (object) or Synthetics monitors (object) or Synthetics stats overview (object) or Time slider control (object) or Visualization (object)) or Section (object) <= 100 items Default: [] Panels and sections in the dashboard. Each entry is either a panel (with a | |
Array of any <= 100 items Default: [] An array of control panels and their state in the control group. | |
| project_routing | string Controls cross-project search behavior for this dashboard (Serverless only). Set to |
object (Query) A search query consisting of an expression and its language. Supports KQL and Lucene syntax. | |
object (Refresh interval) Specifies the auto-refresh interval for the object. | |
| tags | Array of strings <= 100 items Tag IDs to associate with this dashboard. |
object (Time range) Specifies the time range for a query. | |
| title required | string non-empty A human-readable title for the dashboard. |
{- "description": "string",
- "filters": [
- {
- "condition": {
- "field": "string",
- "negate": true,
- "operator": "is",
- "value": "string"
}, - "controlled_by": "string",
- "data_view_id": "string",
- "disabled": true,
- "is_multi_index": true,
- "label": "string",
- "negate": true,
- "type": "condition"
}
], - "options": {
- "auto_apply_filters": true,
- "hide_panel_borders": false,
- "hide_panel_titles": false,
- "sync_colors": false,
- "sync_cursor": true,
- "sync_tooltips": false,
- "use_margins": true
}, - "panels": [ ],
- "pinned_panels": [ ],
- "project_routing": "string",
- "query": {
- "expression": "string",
- "language": "kql"
}, - "refresh_interval": {
- "pause": true,
- "value": 0
}, - "tags": [
- "string"
], - "time_range": {
- "from": "string",
- "mode": "absolute",
- "to": "string"
}, - "title": "string"
}The complete updated dashboard state after a full replacement. Note that meta.created_at is not returned in update responses — use the GET endpoint to retrieve it.
{- "id": "3c4b8e10-d57a-11ef-9a52-4f3c2a8d0e1b",
- "data": {
- "options": {
- "hide_panel_titles": false,
- "hide_panel_borders": false,
- "use_margins": true,
- "auto_apply_filters": true,
- "sync_colors": false,
- "sync_cursor": true,
- "sync_tooltips": false
}, - "panels": [
- {
- "grid": {
- "x": 0,
- "y": 0,
- "w": 24,
- "h": 15
}, - "config": {
- "content": "## Web logs overview\n\n \n\nCreated with the [Dashboards API](https://www.elastic.co/docs/api/doc/kibana) using the Kibana sample web logs dataset (`kibana_sample_data_logs`). Contains:\n- This markdown panel\n- 2 metrics, showing request count and average response size\n- A line chart based on an ES|QL query\n\n \n\n \n\n[Learn more about dashboards](https://www.elastic.co/docs/explore-analyze/dashboards)"
}, - "id": "a1b2c3d4-0001-4000-8000-000000000001",
- "type": "markdown"
}, - {
- "grid": {
- "x": 24,
- "y": 0,
- "w": 12,
- "h": 5
}, - "config": {
- "title": "",
- "data_source": {
- "type": "data_view_spec",
- "index_pattern": "kibana_sample_data_logs",
- "time_field": "timestamp"
}, - "type": "metric",
- "sampling": 1,
- "ignore_global_filters": false,
- "metrics": [
- {
- "type": "primary",
- "operation": "count",
- "empty_as_null": false
}
], - "styling": {
- "primary": {
- "position": "bottom",
- "labels": {
- "alignment": "left"
}, - "value": {
- "sizing": "auto",
- "alignment": "right"
}
}
}
}, - "id": "a1b2c3d4-0001-4000-8000-000000000002",
- "type": "vis"
}, - {
- "grid": {
- "x": 36,
- "y": 0,
- "w": 12,
- "h": 5
}, - "config": {
- "title": "",
- "data_source": {
- "type": "data_view_spec",
- "index_pattern": "kibana_sample_data_logs",
- "time_field": "timestamp"
}, - "type": "metric",
- "sampling": 1,
- "ignore_global_filters": false,
- "metrics": [
- {
- "type": "primary",
- "operation": "average",
- "field": "bytes"
}
], - "styling": {
- "primary": {
- "position": "bottom",
- "labels": {
- "alignment": "left"
}, - "value": {
- "sizing": "auto",
- "alignment": "right"
}
}
}
}, - "id": "a1b2c3d4-0001-4000-8000-000000000003",
- "type": "vis"
}, - {
- "grid": {
- "x": 24,
- "y": 5,
- "w": 24,
- "h": 10
}, - "config": {
- "title": "Requests over time",
- "type": "xy",
- "layers": [
- {
- "type": "line",
- "data_source": {
- "type": "esql",
- "query": "FROM kibana_sample_data_logs | STATS count = COUNT() BY BUCKET(@timestamp, 75, ?_tstart, ?_tend)"
}, - "sampling": 1,
- "ignore_global_filters": false,
- "x": {
- "column": "BUCKET(@timestamp, 75, ?_tstart, ?_tend)"
}, - "y": [
- {
- "column": "count",
- "axis_id": "y"
}
]
}
], - "axis": {
- "x": {
- "title": {
- "visible": false
}, - "ticks": {
- "visible": true
}, - "grid": {
- "visible": true
}, - "domain": {
- "type": "fit",
- "rounding": false
}, - "labels": {
- "orientation": "horizontal"
}, - "scale": "ordinal"
}, - "y": {
- "anchor": "start",
- "title": {
- "visible": true
}, - "scale": "linear",
- "ticks": {
- "visible": true
}, - "grid": {
- "visible": true
}, - "domain": {
- "type": "full",
- "rounding": true
}, - "labels": {
- "orientation": "horizontal"
}
}
}, - "styling": {
- "overlays": {
- "partial_buckets": {
- "visible": false
}, - "current_time_marker": {
- "visible": false
}
}, - "interpolation": "linear",
- "points": {
- "visibility": "auto"
}
}, - "legend": {
- "visibility": "hidden",
- "placement": "outside",
- "position": "right",
- "layout": {
- "type": "grid",
- "truncate": {
- "max_lines": 1
}
}
}
}, - "id": "a1b2c3d4-0001-4000-8000-000000000003",
- "type": "vis"
}, - {
- "grid": {
- "x": 24,
- "y": 8,
- "w": 24,
- "h": 10
}, - "config": {
- "title": "Unique visitors",
- "data_source": {
- "type": "data_view_spec",
- "index_pattern": "kibana_sample_data_logs",
- "time_field": "timestamp"
}, - "type": "metric",
- "sampling": 1,
- "ignore_global_filters": false,
- "metrics": [
- {
- "type": "primary",
- "operation": "unique_count",
- "field": "clientip",
- "empty_as_null": false
}
], - "styling": {
- "primary": {
- "position": "bottom",
- "labels": {
- "alignment": "left"
}, - "value": {
- "sizing": "auto",
- "alignment": "right"
}
}
}
}, - "id": "a1b2c3d4-0001-4000-8000-000000000004",
- "type": "vis"
}
], - "pinned_panels": [ ],
- "title": "Web logs overview"
}, - "meta": {
- "managed": false,
- "updated_at": "2026-04-13T11:00:00.000Z",
- "version": "WzEwMywxXQ=="
}
}Create, retrieve, update, and delete Kibana visualizations. Visualizations created through this API are saved to your visualization library.
Before you begin:
POST, PUT, DELETE) require the kbn-xsrf: true header.s/{space_id}/ to the path.The following example creates a line chart showing log entries over time. You can run it after installing the Kibana sample logs dataset:
curl -X POST "${KIBANA_URL}/api/visualizations" \
-H "Authorization: ApiKey ${API_KEY}" \
-H "kbn-xsrf: true" \
-H "Content-Type: application/json" \
-d '{
"type": "xy",
"title": "Total log entries over time",
"layers": [
{
"type": "line",
"data_source": {
"type": "data_view_spec",
"index_pattern": "kibana_sample_data_logs",
"time_field": "timestamp"
},
"x": {
"operation": "date_histogram",
"field": "timestamp"
},
"y": [
{
"operation": "count"
}
]
}
]
}'
All curl examples in this reference use Kibana sample datasets (kibana_sample_data_logs, kibana_sample_data_ecommerce, kibana_sample_data_flights). To use your own data, replace the index_pattern and field names.
Every visualization requires at minimum:
type: the chart to render. Each chart type has its own required fields, so the full structure of the request body depends on which type you specify.data_source: how data is fetched. You can reference an existing Kibana data view by ID ("type": "data_view_reference"), define a data view inline using an index pattern ("type": "data_view_spec"), or use an ES|QL query ("type": "esql"). Note that ES|QL is only supported via the Dashboards API. For most chart types, data_source is a top-level field. For XY charts, it belongs inside each layer in layers[].You can also include query and filters to apply KQL or Lucene filters to all chart data. Both are optional and can be omitted.
Everything else is chart-specific: layers for XY charts, metrics for metric charts, and so on. Refer to the request schema on the Create a visualization endpoint for the full shape of each type.
The type field in the request body determines the chart type:
| Type | Chart | Documentation |
|---|---|---|
data_table |
Data table | Table |
gauge |
Gauge (bullet, circular) | Gauge |
heatmap |
Heat map | Heat map |
metric |
Single value metric | Metric |
mosaic |
Mosaic | Mosaic |
pie |
Pie or donut (use donut_hole to control the hole size) |
Pie |
region_map |
Region map (choropleth) | Region map |
tag_cloud |
Tag cloud | Tag cloud |
treemap |
Treemap | Treemap |
waffle |
Waffle | Waffle |
xy |
Bar, line, area (and stacked/percentage variants) | Bar, Line, Area |
Spaces method and path for this operation:
Refer to Spaces for more information.
Returns a paginated list of Lens visualizations matching the optional query text.
| fields | Array of strings |
| search_fields | Array of strings |
| query | string Text to match against |
| page | number >= 1 Default: 1 Page number. |
| per_page | number [ 1 .. 1000 ] Default: 20 Results per page. |
curl -X GET "${KIBANA_URL}/api/visualizations?query=requests&per_page=10" \ -H "Authorization: ApiKey ${API_KEY}"
Paginated list of visualizations matching the query. Each item includes the ID, full chart configuration, and metadata. Use the GET endpoint to retrieve a single visualization by ID.
{- "data": [
- {
- "id": "1e4f0a30-b3c5-11ef-bd7a-2b6b1a8c0f3d",
- "data": {
- "title": "Total requests",
- "data_source": {
- "type": "data_view_spec",
- "index_pattern": "kibana_sample_data_logs",
- "time_field": "timestamp"
}, - "type": "metric",
- "sampling": 1,
- "ignore_global_filters": false,
- "metrics": [
- {
- "type": "primary",
- "operation": "count",
- "empty_as_null": false
}
], - "styling": {
- "primary": {
- "position": "bottom",
- "labels": {
- "alignment": "left"
}, - "value": {
- "sizing": "auto",
- "alignment": "right"
}
}
}
}, - "meta": {
- "created_at": "2026-04-13T10:00:00.000Z",
- "managed": false,
- "updated_at": "2026-04-13T10:00:00.000Z",
- "version": "WzU5LDFd"
}
}, - {
- "id": "3a7c2e10-b3c5-11ef-bd7a-2b6b1a8c0f3d",
- "data": {
- "title": "Log entries over time",
- "type": "xy",
- "layers": [
- {
- "type": "line",
- "data_source": {
- "type": "data_view_spec",
- "index_pattern": "kibana_sample_data_logs",
- "time_field": "timestamp"
}, - "sampling": 1,
- "ignore_global_filters": false,
- "x": {
- "operation": "date_histogram",
- "field": "timestamp",
- "suggested_interval": "auto",
- "use_original_time_range": false,
- "include_empty_rows": true,
- "drop_partial_intervals": false
}, - "y": [
- {
- "operation": "count",
- "empty_as_null": false,
- "axis_id": "y"
}
]
}
], - "axis": {
- "x": {
- "title": {
- "visible": true
}, - "ticks": {
- "visible": true
}, - "grid": {
- "visible": true
}, - "domain": {
- "type": "fit",
- "rounding": false
}, - "labels": {
- "orientation": "horizontal"
}
}, - "y": {
- "anchor": "start",
- "title": {
- "visible": true
}, - "scale": "linear",
- "ticks": {
- "visible": true
}, - "grid": {
- "visible": true
}, - "domain": {
- "type": "full",
- "rounding": true
}, - "labels": {
- "orientation": "horizontal"
}
}
}, - "styling": {
- "overlays": {
- "partial_buckets": {
- "visible": false
}, - "current_time_marker": {
- "visible": false
}
}, - "interpolation": "linear",
- "points": {
- "visibility": "auto"
}
}, - "legend": {
- "visibility": "hidden",
- "placement": "outside",
- "position": "right",
- "layout": {
- "type": "grid",
- "truncate": {
- "max_lines": 1
}
}
}
}, - "meta": {
- "created_at": "2026-04-13T10:05:00.000Z",
- "managed": false,
- "updated_at": "2026-04-13T10:05:00.000Z",
- "version": "WzYwLDFd"
}
}
], - "meta": {
- "page": 1,
- "per_page": 20,
- "total": 2
}
}Spaces method and path for this operation:
Refer to Spaces for more information.
Creates a Lens visualization and saves it to the library.
ES|QL visualizations cannot be created through this endpoint.
| overwrite | boolean |
| kbn-xsrf required | string Example: true A required header to protect against CSRF attacks |
Date Histogram Operation (object) or Terms Operation (object) or Histogram Operation (object) or Ranges Operation (object) or Filters Operation (object) | |
required | Data view reference (object) or Data view inline spec (object) |
| description | string |
Array of dashboard_drilldown (object) or discover_drilldown (object) or url_drilldown (object) <= 100 items | |
Array of condition (object) or group (object) or dsl (object) or spatial (object) (lensPanelFilters) <= 100 items Filters applied to the panel | |
| hide_border | boolean |
| hide_title | boolean |
| ignore_global_filters | boolean Default: false When |
required | Array of ((Count Metric Operation (object) or Unique Count Metric Operation (object) or Stats Metric Operation (object) or Sum Metric Operation (object) or Last Value Operation (object) or Percentile Operation (object) or Percentile Ranks Operation (object)) or (Differences Operation (object) or Moving Average Operation (object) or Cumulative Sum Operation (object) or Counter Rate Operation (object)) or Formula Operation (object)) or ((Count Metric Operation (object) or Unique Count Metric Operation (object) or Stats Metric Operation (object) or Sum Metric Operation (object) or Last Value Operation (object) or Percentile Operation (object) or Percentile Ranks Operation (object)) or (Differences Operation (object) or Moving Average Operation (object) or Cumulative Sum Operation (object) or Counter Rate Operation (object)) or Formula Operation (object)) [ 1 .. 2 ] items Metric dimensions to display. The first must be a primary metric; an optional second must be a secondary metric. |
required | object (Filter) A KQL or Lucene query that filters panel data. Applied on top of any dashboard-level filters. |
Array of objects (kbn-content-management-utils-referenceSchema) | |
| sampling | number [ 0 .. 1 ] Default: 1 Sampling factor between 0 (no sampling) and 1 (full sampling). |
object (metricStyling) Visual chart styling options | |
object (Time range) Specifies the time range for a query. | |
| title | string |
| type required | string Value: "metric" |
{- "breakdown_by": {
- "collapse_by": "avg",
- "columns": 3,
- "drop_partial_intervals": true,
- "field": "string",
- "include_empty_rows": true,
- "label": "string",
- "operation": "date_histogram",
- "suggested_interval": "auto",
- "use_original_time_range": false
}, - "data_source": {
- "ref_id": "string",
- "type": "data_view_reference"
}, - "description": "string",
- "drilldowns": [
- {
- "dashboard_id": "string",
- "label": "string",
- "open_in_new_tab": false,
- "trigger": "on_apply_filter",
- "type": "dashboard_drilldown",
- "use_filters": true,
- "use_time_range": true
}
], - "filters": [
- {
- "condition": {
- "field": "string",
- "negate": true,
- "operator": "is",
- "value": "string"
}, - "controlled_by": "string",
- "data_view_id": "string",
- "disabled": true,
- "is_multi_index": true,
- "label": "string",
- "negate": true,
- "type": "condition"
}
], - "hide_border": true,
- "hide_title": true,
- "ignore_global_filters": false,
- "metrics": [
- {
- "apply_color_to": "value",
- "background_chart": {
- "max_value": {
- "filter": {
- "expression": "string",
- "language": "kql"
}, - "format": {
- "compact": false,
- "decimals": 2,
- "suffix": "string",
- "type": "number"
}, - "formula": "string",
- "label": "string",
- "operation": "formula",
- "reduced_time_range": "string",
- "time_scale": "s"
}, - "orientation": "horizontal",
- "type": "bar"
}, - "color": {
- "range": "absolute",
- "steps": [
- {
- "color": "string",
- "gte": 0,
- "lt": 0,
- "lte": 0
}
], - "type": "dynamic"
}, - "empty_as_null": false,
- "field": "string",
- "filter": {
- "expression": "string",
- "language": "kql"
}, - "format": {
- "compact": false,
- "decimals": 2,
- "suffix": "string",
- "type": "number"
}, - "label": "string",
- "operation": "count",
- "reduced_time_range": "string",
- "subtitle": "string",
- "time_scale": "s",
- "time_shift": "string",
- "type": "primary"
}
], - "query": {
- "expression": "string",
- "language": "kql"
}, - "references": [
- {
- "id": "string",
- "name": "string",
- "type": "string"
}
], - "sampling": 1,
- "styling": {
- "icon": {
- "alignment": "left",
- "name": "alert"
}, - "primary": {
- "labels": {
- "alignment": "left"
}, - "position": "top",
- "value": {
- "alignment": "left",
- "sizing": "auto"
}
}, - "secondary": {
- "label": {
- "placement": "before",
- "visible": true
}, - "value": {
- "alignment": "left"
}
}
}, - "time_range": {
- "from": "string",
- "mode": "absolute",
- "to": "string"
}, - "title": "string",
- "type": "metric"
}Response after creating a metric chart (count of requests) using an inline data view. Server-populated defaults are included in the response.
{- "id": "1e4f0a30-b3c5-11ef-bd7a-2b6b1a8c0f3d",
- "data": {
- "title": "Total requests",
- "data_source": {
- "type": "data_view_spec",
- "index_pattern": "kibana_sample_data_logs",
- "time_field": "timestamp"
}, - "type": "metric",
- "sampling": 1,
- "ignore_global_filters": false,
- "metrics": [
- {
- "type": "primary",
- "operation": "count",
- "empty_as_null": false
}
], - "styling": {
- "primary": {
- "position": "bottom",
- "labels": {
- "alignment": "left"
}, - "value": {
- "sizing": "auto",
- "alignment": "right"
}
}
}
}, - "meta": {
- "created_at": "2026-04-13T10:00:00.000Z",
- "managed": false,
- "updated_at": "2026-04-13T10:00:00.000Z",
- "version": "WzU5LDFd"
}
}Spaces method and path for this operation:
Refer to Spaces for more information.
Permanently deletes a Lens visualization. If the visualization is referenced by a dashboard panel, the panel shows an error after deletion.
| id required | string The visualization identifier, as returned by the create or search endpoints. |
| kbn-xsrf required | string Example: true A required header to protect against CSRF attacks |
curl -X DELETE "${KIBANA_URL}/api/visualizations/1e4f0a30-b3c5-11ef-bd7a-2b6b1a8c0f3d" \ -H "Authorization: ApiKey ${API_KEY}" \ -H "kbn-xsrf: true"
Spaces method and path for this operation:
Refer to Spaces for more information.
Returns a single Lens visualization by its ID.
| id required | string The visualization identifier, as returned by the create or search endpoints. |
curl -X GET "${KIBANA_URL}/api/visualizations/1e4f0a30-b3c5-11ef-bd7a-2b6b1a8c0f3d" \ -H "Authorization: ApiKey ${API_KEY}"
The full visualization state including the chart configuration and metadata.
{- "id": "1e4f0a30-b3c5-11ef-bd7a-2b6b1a8c0f3d",
- "data": {
- "title": "Total requests",
- "data_source": {
- "type": "data_view_spec",
- "index_pattern": "kibana_sample_data_logs",
- "time_field": "timestamp"
}, - "type": "metric",
- "sampling": 1,
- "ignore_global_filters": false,
- "metrics": [
- {
- "type": "primary",
- "operation": "count",
- "empty_as_null": false
}
], - "styling": {
- "primary": {
- "position": "bottom",
- "labels": {
- "alignment": "left"
}, - "value": {
- "sizing": "auto",
- "alignment": "right"
}
}
}
}, - "meta": {
- "created_at": "2026-04-13T10:00:00.000Z",
- "managed": false,
- "updated_at": "2026-04-13T10:00:00.000Z",
- "version": "WzU5LDFd"
}
}Spaces method and path for this operation:
Refer to Spaces for more information.
Replaces the full configuration of an existing Lens visualization. Partial updates are not supported. To make incremental changes, retrieve the visualization first, modify the fields you need, then send the complete object back.
If no visualization exists with the specified ID, a new one is created.
ES|QL visualizations cannot be updated through this endpoint.
| id required | string The visualization identifier, as returned by the create or search endpoints. |
| kbn-xsrf required | string Example: true A required header to protect against CSRF attacks |
Date Histogram Operation (object) or Terms Operation (object) or Histogram Operation (object) or Ranges Operation (object) or Filters Operation (object) | |
required | Data view reference (object) or Data view inline spec (object) |
| description | string |
Array of dashboard_drilldown (object) or discover_drilldown (object) or url_drilldown (object) <= 100 items | |
Array of condition (object) or group (object) or dsl (object) or spatial (object) (lensPanelFilters) <= 100 items Filters applied to the panel | |
| hide_border | boolean |
| hide_title | boolean |
| ignore_global_filters | boolean Default: false When |
required | Array of ((Count Metric Operation (object) or Unique Count Metric Operation (object) or Stats Metric Operation (object) or Sum Metric Operation (object) or Last Value Operation (object) or Percentile Operation (object) or Percentile Ranks Operation (object)) or (Differences Operation (object) or Moving Average Operation (object) or Cumulative Sum Operation (object) or Counter Rate Operation (object)) or Formula Operation (object)) or ((Count Metric Operation (object) or Unique Count Metric Operation (object) or Stats Metric Operation (object) or Sum Metric Operation (object) or Last Value Operation (object) or Percentile Operation (object) or Percentile Ranks Operation (object)) or (Differences Operation (object) or Moving Average Operation (object) or Cumulative Sum Operation (object) or Counter Rate Operation (object)) or Formula Operation (object)) [ 1 .. 2 ] items Metric dimensions to display. The first must be a primary metric; an optional second must be a secondary metric. |
required | object (Filter) A KQL or Lucene query that filters panel data. Applied on top of any dashboard-level filters. |
Array of objects (kbn-content-management-utils-referenceSchema) | |
| sampling | number [ 0 .. 1 ] Default: 1 Sampling factor between 0 (no sampling) and 1 (full sampling). |
object (metricStyling) Visual chart styling options | |
object (Time range) Specifies the time range for a query. | |
| title | string |
| type required | string Value: "metric" |
{- "breakdown_by": {
- "collapse_by": "avg",
- "columns": 3,
- "drop_partial_intervals": true,
- "field": "string",
- "include_empty_rows": true,
- "label": "string",
- "operation": "date_histogram",
- "suggested_interval": "auto",
- "use_original_time_range": false
}, - "data_source": {
- "ref_id": "string",
- "type": "data_view_reference"
}, - "description": "string",
- "drilldowns": [
- {
- "dashboard_id": "string",
- "label": "string",
- "open_in_new_tab": false,
- "trigger": "on_apply_filter",
- "type": "dashboard_drilldown",
- "use_filters": true,
- "use_time_range": true
}
], - "filters": [
- {
- "condition": {
- "field": "string",
- "negate": true,
- "operator": "is",
- "value": "string"
}, - "controlled_by": "string",
- "data_view_id": "string",
- "disabled": true,
- "is_multi_index": true,
- "label": "string",
- "negate": true,
- "type": "condition"
}
], - "hide_border": true,
- "hide_title": true,
- "ignore_global_filters": false,
- "metrics": [
- {
- "apply_color_to": "value",
- "background_chart": {
- "max_value": {
- "filter": {
- "expression": "string",
- "language": "kql"
}, - "format": {
- "compact": false,
- "decimals": 2,
- "suffix": "string",
- "type": "number"
}, - "formula": "string",
- "label": "string",
- "operation": "formula",
- "reduced_time_range": "string",
- "time_scale": "s"
}, - "orientation": "horizontal",
- "type": "bar"
}, - "color": {
- "range": "absolute",
- "steps": [
- {
- "color": "string",
- "gte": 0,
- "lt": 0,
- "lte": 0
}
], - "type": "dynamic"
}, - "empty_as_null": false,
- "field": "string",
- "filter": {
- "expression": "string",
- "language": "kql"
}, - "format": {
- "compact": false,
- "decimals": 2,
- "suffix": "string",
- "type": "number"
}, - "label": "string",
- "operation": "count",
- "reduced_time_range": "string",
- "subtitle": "string",
- "time_scale": "s",
- "time_shift": "string",
- "type": "primary"
}
], - "query": {
- "expression": "string",
- "language": "kql"
}, - "references": [
- {
- "id": "string",
- "name": "string",
- "type": "string"
}
], - "sampling": 1,
- "styling": {
- "icon": {
- "alignment": "left",
- "name": "alert"
}, - "primary": {
- "labels": {
- "alignment": "left"
}, - "position": "top",
- "value": {
- "alignment": "left",
- "sizing": "auto"
}
}, - "secondary": {
- "label": {
- "placement": "before",
- "visible": true
}, - "value": {
- "alignment": "left"
}
}
}, - "time_range": {
- "from": "string",
- "mode": "absolute",
- "to": "string"
}, - "title": "string",
- "type": "metric"
}The complete updated visualization state after a full replacement. PUT replaces the entire chart configuration — fields omitted from the request are reset to their defaults. meta.created_at reflects the update time rather than the original creation time.
{- "id": "1e4f0a30-b3c5-11ef-bd7a-2b6b1a8c0f3d",
- "data": {
- "title": "Total requests (updated)",
- "data_source": {
- "type": "data_view_spec",
- "index_pattern": "kibana_sample_data_logs",
- "time_field": "timestamp"
}, - "type": "metric",
- "sampling": 1,
- "ignore_global_filters": false,
- "metrics": [
- {
- "type": "primary",
- "operation": "count",
- "empty_as_null": false
}
], - "styling": {
- "primary": {
- "position": "bottom",
- "labels": {
- "alignment": "left"
}, - "value": {
- "sizing": "auto",
- "alignment": "right"
}
}
}
}, - "meta": {
- "created_at": "2026-04-13T11:00:00.000Z",
- "managed": false,
- "updated_at": "2026-04-13T11:00:00.000Z",
- "version": "WzYxLDFd"
}
}