> ## Documentation Index
> Fetch the complete documentation index at: https://docs.paradime.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Send Elementary dbt alerts to Datadog

> Configure Elementary to send dbt test failures, model errors, and data quality alerts to Datadog as incidents, with project-level defaults via config.yml.

<Info>
  Paradime integrates natively with Elementary CLI to enable you to generate report and/or send alerts using the Bolt scheduler out of the box. **No additional installation required.**
</Info>

Elementary sends alerts to Datadog by creating incidents with detailed information about data quality issues, test failures, and model errors. Each alert becomes a structured incident in your Datadog dashboard with appropriate severity levels and metadata.

***

### 1. Get Datadog API Credentials

To send incidents to Datadog, you'll need both an API key and an Application key.

**Get your API Key**

1. Log in to your Datadog account
2. Navigate to **Organization Settings** → **API Keys**
3. Click **+ New Key** to create a new API key
4. Give it a descriptive name like "Elementary Integration"
5. Copy the API key (you'll need this later)

**Get your Application Key**

1. In **Organization Settings**, go to **Application Keys**
2. Click **+ New Key** to create a new application key
3. Give it a descriptive name like "Elementary Integration"
4. Copy the application key (you'll need this later)

**Ensure Application Key has the below permissions**

1. `incident_notification_settings_read`
2. `incident_read`
3. `incident_write`
4. `teams_read`
5. `user_access_read`

**Identify your Datadog Site**

Your Datadog site depends on your region. You can check your site by looking at your Datadog URL when logged in.

| Region        | Site                |
| ------------- | ------------------- |
| US1 (default) | `datadoghq.com`     |
| US3           | `us3.datadoghq.com` |
| US5           | `us5.datadoghq.com` |
| EU1           | `datadoghq.eu`      |
| AP1           | `ap1.datadoghq.com` |
| GOV           | `ddog-gov.com`      |

***

### 2. Configure the Integration

Pass your credentials directly when running `edr monitor`. You should use environment variables in the Bolt command, as [described here](/products/bolt/creating-schedules/environment-variables-in-commands) for secrets.

```shell theme={"system"}
edr monitor \
  --datadog-api-key <your_api_key> \
  --datadog-application-key <your_application_key> \
  --datadog-site <your_site> \
  --datadog-default-severity SEV-3
```

**Available CLI options:**

| Option                       | Short flag | Description                                    |
| ---------------------------- | ---------- | ---------------------------------------------- |
| `--datadog-api-key`          | `-dak`     | Your Datadog API key                           |
| `--datadog-application-key`  | `-dapp`    | Your Datadog Application key                   |
| `--datadog-site`             | `-ds`      | Your Datadog site (e.g., `datadoghq.com`)      |
| `--datadog-default-severity` | `-dsev`    | Default incident severity (`SEV-1` to `SEV-5`) |

<Note>
  These four flags are the only Datadog settings available on the command line. Other global defaults, such as a default notification handle, commander, or a custom severity mapping, are set once in a `config.yml` file. See [Set project-level defaults](#5-set-project-level-defaults-avoid-repeating-alerts_config).
</Note>

***

### 3. Test your Integration

Run the following command to create a test incident in your Datadog account and verify the integration is configured correctly:

```shell theme={"system"}
edr monitor --test-datadog
```

If successful, you'll see a test incident created in your Datadog dashboard under **Incidents**, including sample error details, metadata, and all configured notification settings.

***

### 4. Execute the CLI

Once configured, run the following command after your dbt™ runs and tests:

```shell theme={"system"}
edr monitor \
  --datadog-api-key <your_api_key> \
  --datadog-application-key <your_app_key> \
  --datadog-site <your_site> \
  --group-by [table | alert]
```

***

### 5. Set project-level defaults (avoid repeating alerts\_config)

<Info>
  You do **not** need to repeat the `alerts_config` block in every model YAML. There are two ways to set defaults once and let them apply across your whole project, and you can combine both.
</Info>

There are two independent mechanisms, and which one to use depends on the setting:

1. **A `config.yml` file** sets true global defaults for the whole project (one value for every alert).
2. **dbt™ config inheritance** (`+meta` in `dbt_project.yml`) sets defaults per folder or domain, using standard dbt™ merging.

This table shows which settings support a project-wide global, and how a per-alert value interacts with it:

| Setting               | Project-wide global                                                                       | How a per-alert value behaves                                        |
| --------------------- | ----------------------------------------------------------------------------------------- | -------------------------------------------------------------------- |
| `severity`            | `config.yml` → `default_severity` (+ `severity_mapping`), or `--datadog-default-severity` | Overrides the global                                                 |
| `notification_handle` | `config.yml` → `notification_handles`                                                     | **Appended** to the global handles (both are notified, not replaced) |
| `commander_uuid`      | `config.yml` → `commander_user_id`                                                        | Overrides the global                                                 |
| `incident_type_uuid`  | No global available                                                                       | Set per node or per folder only (see mechanism 2)                    |

#### Global defaults with a `config.yml` file

Elementary reads global settings from a `config.yml` file. Point `edr` at the directory containing it with the `--config-dir` (`-c`) flag. Because this file is committed to your dbt™ repository, it works in Bolt schedules without any extra setup.

```yaml theme={"system"}
# elementary/config.yml  (committed to your repo, referenced with -c)

datadog:
  site: datadoghq.com
  default_severity: SEV-3
  severity_mapping:            # status -> severity; replaces the built-in error/fail/warn mapping
    error: SEV-1
    fail: SEV-2
    warn: SEV-3
  commander_user_id: "f47ac10b-58cc-4372-a567-0e02b2c3d479"
  notification_handles:        # a list; per-alert handles are added on top of these
    - "@data-platform-oncall"
  customer_impacted: true
```

Then reference the directory when you run `edr`:

```shell theme={"system"}
edr monitor \
  -c ./elementary \
  --datadog-api-key $DATADOG_API_KEY \
  --datadog-application-key $DATADOG_APP_KEY
```

<Warning>
  The `config.yml` file is read as plain YAML. It does **not** render `{{ env_var(...) }}` or any Jinja, so every value is used literally. Keep secrets (`--datadog-api-key` and `--datadog-application-key`) as CLI flags backed by [Bolt environment variables](/products/bolt/creating-schedules/environment-variables-in-commands), and put only non-secret defaults (severity, handles, commander, site) in `config.yml`.
</Warning>

**Supported `datadog:` keys in `config.yml`**

| Key                    | Type    | Description                                                                                                                 |
| ---------------------- | ------- | --------------------------------------------------------------------------------------------------------------------------- |
| `api_key`              | string  | Datadog API key. Prefer the CLI flag for this secret.                                                                       |
| `application_key`      | string  | Datadog Application key. Prefer the CLI flag for this secret.                                                               |
| `site`                 | string  | Your Datadog site (e.g. `datadoghq.com`).                                                                                   |
| `default_severity`     | string  | Fallback severity when nothing else matches (`SEV-1` to `SEV-5`). The CLI flag `--datadog-default-severity` overrides this. |
| `severity_mapping`     | map     | Maps a test status (`error`, `fail`, `warn`) to a severity. Replaces the built-in status mapping.                           |
| `commander_user_id`    | string  | Global incident commander (Datadog **user UUID**).                                                                          |
| `notification_handles` | list    | Global notification handles applied to every incident. Per-alert handles are added on top.                                  |
| `customer_impacted`    | boolean | Marks all incidents as customer-impacting.                                                                                  |

#### Per-folder defaults with dbt™ `+meta` inheritance

Setting `alerts_config` through dbt™'s standard config inheritance (`+meta` in `dbt_project.yml`, applied to a folder) **is respected by Elementary exactly like model-level `meta`.** This is the recommended way to handle `datadog_incident_type_uuid`, which has no `config.yml` global, and to vary handles per domain. You set it once per folder instead of once per model.

```yaml theme={"system"}
# dbt_project.yml

models:
  my_project:
    +meta:
      alerts_config:
        datadog_notification_handle: "@data-platform-oncall"   # applies to every model
    marts:
      finance:
        +meta:
          alerts_config:
            datadog_notification_handle: "@finance-oncall"
            datadog_incident_type_uuid: "f0524b6b-9328-403a-a533-f701a175dff5"
      marketing:
        +meta:
          alerts_config:
            datadog_commander_uuid: "f47ac10b-58cc-4372-a567-0e02b2c3d479"
```

A more specific folder, or an individual model, can override a broader default using standard dbt™ config merging. The recognized keys inside `alerts_config` are `datadog_severity`, `datadog_notification_handle`, `datadog_commander_uuid`, and `datadog_incident_type_uuid`.

<Note>
  **Models vs. tests precedence.** Folder-level `+meta` applies to both. For **models**, a folder or `config.meta` value overrides the model's top-level `meta:`. For **tests**, the reverse holds: a test's own `meta:` takes precedence over folder-level `+meta`. So if a specific test already carries its own `alerts_config` in `meta`, set the override explicitly on that test.
</Note>

**Recommended setup for a large project (many domains, many models)**

1. Put organization-wide defaults (`default_severity`, `severity_mapping`, `notification_handles`, `commander_user_id`, `site`) in one `config.yml`.
2. Put per-domain overrides, especially `datadog_incident_type_uuid` and each domain's notification handle, as folder-level `+meta.alerts_config` in `dbt_project.yml`, one block per domain path.
3. Only drop down to model-level or test-level `meta` for the rare exception that needs a special commander, incident type, or severity.

This removes the repeated `alerts_config` block from every model YAML: nothing needs to be per-model unless you want a deliberate exception.

***

### 6. Per-Alert Customization via dbt™ YAML

<Info>
  You can override Datadog incident settings on a per-model or per-test basis directly in your dbt™ project YAML files. These settings take precedence over the global CLI and `config.yml` defaults.
</Info>

**Where to add these settings**

Per-alert Datadog settings live inside the `alerts_config` block under `config: meta:` in your dbt™ YAML files. They can be applied at:

* **Model level**: affects all alerts from that model's tests
* **Test level**: affects only that specific test (overrides model-level if both are set)

```yaml theme={"system"}
# models/schema.yml

models:
  - name: my_model
    config:
      meta:
        alerts_config:
          datadog_severity: "SEV-2"               # model-level default
          datadog_notification_handle: "@team-data-quality"

    columns:
      - name: user_id
        tests:
          - not_null:
              config:
                meta:
                  alerts_config:
                    datadog_severity: "SEV-1"      # test-level override, takes precedence
                    datadog_commander_uuid: "abc123-uuid-here"
```

**Available per-alert parameters**

| Parameter                     | Type   | Description                                                                                                                                                                                                                                                             |
| ----------------------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `datadog_severity`            | string | Overrides the incident severity for this alert. Accepted values: `SEV-1`, `SEV-2`, `SEV-3`, `SEV-4`, `SEV-5`. Takes precedence over the CLI `--datadog-default-severity` flag and any status-based severity mapping.                                                    |
| `datadog_notification_handle` | string | Adds a Datadog notification handle to the incident (e.g. `@team-first-response` or `@user@example.com`). This sends a notification to the handle but does **not** assign them as a responder. The `@` prefix is optional (Elementary adds it automatically if missing). |
| `datadog_commander_uuid`      | string | Sets the incident commander for this alert. Must be a valid Datadog **user UUID** (not a handle). To find a user's UUID, go to **Organization Settings** → **Users** in Datadog. Overrides the global commander configured via the CLI.                                 |
| `datadog_incident_type_uuid`  | string | Sets a custom incident type for this alert. Must be a valid Datadog **incident type UUID**. To find incident type UUIDs, go to **Incidents** → **Settings** → **Incident Types** in Datadog.                                                                            |

<Warning>
  `datadog_commander_uuid` and `datadog_incident_type_uuid` require **UUIDs**, not handles or display names. Using the wrong format will cause the incident creation to fail.
</Warning>

**How to find the required UUIDs**

**User UUID (`datadog_commander_uuid`)**

1. In Datadog, navigate to **Organization Settings** → **Users**
2. Click on the user you want to assign as commander
3. The UUID is visible in the URL: `app.datadoghq.com/organization-settings/users/<uuid>`

**Incident Type UUID (`datadog_incident_type_uuid`)**

1. In Datadog, navigate to **Incidents** → **Settings** → **Incident Types**
2. Click on the incident type you want to use
3. The UUID is visible in the URL or in the incident type details panel

**Full example**

```yaml theme={"system"}
# models/schema.yml

models:
  - name: payments
    config:
      meta:
        alerts_config:
          datadog_severity: "SEV-2"
          datadog_notification_handle: "@team-payments"
          datadog_commander_uuid: "f47ac10b-58cc-4372-a567-0e02b2c3d479"
          datadog_incident_type_uuid: "f0524b6b-9328-403a-a533-f701a175dff5"

    tests:
      - elementary.volume_anomaly
      - elementary.freshness_anomaly:
          config:
            meta:
              alerts_config:
                datadog_severity: "SEV-1"   # escalate freshness issues specifically
```

**Severity precedence order**

When determining the severity of a Datadog incident, Elementary applies the following precedence (highest to lowest):

1. **Test-level** `datadog_severity` in `config.meta.alerts_config`
2. **Model-level or folder-level** `datadog_severity` in `config.meta.alerts_config`
3. **`config.yml` `severity_mapping`** (status → severity). When set, this replaces the built-in status mapping below.
4. **Built-in status mapping** (`error` → SEV-1, `fail` → SEV-2, `warn` → SEV-3), used only when no `severity_mapping` is configured.
5. **Default severity** from `--datadog-default-severity` (which overrides `config.yml` `default_severity`); fallback `SEV-3`.

***

### Alert on Source Freshness Failures

<Info>
  Not supported in dbt Cloud.
</Info>

To alert on source freshness failures, run `edr run-operation upload-source-freshness` immediately after each execution of `dbt source freshness`. This operation uploads the results to a table, and the subsequent `edr monitor` execution will send the alert as a Datadog incident.

Keep the following in mind:

* `dbt source freshness` and `upload-source-freshness` must run from the same machine.
* `upload-source-freshness` requires the `--project-dir` argument to be passed.

***

### Continuous Alerting

To monitor continuously, use your orchestrator to run `edr monitor` on a regular schedule. We recommend running it right after your dbt™ job ends to catch the latest data updates as quickly as possible.

***

### Deduplication

Elementary automatically deduplicates Datadog incidents. Before creating a new incident, it checks whether an active incident already exists for the same alert. If one is found, no duplicate is created.

This means:

* Re-running `edr monitor` without resolving the underlying issue will **not** create duplicate incidents.
* Once an incident is resolved in Datadog, the next failing run will create a fresh incident.


## Related topics

- [Send Elementary alerts to Slack](/products/bolt/creating-schedules/templates/observability-templates/send-elementary-alerts-to-slack.md)
- [Send Elementary alerts to MS Teams](/products/bolt/creating-schedules/templates/observability-templates/send-elementary-alerts-to-ms-teams.md)
- [Sending Alerts](/integrations/elementary-data/sending-alerts/index.md)
- [Datadog](/integrations/datadog.md)
- [Slack Alerts](/integrations/elementary-data/sending-alerts/slack-alerts.md)
