---
title: "POST /api/projects/{project_id}/platform_alerts/"
method: POST
path: "/api/projects/{project_id}/platform_alerts/"
tags: ["platform_alerts"]
---

# POST /api/projects/{project_id}/platform_alerts/

`POST /api/projects/{project_id}/platform_alerts/`

## Request

- Base URL: `https://us.posthog.com`
- URL: `https://us.posthog.com/api/projects/{project_id}/platform_alerts/`
- Auth: HTTP bearer

## Path parameters

- `project_id` string, required

## Request body

- PlatformAlertConfigurationCreate: The settings of a new alert. Every one but source_config has a default, which is stored.
  - `source_kind` string, required: Product whose data the alert evaluates. It cannot change after the create.
  - `name` string: Human-readable name of the alert. Defaults to 'Untitled alert'.
  - `enabled` boolean: Whether the alert is evaluated on schedule. Defaults to true.
  - `source_config` LogsPlatformAlertSourceConfig, required
    - `filters` LogsAlertFilters, required
      - `filterGroup` PropertyGroupFilter
        - `type` 'AND' | 'OR', required
        - `values` PropertyGroupFilterValue[], required
          - `type` 'AND' | 'OR', required
          - `values` union[], required
            - union
              - …
      - `serviceNames` string[], nullable
      - `severityLevels` LogSeverityLevel[], nullable
    - `condition` LogsPlatformAlertCondition, required
      - `threshold_count` integer, required: Number of matching log entries in the window that breaches the threshold. Use 0 with the above operator to fire on any matching log.
      - `threshold_operator` 'above' | 'below', required
      - `window_minutes` 5 | 10 | 15 | 30 | 60, required
  - `grouping` Grouping
    - `mode` 'single' | 'by_result_labels', required: * `single` - Single * `by_result_labels` - By result labels
    - `keys` string[]: Result labels whose values make a group, such as service_name. Empty for mode single, required for by_result_labels. Changing them deletes the existing instances and closes their notification threads without a message.
    - `max_instances` integer: Most instances the alert keeps at once. Groups past it are not tracked, and the last message says how many were left out.
    - `on_overflow` 'degrade_visible': * `degrade_visible` - Degrade visible
  - `schedule_restriction` AlertScheduleRestriction
    - `blocked_windows` AlertScheduleRestrictionWindow[], required: Blocked local time windows when the alert must not run. Overlapping or identical windows are merged when saved. At most five windows before normalization; empty array clears quiet hours.
      - `start` string, required: Start time HH:MM (24-hour, project timezone). Inclusive. Each window must span ≥ 30 minutes on the local daily timeline (half-open [start, end)).
      - `end` string, required: End time HH:MM (24-hour). Exclusive (half-open interval). Each window must span ≥ 30 minutes locally.
  - `evaluation_periods` integer: Number of recent checks considered when deciding to fire. Defaults to 1.
  - `datapoints_to_alarm` integer: Number of breaching checks within evaluation_periods required to fire. Cannot exceed evaluation_periods. Defaults to 1.
  - `cooldown_minutes` integer: Minimum minutes between notifications for the same alert. Defaults to 0.

## Response `201`

