Dynatrace Automation Purpose
If you are using Dynatrace regularly, there is a good chance that some monitoring tasks are becoming repetitive. Fetching monitor details, checking monitor IDs, disabling a monitor during maintenance, and enabling monitors again after a deployment are all common tasks. Doing these one by one from the Dynatrace UI works, but it is not always the most efficient way.
This is where Dynatrace automation with Python becomes useful.
In this blog, I’ll explain how to automate tasks in Dynatrace using Python, with a practical use case around Synthetic Monitors. Instead of keeping the article only theoretical, I’ll walk through a complete example where we:
- fetch synthetic monitor configurations from Dynatrace
- create a quick monitor summary report
- disable a synthetic monitor using its monitor ID
- enable synthetic monitors again using monitor IDs
I used Google Colab for this implementation because it gave me a quick and convenient Python environment for testing Dynatrace APIs. I had already used Google Colab during my final year project for Python, NLP, and Machine Learning work, so it felt like a natural choice for this automation use case as well.
The goal of this article is simple: help you understand how Dynatrace automation works with Python in a way that is practical, beginner-friendly, and easy to reuse in your own environment.
If you want the short answer first, Dynatrace automation with Python means using Dynatrace REST APIs to perform monitoring and configuration tasks programmatically instead of manually doing them from the Dynatrace UI.
In simple terms, the automation pattern is:
Fetch → Inspect → Modify → Update
Why Use Synthetic Monitors to Learn Dynatrace Automation
Synthetic Monitors are a good starting point because they are easy to understand and they represent a very practical monitoring workflow. That makes them a very good real-world example for explaining Dynatrace API automation with Python.
Prerequisites for Dynatrace Automation with Python
1. Dynatrace environment URL
You need the URL of your Dynatrace environment.
Example: DT_ENV_URL = "https://YOUR_ENV_ID.live.dynatrace.com"
2. Dynatrace API token
You also need a Dynatrace API token with the required permissions and Scopes.
For the Synthetic Monitor use cases in this blog, you typically need:
- settings.read - settings.read is needed to fetch monitor definitions
- settings.write - settings.write is needed to update the monitor definition, such as enabling or disabling a monitor
3. Python environment
You can run the scripts in:
- Google Colab (Free and Open Source)
I used Google Colab for this tutorial because it is quick to start and easy to use for API-based experimentation, and Google Colab is providing GPU and TPU based services to run complex Python code also.
1. Fetch Dynatrace Synthetic Monitor Configurations Using Python
To begin the automation process, the first step is to fetch the available Synthetic Monitors from Dynatrace along with their detailed configuration. In this script, Python connects to the Dynatrace environment using the tenant URL and API token, retrieves the monitor list, and then fetches the complete configuration of each monitor one by one.
The script uses the requests library to make API calls to Dynatrace, json to store the monitor configurations in a structured JSON file, and pprint to display a sample monitor response in a clean and readable way. This step is important because before performing actions like enabling or disabling monitors, we first need to collect their current configuration and monitor IDs.
Python Code:
import requests
import json
from pprint import pprint
# ===========================================================================
# 1. SET YOUR DETAILS HERE Like DT tenant URL and API Token - www.veerpedia.com
# ===========================================================================
DT_ENV_URL = "https://xcz30905.live.dynatrace.com"
API_TOKEN = "dt0c01.ME2HWCRSUVZIHN6MAGVR7MLS.5YPHCLOGOXUKURZKJ4AC7DIWUZ5C4WN2HAZZOBEXABEAWM4THXWRQDSUIYYDLUPO"
headers = {
"Authorization": f"Api-Token {API_TOKEN}",
"Content-Type": "application/json"
}
# ==================================================================
# 2. FETCH ALL SYNTHETIC MONITORS (LIST API) - www.veerpedia.com
# ==================================================================
list_url = f"{DT_ENV_URL}/api/v2/synthetic/monitors"
response = requests.get(list_url, headers=headers)
print("List API status:", response.status_code)
if response.status_code != 200:
print("Error:", response.text)
raise Exception("Failed to fetch synthetic monitors list")
monitors_data = response.json()
monitors = monitors_data.get("monitors", [])
print(f"Total monitors found: {len(monitors)}")
# =============================================================
# 3. FETCH FULL CONFIG FOR EACH MONITOR - www.veerpedia.com
# =============================================================
all_monitor_configs = []
for monitor in monitors:
monitor_id = monitor.get("entityId") or monitor.get("monitorId")
monitor_name = monitor.get("name", "Unknown")
if not monitor_id:
print(f"Skipping monitor with no ID: {monitor}")
continue
detail_url = f"{DT_ENV_URL}/api/v2/synthetic/monitors/{monitor_id}"
detail_response = requests.get(detail_url, headers=headers)
if detail_response.status_code == 200:
config_json = detail_response.json()
all_monitor_configs.append(config_json)
print(f"Fetched: {monitor_name} ({monitor_id})")
else:
print(f"Failed: {monitor_name} ({monitor_id}) -> {detail_response.status_code}")
print(detail_response.text)
# ========================================================
# 4. SAVE OUTPUT TO JSON FILE - www.veerpedia.com
# ========================================================
output_file = "dynatrace_synthetic_monitors.json"
with open(output_file, "w") as f:
json.dump(all_monitor_configs, f, indent=2)
print(f"\nSaved {len(all_monitor_configs)} monitor configs to {output_file}")
# Preview first monitor - www.veerpedia.com
if all_monitor_configs:
print("\nSample monitor config:")
pprint(all_monitor_configs[0]) tag
By the end of this script, all Synthetic Monitor configurations are saved into a JSON file, which can be used later for reporting, analysis, or further Dynatrace automation tasks.
Output of the Python code: (this will change as your synthetic monitors)
List API status: 200 Total monitors found: 9 Fetched: NDTV Home (SYNTHETIC_TEST-0BB7CE1B0B34D01B) Fetched: BCCI Home Page (SYNTHETIC_TEST-327D3FCF8E82DDC6) Fetched: The Hindu Newspaper (SYNTHETIC_TEST-72108BBA0AA9AF78) Fetched: IPL T20 (SYNTHETIC_TEST-8AD29648B7FDEDDB) Fetched: Meta Support (HTTP_CHECK-036BBC9C23F4202E) Fetched: Zoho Home Page (HTTP_CHECK-20CEA0355D2B65E6) Fetched: Microsoft 365 Home (HTTP_CHECK-3CA8B19EDF4827ED) Fetched: Apple Store (HTTP_CHECK-78A3CCB9E1D6B924) Fetched: Azure For Students (HTTP_CHECK-A0D3A2D75122DAA5) Saved 9 monitor configs to dynatrace_synthetic_monitors.json Sample monitor config: {'automaticallyAssignedEntities': [], 'configuration': {'bypassCSP': False, 'chromiumStartupFlags': {'disable-features': {}, 'disable-web-security': False}, 'device': {'height': 1080, 'mobile': False, 'name': 'Desktop', 'touchEnabled': False, 'width': 1920}, 'enablement': {'enableOnGrail': True, 'origin': 'TENANT'}, 'monitorFrames': False, 'networkThrottling': {'download': 0, 'latency': 0, 'upload': 0}, 'useIESupportedAgent': False, 'userAgent': ''}, 'enabled': True, 'entityId': 'SYNTHETIC_TEST-0BB7CE1B0B34D01B', 'frequencyMin': 5, 'keyPerformanceMetrics': {'loadActionKpm': 'VISUALLY_COMPLETE', 'xhrActionKpm': 'VISUALLY_COMPLETE'}, 'locations': ['SYNTHETIC_LOCATION-0000000000000097', 'SYNTHETIC_LOCATION-0000000000000098'], 'modificationTimestamp': 1782019141189, 'name': 'NDTV Home', 'performanceThresholds': {'enabled': False, 'thresholds': []}, 'primaryGrailTags': [], 'steps': [{'entityId': 'SYNTHETIC_TEST_STEP-48423790C8FD9589', 'name': 'Loading of "https://www.ndtv.com/"', 'type': 'NAVIGATE', 'url': 'https://www.ndtv.com/', 'waitCondition': {'type': 'PAGE_COMPLETE'}}], 'syntheticMonitorOutageHandlingSettings': {'globalConsecutiveOutageCountThreshold': 1, 'globalOutages': True, 'localOutages': False, 'origin': 'DEFAULT', 'retryOnError': True}, 'tags': [{'context': 'CONTEXTLESS', 'key': 'ndtv', 'source': 'USER', 'value': 'prod'}], 'type': 'BROWSER'}tag
2. Create a Synthetic Monitor Summary Report Using Pandas
After fetching the complete Synthetic Monitor configurations from Dynatrace, the next useful step is to convert that raw JSON data into a simple tabular report. This makes it much easier to quickly review key monitor details such as the monitor name, monitor ID, monitor type, current enabled status, and execution frequency without going through the full JSON structure.
In this script, the pandas library is used to build a DataFrame from the monitor configuration data stored in all_monitor_configs. The script loops through each monitor configuration, extracts only the important fields required for reporting, and stores them in a clean summary list. That list is then converted into a Pandas DataFrame and displayed directly in Google Colab.
This step is useful in Dynatrace automation because it gives a quick operational view of all Synthetic Monitors in one place. Instead of checking each monitor manually, we can immediately see how many monitors were fetched, which type they belong to, whether they are currently enabled, and what their configured frequency is. This summary also becomes a very good reference before performing actions like enabling, disabling, or bulk monitor updates.
Python Code:
Output:import pandas as pd print("Total configs fetched from API:", len(all_monitor_configs)) summary = [] for cfg in all_monitor_configs: summary.append({ "name": cfg.get("name"), "entityId": cfg.get("entityId"), "type": cfg.get("type"), "enabled": cfg.get("enabled"), "frequencyMin": cfg.get("frequencyMin") }) df = pd.DataFrame(summary) print("Total monitors in dataframe:", len(df)) display(df) # in Colab this shows full tabletag
3. Disable a Dynatrace Synthetic Monitor Using Python
Once the Synthetic Monitor configurations are fetched, the next practical step in Dynatrace automation is to update the state of a monitor whenever needed. In this example, the goal is to disable a specific Synthetic Monitor using its monitor ID. This is especially useful during maintenance windows, testing activities, or whenever a monitor needs to be temporarily paused without manually going into the Dynatrace UI.
This script uses requests to communicate with the Dynatrace API, json for working with API payloads, and deepcopy from Python’s copy module to safely create a separate editable copy of the monitor configuration. The script first fetches the current configuration of the selected monitor, checks its existing status, and then prepares an update payload by changing the enabled field to False.
One important part of this script is the payload cleanup step. Before sending the update request, it removes fields such as entityId, modificationTimestamp, and other read-only values that are returned by the GET API but should not be sent back in the PUT request. After that, the updated payload is pushed back to Dynatrace, and if the API returns 204, it confirms that the monitor has been disabled successfully.
In simple terms, this script shows how to programmatically disable a Dynatrace Synthetic Monitor using Python, which is a very useful automation use case when managing monitors in bulk or handling temporary monitoring changes in a controlled way.
Python Code
Output:import requests import json from copy import deepcopy # ================================================== # 1) YOUR DYNATRACE DETAILS - www.veerpedia.com # ================================================== MONITOR_ID = "SYNTHETIC_TEST-327D3FCF8E82DDC6" # monitor you want to disable headers = { "Authorization": f"Api-Token {API_TOKEN}", "Content-Type": "application/json" } # =================================================== # 2) GET CURRENT MONITOR CONFIG - www.veerpedia.com # =================================================== get_url = f"{DT_ENV_URL}/api/v2/synthetic/monitors/{MONITOR_ID}" get_resp = requests.get(get_url, headers=headers) print("GET status:", get_resp.status_code) if get_resp.status_code != 200: print("Failed to fetch monitor") print(get_resp.text) raise Exception("Cannot continue") monitor_config = get_resp.json() print("Monitor Name :", monitor_config.get("name")) print("Current State:", monitor_config.get("enabled")) # ======================================================== # 3) PREPARE CLEAN PAYLOAD FOR UPDATE - www.veerpedia.com # ======================================================== payload = deepcopy(monitor_config) # Disable monitor payload["enabled"] = False # Remove read-only / GET-only fields payload.pop("entityId", None) payload.pop("modificationTimestamp", None) payload.pop("automaticallyAssignedEntities", None) payload.pop("manuallyAssignedEntities", None) # Remove entityId from steps if present if "steps" in payload and isinstance(payload["steps"], list): for step in payload["steps"]: if isinstance(step, dict): step.pop("entityId", None) # =================================================== # 4) UPDATE MONITOR (DISABLE) - www.veerpedia.com # =================================================== put_url = f"{DT_ENV_URL}/api/v2/synthetic/monitors/{MONITOR_ID}" put_resp = requests.put(put_url, headers=headers, json=payload) print("PUT status:", put_resp.status_code) if put_resp.status_code == 204: print(f" Monitor '{monitor_config.get('name')}' disabled successfully.") else: print("Failed to disable monitor") print("Response:") print(put_resp.text)tag
4. Enable Multiple Dynatrace Synthetic Monitors Using Python
After learning how to disable a single Synthetic Monitor, the next useful automation step is to enable multiple monitors in one go using their monitor IDs. This is helpful in situations where a set of monitors was disabled for maintenance, testing, or deployment activities and now needs to be turned back on without manually opening each monitor in the Dynatrace UI.
In this script, requests is used to call the Dynatrace API, and deepcopy is used to create a safe copy of each monitor configuration before making any changes. The script starts with a list of monitor IDs that need to be enabled. It then processes each monitor one by one by first fetching its current configuration, copying the response into a payload, and updating the enabled field to True.
Just like in the disable use case, the script also removes read-only fields such as entityId, modificationTimestamp, and step-level entityId values before sending the update request. This cleanup is important because these fields are returned by the GET API for reference, but they should not be included in the PUT request used to update the monitor.
Finally, the script sends the updated payload back to Dynatrace and keeps track of which monitors were enabled successfully and which ones failed. At the end, it prints a clean summary showing the number of successful updates and the names of the monitors that were enabled. This makes the script very useful for bulk Dynatrace Synthetic Monitor management, especially when handling multiple monitor state changes through Python automation.
Python Code:
import requests
from copy import deepcopy
# Add the monitor IDs you want to enable - www.veerpedia.com
MONITOR_IDS = [
"HTTP_CHECK-20CEA0355D2B65E6",
"SYNTHETIC_TEST-8AD29648B7FDEDDB"
]
headers = {
"Authorization": f"Api-Token {API_TOKEN}",
"Content-Type": "application/json"
}
success = []
failed = []
for monitor_id in MONITOR_IDS:
print(f"\nProcessing monitor: {monitor_id}")
# =========================================
# 2) GET CURRENT MONITOR CONFIG - www.veerpedia.com
# =========================================
get_url = f"{DT_ENV_URL}/api/v2/synthetic/monitors/{monitor_id}"
get_resp = requests.get(get_url, headers=headers)
if get_resp.status_code != 200:
failed.append((monitor_id, f"GET failed: {get_resp.status_code} - {get_resp.text}"))
print(f"Failed to fetch monitor {monitor_id}")
continue
monitor_config = get_resp.json()
monitor_name = monitor_config.get("name", monitor_id)
# =========================================
# 3) PREPARE PAYLOAD TO ENABLE MONITOR - www.veerpeedia.com
# =========================================
payload = deepcopy(monitor_config)
payload["enabled"] = True
# Remove read-only / GET-only fields
payload.pop("entityId", None)
payload.pop("modificationTimestamp", None)
payload.pop("automaticallyAssignedEntities", None)
payload.pop("manuallyAssignedEntities", None)
# Remove step-level entityId if present
if "steps" in payload and isinstance(payload["steps"], list):
for step in payload["steps"]:
if isinstance(step, dict):
step.pop("entityId", None)
# =========================================
# 4) UPDATE MONITOR - www.veerpedia.com
# =========================================
put_url = f"{DT_ENV_URL}/api/v2/synthetic/monitors/{monitor_id}"
put_resp = requests.put(put_url, headers=headers, json=payload)
if put_resp.status_code == 204:
success.append((monitor_id, monitor_name))
print(f"Enabled: {monitor_name} ({monitor_id})")
else:
failed.append((monitor_id, f"PUT failed: {put_resp.status_code} - {put_resp.text}"))
print(f"Failed to enable: {monitor_name} ({monitor_id})")
print(put_resp.text)
# =========================================
# 5) SUMMARY - www.veerpedia.com
# =========================================
print("\n========== SUMMARY ==========")
print(f"Enabled successfully: {len(success)}")
print(f"Failed: {len(failed)}")
if success:
print("\nEnabled monitors:")
for mid, mname in success:
print(f"- {mname} ({mid})")
if failed:
print("\nFailed monitors:")
for mid, reason in failed:
print(f"- {mid}: {reason}") tag
Output:


