---
title: "List alerts"
method: GET
path: "/v1/projects/{projectId}/alerts"
tags: ["Alerts", "tier:standard"]
---

# List alerts

`GET /v1/projects/{projectId}/alerts`

## Request

- Base URL: `https://api.particle.pro`
- URL: `https://api.particle.pro/v1/projects/{projectId}/alerts`
- Auth: one of:
  - API key in header `X-API-Key`
  - HTTP bearer

List alerts owned by the given project, newest first.

## Path parameters

- `projectId` string, required: Project ID.

## Query parameters

- `limit` integer: Results per page
- `cursor` string: Opaque pagination cursor from previous response

## Response `200`

OK

- PageAlert
  - `cursor` string: Pass to next request for more results
  - `data` Alert[], nullable, required: List of results
    - `created_at` string, date-time, required
    - `created_by` Creator
      - `id` string, required: Creator's user ID
      - `name` string, required: Creator's display name
    - `delivery_cadence` string, required: How often matches are delivered: REALTIME (a separate email per match), DAILY (one bundled email each morning at 13:00 UTC), or WEEKLY (one bundled email Monday 13:00 UTC). Defaults to REALTIME.
    - `description` string
    - `entities` AlertEntity[], nullable, required
      - `entity_id` string, required
      - `entity_type` 'PERSON' | 'COMPANY' | 'KNOWLEDGE_GRAPH_ENTITY', required
      - `image_url` string: Image URL for the watched entity (headshot for PERSON, logo for COMPANY, image for KGE). Omitted from the response when no image is available.
      - `name` string: Display name of the watched entity. Omitted from the response when the underlying record cannot be resolved (e.g. deleted).
    - `filters` AlertFilters
      - `languages` string[], nullable: Primary language tags the source episode must be in. Accepts a 2-3 letter primary tag (e.g. 'en', 'de', 'sma') and tolerates an optional 2-4 char region or script subtag for readability (e.g. 'pt-BR', 'zh-Hant'); matching is on the PRIMARY tag only, so 'pt-BR' surfaces every Portuguese episode regardless of region and 'pt-BR' + 'pt-PT' collapse to one. Empty or missing means all languages are surfaced. Codes are compared case-insensitively; the API echoes back the canonical primary-tag form.
      - `relevance` 'EVERYTHING' | 'RELEVANT': EVERYTHING (the default) returns both on-target and incidental matches — the watched entity is correctly identified in both, only the depth of discussion differs. RELEVANT narrows to on-target only: matches where the watched entity is the subject being discussed, dropping passing mentions. Wrong-entity matches (knowledge-graph name collisions, e.g. the podcast 'Truckie' for an alert on the town 'Truckee') are globally suppressed before any filter runs.
      - `source_popularity` 'ANY' | 'POPULAR': ANY (the default) keeps matches from every source. POPULAR keeps only matches whose source podcast scores in the top 5% by chart-popularity percentile (Podcast.Popularity >= 0.95; cume_dist over current chart entries, multi-region weighted). Podcasts that aren't currently charting drop out.
      - `speaker_roles` string[], nullable: PODCAST_SPEAKER alerts only. REPLACES (not intersects with) the default appearance set the alert matches against. Default when omitted is GUEST, PANELIST, CORRESPONDENT, AUDIENCE, SOUNDBITE_SPEAKER — HOST is intentionally excluded because hosting the show isn't an appearance. Setting ['HOST'] flips that — only HOST appearances match. Setting ['GUEST'] alone narrows further. Sending this on an ENTITY_MENTION alert returns 422 — the wire layer can't tell at validation time, so the handler boundary rejects it once the parent kind is known. Input casing is not significant — 'guest' and 'GUEST' are the same value — and the filter is persisted and echoed back in canonical uppercase form. Raw STT/LLM labels like CALLER or REPORTER are not accepted because podcast_episode_speakers.role canonicalizes to the buckets above at write time.
    - `id` string, required
    - `is_active` boolean, required: Whether the alert produces matches. Disabled alerts retain history but accumulate no new matches until re-enabled.
    - `keyword` string: KEYWORD_MENTION alerts only: the phrase the alert watches (see the create request's keyword for how it matches). Absent on entity alerts.
    - `kind` 'ENTITY_MENTION' | 'PODCAST_SPEAKER' | 'KEYWORD_MENTION', required: What signal the alert watches for. ENTITY_MENTION fires whenever a watched entity is mentioned in a podcast episode. PODCAST_SPEAKER fires only when a watched entity is themself an identified speaker on the episode, in one of the alert's speaker roles. By default those are GUEST, PANELIST, CORRESPONDENT, AUDIENCE (which absorbs callers, listeners, and other audience-side roles after server-side canonicalization), and SOUNDBITE_SPEAKER (an excerpted clip of them played on the episode); HOST is excluded by default because hosting the show isn't an appearance. speaker_roles replaces the default set. KEYWORD_MENTION fires whenever the alert's keyword is spoken in a podcast episode, for names the entity resolvers don't know; it watches a keyword instead of entities. Kind is fixed at creation.
    - `notifications` AlertNotificationChannel[], nullable, required
      - `created_by` Creator
        - `id` string, required: Creator's user ID
        - `name` string, required: Creator's display name
      - `email` string, email: Required when type=EMAIL.
      - `id` string
      - `slack_channel_id` string: Required when type=SLACK. Slack vendor channel id (e.g. C01234XYZ for public channels, G... for private channels). Must be a channel returned by GET /v1/projects/{projectId}/slack/connections/{id}/channels.
      - `slack_channel_name` string: Optional. Display label for the destination channel. The server overwrites this from the cached slack_channels row on save, so clients do not need to supply it.
      - `slack_connection_id` string: Required when type=SLACK. The Slack workspace connection that owns the channel. Any active connection belonging to the alert's project is accepted, whichever surface installed it, so an alert created in one app can be managed from the other.
      - `type` 'EMAIL' | 'SLACK' | 'WEBHOOK', required: Delivery channel type. EMAIL writes to email; SLACK posts a message to a channel in a connected Slack workspace; WEBHOOK POSTs a signed JSON payload to a configured webhook connection.
      - `webhook_connection_id` string: Required when type=WEBHOOK. The webhook connection that receives the signed payload.
    - `project_id` string, required
    - `title` string, required
    - `updated_at` string, date-time, required
  - `has_more` boolean, required: Whether more results exist

## Other responses

- `default`: Error

---

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