Skip to main content
You can create an alert two ways: point-and-click in the platform dashboard, or programmatically through the API. Both produce the same resource and both are covered below.

Before you start

  • Plan — Alerts require a Team, Business, or Enterprise plan. On a plan that doesn’t include them, the create call returns plan_does_not_support_alerts.
  • API key — Alerts CRUD works with a standard X-API-Key. Create one on the . Your key is bound to a project, and the create endpoint is project-scoped — pass that same project’s ID in the path.
  • A notification email — Matches are delivered by email to a verified address. Auto-verification works for dashboard users; API-key callers must use an address that’s already verified for the organization. See Notification emails.

Create from the dashboard

1

Open Alerts and start a new one

Go to Alerts in the project sidebar and click Create Alert.
Alerts list with the Create Alert button and allowance counter
2

Choose what triggers the alert

Pick Any mention — notify whenever the entity is mentioned — or Speaker appearance — notify only when the entity is themself a speaker on the episode (guest, panelist, correspondent, or audience). The trigger is fixed once the alert is created.
Create alert trigger picker with Any mention and Speaker appearance
3

Pick the entity and delivery frequency

Search for the entity to watch — the field is labelled Person to watch for a speaker-appearance alert — and choose a Delivery frequency: As it happens, Daily digest, or Weekly digest.
Entity search autocomplete showing companies, people, and concepts
Create alert form watching Sam Altman with Daily digest selected
4

Name it and set the recipient

Give the alert a Title and a Send to email address, then create it. The alert’s detail page shows its configuration, an Active/paused badge, and a recent-deliveries log.
Alert detail page showing the watched entity, trigger, recipient, frequency, and deliveries

Create with the API

1. Resolve the entity

An alert watches entities by canonical ID, not by name. Resolve the entity first, then use its id as the entity_id. entity_type is one of PERSON, COMPANY, or KNOWLEDGE_GRAPH_ENTITY:
entity_typeResolve withUse as entity_id
COMPANYGET /v1/companies/{id}the company’s id
KNOWLEDGE_GRAPH_ENTITYGET /v1/entities/{id}the entity’s id (people, organizations, places, and topics in the knowledge graph)
PERSONa Particle person record, e.g. a resolved podcast guestthe person’s id
# Resolve a company
curl "https://api.particle.pro/v1/companies/nvidia" \
  -H "X-API-Key: $PARTICLE_API_KEY"
# → "id": "3CensCwu5G2oKCFgPrNf89"

# Resolve a knowledge-graph entity (a person, here)
curl "https://api.particle.pro/v1/entities/sam-altman" \
  -H "X-API-Key: $PARTICLE_API_KEY"
# → "id": "17PzxG1t12xzno"
Use the canonical id, not the slug. For PERSON and COMPANY, entity_id must decode to a valid UUID — a slug like nvidia is rejected with a 422. A well-formed id that doesn’t match a real entity is accepted, but the alert is created without the enriched name/image_url and won’t match anything, so confirm the ID resolves first.

2. Preview match frequency (optional)

Before you commit, run a preview to see how often the alert would have fired over the past window_days days (default 7, max 30). The sweep is asynchronous, and the POST returns only status fields (preview_id, status, window_days) — never the counts. A fresh sweep returns 202 Accepted with status: "in_progress"; poll GET /v1/alerts/preview/{previewId} until status is terminal (completed or failed), then read total_matches, by_day, and sample from that GET response. If an identical preview ran within the past hour, the POST returns 200 OK with status: "completed" instead — the result is ready, so a single GET retrieves it without a polling loop.
# Kick off the sweep
curl -X POST "https://api.particle.pro/v1/projects/$PARTICLE_PROJECT_ID/alerts/preview?window_days=7" \
  -H "X-API-Key: $PARTICLE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "kind": "ENTITY_MENTION",
    "entities": [
      { "entity_type": "COMPANY", "entity_id": "3CensCwu5G2oKCFgPrNf89" }
    ]
  }'
Response (202 Accepted)
{
  "preview_id": "9f1c2a7b8e3d4f60",
  "status": "in_progress",
  "window_days": 7
}
# Poll until status is completed or failed
curl "https://api.particle.pro/v1/alerts/preview/9f1c2a7b8e3d4f60" \
  -H "X-API-Key: $PARTICLE_API_KEY"
Response (200 OK)
{
  "status": "completed",
  "window_days": 7,
  "started_at": "2026-06-16T15:04:00Z",
  "completed_at": "2026-06-16T15:04:06Z",
  "total_matches": 42,
  "by_day": [
    { "date": "2026-06-10", "count": 5 },
    { "date": "2026-06-11", "count": 9 }
  ],
  "sample": [
    {
      "kind": "ENTITY_MENTION",
      "entity_type": "COMPANY",
      "entity_id": "3CensCwu5G2oKCFgPrNf89",
      "mention_count": 4,
      "episode": { "title": "…", "podcast_title": "…" }
    }
  ]
}
total_matches is the count over the whole window; by_day is the per-day histogram (empty days included so a chart has no gaps); sample is the few most-recent matches with full payload so you can show “here’s what it would have caught.” Preview IDs are deterministic — repeating the same body within the hour returns the same preview_id and a cached result, so polling is cheap. If the sweep errors, the same endpoint returns status: "failed" with a human-readable error string instead of counts — treat failed as terminal alongside completed and stop polling. Previews are retained for one hour; an expired preview_id returns 404.

