Skip to content
Maple Docs
Open app

Alert rules

Create an alert rule in Maple: pick what to watch, set warning and critical thresholds, choose who gets notified, and replay the rule against past data. In the app or over the API.

An alert rule watches one signal, checks it against a threshold on a fixed interval, and opens an incident when the threshold is crossed for long enough. Each incident notifies the destinations attached to the rule.

You manage rules on the Rules tab of the Alerts page. Creating, editing and deleting rules requires the organization admin role.

Prerequisites

  • Telemetry arriving in Maple. Built-in signals read traces.
  • At least one notification destination, or the admin role to add one from the editor. A rule cannot be saved without one.

Create a rule

  1. Open Alerts and click New rule. To start from a service, open the service and click Create alert, which fills in the service.
  2. Start with a template opens first. Pick a template, or Start blank. Every field a template sets stays editable.
  3. Fill in the four sections of the editor: What to watch, When to alert, Who gets notified and Name it.
  4. Check the chart under When to alert. It replays the rule against past data as you edit.
  5. Click Create rule.

To alert on a dashboard chart instead, open the chart’s menu on the dashboard and choose Create alert. The rule opens with the chart’s query.

The Start with a template dialog with six options: High error rate, Slow P95 latency, Slow P99 latency, Low Apdex score, Throughput drop and Start blank, plus From a dashboard chart.
The template picker that opens when you create a rule.
TemplateSignalFires whenWindowAlso sets
High error rateError rateabove 5%5 minSplit by service.name when no service is set
Slow P95 latencyP95above 1000 ms5 min
Slow P99 latencyP99above 2000 ms5 min
Low Apdex scoreApdexbelow 0.8 (T 500ms)5 min
Throughput dropThroughputbelow 1005 minMinimum samples 0

Skip and use defaults closes the picker with an empty rule. Templates in the bar at the bottom of the editor opens it again.

What to watch

The Query mode is Built-in, Query builder or SQL. A blank rule opens in Query builder. The templates use Built-in.

Built-in

Built-in signals read the entry-point spans of each service: server and consumer spans, and trace roots. That is the same set of requests the service pages chart.

SignalAPI valueValue compared against the threshold
Error rateerror_rateShare of requests with status Error. Entered as a percent in the app, a 0 to 1 ratio in the API.
P95p95_latency95th percentile duration, in milliseconds.
P99p99_latency99th percentile duration, in milliseconds.
ApdexapdexApdex score from 0 to 1, against the Apdex target. See Apdex alerts.
ThroughputthroughputEstimated number of requests in the window.

Counts and rates are weighted for sampling. See Sampling and throughput.

A built-in signal only sees entry-point spans. A service that records a failure on a child span and still returns success from its entry point stays healthy on these signals. Use Query builder or SQL for that case. Open in query builder turns the current signal into a query.

Built-in rules pick their services and environments here:

  • Services. Empty means every service. When you pick more than one service, Maple evaluates each service on its own and opens a separate incident per service.
  • Environment. Empty means every environment. Otherwise the rule only counts spans from the listed deployment environments (deployment.environment.name).
  • Split by. With no services selected, a field such as service.name or an attribute like attr.http.route evaluates each group on its own. You get one incident per group that breaches, instead of one blended value that may never cross the threshold.
  • Exclude. Skips named services. It only applies when no services are selected.

Query builder

Query builder (builder_query) uses the same query builder as dashboard charts. It can read traces, logs, metrics or product events, with its own filters and group-by. Each group is checked on its own and gets its own incident.

SQL

SQL (raw_query) runs your own ClickHouse SQL. The query must include $__orgFilter and a $__timeFilter(...) on the time column, and return a time bucket and a numeric value. Reduce each window by turns the buckets in the window into one value: Last bucket, Sum, Average, Minimum or Maximum.

  • To evaluate several groups, return a group column.
  • Return a samples column with the number of events behind each row. Minimum samples sums it. Without it, every row counts as one sample, so the minimum counts buckets rather than events.
  • A query that returns no rows is a no-data check.

The editor times the query as you write it and shows Query time against the limit of the check interval. See the SQL reference for the macros, and Query time limits for the limits.

For Query builder and SQL rules the query carries its own filters, so the service and environment fields are hidden.

When to alert

The chart at the top of this section replays the rule over a past range. It shows the value for each window, the threshold as a dashed line, and shaded bands where the rule would have held an incident open. The header reads Would have fired with a count, or No breaches in this window. Pick the range in the time picker above the chart.

Dry run evaluates the rule once against current data and shows the value with Would trigger or Within threshold. Neither the chart nor the dry run sends a notification.

Below the chart:

  • Alert when the value is the condition: is above, is at or above, is below, is at or below, equals, is not, is between or is outside. The last two use From and To.
  • Thresholds sets the value the signal is compared against, its Severity (Warning or Critical), and an optional recovery value (Recovers below or Recovers above). With a recovery value set, the incident clears only once the signal crosses back over it.
  • How it is checked sets the window, how many breaches open an incident, the sample floor and the check interval.
  • After it fires sets when the incident resolves, how often it reminds, and what an empty window means.

Warning and critical tiers

