PUT — cut that down before a message is ever sent.
These fields live on the rule itself (see Create and manage alert rules) — there’s no separate noise-control endpoint. All three are optional; omit them and the rule fires on every condition match, every time.
The three controls
They apply in this order: persistence gates whether a fire is considered at all, then cooldown and dedupe gate whether that fire is actually delivered.
1. Cooldown — enforce a minimum gap between firings
curl
cooldown_minutes: 60, once this rule fires for a given opportunity, it won’t fire again for that same opportunity for an hour — regardless of how many times the APY dips below 5% and recovers in between. A different opportunity (a different asset/venue pair the rule also watches) has its own independent cooldown clock.
2. Persistence — require the condition to hold, not just touch
curl
require_persistence_minutes: 15 means the condition has to stay true for a continuous 15-minute stretch before the rule fires. If the APY drops below 5% and climbs back above it two minutes later, that dip never fires — it didn’t persist long enough. This is the field to reach for when a source is naturally noisy (perp funding rates, thin-liquidity APYs) and single-tick crossings aren’t actionable on their own.
3. Dedupe — collapse repeats of the same values
curl
Validation
All three fields reject negative values with400:
dedupe_window_minutes. There’s no upper bound enforced server-side — pick a window that matches how often the underlying data actually refreshes; a require_persistence_minutes longer than your data source’s polling interval will never be satisfiable.
Troubleshooting
- A rule I expected to fire didn’t: check
require_persistence_minutesfirst — a condition that flickers in and out never accumulates a persistent match. PullGET /v1/alerts/events?rule_id=$RULE_ID&status=suppressedto see fires the platform held back and why. - I’m still getting near-duplicate alerts seconds apart:
dedupe_window_minutesonly collapses fires with identical condition values; if the underlying value is still moving (APY ticking down by 0.1% each time), each fire looks different and dedupe won’t merge them — usecooldown_minutesinstead, which doesn’t care whether the values match. 400on create or update: re-check for a negative value onrequire_persistence_minutesordedupe_window_minutes— see Validation above.