SigNoz is rolling out a redesigned Dashboards experience. Your existing dashboards, queries, variables, and panels continue to work exactly as they do now. This release keeps all of that intact and adds improvements that make dashboards easier to find, organize, and manage at scale.
Dashboards get easier to find and manage: organize with key-value tags, personal pins, shared saved views, and quick cloning, plus a defined JSON/Terraform schema that enables direct editing, partial (token-efficient) updates, and reliable AI-driven changes.Panels get more expressive: new styling controls (fill mode, line interpolation, disconnect lines, show points) and PNG/SVG export for sharing in reports and incident write-ups.
What you need to know
- Dashboards will be migrated in the week of 27th July.
- Nothing breaks on the platform. Your existing dashboards keep working, and this rolls out alongside them.
- If you don't use Terraform or don't have any scripts directly working with the SigNoz Dashboards APIs, no action is required from you today.
If you have scripts that use the Dashboards API directly
We suggest you migrate those scripts to use the new V2 Dashboards APIs. You can follow the examples in this guide below.
If you have dashboards synced via Terraform
The Terraform Provider release corresponding to this SigNoz release will contain the required script to migrate your resources to the new schema. You can run that, then arrange your resources and define any variables on top of that. See the Terraform provider guide for details.
Dashboards V2 API Guide
Dashboards APIs now work on a properly enforced schema that follows the Perses schema guidelines.
A dashboard is divided into layouts, and each layout has panels arranged in it. Variables can be used to filter data across panels as before.
Dashboards also have tags as key: value
pairs, which help organize them into groups and provide an easy way to query by key or value.
The full schema can be seen in the payload of the new Create Dashboard API.
Bird's eye view of the dashboards schema
{
"tags": [
{
"key": "string",
"value": "string"
}
],
"spec": {
"display": {
"name": "string",
"description": "string"
},
"layouts": [],
"panels": {
"panel-name": { /* panel details */ }
},
"variables": []
}
}
Dashboard APIs
The List and CRUD (Create, Read, Update, Delete) APIs for dashboards all now get a V2 variant:
GET /api/v2/dashboards -- List Dashboards
POST /api/v2/dashboards -- Create a Dashboard
GET /api/v2/dashboards/{id} -- Fetch Details for a Dashboard
PUT /api/v2/dashboards/{id} -- Update a Dashboard
DELETE /api/v2/dashboards/{id} -- Delete a Dashboard
Locking and unlocking a dashboard get new endpoints:
PUT /api/v2/dashboards/{id}/lock -- Lock a Dashboard
DELETE /api/v2/dashboards/{id}/lock -- Unlock a Dashboard
Users can now personally pin any dashboard, so there's a special List API to get dashboards that takes pins into account:
GET /api/v2/users/me/dashboards -- List Dashboards for a User
The biggest quality-of-life improvement is the new partial updates API, so that updating dashboards no longer involves building the whole dashboard JSON again:
PATCH /api/v2/dashboards/{id} -- Patch a Dashboard
Full details of all the APIs are present in the API Reference.
New listing APIs
Both List APIs (the user-agnostic one and the user-specific one) now support pagination. They also get a proper query field where dashboards can be searched by name, description, tags, and other properties using many different operations.
Following are some examples. Only the path differs between the two APIs; the API query parameters can be passed the same way.
## Get 20 latest dashboards
curl --location '<YOUR-SIGNOZ-URL>/api/v2/dashboards?limit=20' \
--header 'SIGNOZ-API-KEY: <YOUR-API-KEY>'
## Get the next 20 latest dashboards
curl --location '<YOUR-SIGNOZ-URL>/api/v2/dashboards?limit=20&offset=20' \
--header 'SIGNOZ-API-KEY: <YOUR-API-KEY>'
## Get the first 20 dashboards sorted in alphabetical order
curl --location '<YOUR-SIGNOZ-URL>/api/v2/dashboards?sort=name&order=asc&limit=20' \
--header 'SIGNOZ-API-KEY: <YOUR-API-KEY>'
Some examples of the query DSL:
## Get dashboards that contain "prod" in their name
## Unencoded query: name contains prod
curl --location '<YOUR-SIGNOZ-URL>/api/v2/dashboards?query=name%20contains%20prod&limit=20' \
--header 'SIGNOZ-API-KEY: <YOUR-API-KEY>'
## Get dashboards that have the `env = prod` tag on them or have "prod" in their name
## Unencoded query: name contains prod OR env = prod
curl --location '<YOUR-SIGNOZ-URL>/api/v2/dashboards?query=name%20contains%20prod%20OR%20env%20%3D%20prod&limit=20' \
--header 'SIGNOZ-API-KEY: <YOUR-API-KEY>'
Partial updates API
This API allows for pinpointed updates to a dashboard, which makes building requests much easier.
For example, updating the description of a dashboard is just this:
curl --location --request PATCH '<YOUR-SIGNOZ-URL>/api/v2/dashboards/<ID>' \
--header 'SIGNOZ-API-KEY: <YOUR-API-KEY>' \
--data '[
{
"op": "add",
"path": "/spec/display/description",
"value": "New Description"
}
]'
Adding a tag:
curl --location --request PATCH '<YOUR-SIGNOZ-URL>/api/v2/dashboards/<ID>' \
--header 'SIGNOZ-API-KEY: <YOUR-API-KEY>' \
--data '[
{
"op": "add",
"path": "/tags/-",
"value": {
"key": "env",
"value": "prod"
}
}
]'
Changing the value for a tag:
curl --location --request PATCH '<YOUR-SIGNOZ-URL>/api/v2/dashboards/<ID>' \
--header 'SIGNOZ-API-KEY: <YOUR-API-KEY>' \
--data '[
{
"op": "replace",
"path": "/tags/0/value",
"value": "production"
}
]'
Adding a new panel involves one request object to add the panel, and another to add it to the layout:
curl --location --request PATCH '<YOUR-SIGNOZ-URL>/api/v2/dashboards/<ID>' \
--header 'SIGNOZ-API-KEY: <YOUR-API-KEY>' \
--data '[
{
"op": "add",
"path": "/spec/panels/196021a6-3b94-454c-9c9d-2b4170708038",
"value": {
"kind": "Panel",
"spec": {
"display": {
"name": "CPU Time"
},
"plugin": {
"kind": "signoz/TimeSeriesPanel",
"spec": {
"visualization": {
"timePreference": "global_time"
},
"legend": {
"position": "bottom"
},
"chartAppearance": {
"lineStyle": "solid",
"lineInterpolation": "spline",
"fillMode": "none"
},
"formatting": {
"unit": "s"
}
}
},
"queries": [
{
"kind": "time_series",
"spec": {
"plugin": {
"kind": "signoz/CompositeQuery",
"spec": {
"queries": [
{
"type": "builder_query",
"spec": {
"name": "A",
"signal": "metrics",
"source": "",
"stepInterval": null,
"disabled": false,
"filter": {
"expression": ""
},
"having": {
"expression": ""
},
"aggregations": [
{
"metricName": "system.cpu.time",
"timeAggregation": "rate",
"spaceAggregation": "sum"
}
]
}
}
]
}
}
}
}
]
}
}
},
{
"op": "add",
"path": "/spec/layouts/0/spec/items/-",
"value": {
"x": 0,
"y": 6,
"width": 6,
"height": 6,
"content": {
"$ref": "#/spec/panels/196021a6-3b94-454c-9c9d-2b4170708038"
}
}
}
]'
Updating the filter in a query inside a panel, for example the panel added above:
curl --location --request PATCH '<YOUR-SIGNOZ-URL>/api/v2/dashboards/<ID>' \
--header 'SIGNOZ-API-KEY: <YOUR-API-KEY>' \
--data '[
{
"op": "replace",
"path": "/spec/panels/196021a6-3b94-454c-9c9d-2b4170708038/spec/queries/0/spec/plugin/spec/queries/0/spec/filter/expression",
"value": "service.name = '\''signoz'\''"
}
]'
Removing a panel involves one request object to remove the panel, and another to remove it from the layout it is in (check which layout, and within that layout which item the panel is in, then remove that whole item):
curl --location --request PATCH '<YOUR-SIGNOZ-URL>/api/v2/dashboards/<ID>' \
--header 'SIGNOZ-API-KEY: <YOUR-API-KEY>' \
--data '[
{
"op": "remove",
"path": "/spec/panels/196021a6-3b94-454c-9c9d-2b4170708038"
},
{
"op": "remove",
"path": "/spec/layouts/0/spec/items/3"
}
]'
Adding a variable is similar to adding a tag. Here's an example of adding a dynamic variable named httproute
that takes values from the http.route
attribute:
curl --location --request PATCH '<YOUR-SIGNOZ-URL>/api/v2/dashboards/<ID>' \
--header 'SIGNOZ-API-KEY: <YOUR-API-KEY>' \
--data '[
{
"op": "add",
"path": "/spec/variables/-",
"value": {
"kind": "ListVariable",
"spec": {
"name": "httproute",
"display": {
"name": "httproute",
"description": ""
},
"allowMultiple": false,
"allowAllValue": true,
"sort": "none",
"plugin": {
"kind": "signoz/DynamicVariable",
"spec": {
"name": "http.route",
"signal": ""
}
}
}
}
}
]'
Removing a variable just requires knowing the index it is on in the variables array:
curl --location --request PATCH '<YOUR-SIGNOZ-URL>/api/v2/dashboards/<ID>' \
--header 'SIGNOZ-API-KEY: <YOUR-API-KEY>' \
--data '[
{
"op": "remove",
"path": "/spec/variables/2"
}
]'