kibana-dashboards
Create and manage Kibana Dashboards and Lens visualizations. Use when you need to define dashboards and visualizations declaratively, version control them, or automate their deployment.
By elastic · 3,415 installs
npx skills add elastic/agent-skills --skill kibana-dashboards
Source repository · Upstream listing
Kibana Dashboards and Lens Visualizations
Create, update, and delete Kibana dashboards and standalone Lens visualizations using the Kibana 9.4+ Dashboards and
Visualizations APIs. Produce minimal, diffable JSON bodies; prefer inline panel definitions over library references;
choose the correct dataset type (data view vs ES QL) before writing metrics or chart layers; and follow the design
guidance in [Dashboard Design Guidelines](references/dashboard design.md) and
[Chart Design Guidelines](references/chart design.md) so the result reads like a well made Kibana dashboard, not a
schema dump.
<! begin partial: preamble
Environment Configuration
This skill executes Elasticsearch operations through the elastic CLI. If the
[ elastic CLI](https://github.com/elastic/cli configuration) is not installed, tell the user what it is needed for. Do
not guess credentials, call the HTTP API directly, or attempt other workarounds.
This skill references operations in HTTP shorthand form (e.g., GET / , GET / cat/indices , GET /{index}/ mapping ,
GET /{index}/ settings/index.mode , POST / query ). The [Operations]( operations) table at the end of this document
maps each shorthand to the equivalent elastic CLI command — always use the CLI rather than calling the HTTP API
directly.
<! end partial: preamble
Prerequisites
Version requirement: Kibana 9.4+ (Dashboards and Visualizations APIs).
ES QL placement:
Standalone library charts: PUT kbn:/api/visualizations/{id} with data source.type: "esql" .
ES QL panels embedded in a dashboard: inline vis panel config with data source.type: "esql" via
PUT kbn:/api/dashboards/{id} .
Do not use data source.type: "data view reference" or index pattern aggregations when the user explicitly requests
ES QL — the persisted Lens state must use a text based ES QL datasource ( textBased / esql ), not a data view count
operation.
Process
1. Verify Kibana connectivity. Call GET kbn:/api/status . If the call fails, stop and surface the error — do not
guess endpoints or credentials. Read version.number to confirm the cluster meets the 9.4+ requirement, and keep the
version in mind: a few settings are marked 9.5+ or 9.6+ in [Design essentials]( design essentials) and have a
fallback for older clusters. Never refuse a dashboard on 9.4 because of them.
2. Classify the task. Decide whether the user needs a dashboard (collection of panels, optional time range), a
standalone Lens visualization (library item referenced by id or used alone), or both . Determine whether a
deterministic saved object id was supplied — when given, use upsert ( PUT ) with that id rather than POST (which
auto generates ids).
3. Choose the dataset type before building metrics or layers.
User intent Dataset Metric / axis pattern
Simple count or aggregation on a saved data view data source.type: "data view reference" with ref id metrics: [{ type: "primary", operation: "count" }] (or other aggregation operations)
Ad hoc index pattern data source.type: "data view spec" with index pattern and time field Same aggregation operation fields
ES\ QL query (explicit or complex logic) data source.type: "esql" with query metrics: [{ type: "primary", column: "<alias " }] or layer axes { column: "<alias " } — never operation: "count" on the metric
Write the aggregation in the ES QL query ( STATS count = COUNT() ), then reference the resulting column by name.
Write the ES QL with the elasticsearch esql skill. It covers schema discovery, time series data streams ( TS ,
RATE for counters, METRICS INFO ), and query execution. Two dashboard specific points on top of it:
Run every panel query before saving it, substituting fixed expressions such as NOW() 7 days for ? tstart and
? tend , which only Kibana can supply.
Check the data's time span ( STATS MIN(@timestamp), MAX(@timestamp) ). Without a saved time range , Kibana opens
the dashboard on the last 15 minutes, so a dashboard over older or historical data renders empty panels. Tell the
user which range shows data, or ask whether to persist one.
4. Design before you write. Read [Dashboard Design Guidelines](references/dashboard design.md) and
[Chart Design Guidelines](references/chart design.md) and decide the composition, the chart type and grid size of
each panel, the per chart presentation settings, and the exact grid coordinates. The rules most often missed are
summarized in [Design essentials]( design essentials) below. Choices you do not make deliberately fall back to those
defaults; they are not optional polish.
5. Build a dashboard body when creating or updating dashboards. The request body is flat — title , panels , and
optional description , time range , and pinned panels at the root. Do not wrap in { data: ... } on write.
Required fields:
title — exact string the user requested; otherwise a title derived from what the panels measure. Never empty.
description — set on every new dashboard.
panels — array of panels and sections; use [] when the user asks for an empty dashboard (do not omit the key or
invent panels).
time range — when the user specifies a default time filter, set { "from": "<expr ", "to": "<expr " } (for
example { "from": "now 7d", "to": "now" } ). Supplying time range persists the dashboard time filter on open
(equivalent to enabling time restore in the UI). Do not invent a range the user did not ask for.
pinned panels — the controls chosen in the design step (see the Controls section of the design guidelines).
Upsert with a deterministic id:
Call PUT kbn:/api/dashboards/eval sales overview with the body above when the user supplies that id.
Inline ES QL metric panel example (inside panels ):
The metric has no title because its label already names it, and it is a quarter width, 5 row panel — both are
design defaults, not stylistic choices. Prefer inline config properties over config.ref id for portable
dashboards. Read [Dashboard API Reference](references/dashboard api reference.md) for panel types and copy workflows.
6. Build a standalone Lens visualization when the user asks for a library chart. Use the Visualizations API. Upsert
with PUT kbn:/api/visualizations/{id} when an id is supplied; otherwise POST kbn:/api/visualizations and report
the generated id from the response.
ES QL metric (total count from logs):
Call PUT kbn:/api/visualizations/eval total requests when that id is required. The API persists a Lens saved object
whose datasource state uses ES QL ( textBased / esql ), not an index pattern aggregation.
Read [Lens API Reference](references/lens api reference.md) and
[Chart Types Reference](references/chart types reference.md) for xy, gauge, heatmap, and other chart schemas, and
apply the same [Chart Design Guidelines](references/chart design.md) as for dashboard panels.
7. Edit existing objects in place. PUT replaces the whole document, so GET first, change only what was asked,
and send everything else back unchanged — panel id s, queries, filters, controls, and time range included.
8. Execute and confirm. Perform the write with PUT kbn:/api/dashboards/{id} or PUT kbn:/api/visualizations/{id}
(or POST when no id is supplied). Confirm with GET kbn:/api/dashboards/{id} or
GET kbn:/api/visualizations/{id} . Report the id and title back to the user — do not claim success without a
successful read back.
A successful read back proves the object persisted, not that it renders. The API normalizes the body and fills in
defaults. Compare the returned config against what you sent and look for values you did not intend, for example
legend.visibility: "hidden" on a multi series chart.
9. List, export, or delete when requested. Call GET kbn:/api/dashboards or GET kbn:/api/visualizations to
discover existing objects. Call DELETE kbn:/api/dashboards/{id} or DELETE kbn:/api/visualizations/{id} to remove
objects. For bulk export or import of saved objects, call POST kbn:/api/saved objects/ export or
POST kbn:/api/saved objects/ import .
Design essentials
The full rules live in the references; these are the ones most often missed. They apply to every dashboard and
visualization you write.
Version gated settings. Everything else in this skill works on Kibana 9.4. These three need a newer Kibana; below
that version use the fallback instead of the setting.
Setting Needs Fallback on older clusters
options list control with values source: "esql" 9.5 data view id and field name ; create a data view if none covers the index
background chart: { type: "trend" } on an ES\ QL metric 9.5 Omit background chart ; the metric shows the value only
styling: { areas: { fill: "gradient" } } 9.6 Omit styling.areas ; areas render with a solid fill
Dashboard ([Dashboard Design Guidelines](references/dashboard design.md))
Order panels summary metrics → trends → breakdowns. Let the fields drive the panel count; every panel needs a purpose.
Non empty title and a description on every new dashboard, derived from what the queries measure.
Sections ( { title, collapsed, grid: { y }, panels } entries in panels ) for roughly 6+ visualization panels, each
holding only panels matching its purpose. 3–5 options list controls in pinned panels on new dashboards; on an
all ES QL dashboard, source their values from an ES QL query ( values source: "esql" , 9.5+) instead of a data view.
48 column grid, 20–24 rows above the fold, 8–12 panels in that band. Sizes by chart type:
Panel w h
Metric 6, 8, or 12 5–6
Gauge 12 8
XY, heatmap, tag cloud 24 (48 for the primary time series) 10
Treemap / waffle / mosaic 24 10
Pie / donut 12 10
Markdown 24–48 4–9
Data table 24–48 12–16
Never make a metric or gauge full width. Use w values that divide 48. Fill rows left to right; a new row's y is
the previous row's y + max(h) ; panels in a row share h ; x + w ≤ 48 . Kibana compacts panels upward, so blank rows
do not survive — separate groups with sections. Section panels use section relative coordinates and a section occupies
one outer row.
Charts ([Chart Design Guidelines](references/chart design.md))
Pick the chart type from the selection list; tag clouds only for short strings, pies for fewer than about 7 slices.
No panel title on metric, gauge, tag cloud, and waffle charts; elsewhere a self explanatory title and no axis titles
( title: { visible: false } on both axes). Never repeat information across title, axes, and labels.
Natural units via for