VisualizationsClient

Client for the Kibana Visualizations HTTP API.

Note

The Visualizations HTTP API is in technical preview (added in Kibana 9.4.0) and may change in future releases.

Manages Lens visualizations (metric, XY, pie, gauge, heatmap, tag cloud, region map, datatable, mosaic, treemap, waffle, legacy metric) through the /api/visualizations endpoints. Responses use the same {id, data, meta} envelope as the Dashboards API: data holds the chart configuration and meta holds timestamps and version information.

All operations support Kibana spaces via the space_id parameter or a space-scoped client created with client.space("my-space").

class kibana._sync.client.visualizations.VisualizationsClient(client, default_space_id=None, validate_spaces=True)[source]

Bases: NamespaceClient

Client for the Kibana Visualizations HTTP API.

Technical preview in 9.4 (added in 9.4.0). Manages Lens visualizations (metric, XY, pie, gauge, heatmap, tag cloud, region map, datatable, mosaic, treemap, waffle, legacy metric) through the /api/visualizations endpoints. Responses use the same {id, data, meta} envelope as the Dashboards API: data holds the chart configuration and meta holds timestamps and version information.

All operations support Kibana spaces via the space_id parameter or a space-scoped client created with client.space("my-space").

Example

>>> from kibana import Kibana
>>> client = Kibana("http://localhost:5601", api_key="...")
>>>
>>> # Create a metric visualization
>>> created = client.visualizations.create(
...     data={
...         "type": "metric",
...         "title": "Total log documents",
...         "data_source": {
...             "type": "data_view_spec",
...             "index_pattern": "logs-*",
...         },
...         "query": {"expression": "", "language": "kql"},
...         "metrics": [{"type": "primary", "operation": "count"}],
...     }
... )
>>> viz_id = created.body["id"]
>>>
>>> # Search visualizations by title
>>> results = client.visualizations.get_all(query="Total log*")
>>> print(results.body["meta"]["total"])

Creating Visualizations

Create a Lens visualization with the create() method. The data object carries the chart type and configuration:

from kibana import Kibana

client = Kibana("http://localhost:5601", api_key="your_api_key")

# Create a metric visualization
created = client.visualizations.create(
    data={
        "type": "metric",
        "title": "Total log documents",
        "data_source": {
            "type": "data_view_spec",
            "index_pattern": "logs-*",
        },
        "query": {"expression": "", "language": "kql"},
        "metrics": [{"type": "primary", "operation": "count"}],
    }
)

viz_id = created.body["id"]
print(f"Created visualization: {viz_id}")

Retrieving and Searching

# Get a visualization by ID
viz = client.visualizations.get(id=viz_id)
print(viz.body["data"]["title"])

# Search visualizations by title
results = client.visualizations.get_all(query="Total log*")
print(f"Total matches: {results.body['meta']['total']}")

Updating and Deleting

# Replace the visualization configuration
client.visualizations.update(
    id=viz_id,
    data={
        "type": "metric",
        "title": "Total log documents (updated)",
        "data_source": {
            "type": "data_view_spec",
            "index_pattern": "logs-*",
        },
        "query": {"expression": "", "language": "kql"},
        "metrics": [{"type": "primary", "operation": "count"}],
    },
)

# Delete the visualization
client.visualizations.delete(id=viz_id)

Space-Scoped Visualizations

# Target a space explicitly
viz = client.visualizations.create(
    data={"type": "metric", "title": "Marketing metric"},
    space_id="marketing",
)

# Or use a space-scoped client
marketing = client.space("marketing")
viz = marketing.visualizations.get_all()
get_all(*, query=None, search_fields=None, fields=None, page=None, per_page=None, space_id=None, validate_spaces=None)[source]

Search visualizations.

Technical preview in 9.4. Returns a paginated envelope with a data array of {id, data, meta} items and a meta object containing page, per_page and total.

Parameters:
  • query (str | None) – Text to match against search_fields. Supports simple query syntax (e.g. trailing * wildcards).

  • search_fields (str | list[str] | None) – Attribute field(s) the query is matched against (e.g. ["title"]). Note: on live Kibana 9.4.3 this parameter triggers a 500 Internal Server Error (server-side bug in the technical preview API); prefer query alone until fixed upstream.

  • fields (str | list[str] | None) – Attribute field(s) to return in the data payload of each result (e.g. ["title"]); omit to return the full visualization configuration. Note: on live Kibana 9.4.3 this parameter triggers a 500 Internal Server Error whenever the search matches existing objects (server-side bug in the technical preview API).

  • page (int | None) – Page number (default 1).

  • per_page (int | None) – Results per page (default 20, maximum 1000).

  • space_id (str | None) – Optional space ID to scope the operation to.

  • validate_spaces (bool | None) – Override space validation for this call.

