---
title: "Estimate how often a rule would have fired"
method: POST
path: "/rest/api/v1/projects/{projectId}/notificationRules/preview"
tags: ["Notifications API"]
---

# Estimate how often a rule would have fired

`POST /rest/api/v1/projects/{projectId}/notificationRules/preview`

## Request

- Base URL: `https://api.metacopier.io`
- URL: `https://api.metacopier.io/rest/api/v1/projects/{projectId}/notificationRules/preview`
- Auth: API key in header `X-API-KEY`
- TypeScript: <https://skmtc.dev/metacopier/apis/metacopier-api/docs/rest/api/v1/projects/:projectId/notificationRules/preview/post.ts> (a function with typed inputs; its response is checked against the schema)

Replays the stored logs of the window (default: last 24 hours, at most 7 days) through the rule, including digest, quiet hours and cooldown. Nothing is sent.

## Path parameters

- `projectId` string, uuid, required

## Request body

- NotificationRulePreviewRequestDTO: Unsaved rule and the time range to simulate
  - `from` string, date-time: Start, default 24 hours ago
  - `rule` FeatureNotificationRuleDTO: Notification rule (feature type 58): which log events go to which channels
    - `accountIds` string[]: Only these accounts; empty = all accounts including future ones
    - `categories` string[]: Categories; empty = all
    - `cooldown` NotificationCooldownDTO: Suppresses repeats of the same message for a while
      - `enabled` boolean: Cooldown on/off
      - `minutes` integer: Cooldown length, 1 to 1440 minutes
    - `digest` NotificationDigestDTO: Bundles messages of a rule: the first is sent, further ones within the window become one summary
      - `enabled` boolean: Digest on/off
      - `errorsImmediate` boolean: Never bundle ERROR messages
      - `windowSeconds` integer: Window length, 10 to 3600 seconds
    - `enabled` boolean: Rule on/off
    - `events` string[]: Fine grained events; empty = all events of the selected categories
    - `excludeAccountIds` string[]: All accounts except these; cannot be combined with accountIds
    - `includeProjectEvents` boolean: With accountIds: still deliver events that belong to no account
    - `kind` string: Setting discriminator, always RULE
    - `migratedFromFeatureId` string, uuid: Set when the rule was created from a legacy Telegram notification
    - `minLogLevel` LogTypeDTO, required: Lowest level delivered: 1 = ERROR, 2 = WARN, 3 = INFO
      - `id` integer, required
      - `name` string
    - `name` string, required: Free label of the rule
    - `quietHours` NotificationQuietHoursDTO: Suppresses deliveries of a rule during a daily time window
      - `activeDays` integer[]: Days the window starts on, 1 = Monday ... 7 = Sunday; empty = daily
      - `after` string: What happens at the end: SUMMARY or DISCARD
      - `allowErrors` boolean: ERROR messages are still delivered
      - `enabled` boolean: Quiet hours on/off
      - `from` string: Start, HH:mm, inclusive
      - `timeZone` string: IANA time zone
      - `to` string: End, HH:mm, exclusive; may span midnight
    - `sourceFeatureIds` string[]: Only events raised by these feature instances; empty = all
    - `sourceFeatureTypeIds` integer[]: Only events raised by these feature types (tools); empty = all
    - `targets` NotificationTargetDTO[]: Channels to deliver to; recipient only for Telegram
      - `featureId` string, uuid: Id of the channel feature instance, for example the project's Telegram feature
      - `recipient` string: Null means every recipient of that channel. Telegram: the username. Email: the address. Slack, Discord, Teams and webhook always leave this null.
    - `useAlias` boolean: Show the account alias instead of the account id
  - `to` string, date-time: End, default now; at most 7 days after from

## Response `200`

OK

- NotificationRulePreviewDTO: Estimate of what a rule would have sent; never an exact delivery prediction
  - `assumptions` string[]: What the estimate assumes
  - `complete` boolean: All entries in the range were evaluated
  - `estimatedRequestCount` integer: Estimated provider requests over all channels
  - `evaluatedCount` integer: Log entries evaluated
  - `from` string, date-time: Simulated start
  - `matchedCount` integer: Entries matching the rule
  - `perChannel` NotificationRulePreviewChannelDTO[]: Per channel
    - `channelType` 'TELEGRAM' | 'WEBHOOK' | 'SLACK' | 'MS_TEAMS' | 'DISCORD': Channel type
    - `estimatedRequestCount` integer: Estimated provider requests after digest/quiet hours/cooldown
    - `featureId` string, uuid: Channel feature
    - `matchedCount` integer: Events that would reach this channel
    - `recipient` string: Recipient (Telegram)
  - `to` string, date-time: Simulated end
  - `truncated` boolean: More than 10000 entries; the result is a sample
  - `unclassifiedCount` integer: Entries without event metadata (logged before tagging)

## Changes

- **2026-11-02** `2ac6d7461345`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/metacopier/apis/metacopier-api/changes/rest/api/v1/projects/:projectId/notificationRules/preview/post.md)

---

[API](https://skmtc.dev/metacopier/apis/metacopier-api.md) - [All operations](https://skmtc.dev/metacopier/apis/metacopier-api/llms.txt) - [OpenAPI document](https://skmtc.dev/metacopier/apis/metacopier-api/revisions/2ac6d7461345?raw)
