Skip to main content
This cookbook explains how to dismiss many data rule alerts in a single API call, with one shared reason.

Example Scenario

A data rule has flagged dozens of records — for example, a “Negative Temp Alert” firing on a winter’s worth of ambient-temperature readings. After reviewing them with your site engineer, you’ve confirmed they’re expected and want to dismiss them all at once with a single reason, while preserving the audit trail.
Dismissing an alert only changes how it is surfaced — it never edits the underlying datapoint or model run. If the record is recalculated and the rule still matches, a fresh alert can be raised. See Managing alerts for the full alert lifecycle.

How it works

Every rule alert is backed by a rule result with its own friendly ID:
Result typeID prefixRaised by
Data point rule resultdpres_Event Data rules
Model run rule resultmrres_Batch Calculations rules
The Bulk dismiss rule results endpoint takes a list of these IDs plus one reason, and dismisses them in a single transaction. You can mix dpres_ and mrres_ IDs in the same request.
Pass rule-result IDs (dpres_..., mrres_...) — not data point (in_...), event (evt_...), or model run (mr_...) IDs. The rule-result ID is the id on each entry in a record’s rule_results array.
The call is all-or-nothing: if the reason is blank, the list is empty, or any ID is unknown to the project or points at a passing result, nothing is dismissed and the API returns 422. Already-dismissed results are a no-op, so retrying a request is safe.

Dismissing alerts with code

1

Prerequisites

Before starting, make sure you have:
  • A Mangrove API token with Data Rules access for the project
  • The rules engine feature enabled on your account (the endpoint returns 403 otherwise)
  • The project ID containing the alerts
2

Collect the rule-result IDs to dismiss

List the results for the rule you want to triage and filter to the alerts (status=fail), then read the id of each failing result.
curl
curl "https://app.gomangrove.com/api/v1/projects/prj_W55PYc6xVeXb2iuT/rules/rule_Qb3k9TzdL0pWnXyz/results?status=fail&page_size=100" \
  -H "Authorization: YOUR_API_TOKEN"
Each entry’s id (e.g. dpres_8XF1QtGs79oX9A6k) is what you collect.
Re-list right before dismissing. Recreating or re-saving a rule regenerates its rule-result friendly IDs, so IDs cached from an earlier session can become “Unknown result ids” (422). Always work from a fresh list.
3

Dismiss them in one call

Send all the IDs and a single reason to the bulk dismiss endpoint.
curl
curl -X POST "https://app.gomangrove.com/api/v1/projects/prj_W55PYc6xVeXb2iuT/rule_results/bulk_dismiss" \
  -H "Authorization: YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "result_ids": [
      "dpres_8XF1QtGs79oX9A6k",
      "dpres_7nxaDUf65c36v6mz",
      "mrres_AIKqFEtr5OpAqram"
    ],
    "reason": "Reviewed with site engineer — sensor recalibrated, readings are expected."
  }'
The response returns every targeted result with its final state, so dismissed entries come back with status: dismissed and the dismissal_reason, dismissed_by, and dismissed_at fields populated.

End-to-end example

This script lists a rule’s failing results, collects their IDs, and dismisses them in one request.
import requests

API_TOKEN = "YOUR_API_TOKEN"
BASE_URL = "https://app.gomangrove.com/api/v1"
PROJECT_ID = "prj_W55PYc6xVeXb2iuT"
RULE_ID = "rule_Qb3k9TzdL0pWnXyz"
REASON = "Reviewed with site engineer — sensor recalibrated, readings are expected."

headers = {
    "Authorization": API_TOKEN,
    "Content-Type": "application/json",
}

# 1. Collect the failing rule-result IDs (re-list right before dismissing).
result_ids = []
page = 1
while True:
    resp = requests.get(
        f"{BASE_URL}/projects/{PROJECT_ID}/rules/{RULE_ID}/results",
        headers=headers,
        params={"status": "fail", "page": page, "page_size": 100},
    )
    resp.raise_for_status()
    body = resp.json()
    result_ids += [r["id"] for r in body["data"]]
    if page >= body["info"]["total_pages"]:
        break
    page += 1

if not result_ids:
    print("No alerts to dismiss.")
else:
    # 2. Dismiss them all in one call.
    resp = requests.post(
        f"{BASE_URL}/projects/{PROJECT_ID}/rule_results/bulk_dismiss",
        headers=headers,
        json={"result_ids": result_ids, "reason": REASON},
    )
    resp.raise_for_status()
    dismissed = resp.json()["data"]
    print(f"Dismissed {len(dismissed)} results.")

Troubleshooting

ResponseMeaningWhat to do
403 Rules engine feature is not enabledThe rules engine feature is off for the account.Contact your Mangrove account team to enable it.
404 record not foundThe project ID is wrong, or the route isn’t reachable for this token.Double-check the project_id in the path and that the token is scoped to that project.
422 Unknown result ids: ...One or more IDs don’t belong to the project — often stale IDs after a rule was recreated.Re-list the rule’s results and rebuild the ID set from the fresh response.
422 Cannot dismiss passing results: ...The batch includes a result whose status is pass.Filter to status=fail (or dismissed) before collecting IDs.
422 Dismissal reason can't be blankThe reason was empty or whitespace.Provide a non-empty reason — it’s stored on the audit trail.
The split between 404 and 422 is diagnostic: a 404 points at the path or record lookup (wrong project_id, route not reachable), while a 422 is business validation (blank reason, empty list, unknown or passing IDs). If a previously working call starts returning 404, suspect a routing or scoping issue rather than your payload.