particle_podcast_find_mentions
Find dialogue lines where a specific person or company is named in podcast transcripts.
## Three response modes
**`format="summary"` (default, wide scan).** Returns up to `limit` episodes (reverse-chronological), each with metadata + the first 10 mention-only lines (just the lines naming the entity, no surrounding dialogue). Use this to see *what's been said across episodes* and decide which episodes are worth reading in full. Paginate older episodes with `cursor`.
**`format="detail"` (narrow drill-in).** Requires `episode_slug`. Returns the full mention windows with `context_lines` of surrounding dialogue around each mention. Pass one slug for a single episode, or up to 10 comma-separated slugs (e.g. `episode_slug="all-in-200,all-in-201,all-in-202"`) to multi-get several episodes in one call. `limit`/`cursor` don't apply.
**`format="compact"` (screening).** The same episodes as summary, each with its mention count, the strings it was mentioned as, and the segments carrying the mentions (id, title, type, first mention time) — no dialogue lines at all, the smallest shape. `limit` and `cursor` page it exactly as summary. Use it to fan out over many entities or a long date range and decide where to read; the segment ids are citations, and `format="detail"` with the episode slug reads the lines.
## Workflow
Two patterns, depending on what you already know:
- **No specific episode in mind:** call `format="summary"` first to scan, then call `format="detail"` with the slug(s) of the episodes worth reading in full. For most questions (sentiment, recurring themes, who said what when), summary alone has enough signal and the second call isn't needed.
- **Already have the episode slug** (e.g. user mentioned the episode by name, or you have it from another tool like `particle_podcast_get_episode` or `particle_podcast_search_transcripts`): skip summary entirely and call `format="detail"` with `episode_slug` directly.
## Examples
*Wide scan, then drill in:* User asks "what has All-In said about OpenAI recently?". Call `format="summary"`, `company_slug="openai"`, `podcast_slug="all-in"`, `since="2025-11-01"`, `limit=20`. Read the mention lines per episode; if 2-3 episodes have substantive discussion, call `format="detail"`, `episode_slug="slug1,slug2,slug3"` for full context in one round-trip.
*Direct drill-in:* User says "In All-In #200 they discuss OpenAI's strategy — pull the full quotes". Call `format="detail"`, `episode_slug="all-in-200"`, `company_slug="openai"` directly — no summary needed.
## Who said it
The `guest_` filters keep only the mentions a matching guest spoke: `guest_field="banking-finance-and-investment"` with `guest_standing="established"` reads what established finance experts said about a company. When the question names who speaks ("doctors", "economists", "people in finance"), resolve the words with `particle_expertise_resolve` first and filter by the code; on `unresolved_reference`, resolve and retry rather than dropping the filter. A word no occupation names may name a capacity instead ("founders", "politicians"): pass it as `guest_capacity`. Each episode lists its identified speakers with their occupation codes, standing and seniority. For the split of all mentions across occupations or fields use `particle_podcast_get_share_of_voice`.
## When NOT to use this tool
For dialogue that *discusses* a topic without naming a specific person or company (paraphrase-tolerant search), use `particle_podcast_search_transcripts` instead — that one ranks segments by relevance to a free-text query.
For how often the subject comes up, or which shows mentioned it this week versus last, use `particle_podcast_get_mention_trends` instead of paging this tool once per period; its podcast slugs come back here as `podcast_slug` to read what a show said.
## Strongest first
With `speaker_statement_characteristics`, `sort="strength"` puts the episodes whose mentions carry the labels most clearly first: the most clearly negative takes on a company, the most confident predictions about a drug. This is the tool for the strongest lines about a subject; `particle_podcast_search_transcripts` refuses a subject without a topic and sends you here.
## Required inputs
One of `person_slug`, `company_slug`, or `entity_slug` is required: `person_slug` for a person, `company_slug` for a company, `entity_slug` for any other knowledge-graph entity (places, organizations, events, concepts). Resolve a name to a slug first with `particle_person_resolve`, `particle_company_resolve`, or `particle_entity_resolve`. Slugs are case-insensitive on input.
**How each line is said.** Lines in topic and interview segments end with their speaker statement characteristics, pole labels only, e.g. `_[positive · confident · future]_`: sentiment (negative/positive), certainty (hedged/confident), specificity (vague/specific) and temporal orientation (past/future). A pole label means the line clearly reads that way; `_[neutral]_` means it leans clearly on no axis; no brackets means the line was not read (short lines, intros, ad breaks). With `output_format=json` they are each line's `speaker_statement_characteristics` object, middle labels included.
**Filtering by how a line is said.** Pass `speaker_statement_characteristics` to keep only lines said a certain way: `{"sentiment": ["negative"]}` for criticism, `{"specificity": ["specific"], "temporal_orientation": ["future"]}` for concrete predictions, `{"certainty": ["confident"], "sentiment": ["positive"], "temporal_orientation": ["future"]}` for a high-conviction outlook. Put the topic, never the tone, in `semantic_search`. Every matched or mention line then carries labels the filter accepts.
**Without a topic.** On `particle_podcast_search_transcripts`, the filter alone with `episode_slug`, `speaker` or a `guest_` filter (no `semantic_search` or `keyword_search`) returns the strongest lines said that way, at most 50, strongest first: an episode's boldest predictions, or a person's most confident claims. Their `Match` row reads `characteristics`. For the strongest lines naming a person, company or entity, pass the filter with `sort: "strength"` on `particle_podcast_find_mentions` instead.
particle_podcast_resolve
Find a podcast by free-text title, exact slug, iTunes ID, or RSS feed URL. Returns slug, title, episode count, bias, and the top recurring speakers (with entity slugs). Use the slug as the agent-facing handle to feed into other podcast tools (`particle_podcast_find_mentions`, `particle_podcast_list_episodes`, `particle_podcast_get_sponsors`).
Free-text matching is forgiving — typos, missing or extra words, and pasted episode titles all work. Results are ordered best-match-first; text matches carry a `match_quality` field, and an empty list means the catalog has no plausible candidate.
With all identifiers omitted, returns the most recently updated podcasts — useful for browsing the catalog when you don't have a name in mind. Narrow free-text browsing with `topic_slug` (topic concentration, descendants included), `suitability_tier`, or `min_popularity` (global popularity percentile over charting podcasts).
Optional hydrations attach extra data to each result in the same call:
- `include: ["external_links"]`: third-party platform presences (directories, social profiles, video channels, publisher websites) with resolved URLs and audience metrics.
- `include: ["suitability"]`: per-category brand-suitability breakdown (12 categories with prevalence, treatment, derived risk level, reasoning, and evidence excerpts) — premium-grade data, requires a plan with premium endpoints. The high-level `suitability_tier` enum (SAFE / LIMITED / SENSITIVE / UNSAFE) is rendered on every result without opt-in.
- `include: ["ratings_summary"]`: listener-review aggregate (average stars, count, per-platform breakdown).
- `include: ["bias"]`: full political-bias analysis (the high-level bias enum is always rendered without opt-in).
- `include: ["rankings"]`: current chart positions across sources/countries/categories — premium-grade data, requires a plan with premium endpoints. For movers and history use `particle_podcast_get_rankings`.
- `include: ["format"]`: the show's format profile — how often episodes feature guests, detected production formats (interview, panel, call_in, solo_narrated), ad and video presence, episode-length distribution, publishing cadence, and the publish-day pattern.
- `include: ["guest_expertise"]`: the show's guest mix — shares of its analyzed guest appearances by established, senior and in-field guests and promotional appearances, and the occupations and fields it books most.
- `recent_episodes: N`: inline this many of each result's most recent episodes (slug, title, published_at, duration) — skip the follow-up `particle_podcast_list_episodes` call when you only need the most recent tail.
Find shows by who they book with `guest_occupation` or `guest_field` (resolve the words to codes with `particle_expertise_resolve` first) and the share floors `min_established_guest_share`, `min_in_field_guest_share` and `max_promotional_guest_share`: `guest_field="banking-finance-and-investment"` with `min_established_guest_share=0.5` finds shows that book established finance experts. For the shows that booked an occupation's or field's guests most in a recent window, use `particle_expertise_get` with `include: ["top_podcasts"]`.
particle_podcast_search_transcripts
Search the podcast catalog by what is said in episodes — by meaning (`semantic_search`), by exact phrase (`keyword_search`), or both at once (hybrid ranking). This is THE way to retrieve relevant dialogue, segments, and clips: each result is one segment of one episode with bounded transcript windows pinpointing the highest-relevance lines, plus any highlight clips that overlap the segment inline on the match.
Segments partition an episode's transcript — where start_line and end_line are present, every spoken line belongs to exactly one segment and one segment's end_line + 1 is the next one's start_line. They are contiguous in transcript lines, not in wall-clock seconds: the seconds between one segment's end_seconds and the next's start_seconds contain no transcribed speech. These matches do not carry the line ranges themselves — fetch them with `particle_podcast_get_episode` and `include: ["segments"]`, where their absence marks an episode segmented by an earlier version, a small share of which do leave lines uncovered. Clips are sparse, engagement-ranked highlights that overlap some segments. There is no separate clip-search tool — relevant clips arrive on these matches, and a known episode's full clip list is `particle_podcast_get_episode` with `include: ["clips"]`.
A match window defaults to one line of context around each matched line; raise `context` to widen windows in place instead of fetching the full transcript.
**Screening many results?** Pass `format: "compact"`. Each match then carries only its identity — episode and podcast slugs, segment id and bounds, segment type, the segment's one-line description, and the relevance score — with no dialogue or clips, at a fraction of the size and latency of the default. Fan out compact searches over companies, themes, or dates, decide which segments matter, then read dialogue only for those: `particle_podcast_get_episode` with `include: ["transcript"]` and `transcript_start`/`transcript_end` set to the segment's bounds, or this tool again with `episode_slug` narrowed to that episode.
Use this for "find dialogue *about* a topic". For "every line *naming* a person or company" use `particle_podcast_find_mentions` instead — `person_slug` and `company_slug` here narrow ranked results, they don't drive the ranking.
**Choosing your query.** At least one of `semantic_search` or `keyword_search` is required, and they do different jobs:
- `semantic_search` carries the *idea*. Write it as a sentence describing what should be discussed, in the vocabulary a speaker would use. It is paraphrase-tolerant, so it finds the topic however it happens to be worded.
- `keyword_search` carries words that must be *literally spoken*. Every word must occur in the same passage, so it is for one or two exact tokens — a ticker, a product name — not for a description. Putting a sentence here returns nothing.
- Use both when a topic must also contain an exact term. The result is their intersection, which is narrow by design; if that comes back empty, `keyword_match: "ranked"` relaxes the keyword side to a relevance hint.
**Do not put a name in `semantic_search`.** Resolve it (`particle_person_resolve`, `particle_company_resolve`, `particle_entity_resolve`) and pass the slug — searching for "Sam Altman" as text finds passages that *sound like* him, while `person_slug` finds the episodes actually featuring him.
**The question's constraints go on the first call.** Who is speaking, which person, company or show, which window or language: when the question states it, pass it from the start, because a search without it answers a different question. Hold back only the filters you add on your own (a `segment_type`, a `role`, a narrower window) until a search shows the topic has coverage: every filter compounds, and each one can remove all results. If a search returns nothing because of a filter, the error names the parameter responsible and the retry to make — act on it rather than re-issuing variations of the same query, and when a constraint the question stated is what emptied it, say so before showing anything wider.
**Note on `role`.** It describes how someone relates to the episode: `guest`/`host`/`panelist`/`correspondent` mean they *spoke*, `mention` means they were *talked about*. Omitting `role` covers both and is almost always what you want.
**Who is speaking.** When the question restricts who speaks by occupation, profession or industry ("medical professionals", "economists", "lawyers"), pass the words themselves as `guest_occupation`, which resolves an everyday word to the occupation, field or capacity it names, or a code from `particle_expertise_resolve` as `guest_occupation`/`guest_field` (plus `guest_standing="established"` or `guest_practicing=true` when credentials matter); never stand the profession in for a filter inside `semantic_search`. On `unresolved_reference`, resolve and retry; never drop the filter. A word no occupation names may name a capacity ("founders", "politicians"): pass it as `guest_capacity`. The filters AND together, so two groups ("founders and VCs") take one call each. The filters keep segments in which such a guest speaks, so a window can also carry the host's lines: each full-format match lists its identified speakers as `**Speaker:**` rows with their occupation codes, standing and seniority — check them before attributing a line to a credential.
**How each line is said.** Lines in topic and interview segments end with their speaker statement characteristics, pole labels only, e.g. `_[positive · confident · future]_`: sentiment (negative/positive), certainty (hedged/confident), specificity (vague/specific) and temporal orientation (past/future). A pole label means the line clearly reads that way; `_[neutral]_` means it leans clearly on no axis; no brackets means the line was not read (short lines, intros, ad breaks). With `output_format=json` they are each line's `speaker_statement_characteristics` object, middle labels included.
**Filtering by how a line is said.** Pass `speaker_statement_characteristics` to keep only lines said a certain way: `{"sentiment": ["negative"]}` for criticism, `{"specificity": ["specific"], "temporal_orientation": ["future"]}` for concrete predictions, `{"certainty": ["confident"], "sentiment": ["positive"], "temporal_orientation": ["future"]}` for a high-conviction outlook. Put the topic, never the tone, in `semantic_search`. Every matched or mention line then carries labels the filter accepts.
**Without a topic.** On `particle_podcast_search_transcripts`, the filter alone with `episode_slug`, `speaker` or a `guest_` filter (no `semantic_search` or `keyword_search`) returns the strongest lines said that way, at most 50, strongest first: an episode's boldest predictions, or a person's most confident claims. Their `Match` row reads `characteristics`. For the strongest lines naming a person, company or entity, pass the filter with `sort: "strength"` on `particle_podcast_find_mentions` instead.