- PlatformAlertConfiguration
  - `id` string, uuid, required: Unique identifier of the alert configuration.
  - `name` string, required: Human-readable name of the alert.
  - `enabled` boolean, required: Whether the alert is evaluated on schedule.
  - `source_kind` 'logs' | 'insight', required: * `logs` - Logs * `insight` - Insight
  - `source_config` object, required: Source-specific settings. The shape depends on source_kind. The bound the alert is evaluated against is under the condition key.
  - `check_interval_minutes` integer, required: Minutes between scheduled checks. Applies when recurrence_unit is null.
  - `recurrence_unit` union, required: Calendar unit the alert recurs on. Null means it recurs on check_interval_minutes. * `day` - Day * `week` - Week * `month` - Month
    - 'day' | 'week' | 'month': * `day` - Day * `week` - Week * `month` - Month
    - unknown
  - `anchor_time` string, nullable, required: Local time (HH:MM in the project timezone) a calendar recurrence lands on. Null means the default anchor for the unit.
  - `evaluation_periods` integer, required: Number of recent checks considered when deciding to fire.
  - `datapoints_to_alarm` integer, required: Number of breaching checks within evaluation_periods required to fire.
  - `cooldown_minutes` integer, required: Minimum minutes between notifications for the same alert.
  - `schedule_restriction` AlertScheduleRestriction, required
    - `blocked_windows` AlertScheduleRestrictionWindow[], required: Blocked local time windows when the alert must not run. Overlapping or identical windows are merged when saved. At most five windows before normalization; empty array clears quiet hours.
      - `start` string, required: Start time HH:MM (24-hour, project timezone). Inclusive. Each window must span ≥ 30 minutes on the local daily timeline (half-open [start, end)).
      - `end` string, required: End time HH:MM (24-hour). Exclusive (half-open interval). Each window must span ≥ 30 minutes locally.
  - `next_check_at` string, date-time, nullable, required: When the next check is due. Null when no check is scheduled.
  - `consecutive_failures` integer, required: Number of checks in a row that failed to evaluate.
  - `legacy_configuration_id` string, uuid, nullable, required: ID of the legacy source configuration this row was backfilled from. Null for alerts created on the platform.
  - `grouping` Grouping, required
    - `mode` 'single' | 'by_result_labels', required: * `single` - Single * `by_result_labels` - By result labels
    - `keys` string[]: Result labels whose values make a group, such as service_name. Empty for mode single, required for by_result_labels. Changing them deletes the existing instances and closes their notification threads without a message.
    - `max_instances` integer: Most instances the alert keeps at once. Groups past it are not tracked, and the last message says how many were left out.
    - `on_overflow` 'degrade_visible': * `degrade_visible` - Degrade visible
  - `snooze_until` string, date-time, nullable, required: Time until which every instance's notifications are muted. Null when not muted. An instance's own snooze_until mutes one group, and the later of the two holds.
  - `check_status` 'ok' | 'errored' | 'broken', required: * `ok` - OK * `errored` - Errored * `broken` - Broken
  - `overflowed_groups` integer, required: New groups the last successful check could not track because the alert already held grouping.max_instances instances. 0 when every group fit.
  - `overflow_is_lower_bound` boolean, required: Whether the last successful check cut its results before counting overflowed_groups. When true, more groups than overflowed_groups may be untracked.
  - `owner` 'source' | 'platform', required: * `source` - Source * `platform` - Platform
  - `created_at` string, date-time, required: When the configuration was created.
  - `updated_at` string, date-time, required: When the configuration was last changed.
  - `alerts` PlatformAlert[], required: Runtime state for each result group of this configuration.
    - `id` string, uuid, required: Unique identifier of this alert instance.
    - `grouping_key` string, required: Key of the result group this instance tracks. Empty when the source does not group results.
    - `state` 'not_firing' | 'firing' | 'errored' | 'snoozed' | 'broken', required: * `not_firing` - Not firing * `firing` - Firing * `errored` - Errored * `snoozed` - Snoozed * `broken` - Broken
    - `firing_started_at` string, date-time, nullable, required: When the current firing started. Null when the instance is not firing.
    - `last_notified_at` string, date-time, nullable, required: When a notification was last sent for this instance.
    - `snooze_until` string, date-time, nullable, required: Time until which notifications are snoozed. Null when not snoozed.
    - `labels` object, required: Result labels and their values for the group this instance tracks, such as {"service_name": "checkout"}. Empty when the source does not group results.

## Other responses

- `400`: The settings are invalid, or the source refused the create.
- `403`: The caller cannot write alerts of this source kind.
- `409`: The URL names an environment, whose alerts are created on its own page.

## Changes

> 53 revisions in range; 1 not diffed.

- **2026-10-21** `61d9f96ff855`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/posthog/apis/posthog-api/changes/api/projects/:project_id/platform_alerts/post.md)

---

[API](https://skmtc.dev/posthog/apis/posthog-api.md) · [All operations](https://skmtc.dev/posthog/apis/posthog-api/llms.txt) · [OpenAPI document](https://skmtc.dev/posthog/apis/posthog-api/revisions/993f70ab941b?raw)
