Skip to main content

Send Incident Data to LinearB Using Dynatrace Workflows

Send Dynatrace problem lifecycle data to LinearB's Incident API using a single workflow, so Change Failure Rate (CFR) and Mean Time to Recovery (MTTR) reflect real incident timestamps.

Steven Silverstone
Updated by Steven Silverstone

Send your Dynatrace problem lifecycle directly to LinearB's Incident API using Dynatrace Workflows. This keeps Change Failure Rate (CFR) and Mean Time to Recovery (MTTR) accurate without requiring custom code or additional servers.

Each time a Davis problem becomes active or closes, one workflow sends the corresponding incident data and timestamp to LinearB.


Overview

This configuration uses one Dynatrace workflow with two HTTP request tasks. The workflow runs when a Davis problem becomes active and again when it closes. A condition on each task sends the corresponding request to LinearB.

Event Dynatrace action LinearB action
Problem opens Problem status becomes ACTIVE Creates the incident and sets issued_at
Problem closes Problem status becomes CLOSED Updates the incident and sets ended_at
Why these timestamps matter: LinearB uses issued_at and ended_at when calculating Change Failure Rate (CFR) and Mean Time to Recovery (MTTR), two of the four DORA metrics.

Prerequisites

In LinearB

  1. Generate a LinearB API token from Company Settings → API Tokens.
  2. Copy the token. You will use it when configuring both Dynatrace tasks.
  3. Go to Company Settings → Project Management → Incidents.
  4. Set Incidents Detection to API Integration.
  5. Click Save.
Incident detection can also be overridden for an individual team under Team Settings → Project Management → Incidents if only specific teams should use API-based incident detection.

In Dynatrace

This configuration requires the Workflows app on the Grail-based Dynatrace platform at <environment-id>.apps.dynatrace.com. Before you begin, make sure you have:

  • The Workflows app installed.
  • Permission to create and execute workflows.
  • An outbound allowlist entry for public-api.linearb.io. Go to Settings → General → External requests, select New host pattern, and add the host.
Classic Dynatrace Managed: Environments without Workflows provide problem notification webhooks, but those webhooks cannot alternate between POST and PATCH. Those environments require a relay service and cannot use the configuration in this article directly.

Map Dynatrace Values to the Incident API

Every request contains your LinearB API token and identifies the incident by the Dynatrace problem event ID. The values below are Jinja expressions used in the HTTP task URL and payload.

LinearB field Dynatrace expression Description
provider_id {{ event()['event.id'] }} Unique incident identifier. The same value is used in the PATCH URL.
http_url {{ problem_link() }} Link to the problem in the Dynatrace Problems app.
title {{ event()['event.name'] }} Dynatrace problem title.
issued_at {{ now().strftime('%Y-%m-%dT%H:%M:%SZ') }} Workflow execution time when the problem becomes active, in ISO 8601 UTC format.
ended_at {{ now().strftime('%Y-%m-%dT%H:%M:%SZ') }} Workflow execution time when the problem closes, in ISO 8601 UTC format.

Create the Workflow and Problem Trigger

  1. Open Workflows from the app launcher. You can also press Ctrl+K or Cmd+K and search for Workflows.
  2. On the Workflows tab, select Workflow in the upper-right corner to open the editor.
  3. Name the workflow, for example LinearB incident sync. Use a standard workflow, not a simple workflow.
  4. Under Select a trigger, choose the Davis problem trigger listed under Event triggers.
  5. Set the problem state to active or closed. The workflow will run once when a problem becomes active and again when it closes.
  6. Scope the trigger by severity, affected-entity tags, or a custom DQL filter so that only problems you consider incidents are sent to LinearB.
Decide the scope before deploying: Davis raises many kinds of problems. Without a suitable trigger filter, every detected anomaly can become an incident in LinearB and inflate CFR and MTTR.

Create Task A: Incident Created

This task runs when the problem becomes active, creates the incident in LinearB, and records issued_at.

  1. Hover over the trigger node and select Add task.
  2. Choose the HTTP Request action.
  3. Configure the request using the values below.

Method: POST

URL:

https://public-api.linearb.io/api/v1/incidents

Headers:

x-api-key: YOUR_LINEARB_API_TOKEN
          Content-Type: application/json

Payload:

{
            "provider_id": "{{ event()['event.id'] }}",
            "http_url": "{{ problem_link() }}",
            "title": "{{ event()['event.name'] }}",
            "issued_at": "{{ now().strftime('%Y-%m-%dT%H:%M:%SZ') }}"
          }

Open the task options and add this custom condition so the task runs only when the problem is opening:

{{ event()["event.status"] == "ACTIVE" }}
Protect your API token: Static header values are visible in the workflow monitor to users who can access the workflow. Restrict workflow access accordingly. Dynatrace Credential Vault authentication cannot set the custom x-api-key header; using the vault requires replacing the HTTP tasks with a Run JavaScript task.

Create Task B: Incident Closed

