July 2026
POST /v1/alerts/{id}/test-webhook — send a test webhook
A new POST /v1/alerts/{id}/test-webhook fires a synthetic alert.match.created delivery to every webhook connection on an alert, so you can verify your endpoint — receipt, signature, and parsing — without waiting for a real match. The payload is byte-for-byte shaped like a live delivery and carries the alert’s real id, title, kind, and first watched entity, with illustrative sample match content.
- The webhook envelope gains a
testboolean, set totrueonly on these test deliveries and absent on real matches, so your handler can exercise its parse-and-verify path while skipping real side effects. Existing consumers are unaffected — real matches never carry the field. - Nothing is persisted: a test never appears in the alert’s delivery log. The response reports each connection’s outcome (
delivered,status_code,duration_ms,error); a non-2xx or unreachable endpoint comes back asdelivered: falsewhile the request itself still returns200.
June 2026
Alert filters — narrow what an alert surfaces
POST /v1/projects/{projectId}/alerts and PATCH /v1/alerts/{id} now accept a filters object that narrows matches after detection — applied identically to the matches list, the realtime email, and the daily/weekly digests. Four axes:
languages— restrict to source episodes in specific BCP-47-like language tags (e.g.["en", "pt-BR", "zh-Hant"]). Empty (the default) keeps every language.relevance—EVERYTHING(default) returns on-target and incidental matches;RELEVANTnarrows to on-target only, dropping passing mentions.source_popularity—ANY(default) keeps every match;POPULARkeeps only matches from the top 5% of currently-charting podcasts.speaker_roles—PODCAST_SPEAKERalerts only. Replaces the default appearance set (GUEST,PANELIST,CORRESPONDENT,AUDIENCE,SOUNDBITE_SPEAKER—HOSTexcluded). Sending this on anENTITY_MENTIONalert returns422.
PATCH with filters replaces the alert’s filter set wholesale — there’s no per-axis merge, so to add languages to an alert that already has relevance: "RELEVANT" you must send both. Send "filters": {} to clear every filter at once, or omit filters from the patch body to leave the existing set unchanged.
Filters that narrow what gets detected (languages, speaker_roles) also gate the post-create historical backfill, so older matches that wouldn’t have passed the current filter were never stored — broadening either axis later won’t surface them. relevance and source_popularity are applied at read/delivery time, so the matches list and emails immediately reflect the change.
Existing alerts keep their current behavior (no filters → every match surfaced). See Alerts → Filtering matches for the full spec and examples.
GET /v1/entities/search — purpose-built entity search (breaking change)
A new GET /v1/entities/search ranks people, companies, and knowledge graph entities for a free-text query — a name, partial name, nickname, stock ticker, @handle, or website domain — in one call. Each result is a discriminated union: type (person, company, or knowledge_graph_entity) says which kind it is, and exactly one of person/company/knowledge_graph_entity holds the matched record in the same compact shape those resources return elsewhere. Alongside it, match_quality and a mentions object (podcast_episodes, news_articles) help confirm the hit. Take the embedded record’s id (or slug) to the matching resource endpoint, or its id to alert creation.
- The
q=parameter onGET /v1/entitieshas been removed. Move name search to/v1/entities/search— passingqtoGET /v1/entitiesnow returns a422directing you there.GET /v1/entitiesstill lists the most-mentioned entities and filters bytype,podcast_id, orids. - Search results are union-shaped (a person, company, or knowledge graph entity) rather than the always-an-entity shape
GET /v1/entitiesreturns — a match may be a person or company with no standalone entity, and vice versa.
GET /v1/podcasts/search now searches podcasts (breaking change)
As announced, GET /v1/podcasts/search now does what its name says: it searches podcasts by name and returns a ranked, paginated list of podcast objects. See Search.
- If you used it to search episode dialogue (
semantic_search/keyword_search), migrate toGET /v1/podcasts/episodes/search— the parameters and response shape are identical to what/v1/podcasts/searchreturned before this change. GET /v1/podcasts?q=…keeps working and returns the same results as the new/v1/podcasts/search— it remains supported for backwards compatibility, but/v1/podcasts/searchis now the canonical way to search podcasts, and theqparameter on/v1/podcastsmay be retired in a future version.- Podcast search is metered as a standard endpoint — searching the catalog at
/v1/podcasts/searchnow costs the same as/v1/podcasts.
Missing something? Email api@particle.pro.