Returns:

ObjectApiResponse with data (list of visualizations) and meta (page, per_page, total).

Raises:
Return type:

ObjectApiResponse[Any]

Example

>>> results = client.visualizations.get_all(
...     query="sales*", per_page=10
... )
>>> for item in results.body["data"]:
...     print(item["id"], item["data"]["title"])
create(*, data, overwrite=None, space_id=None, validate_spaces=None)[source]

Create a visualization.

Technical preview in 9.4. The server assigns the visualization ID and returns the created object in the {id, data, meta} envelope.

Parameters:
  • data (dict[str, Any]) – Visualization configuration (the Lens API config). Must include type (one of metric, xy, pie, gauge, heatmap, tagcloud, regionmap, datatable, mosaic, treemap, waffle or a legacy metric), a data_source (data view reference or spec), a query filter and the chart-type-specific dimensions (e.g. metrics for metric charts).

  • overwrite (bool | None) – When True, overwrite an existing object on ID clash.

  • space_id (str | None) – Optional space ID to create the visualization in.

  • validate_spaces (bool | None) – Override space validation for this call.

Returns:

ObjectApiResponse with id, data (normalized configuration) and meta (created_at, updated_at, version …).

Raises:
Return type:

ObjectApiResponse[Any]

Example

>>> created = client.visualizations.create(
...     data={
...         "type": "metric",
...         "title": "Order count",
...         "data_source": {
...             "type": "data_view_spec",
...             "index_pattern": "orders-*",
...         },
...         "query": {"expression": "", "language": "kql"},
...         "metrics": [{"type": "primary", "operation": "count"}],
...     }
... )
>>> print(created.body["id"])
get(*, id, space_id=None, validate_spaces=None)[source]

Get a visualization by ID.

Technical preview in 9.4.

Parameters:
  • id (str) – The visualization ID.

  • space_id (str | None) – Optional space ID to read the visualization from.

  • validate_spaces (bool | None) – Override space validation for this call.

Returns:

ObjectApiResponse with id, data (the visualization configuration) and meta.

Raises:
Return type:

ObjectApiResponse[Any]

Example

>>> viz = client.visualizations.get(id="my-viz-id")
>>> print(viz.body["data"]["title"])
update(*, id, data, space_id=None, validate_spaces=None)[source]

Update (or create with a chosen ID) a visualization.

Technical preview in 9.4. The body fully replaces the stored configuration. If no visualization exists with the given ID the server creates one (upsert; HTTP 201 instead of 200).

Parameters:
  • id (str) – The visualization ID to update or create.

  • data (dict[str, Any]) – Full visualization configuration (same shape as create).

  • space_id (str | None) – Optional space ID the visualization lives in.

  • validate_spaces (bool | None) – Override space validation for this call.

Returns:

ObjectApiResponse with the updated id, data and meta.

Raises:
Return type:

ObjectApiResponse[Any]

Example

>>> updated = client.visualizations.update(
...     id="my-viz-id",
...     data={
...         "type": "metric",
...         "title": "Order count (renamed)",
...         "data_source": {
...             "type": "data_view_spec",
...             "index_pattern": "orders-*",
...         },
...         "query": {"expression": "", "language": "kql"},
...         "metrics": [{"type": "primary", "operation": "count"}],
...     },
... )
>>> print(updated.body["data"]["title"])
delete(*, id, space_id=None, validate_spaces=None)[source]

Delete a visualization by ID.

Technical preview in 9.4. Returns HTTP 204 with an empty body on success.

Parameters:
  • id (str) – The visualization ID to delete.

  • space_id (str | None) – Optional space ID the visualization lives in.

  • validate_spaces (bool | None) – Override space validation for this call.

Returns:

ObjectApiResponse with an empty body (HTTP 204 No Content).

Raises:
Return type:

ObjectApiResponse[Any]

Example

>>> client.visualizations.delete(id="my-viz-id")
__init__(client, default_space_id=None, validate_spaces=True)

Initialize NamespaceClient with optional space support.

Parameters:
  • client (BaseClient) – Parent BaseClient instance to delegate requests to

  • default_space_id (str | None) – Optional default space ID for all operations

  • validate_spaces (bool) – Whether to validate space existence (default: True)

perform_request(method, path, *, params=None, headers=None, body=None)

Perform an HTTP request via the parent client with space context enhancement.

Parameters:
  • method (str) – HTTP method (GET, POST, PUT, DELETE, etc.)

  • path (str) – API endpoint path

  • params (dict[str, Any] | None) – Query parameters

  • headers (dict[str, str] | None) – Request headers

  • body (dict[str, Any] | None) – Request body

Returns:

API response

Raises:

ApiError – If the API returns an error response (enhanced with space context)

Return type:

ObjectApiResponse[Any]

AsyncVisualizationsClient

Asynchronous version of the VisualizationsClient for use with async/await syntax.

class kibana._async.client.visualizations.AsyncVisualizationsClient(client, default_space_id=None, validate_spaces=True)[source]

Bases: AsyncNamespaceClient

Async client for the Kibana Visualizations HTTP API.

Technical preview in 9.4 (added in 9.4.0). Manages Lens visualizations (metric, XY, pie, gauge, heatmap, tag cloud, region map, datatable, mosaic, treemap, waffle, legacy metric) through the /api/visualizations endpoints. Responses use the same {id, data, meta} envelope as the Dashboards API: data holds the chart configuration and meta holds timestamps and version information.

All operations support Kibana spaces via the space_id parameter or a space-scoped client created with client.space("my-space").

Example

>>> from kibana import AsyncKibana
>>> client = AsyncKibana("http://localhost:5601", api_key="...")
>>>
>>> # Create a metric visualization
>>> created = await client.visualizations.create(
...     data={
...         "type": "metric",
...         "title": "Total log documents",
...         "data_source": {
...             "type": "data_view_spec",
...             "index_pattern": "logs-*",
...         },
...         "query": {"expression": "", "language": "kql"},
...         "metrics": [{"type": "primary", "operation": "count"}],
...     }
... )
>>> viz_id = created.body["id"]
>>>
>>> # Search visualizations by title
>>> results = await client.visualizations.get_all(query="Total log*")
>>> print(results.body["meta"]["total"])

Usage

The AsyncVisualizationsClient provides the same methods as VisualizationsClient but all methods are async and must be awaited:

from kibana import AsyncKibana
import asyncio

async def main():
    async with AsyncKibana("http://localhost:5601") as client:
        # Create a visualization (async)
        created = await client.visualizations.create(
            data={
                "type": "metric",
                "title": "Async metric",
                "data_source": {
                    "type": "data_view_spec",
                    "index_pattern": "logs-*",
                },
                "query": {"expression": "", "language": "kql"},
                "metrics": [{"type": "primary", "operation": "count"}],
            }
        )

        # Search visualizations (async)
        results = await client.visualizations.get_all(query="Async*")

        # Delete (async)
        await client.visualizations.delete(id=created.body["id"])

asyncio.run(main())
async get_all(*, query=None, search_fields=None, fields=None, page=None, per_page=None, space_id=None, validate_spaces=None)[source]

Search visualizations.

Technical preview in 9.4. Returns a paginated envelope with a data array of {id, data, meta} items and a meta object containing page, per_page and total.

Parameters:
  • query (str | None) – Text to match against search_fields. Supports simple query syntax (e.g. trailing * wildcards).

  • search_fields (str | list[str] | None) – Attribute field(s) the query is matched against (e.g. ["title"]). Note: on live Kibana 9.4.3 this parameter triggers a 500 Internal Server Error (server-side bug in the technical preview API); prefer query alone until fixed upstream.

  • fields (str | list[str] | None) – Attribute field(s) to return in the data payload of each result (e.g. ["title"]); omit to return the full visualization configuration. Note: on live Kibana 9.4.3 this parameter triggers a 500 Internal Server Error whenever the search matches existing objects (server-side bug in the technical preview API).

  • page (int | None) – Page number (default 1).

  • per_page (int | None) – Results per page (default 20, maximum 1000).

  • space_id (str | None) – Optional space ID to scope the operation to.

  • validate_spaces (bool | None) – Override space validation for this call.

Returns:

ObjectApiResponse with data (list of visualizations) and meta (page, per_page, total).

Raises:
Return type:

ObjectApiResponse[Any]

Example

>>> results = await client.visualizations.get_all(
...     query="sales*", per_page=10
... )
>>> for item in results.body["data"]:
...     print(item["id"], item["data"]["title"])
async create(*, data, overwrite=None, space_id=None, validate_spaces=None)[source]

