The Dynatrace API is your secret weapon for creating dashboards programmatically, turning a manual chore into an automated workflow.
Let’s see it in action. Imagine you want to create a dashboard for a new microservice called user-service. First, you need a dashboard object. This is a JSON structure that defines the dashboard’s properties and its tiles.
{
"dashboardMetadata": {
"name": "User Service Overview",
"owner": "devops-team@example.com",
"sharingDetails": {
"permissions": [
{
"type": "USER",
"name": "devops-team@example.com",
"access": "EDIT"
},
{
"type": "TENANT_GROUP",
"name": "Developers",
"access": "VIEW"
}
]
}
},
"tiles": [
// Tiles will go here
]
}
This basic structure defines the dashboard’s name, who owns it, and who can see or edit it. Now, let’s add a tile. A common tile is a "SMART CHART" which can display various metrics.
{
"tileType": "SMART_CHART",
"name": "Request Throughput",
"configured": true,
"tileSettings": {
"chartType": "LINE",
"series": [
{
"metric": "builtin:service.requestCount.total",
"dimensions": [],
"splitBy": [],
"aggregation": "SUM",
"name": "Total Requests"
}
],
"timeframe": {
"from": "now-2h"
}
},
"bounds": {
"top": 0,
"left": 0,
"width": 600,
"height": 300
}
}
This tile will show the total request count for the user-service over the last two hours as a line chart. The bounds define its position and size on the dashboard grid. You can add many more tiles: "TOP LIST" for top errors, "SINGLE VALUE" for error rates, "TPM" for transactions per minute, and even custom "AUTOTAG BASED CARD" tiles.
The full dashboard JSON would look like this, with multiple tiles:
{
"dashboardMetadata": {
"name": "User Service Overview",
"owner": "devops-team@example.com",
"sharingDetails": {
"permissions": [
{
"type": "USER",
"name": "devops-team@example.com",
"access": "EDIT"
},
{
"type": "TENANT_GROUP",
"name": "Developers",
"access": "VIEW"
}
]
}
},
"tiles": [
{
"tileType": "SMART_CHART",
"name": "Request Throughput",
"configured": true,
"tileSettings": {
"chartType": "LINE",
"series": [
{
"metric": "builtin:service.requestCount.total",
"dimensions": [],
"splitBy": [],
"aggregation": "SUM",
"name": "Total Requests"
}
],
"timeframe": {
"from": "now-2h"
}
},
"bounds": {
"top": 0,
"left": 0,
"width": 600,
"height": 300
}
},
{
"tileType": "SMART_CHART",
"name": "Error Rate",
"configured": true,
"tileSettings": {
"chartType": "LINE",
"series": [
{
"metric": "builtin:service.errors.total",
"dimensions": [],
"splitBy": [],
"aggregation": "SUM",
"name": "Total Errors"
},
{
"metric": "builtin:service.requestCount.total",
"dimensions": [],
"splitBy": [],
"aggregation": "SUM",
"name": "Total Requests",
"displayAggregationImplicitly": true
}
],
"timeframe": {
"from": "now-2h"
}
},
"bounds": {
"top": 0,
"left": 600,
"width": 600,
"height": 300
}
}
]
}
To send this to Dynatrace, you’ll use the /api/v2/dashboards endpoint with a POST request. You’ll need an API token with davis.data:dashboards:create and davis.data:dashboards:read permissions.
curl -X POST \
'https://<your-environment-id>.live.dynatrace.com/api/v2/dashboards' \
-H 'Authorization: Api-Token <your-api-token>' \
-H 'Content-Type: application/json' \
-d '{
"dashboardMetadata": {
"name": "User Service Overview",
"owner": "devops-team@example.com",
"sharingDetails": {
"permissions": [
{
"type": "USER",
"name": "devops-team@example.com",
"access": "EDIT"
},
{
"type": "TENANT_GROUP",
"name": "Developers",
"access": "VIEW"
}
]
}
},
"tiles": [
{
"tileType": "SMART_CHART",
"name": "Request Throughput",
"configured": true,
"tileSettings": {
"chartType": "LINE",
"series": [
{
"metric": "builtin:service.requestCount.total",
"dimensions": [],
"splitBy": [],
"aggregation": "SUM",
"name": "Total Requests"
}
],
"timeframe": {
"from": "now-2h"
}
},
"bounds": {
"top": 0,
"left": 0,
"width": 600,
"height": 300
}
},
{
"tileType": "SMART_CHART",
"name": "Error Rate",
"configured": true,
"tileSettings": {
"chartType": "LINE",
"series": [
{
"metric": "builtin:service.errors.total",
"dimensions": [],
"splitBy": [],
"aggregation": "SUM",
"name": "Total Errors"
},
{
"metric": "builtin:service.requestCount.total",
"dimensions": [],
"splitBy": [],
"aggregation": "SUM",
"name": "Total Requests",
"displayAggregationImplicitly": true
}
],
"timeframe": {
"from": "now-2h"
}
},
"bounds": {
"top": 0,
"left": 600,
"width": 600,
"height": 300
}
}
]
}'
The API gives you fine-grained control over every aspect of a dashboard, from its name and owner to the exact metrics and visualizations displayed in each tile. You can automate the creation of dashboards for new services, ensuring consistent monitoring across your entire infrastructure. This is particularly powerful when integrated into CI/CD pipelines, where a new service deployment can automatically trigger the creation of its corresponding monitoring dashboard.
When defining tiles, you’re not just picking metrics; you’re telling Dynatrace how to aggregate them (SUM, AVG, MAX), how to split them (e.g., by host, process group, or custom dimensions), and how to display them (line chart, bar chart, single value). The dimensions and splitBy arrays are crucial here; an empty dimensions array means you’re looking at the metric globally, while splitBy: ["PROCESS_GROUP"] would break down the metric by each individual process group.
The bounds object uses a coordinate system where top and left are the pixel positions of the top-left corner of the tile, and width and height are its dimensions. This allows for precise layout control, though you can often rely on Dynatrace’s default grid system if you don’t need pixel-perfect placement.
The most surprising thing about Dynatrace’s dashboard API is how deeply you can customize individual tiles, even down to the series display names and the aggregation behavior for each metric within a single chart.
This approach unlocks a new level of automation for your monitoring strategy, moving beyond static dashboards to dynamic, programmatically generated views that adapt to your evolving infrastructure.
The next step is to explore how to update existing dashboards and manage their lifecycle using the API.