Add a second HTTP Request task directly from the trigger. Place it alongside Task A, not after it. This task updates the existing incident and records ended_at.

Method: PATCH

URL:

https://public-api.linearb.io/api/v1/incidents/{{ event()['event.id'] }}

Headers:

x-api-key: YOUR_LINEARB_API_TOKEN
          Content-Type: application/json

Payload:

{
            "ended_at": "{{ now().strftime('%Y-%m-%dT%H:%M:%SZ') }}"
          }

Add this custom condition:

{{ event()["event.status"] == "CLOSED" }}

Save and deploy the workflow, then confirm that the trigger toggle in the upper-right corner is on. Triggers run only on deployed workflows.


Handle started_at

Dynatrace problems do not have a work-started transition equivalent to a Jira issue moving to In Progress. Choose the option that best represents your incident-response process:

Option When to use it Configuration
Leave it unset Recommended default Send only issued_at and ended_at, the timestamps used for CFR and MTTR.
Match issued_at Response work begins when the problem opens Add started_at to Task A using the same timestamp expression.
Patch it later Another system records a real acknowledgement or work-started event Have that system PATCH the incident by Dynatrace event ID and set started_at.

To set started_at when the problem opens, add this field to Task A:

"started_at": "{{ now().strftime('%Y-%m-%dT%H:%M:%SZ') }}"

Incident API requests can include optional team and repository information. Adding this information allows LinearB to associate incidents more accurately with the teams and code affected by the incident.

Add a Team to the Request

Add a teams array containing LinearB team names. Team names must be lowercase and match the corresponding team names in LinearB.

{
            "provider_id": "{{ event()['event.id'] }}",
            "http_url": "{{ problem_link() }}",
            "title": "{{ event()['event.name'] }}",
            "issued_at": "{{ now().strftime('%Y-%m-%dT%H:%M:%SZ') }}",
            "teams": ["payments"]
          }

LinearB calculates CFR and MTTR by team. Associating an incident with its owning team allows it to contribute to that team's reliability metrics and to roll up to any parent group that aggregates the team.

If one workflow serves multiple teams, you can:

  • Use one workflow per team. Duplicate the workflow, filter each trigger by the entity tags for that team's services, and hard-code the matching LinearB team name in the payload.
  • Derive the team from the event. If ownership is stored in an entity tag or another event field, use a Jinja expression to include it. Validate the exact field against a real trigger payload using the expression preview in the task editor.

You can also add the team later using a PATCH request because the teams array is supported when updating an incident.

Include Repository URLs

If the affected repository can be derived from the problem, include it in the repository_urls array. Provide the full repository URL exactly as it appears in LinearB, typically the clone URL.

"repository_urls": ["https://github.com/your-org/checkout-service"]

The teams and repository_urls arrays can be included in the same request. If a value does not apply, omit the array instead of sending an empty string.


Troubleshoot the Integration

  • Confirm that PATCH is available. Before rollout, verify that PATCH appears in the HTTP Request action's Method list in your Dynatrace environment.
  • Request to public-api.linearb.io is blocked. Add the host under Settings → General → External requests.
  • 401 Unauthorized: Check the x-api-key value and confirm that the API token belongs to the correct LinearB organization.
  • 422 response: Confirm that timestamps use ISO 8601 UTC format with a trailing Z, for example 2026-08-19T14:05:00Z. If a PATCH request still returns 422, include title in the PATCH payload; some API versions expect additional fields on update.
  • Keep provider_id unchanged. Compare the ACTIVE and CLOSED workflow executions and confirm that both contain the same event.id.
  • Reopened problems: A reopened problem triggers the ACTIVE state again, so Task A can POST a provider_id that already exists. After confirming LinearB's duplicate response code, configure the task's error handling so that response does not mark the execution as failed.
  • The workflow never runs: Confirm that the workflow is deployed, the trigger toggle is on, and the workflow actor has the storage:events:read permission.
  • No problems match: Use Query past events on the trigger to check which recent problems match the filter.
  • Timestamps differ from detection time: now() records task execution time. If the trigger is delayed, such as by maintenance-window settings, the incident timestamps shift by the same amount.

Verify the Integration

  1. Trigger a test problem, or use Query past events to replay a recent one.
  2. In the workflow monitor, confirm that Task A runs for the ACTIVE event and Task B is skipped by its condition. Check the LinearB status_code and response body in the task result.
  3. Close the problem and confirm that a second execution runs Task B.
  4. Optionally, retrieve the incident directly by sending a GET request with the x-api-key header to:
https://public-api.linearb.io/api/v1/incidents/<event.id>
  1. In LinearB, go to Metrics → Git Activity → Incidents and confirm that the incident appears with its timestamps populated.
  2. Confirm that the incident contributes to the CFR and MTTR widgets on the Metrics dashboard.

References

LinearB

Dynatrace

How did we do?

Send Incident Data to LinearB Using Jira Automation

Contact