What is synthetic monitoring?
Synthetic monitoring simulates real user workflows by executing a sequence of HTTP requests. Instead of checking a single endpoint, you can model an entire flow — authenticate, create a resource, verify it, then clean up — and validate each step along the way.
Creating a synthetic monitor
- Navigate to Monitors > New Monitor and select Synthetic as the type.
- Enter a name and set the check interval.
- Define your steps as a JSON array in the Steps editor.
Step definition
Each step is a JSON object with the following fields:
{
"name": "Authenticate",
"url": "https://api.example.com/auth/login",
"method": "POST",
"headers": {
"Content-Type": "application/json"
},
"body": "{\"email\": \"test@example.com\", \"password\": \"testpass\"}",
"expected_status": 200
}
Required fields
- name — A descriptive label for the step, shown in results.
- url — The endpoint to call.
- method — HTTP method (GET, POST, PUT, PATCH, DELETE).
- expected_status — The expected HTTP status code. The step fails if the actual status doesn’t match.
Optional fields
- headers — Key-value pairs of HTTP headers.
- body — Request body as a string (typically JSON).
- extract_json — Extract values from the response for use in later steps.
- assert_body — Validate that the response body contains a specific string.
Extracting values between steps
Use extract_json to pull values from a response and reference them in subsequent steps with {{variable}} syntax. The extractor uses dot notation to traverse JSON:
[
{
"name": "Login",
"url": "https://api.example.com/auth/login",
"method": "POST",
"headers": { "Content-Type": "application/json" },
"body": "{\"email\": \"test@example.com\", \"password\": \"testpass\"}",
"expected_status": 200,
"extract_json": {
"auth_token": "token",
"user_id": "user.id"
}
},
{
"name": "Get user profile",
"url": "https://api.example.com/users/{{user_id}}",
"method": "GET",
"headers": {
"Authorization": "Bearer {{auth_token}}"
},
"expected_status": 200,
"assert_body": "test@example.com"
}
]
In this example, the first step logs in and extracts token (from the response root) and user.id (nested under the user object). The second step uses both values in the URL and headers.
Dot notation examples
Given a response:
{
"token": "abc123",
"user": {
"id": "usr_456",
"profile": {
"name": "Test User"
}
},
"items": [{ "id": "item_1" }]
}
tokenextracts"abc123"user.idextracts"usr_456"user.profile.nameextracts"Test User"
Asserting response content
Use assert_body to verify the response body contains a specific string. This is a simple substring match — if the string is not found in the response, the step fails.
{
"name": "Verify dashboard loads",
"url": "https://app.example.com/dashboard",
"method": "GET",
"expected_status": 200,
"assert_body": "Welcome back"
}
Execution and results
Steps execute sequentially. If any step fails (wrong status code, missing assertion, network error), the entire synthetic check is marked as failed and subsequent steps are skipped.
Results show each step’s outcome: status code, response time, extracted values, and any assertion failures. This makes it easy to pinpoint exactly where a workflow breaks.
Next steps
- Configure alerts to get notified when synthetic checks fail
- Track deployments to correlate failures with releases