Create a visualization.

Technical preview in 9.4. The server assigns the visualization ID and returns the created object in the {id, data, meta} envelope.

Parameters:
  • data (dict[str, Any]) – Visualization configuration (the Lens API config). Must include type (one of metric, xy, pie, gauge, heatmap, tagcloud, regionmap, datatable, mosaic, treemap, waffle or a legacy metric), a data_source (data view reference or spec), a query filter and the chart-type-specific dimensions (e.g. metrics for metric charts).

  • overwrite (bool | None) – When True, overwrite an existing object on ID clash.

  • space_id (str | None) – Optional space ID to create the visualization in.

  • validate_spaces (bool | None) – Override space validation for this call.

Returns:

ObjectApiResponse with id, data (normalized configuration) and meta (created_at, updated_at, version …).

Raises:
Return type:

ObjectApiResponse[Any]

Example

>>> created = await client.visualizations.create(
...     data={
...         "type": "metric",
...         "title": "Order count",
...         "data_source": {
...             "type": "data_view_spec",
...             "index_pattern": "orders-*",
...         },
...         "query": {"expression": "", "language": "kql"},
...         "metrics": [{"type": "primary", "operation": "count"}],
...     }
... )
>>> print(created.body["id"])
async get(*, id, space_id=None, validate_spaces=None)[source]

Get a visualization by ID.

Technical preview in 9.4.

Parameters:
  • id (str) – The visualization ID.

  • space_id (str | None) – Optional space ID to read the visualization from.

  • validate_spaces (bool | None) – Override space validation for this call.

Returns:

ObjectApiResponse with id, data (the visualization configuration) and meta.

Raises:
Return type:

ObjectApiResponse[Any]

Example

>>> viz = await client.visualizations.get(id="my-viz-id")
>>> print(viz.body["data"]["title"])
async update(*, id, data, space_id=None, validate_spaces=None)[source]

Update (or create with a chosen ID) a visualization.

Technical preview in 9.4. The body fully replaces the stored configuration. If no visualization exists with the given ID the server creates one (upsert; HTTP 201 instead of 200).

Parameters:
  • id (str) – The visualization ID to update or create.

  • data (dict[str, Any]) – Full visualization configuration (same shape as create).

  • space_id (str | None) – Optional space ID the visualization lives in.

  • validate_spaces (bool | None) – Override space validation for this call.

Returns:

ObjectApiResponse with the updated id, data and meta.

Raises:
Return type:

ObjectApiResponse[Any]

Example

>>> updated = await client.visualizations.update(
...     id="my-viz-id",
...     data={
...         "type": "metric",
...         "title": "Order count (renamed)",
...         "data_source": {
...             "type": "data_view_spec",
...             "index_pattern": "orders-*",
...         },
...         "query": {"expression": "", "language": "kql"},
...         "metrics": [{"type": "primary", "operation": "count"}],
...     },
... )
>>> print(updated.body["data"]["title"])
async delete(*, id, space_id=None, validate_spaces=None)[source]

Delete a visualization by ID.

Technical preview in 9.4. Returns HTTP 204 with an empty body on success.

Parameters:
  • id (str) – The visualization ID to delete.

  • space_id (str | None) – Optional space ID the visualization lives in.

  • validate_spaces (bool | None) – Override space validation for this call.

Returns:

ObjectApiResponse with an empty body (HTTP 204 No Content).

Raises:
Return type:

ObjectApiResponse[Any]

Example

>>> await client.visualizations.delete(id="my-viz-id")
__init__(client, default_space_id=None, validate_spaces=True)

Initialize AsyncNamespaceClient with optional space support.

Parameters:
  • client (AsyncBaseClient) – Parent AsyncBaseClient instance to delegate requests to

  • default_space_id (str | None) – Optional default space ID for all operations

  • validate_spaces (bool) – Whether to validate space existence (default: True)

async perform_request(method, path, *, params=None, headers=None, body=None)

Perform an async HTTP request via the parent client with space context enhancement.

Parameters:
  • method (str) – HTTP method (GET, POST, PUT, DELETE, etc.)

  • path (str) – API endpoint path

  • params (dict[str, Any] | None) – Query parameters

  • headers (dict[str, str] | None) – Request headers

  • body (dict[str, Any] | None) – Request body

Returns:

API response

Raises:

ApiError – If the API returns an error response (enhanced with space context)

Return type:

ObjectApiResponse[Any]