Best approach to create visualizations/dashboard via API calls?

Hi.
I'm trying to create a visualization in Kibana via API calls. So far i'm a little bit confused on how to do this. Please try to follow me.. and correct me if i'm wrong...
So far i discovered two types of API calls...

  1. One for Elasticsearch (https://www.elastic.co/guide/en/elasticsearch/reference/current/docs.html) (which can be called even from the dev tools via kibana web). This set of APIs is called to port 9200

  2. And the other set of APIs from Kibana (https://www.elastic.co/guide/en/kibana/7.x/saved-objects-api.html). This set of APIs is called to port 5601

So far i was able to get via API (Elasticsearch and Kibana) the "visualizations" or "dashboards" already created in my platform. So far so good. But the problem i have found is how to create a new Visualization or Dashboard.... which API do i need to use or which API is recommended for this task?. Seems that the Kibana API's are more suited for this... i have discovered that the API's for "Saved Objects" seems to manage the creation of dashboards and visualizations better. But here i'm a little bit lost with the documentation... for example... i want to create a Timeseries visualization and in the kibana web there are a lot of parameters to configure.... where can i find docs related to this?. so far i have run an example like this:

POST localhost:5601/api/saved_objects/visualization/mivis2
{
    "attributes": {
        "title": "Mi Visualizacion 2",
        "visState": "{\"title\":\"Mi Visualizacion 2\",\"type\":\"timeseries\"}"
    }
}

I'm getting this:

{
    "type": "visualization",
    "id": "mivis2",
    "attributes": {
        "title": "Mi Visualizacion 2",
        "visState": "{\"title\":\"Mi Visualizacion 2\",\"type\":\"timeseries\"}"
    },
    "references": [],
    "migrationVersion": {
        "visualization": "7.11.0"
    },
    "updated_at": "2021-04-16T20:25:39.409Z",
    "version": "WzIxODQzNywyXQ==",
    "namespaces": [
        "default"
    ]
}

Seems the paramenter "visState" contain the configuration for this Timeseries... but i'm not sure ...
For the latter POST i'm getting this in the web:

but I'm missing a lot of parameters...

On the other hand maybe the Kibana API is not the best way to do this and the API's for Elasticsearch is the solution?.
Can someone guide me on this matter??

Thanks!

The Kibana apis are definitely the best approach here. The internal saved object format isn't really documented - I noticed the approach that works best is to build a visualization close to what you want to automate manually in the UI, export the result and look and the resulting json structure. This will give you a good hunch at how things work.

Let me know whether you have specific questions starting from there.

Hi Joe.
Thanks for pointing me in the correct direction. So ..i'm doing a GET for a "saved object" which is a Visualization.
Something like this:

GET http://localhost:5601/api/saved_objects/visualization/09cc94f0-98bf-11eb-93bf-9755e86f79b7

I'm getting this JSON:

{
    "id": "09cc94f0-98bf-11eb-93bf-9755e86f79b7",
    "type": "visualization",
    "namespaces": [
        "default"
    ],
    "updated_at": "2021-04-12T14:29:27.524Z",
    "version": "WzE2NTI5NSwxXQ==",
    "attributes": {
        "title": "New V1 OUT",
        "visState": "{\"title\":\"New V1 OUT\",\"type\":\"metrics\",\"aggs\":[],\"params\":{\"id\":\"61ca57f0-469d-11e7-af02-69e470af7417\",\"type\":\"timeseries\",\"series\":[{\"id\":\"61ca57f1-469d-11e7-af02-69e470af7417\",\"color\":\"#68BC00\",\"split_mode\":\"everything\",\"split_color_mode\":\"kibana\",\"metrics\":[{\"id\":\"61ca57f2-469d-11e7-af02-69e470af7417\",\"type\":\"avg\",\"field\":\"totalcalls\"}],\"separate_axis\":0,\"axis_position\":\"right\",\"formatter\":\"number\",\"chart_type\":\"bar\",\"line_width\":1,\"point_size\":1,\"fill\":0.5,\"stacked\":\"none\",\"label\":\"LLamadas\",\"type\":\"timeseries\",\"hidden\":false},{\"id\":\"474da090-98be-11eb-a954-47101132062a\",\"color\":\"rgba(211,96,134,1)\",\"split_mode\":\"everything\",\"metrics\":[{\"id\":\"474da091-98be-11eb-a954-47101132062a\",\"type\":\"avg\",\"field\":\"totalcalls\"},{\"model_type\":\"simple\",\"alpha\":0.3,\"beta\":0.1,\"gamma\":0.3,\"period\":1,\"multiplicative\":true,\"window\":5,\"id\":\"6afd85a0-98be-11eb-a954-47101132062a\",\"type\":\"moving_average\",\"field\":\"474da091-98be-11eb-a954-47101132062a\"}],\"separate_axis\":0,\"axis_position\":\"right\",\"formatter\":\"number\",\"chart_type\":\"line\",\"line_width\":1,\"point_size\":1,\"fill\":\"0\",\"stacked\":\"none\",\"label\":\"Promedio\",\"type\":\"timeseries\"}],\"time_field\":\"@fecha_exe\",\"index_pattern\":\"calls*\",\"interval\":\">=1m\",\"axis_position\":\"left\",\"axis_formatter\":\"number\",\"axis_scale\":\"normal\",\"show_legend\":0,\"show_grid\":1,\"tooltip_mode\":\"show_all\",\"default_index_pattern\":\"kibana_sample_data_flights\",\"default_timefield\":\"timestamp\",\"isModelInvalid\":false,\"filter\":{\"query\":\"user.keyword :\\\"usuario1\\\" and fields.type.keyword :\\\"outbound-activecalls\\\" \",\"language\":\"kuery\"},\"legend_position\":\"bottom\",\"background_color_rules\":[{\"id\":\"7ca3f460-98be-11eb-a954-47101132062a\"}],\"time_range_mode\":\"entire_time_range\"}}",
        "uiStateJSON": "{}",
        "description": "",
        "version": 1,
        "kibanaSavedObjectMeta": {
            "searchSourceJSON": "{\"query\":{\"query\":\"\",\"language\":\"kuery\"},\"filter\":[]}"
        }
    },
    "references": [],
    "migrationVersion": {
        "visualization": "7.11.0"
    }
}

According to my needs the key parameter seems to be the visState.. so regarding to this parameter my doubts are:

  • The first id parameter is the id of the visualization... so far i was able to explicity add it in the inside the API CREATE call... is there a way to make Kibana do this automatically?. Or always i need to generate it?
  • Inside visState parameter seems to be a couple of more id's. Do i need to generate them? or the API call can create them automatically?.

Hope you can clarify me this!.
Thanks!
Ricardo

Hi @flash1293
I made a GET from a saved object.. (a visualization from my kibana), according to the response i created this body, to use it as a POST to CREATE a visualization:

POST /api/saved_objects/visualization/2lpfqhq3-qufg-8o7k-s1n7-xu3u3ge4ej9a

This is the body:

{
    "id": "2lpfqhq3-qufg-8o7k-s1n7-xu3u3ge4ej9a",
    "type": "visualization",
    "namespaces": [
        "default"
    ],
    "attributes": {
        "title": "Llamadas Salientes Test",
        "visState": "{\"title\":\"Llamadas Salientes Test\",\"type\":\"metrics\",\"aggs\":[],\"params\":{\"id\":\"61ca57f0-469d-11e7-af02-69e470af7417\",\"type\":\"timeseries\",\"series\":[{\"id\":\"61ca57f1-469d-11e7-af02-69e470af7417\",\"color\":\"#68BC00\",\"split_mode\":\"everything\",\"split_color_mode\":\"kibana\",\"metrics\":[{\"id\":\"61ca57f2-469d-11e7-af02-69e470af7417\",\"type\":\"avg\",\"field\":\"totalcalls\"}],\"separate_axis\":0,\"axis_position\":\"right\",\"formatter\":\"number\",\"chart_type\":\"bar\",\"line_width\":1,\"point_size\":1,\"fill\":0.5,\"stacked\":\"none\",\"label\":\"LLamadas\",\"type\":\"timeseries\",\"hidden\":false},{\"id\":\"474da090-98be-11eb-a954-47101132062a\",\"color\":\"rgba(211,96,134,1)\",\"split_mode\":\"everything\",\"metrics\":[{\"id\":\"474da091-98be-11eb-a954-47101132062a\",\"type\":\"avg\",\"field\":\"totalcalls\"},{\"model_type\":\"simple\",\"alpha\":0.3,\"beta\":0.1,\"gamma\":0.3,\"period\":1,\"multiplicative\":true,\"window\":5,\"id\":\"6afd85a0-98be-11eb-a954-47101132062a\",\"type\":\"moving_average\",\"field\":\"474da091-98be-11eb-a954-47101132062a\"}],\"separate_axis\":0,\"axis_position\":\"right\",\"formatter\":\"number\",\"chart_type\":\"line\",\"line_width\":1,\"point_size\":1,\"fill\":\"0\",\"stacked\":\"none\",\"label\":\"Promedio\",\"type\":\"timeseries\"}],\"time_field\":\"@fecha_exe\",\"index_pattern\":\"calls*\",\"interval\":\">=1m\",\"axis_position\":\"left\",\"axis_formatter\":\"number\",\"axis_scale\":\"normal\",\"show_legend\":0,\"show_grid\":1,\"tooltip_mode\":\"show_all\",\"default_index_pattern\":\"kibana_sample_data_flights\",\"default_timefield\":\"timestamp\",\"isModelInvalid\":false,\"filter\":{\"query\":\"user.keyword :\\\"user2\\\" and fields.type.keyword :\\\"outbound-activecalls\\\" \",\"language\":\"kuery\"},\"legend_position\":\"bottom\",\"background_color_rules\":[{\"id\":\"7ca3f460-98be-11eb-a954-47101132062a\"}],\"time_range_mode\":\"entire_time_range\"}}",
        "uiStateJSON": "{}",
        "description": "",
        "kibanaSavedObjectMeta": {
            "searchSourceJSON": "{\"query\":{\"query\":\"\",\"language\":\"kuery\"},\"filter\":[]}"
        }
    }
}

But i'm getting this response:

{
    "statusCode": 400,
    "error": "Bad Request",
    "message": "[request body.id]: definition for this key is missing"
}

What could be happening?

Thanks!
Ricardo

The top level id will be set by the id in the path (you can also omit it and Kibana will pick one for you). You only need to specify the attributes, everything else will be taken care of by Kibana. Like in the example here: Create saved objects API | Kibana Guide [7.12] | Elastic

The ids within the visState are only used locally within the visualization. You have to pick them yourself, but they just have to be unique within this saved object (so using '1', '2', '3' will be fine). The Kibana UI uses uuids for this because they will always be unique which makes it easier to generate them in most circumstances.

Hi @flash1293
Thanks for the tips. In fact that made it work. I was able to create visualization and dashboards through the Kibana API calls. !

Best Regards.
Ricardo

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.