A rule starts with one tier. On a Warning rule, Add critical tier adds a second, stricter threshold. An open incident escalates to Critical when the value crosses it, and drops back to Warning when it recovers. Each tier has its own recovery value and its own destinations, and a critical incident also notifies the warning tier’s destinations.

Tiers work with the above and below conditions. Equals, is not, is between and is outside have one tier, and saving drops a critical tier.

Fields and defaults

How it is checked

FieldDefaultAPI fieldWhat it does
Window5 minwindow_minutesLength of the window each check aggregates. 1 to 1440 minutes.
Breaches to fire2consecutive_breaches_requiredBreaching checks before an incident opens.
Out of the lastIn a rowbreaches_out_ofFire when Breaches to fire of the last N checks breach, instead of in a row. 1 to 30.
Minimum samples50minimum_sample_countA window with fewer samples is skipped and cannot fire.
Check everyAutoevaluation_interval_minutes1, 5, 10, 15, 30 or 60 minutes. Auto is a fifth of the window, from 1 to 5 minutes.

After it fires

FieldDefaultAPI fieldWhat it does
Resolve after2consecutive_healthy_requiredHealthy checks in a row before an incident resolves.
Remind while open, every30 minrenotify_interval_minutesHow often an open incident notifies again while it keeps breaching.
Alert when there is no dataOffalert_on_no_dataCount an empty window as a breach. Off, those windows are skipped.

Over the API, minimum_sample_count defaults to 0. The other API defaults match the editor.

For a Throughput drop rule, set Minimum samples to 0, as the Throughput drop template does. With 50, a window under 50 requests is skipped, so a full outage cannot fire. How alert rules are evaluated covers skipped windows, no data and the check interval in detail.

Who gets notified

Click Add destination to attach an existing destination, or create one from the same menu. With a critical tier, the section has one list for Warning and one for Critical, on top of the warning destinations.

Send test delivers a test notification for this rule to the selected destinations.

Message template customizes the Title and Body (Markdown) of Slack, Discord, Telegram and PagerDuty notifications with {{ variable }} substitution, for example {{ rule.name }}, {{ value }} or {{ links.app }}. Leave it blank for the built-in format. Email, webhook and Hazel destinations always use the built-in format.

Name it

Rule name is required. Tags (up to 20, each up to 32 characters) group and filter rules in the alerts list. Add notes opens a free-text Notes field for runbook links or ownership.

The bar at the bottom of the editor reads Ready to save, or lists what is still missing. Click Create rule, or Save changes on an existing rule.

Create a rule over the API

Rules are available at /v2/alerts/rules on https://api.maple.dev (https://api.eu.maple.dev for EU organizations). Use an API key (maple_ak_…) from Settings → Keys. Creating, updating, deleting and testing a rule requires the alerts:write scope and the org admin role.

curl -X POST https://api.maple.dev/v2/alerts/rules \
  -H "Authorization: Bearer maple_ak_…" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Checkout error rate",
    "signal_type": "error_rate",
    "comparator": "gt",
    "threshold": 0.05,
    "window_minutes": 5,
    "service_names": ["checkout"],
    "environments": ["production"],
    "severity": "critical",
    "minimum_sample_count": 50,
    "destination_ids": ["dest_oybbpTBhtSFGShMjjLiCrh"]
  }'

Error rate thresholds are 0 to 1 ratios in the API (0.05 is 5%). destination_ids must name at least one existing destination.

For a warning and a critical tier, send thresholds in place of severity, threshold and destination_ids. Tiers go lowest first, at most one of each severity:

"thresholds": [
  { "severity": "warning", "value": 0.02, "destination_ids": ["dest_oybbpTBhtSFGShMjjLiCrh"] },
  { "severity": "critical", "value": 0.05, "recovery_value": 0.03, "destination_ids": ["dest_4tqzJ2bXvN8yWkLmPa6sRc"] }
]

To preview a rule over a past range, POST /v2/alerts/rules/preview with the rule under rule and the range in start_time and end_time. It needs the alerts:read scope and sends nothing.

curl -X POST https://api.maple.dev/v2/alerts/rules/preview \
  -H "Authorization: Bearer maple_ak_…" \
  -H "Content-Type: application/json" \
  -d '{
    "rule": {
      "name": "Checkout error rate",
      "signal_type": "error_rate",
      "comparator": "gt",
      "threshold": 0.05,
      "window_minutes": 5,
      "service_names": ["checkout"],
      "severity": "critical",
      "destination_ids": ["dest_oybbpTBhtSFGShMjjLiCrh"]
    },
    "start_time": "2026-07-14T00:00:00.000Z",
    "end_time": "2026-07-15T00:00:00.000Z"
  }'

The response lists the value and status of each window per group in series, and the spans where an incident would have been open in would_fire.

POST /v2/alerts/rules/test evaluates a rule once against current data. Set send_notification to true to also deliver a test notification. See the API reference for every endpoint and field.

Troubleshooting

  • The rule never fires. Open the rule and look at its Checks. Skipped checks mean the window had no data or fewer samples than Minimum samples. In the editor, the chart says how many windows would be skipped and why. Check the service names and environments against what is arriving.
  • The rule fires and resolves over and over. Raise Breaches to fire and Resolve after, or widen the window.
  • Save is disabled. The bar at the bottom of the editor lists what is missing, such as a rule name or a destination.

Next steps