---
title: "Create an alert rule (email, Slack or webhook)"
method: POST
path: "/alert-rules"
tags: ["Alerts"]
---

# Create an alert rule (email, Slack or webhook)

`POST /alert-rules`

## Request

- Base URL: `https://adslighthouse.com/api/v1`
- URL: `https://adslighthouse.com/api/v1/alert-rules`
- Auth: HTTP bearer

Creates an alert rule for a project, exactly like Settings > Alert rules. Types: competitor_new (a domain the project does not own shows an ad for the first time), competitor_returning (an advertiser returns after at least 30 days away), hijack_detected (an ad from another domain mentions the brand in its copy), affiliate_detected (one of your affiliate IDs appears in an ad's destination URL; needs the project's affiliate parameter), summary_digest (a scheduled summary sent daily or weekly at a local hour, even when nothing changed: checks saved against expected, new and returning advertisers, brand mentions, affiliate IDs, non-compliant affiliates, policy cases and the top advertisers by observed visibility for the complete local days before delivery; give cadence, weekday for weekly, hour and optionally time_zone). Channels: email (target is an address, or omit it to notify the account owner), slack (target must be an https://hooks.slack.com/services/ URL) or webhook (target must be a public HTTPS URL; each delivery is signed with HMAC-SHA256 in x-ads-lighthouse-signature). Optional engines, devices and countries restrict which observations fire the rule. Alerts are leads to review: an observation is not proof of a purchased keyword, spend or a violation. Requires the write scope and an idempotency key; a retry with the same key returns the same rule. For webhook rules the response carries the signing secret once.

## Headers

- `Idempotency-Key` string, required: A unique value you choose for this request, such as a UUID. Repeating the same key returns the first result instead of starting paid work again.

## Request body

- object
  - `project_id` string, required: The project: its id, its brand domain (for example nike.example) or its exact project or brand name. Unknown or ambiguous references return not_found; call list_projects then.
  - `type` 'competitor_new' | 'competitor_returning' | 'hijack_detected' | 'affiliate_detected' | 'summary_digest', required: What fires the rule: a finding, or a schedule for summary_digest.
  - `channel` 'email' | 'webhook' | 'slack', required: How alerts are delivered.
  - `target` string: For email, the confirmed address of a person in this account (empty sends to the account owner); otherwise a Slack incoming webhook URL or your HTTPS webhook URL.
  - `engines` string[], nullable: Only observations from these search engines. Omit or null for every engine.
  - `devices` string[], nullable: Only observations on these devices. Omit or null for every device.
  - `countries` string[], nullable: Only observations in these ISO 3166-1 alpha-2 countries, such as US.
  - `cadence` 'daily' | 'weekly': summary_digest only: daily or weekly. Required when creating a summary.
  - `weekday` 'monday' | 'tuesday' | 'wednesday' | 'thursday' | 'friday' | 'saturday' | 'sunday': summary_digest only: the day of a weekly summary. Default monday.
  - `hour` integer: summary_digest only: local delivery hour, 0 to 23. Default 8 (08:00).
  - `time_zone` string: summary_digest only: IANA time zone such as America/New_York. Defaults to the acting person's time zone when creating, and keeps the stored zone when updating.

## Response `201`

Create an alert rule (email, Slack or webhook)

- object
  - `created` boolean, required: False when this key already created the rule.
  - `rule` object, required
    - `id` string, required
    - `project_id` string, nullable, required
    - `project_name` string, nullable, required
    - `brand_name` string, required
    - `type` 'competitor_new' | 'competitor_returning' | 'hijack_detected' | 'affiliate_detected' | 'ranking_drop' | 'nklg_re_enable' | 'ingestion_failed' | 'summary_digest', required
    - `type_label` string, required
    - `channel` 'email' | 'webhook' | 'slack', required
    - `destination` string, nullable, required: Email address, or the host of a webhook or Slack URL (the full URL is never returned). null for an email rule that goes to the account owner.
    - `enabled` boolean, required
    - `filters` object, nullable, required: Which observations the rule watches. null in a dimension means every value; values within a dimension combine with OR, dimensions with AND.
      - `engines` string[], nullable, required
      - `devices` string[], nullable, required
      - `countries` string[], nullable, required
    - `schedule` object, nullable, required: When a scheduled summary (type summary_digest) is sent. Each summary covers the complete local days before its delivery day: the day before (daily) or the seven days before (weekly).
      - `cadence` 'daily' | 'weekly', required
      - `weekday` 'monday' | 'tuesday' | 'wednesday' | 'thursday' | 'friday' | 'saturday' | 'sunday', nullable, required: The day a weekly summary is sent; null for a daily summary.
      - `hour` integer, required: Local hour of delivery, 0 to 23, at minute 00.
      - `time_zone` string, required: The IANA time zone the hour and the covered days use, kept on the rule when someone else edits it.
      - `next_delivery_at` string, nullable, required: When the next summary is sent; null while the rule is paused.
    - `created_at` string, required
  - `signing_secret` string, nullable, required: The webhook signing secret (whsec_...). Returned only here and by rotate_webhook_secret, only for webhook rules and only to owners and account admins. Store it now: list and get never return it.
  - `request_id` string

## Other responses

- `400`: Invalid parameters, cursor or body.
- `401`: Missing, invalid, expired or revoked credential.
- `403`: The credential lacks the write scope, the plan does not include the API, or the allowance is used up.
- `404`: Unknown project, keyword or run in this account.
- `409`: The idempotency key was already used for a different request.
- `429`: Rate limit reached. Retry after the Retry-After seconds.
- `503`: The requested service or file is temporarily unavailable.

---

[API](https://skmtc.dev/adslighthouse/apis/ads-lighthouse-api.md) · [All operations](https://skmtc.dev/adslighthouse/apis/ads-lighthouse-api/llms.txt) · [OpenAPI document](https://skmtc.dev/adslighthouse/apis/ads-lighthouse-api/revisions/e1a4a40b11a9?raw)