3. Create the alert

POST the configuration to the project-scoped endpoint. The body sets the title, kind, delivery cadence, the entities to watch, and one or more email channels.
curl -X POST "https://api.particle.pro/v1/projects/$PARTICLE_PROJECT_ID/alerts" \
  -H "X-API-Key: $PARTICLE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Nvidia mentions on podcasts",
    "kind": "ENTITY_MENTION",
    "delivery_cadence": "REALTIME",
    "entities": [
      { "entity_type": "COMPANY", "entity_id": "3CensCwu5G2oKCFgPrNf89" }
    ],
    "notifications": [
      { "type": "EMAIL", "email": "you@example.com" }
    ]
  }'
Response (200)
{
  "id": "8Qw2mRk7Tf9LpZ",
  "project_id": "Vb3xN1aPq8",
  "title": "Nvidia mentions on podcasts",
  "kind": "ENTITY_MENTION",
  "delivery_cadence": "REALTIME",
  "is_active": true,
  "entities": [
    {
      "entity_type": "COMPANY",
      "entity_id": "3CensCwu5G2oKCFgPrNf89",
      "name": "Nvidia",
      "image_url": "https://cdn.particle.pro/…"
    }
  ],
  "notifications": [
    { "id": "Nk4d…", "type": "EMAIL", "email": "you@example.com" }
  ],
  "created_at": "2026-06-16T15:10:00Z",
  "updated_at": "2026-06-16T15:10:00Z"
}
The created_by field is omitted here because the request authenticated with an API key; it’s populated with the creating user only for alerts created by a signed-in dashboard user. To alert on a person’s appearances rather than mentions, set kind to PODCAST_SPEAKER and watch a person entity — either a PERSON record or the person’s knowledge-graph entity. This fires only when the person is an identified speaker on the episode — a guest, panelist, correspondent, or audience member — not when they’re merely talked about.
curl -X POST "https://api.particle.pro/v1/projects/$PARTICLE_PROJECT_ID/alerts" \
  -H "X-API-Key: $PARTICLE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Sam Altman podcast appearances",
    "kind": "PODCAST_SPEAKER",
    "delivery_cadence": "REALTIME",
    "entities": [
      { "entity_type": "KNOWLEDGE_GRAPH_ENTITY", "entity_id": "17PzxG1t12xzno" }
    ],
    "notifications": [
      { "type": "EMAIL", "email": "you@example.com" }
    ]
  }'
A few rules worth knowing:
  • kind is fixed at creation. Switching mention vs appearance later would invalidate the match history, so create a new alert instead.
  • delivery_cadence defaults to REALTIME. Use DAILY or WEEKLY for bundled digest emails — see Delivery frequency.
  • is_active defaults to true. Pass false to create the alert paused: it won’t match new episodes or send email going forward, and it doesn’t count against your plan’s allowance until enabled. The one-time creation backfill still runs, so a paused alert can still show up to 7 days of historical (backfilled) matches.
  • A new alert is backfilled. Right after creation — even if you create it paused — Particle sweeps the past 7 days so the alert isn’t empty. Backfilled matches never send email — see Alert results → Backfill.

Notification emails

Every email channel must be verified for your organization before it receives mail. What gets verified automatically depends on how you authenticate:
  • Dashboard / logged-in users — your own address and any address belonging to a member of your organization are verified automatically the first time you use them.
  • API-key callers — an API key carries no user identity, so nothing is auto-verified. The address must already be verified for the organization (verify it once from the dashboard, or through the verification-link flow); otherwise the create or update call returns email_verification_required.
  • Any third-party address must confirm a one-time verification link before it receives mail.
Deleting a verified notification email that is still referenced by an alert returns notification_email_in_use — remove it from the alert’s notifications first.

Update, pause, and delete

PATCH /v1/alerts/{id} applies a partial update. Only the fields you send change — but entities and notifications, when present, replace the whole set (they aren’t merged).
# Pause an alert without losing its history
curl -X PATCH "https://api.particle.pro/v1/alerts/8Qw2mRk7Tf9LpZ" \
  -H "X-API-Key: $PARTICLE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "is_active": false }'
# Resume it
curl -X PATCH "https://api.particle.pro/v1/alerts/8Qw2mRk7Tf9LpZ" \
  -H "X-API-Key: $PARTICLE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "is_active": true }'
# Delete it (soft delete — existing matches and deliveries are retained for audit)
curl -X DELETE "https://api.particle.pro/v1/alerts/8Qw2mRk7Tf9LpZ" \
  -H "X-API-Key: $PARTICLE_API_KEY"
Recipients can also turn an alert off without an account: every alert email has a Disable this alert link in its footer that flips the alert to inactive in one click. See Alert results → Stop delivery.

Errors

ErrorWhen
plan_does_not_support_alertsThe organization’s plan doesn’t include alerts.
add_on_requiredPlan’s included alert allowance is reached. Buy an Alerts Pack.
email_verification_requiredA third-party notification email hasn’t confirmed its link.
validation_errorMalformed entity_id (e.g. a slug where a canonical PERSON/COMPANY ID is required), unknown kind, or an EMAIL channel with no address.