> ## Documentation Index
> Fetch the complete documentation index at: https://docs.particle.pro/llms.txt
> Use this file to discover all available pages before exploring further.

# Guests

> Track the people who appear on podcasts — lifetime profiles, every appearance, the shows they join, who's doing the rounds, and brand-suitability exposure.

A *guest* is a **Person** — Particle's first-class entity for an individual,
served in full at `GET /v1/people/{id}` — identified in a non-host listing role
on at least one episode. The guest endpoints are built around that Person
identity: every guest carries the same canonical handle used everywhere else on
the platform, so the speaker you find in a transcript, the person served by the
People API, and the guest in this directory are the same record. Resolve a guest
by **slug** (recommended — e.g. `brad-gerstner`) or by the encoded Person ID
returned as `id`.

<Note>
  A guest is someone who *appeared* on an episode in a listing role — distinct from
  a [mention](/podcasts/mentions), which is any line of dialogue where a person is
  named, whether they're in the room or not. Use Guests to follow who shows up; use
  Mentions to follow who gets talked about.
</Note>

## What you can build

* **Booking and PR research** — find a guest's complete appearance history, the
  shows they favor, and who else those shows book.
* **Press-tour detection** — surface people making the rounds right now with
  [trends](#trending-guests), the signal behind a book launch or product unveil.
* **Brand-safety screening** — read a guest's [suitability exposure](#brand-suitability-exposure)
  across the shows they join before a sponsorship or partnership.
* **Talent graphs** — pivot from a podcast to its [guest roster](#guest-roster-for-a-podcast)
  and back out to each guest's wider footprint.

## Choosing the right endpoint

| You want…                                                     | Use this                                                                                     |
| ------------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
| Browse or search the directory of podcast guests              | [`GET /v1/podcasts/guests`](#the-guest-directory)                                            |
| A single guest's lifetime profile and stats                   | [`GET /v1/podcasts/guests/{id}`](#a-guest-profile)                                           |
| Every episode a guest appeared on                             | [`GET /v1/podcasts/guests/{id}/appearances`](#appearances)                                   |
| The distinct shows a guest has appeared on                    | [`GET /v1/podcasts/guests/{id}/podcasts`](#podcasts-a-guest-has-joined)                      |
| Who has been a guest on a specific podcast                    | [`GET /v1/podcasts/{id}/guests`](#guest-roster-for-a-podcast)                                |
| Guests currently doing the podcast rounds                     | [`GET /v1/podcasts/guests/trends`](#trending-guests)                                         |
| A guest's brand-suitability exposure                          | [`GET /v1/podcasts/guests/{id}/suitability`](#brand-suitability-exposure)                    |
| Shows a guest could plausibly appear on next (the pitch list) | [`GET /v1/podcasts/guests/{id}/recommendations/podcasts`](#recommended-podcasts-for-a-guest) |
| Guests a show could plausibly book (the booking pipeline)     | [`GET /v1/podcasts/{id}/recommendations/guests`](#recommended-guests-for-a-podcast)          |

The `{id}` in every endpoint above is a **Person** reference (slug or encoded ID).
The exceptions are the two podcast-keyed views, [`GET /v1/podcasts/{id}/guests`](#guest-roster-for-a-podcast)
and [`GET /v1/podcasts/{id}/recommendations/guests`](#recommended-guests-for-a-podcast),
where `{id}` is a **podcast** reference (slug, Particle ID, or Apple/iTunes ID) —
they are the inverse views, listing the guests *of* a show and the guests a show
*could* book.

## The guest directory

`GET /v1/podcasts/guests` returns a paginated directory of everyone who has
guested on the catalog, ranked by lifetime appearances by default.

<CodeGroup>
  ```bash curl theme={"dark"}
  curl --get "https://api.particle.pro/v1/podcasts/guests" \
    --data-urlencode "q=gerstner" \
    --data-urlencode "min_appearances=5" \
    -H "X-API-Key: $PARTICLE_API_KEY"
  ```

  ```js JavaScript theme={"dark"}
  const params = new URLSearchParams({ q: "gerstner", min_appearances: "5" });
  const res = await fetch(
    `https://api.particle.pro/v1/podcasts/guests?${params}`,
    { headers: { "X-API-Key": process.env.PARTICLE_API_KEY } },
  );
  const { data } = await res.json();
  ```

  ```python Python theme={"dark"}
  import os, requests

  res = requests.get(
      "https://api.particle.pro/v1/podcasts/guests",
      params={"q": "gerstner", "min_appearances": 5},
      headers={"X-API-Key": os.environ["PARTICLE_API_KEY"]},
  )
  guests = res.json()["data"]
  ```
</CodeGroup>

```json Response theme={"dark"}
{
  "data": [
    {
      "id": "5njEX8HDc7oNdM8kr9ItRs",
      "slug": "brad-gerstner",
      "name": "Brad Gerstner",
      "appearance_count": 35,
      "distinct_podcasts": 10,
      "first_appearance_at": "2020-11-04T10:06:21Z",
      "last_appearance_at": "2026-05-29T22:16:05Z"
    }
  ],
  "has_more": false
}
```

Each row is a compact guest: the Person identity (`id`, `slug`, `name`, and
`image_url` when a headshot is known) plus lifetime `appearance_count` and
`distinct_podcasts`. Pass any `slug` or `id` straight into the
[profile endpoint](#a-guest-profile) to expand it.

### Filters

| Param                  | Notes                                                                                                                           |
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| `q`                    | Case-insensitive substring match on the guest's display name.                                                                   |
| `min_appearances`      | Minimum lifetime appearance count. Default 1.                                                                                   |
| `podcast_id`           | Slug or ID. Restrict to guests who have appeared on this podcast. When set, `appearance_count` is scoped to that show.          |
| `topic_id`             | Restrict to guests with at least one appearance on an episode under this topic.                                                 |
| `appeared_since`       | ISO 8601 date. Guests with an appearance on or after this date.                                                                 |
| `suitability_tier_max` | `SAFE`, `LIMITED`, `SENSITIVE`, `UNSAFE`. Restrict to guests whose appearances are on shows at or below this IAB Tech Lab tier. |
| `sort`                 | `appearances` (default) or `recency`.                                                                                           |

## A guest profile

`GET /v1/podcasts/guests/{id}` returns the lifetime profile: the full Person
payload — the same one served at `/v1/people/{id}` — plus a podcast-guest
activity block.

```bash theme={"dark"}
curl "https://api.particle.pro/v1/podcasts/guests/brad-gerstner" \
  -H "X-API-Key: $PARTICLE_API_KEY"
```

```json Response (truncated) theme={"dark"}
{
  "id": "5njEX8HDc7oNdM8kr9ItRs",
  "slug": "brad-gerstner",
  "name": "Brad Gerstner",
  "description": "Founder, Chairman, and CEO of Altimeter Capital; co-host of BG2Pod",
  "detailed_description": "Brad Gerstner is an American entrepreneur, investor, and hedge fund manager who founded Altimeter Capital…",
  "external_links": [
    { "platform": { "name": "linkedin", "display_name": "LinkedIn", "type": "social_profile" }, "identifier": "in/bradgerstner", "url": "https://www.linkedin.com/in/bradgerstner/" },
    { "platform": { "name": "wikipedia", "display_name": "Wikipedia", "type": "other" }, "url": "https://en.wikipedia.org/wiki/Brad_Gerstner" }
  ],
  "knowledge_graph_entity": {
    "id": "1GmOP1C2tsrQUoriBU",
    "slug": "brad-gerstner",
    "wikipedia_url": "https://en.wikipedia.org/wiki/Brad_Gerstner"
  },
  "stats": {
    "appearance_count": 35,
    "distinct_podcasts": 10,
    "first_appearance_at": "2020-11-04T10:06:21Z",
    "last_appearance_at": "2026-05-29T22:16:05Z",
    "total_speaking_seconds": 28012.23,
    "appearances_by_bias": { "NOT_POLITICAL": 3, "CENTER": 4, "LEANS_LEFT": 2, "LEANS_RIGHT": 19, "RIGHT": 7 },
    "appearances_by_suitability_tier": { "SAFE": 28, "LIMITED": 5, "SENSITIVE": 2 }
  },
  "top_podcasts": [
    {
      "podcast": { "id": "4t9PU1WkzOroEXfBl6ia7r", "title": "All-In with Chamath, Jason, Sacks & Friedberg", "slug": "all-in", "image_url": "https://cdn.particle.pro/url/media/a0a7b2fa-…" },
      "appearance_count": 19,
      "first_appearance_at": "2020-11-04T10:06:21Z",
      "last_appearance_at": "2026-05-08T22:16:00Z",
      "suitability_tier": "SAFE",
      "bias": "LEANS_RIGHT"
    }
  ]
}
```

The Person fields (`description`, `detailed_description`, `external_links`, and —
when a company affiliation is known — `current_role` and `roles`) carry the
guest's identity. `knowledge_graph_entity` is an optional secondary identifier —
a [knowledge graph entity](/knowledge-graph/entities) cross-reference attached to
some people — not the Person itself; rely on `id`/`slug` to identify a guest. The
`stats` block is the guest-specific part:

* `appearances_by_bias` buckets appearances by the political-bias rating of the
  host show. Keys include `NOT_POLITICAL` (the dominant bucket for most guests,
  since most shows aren't political) alongside `EXTREME_LEFT … EXTREME_RIGHT`, so
  the political mix is contextualized. Counts sum to at most `appearance_count` —
  appearances on shows whose bias hasn't been evaluated are omitted.
* `appearances_by_suitability_tier` does the same for the IAB Tech Lab
  brand-suitability tier (`SAFE`, `LIMITED`, `SENSITIVE`, `UNSAFE`).
* `top_podcasts` is the (up to five) most-frequent shows, each with the guest's
  per-show appearance count and the show's `suitability_tier` and `bias`.

A guest profile returns **404** when the Person exists but has never appeared as
a guest, so a 200 is itself confirmation of guest activity.

## Appearances

`GET /v1/podcasts/guests/{id}/appearances` lists the episodes a guest appeared
on, most recent first.

```bash theme={"dark"}
curl --get "https://api.particle.pro/v1/podcasts/guests/brad-gerstner/appearances" \
  --data-urlencode "min_speaking_seconds=120" \
  -H "X-API-Key: $PARTICLE_API_KEY"
```

```json Response (truncated) theme={"dark"}
{
  "data": [
    {
      "episode": {
        "id": "1lYfNtoWjotDDGoK77IAc4",
        "title": "Crypto Fueling a War",
        "slug": "crypto-fueling-a-war-2",
        "published_at": "2026-05-22T17:16:40Z",
        "duration_seconds": 2296
      },
      "podcast": {
        "id": "6aSPee2tS89h0BMiIjlA6X",
        "title": "Armstrong & Getty Podcast",
        "slug": "armstrong-and-getty",
        "image_url": "https://cdn.particle.pro/url/media/d876513c-…"
      },
      "speaking_seconds": 345.95,
      "suitability_tier": "SAFE",
      "bias": "RIGHT"
    }
  ],
  "has_more": true,
  "cursor": "r.4gfFC6"
}
```

Each row pairs the `episode` with the `podcast` that published it, the guest's
identified `speaking_seconds` on that episode, and the show's `suitability_tier`
and `bias`.

### Filters

| Param                                  | Notes                                                                |
| -------------------------------------- | -------------------------------------------------------------------- |
| `podcast_id`                           | Slug or ID. Restrict to appearances on one podcast.                  |
| `topic_id`                             | Restrict to appearances on episodes under this topic.                |
| `published_after` / `published_before` | ISO 8601 dates bounding the episode publication window.              |
| `suitability_tier_max`                 | `SAFE`, `LIMITED`, `SENSITIVE`, `UNSAFE`.                            |
| `min_speaking_seconds`                 | Only appearances with identified speaking time above this threshold. |

## Podcasts a guest has joined

`GET /v1/podcasts/guests/{id}/podcasts` returns the distinct set of shows a guest
has appeared on, with a per-show rollup.

```bash theme={"dark"}
curl "https://api.particle.pro/v1/podcasts/guests/brad-gerstner/podcasts" \
  -H "X-API-Key: $PARTICLE_API_KEY"
```

```json Response (truncated) theme={"dark"}
{
  "data": [
    {
      "podcast": {
        "id": "4t9PU1WkzOroEXfBl6ia7r",
        "title": "All-In with Chamath, Jason, Sacks & Friedberg",
        "slug": "all-in",
        "image_url": "https://cdn.particle.pro/url/media/a0a7b2fa-…"
      },
      "appearance_count": 19,
      "first_appearance_at": "2020-11-04T10:06:21Z",
      "last_appearance_at": "2026-05-08T22:16:00Z",
      "suitability_tier": "SAFE",
      "bias": "LEANS_RIGHT"
    }
  ],
  "has_more": false
}
```

This is the aggregate behind `top_podcasts` on the profile, but unbounded and
paginated — every show, not just the top five.

## Guest roster for a podcast

`GET /v1/podcasts/{id}/guests` is the inverse pivot: the identified guests of a
*given show*. Here `{id}` is a **podcast** reference.

```bash theme={"dark"}
curl "https://api.particle.pro/v1/podcasts/all-in/guests" \
  -H "X-API-Key: $PARTICLE_API_KEY"
```

```json Response (truncated) theme={"dark"}
{
  "data": [
    {
      "id": "5njEX8HDc7oNdM8kr9ItRs",
      "slug": "brad-gerstner",
      "name": "Brad Gerstner",
      "appearance_count": 19,
      "distinct_podcasts": 10,
      "first_appearance_at": "2020-11-04T10:06:21Z",
      "last_appearance_at": "2026-05-08T22:16:00Z"
    }
  ],
  "has_more": true,
  "cursor": "r.4gfFC6"
}
```

The rows are the same compact guest shape as the directory, but here
`appearance_count` is scoped to *this show* (Brad Gerstner's 19 appearances on
All-In), while `distinct_podcasts` stays his lifetime count across the catalog.
Returns **404** when the podcast can't be resolved.

## Trending guests

`GET /v1/podcasts/guests/trends` surfaces guests who are currently making the
rounds — the cross-show interview activity that signals a book launch, product
unveil, news-cycle moment, or new-on-the-scene debut.

```bash theme={"dark"}
curl --get "https://api.particle.pro/v1/podcasts/guests/trends" \
  --data-urlencode "min_distinct_podcasts=3" \
  -H "X-API-Key: $PARTICLE_API_KEY"
```

```json Response (truncated) theme={"dark"}
{
  "data": [
    {
      "guest": {
        "id": "57kYjDofrt8lUZgIDz4qMb",
        "slug": "david-epstein",
        "name": "David Epstein",
        "appearance_count": 30,
        "distinct_podcasts": 29,
        "last_appearance_at": "2026-05-25T07:00:00Z"
      },
      "recent_appearances": 20,
      "first_appearance_in_window": "2026-05-04T07:03:00Z",
      "last_appearance_at": "2026-05-25T07:00:00Z"
    }
  ],
  "has_more": true,
  "cursor": "r.4gfFC7"
}
```

`guest` carries lifetime stats; `recent_appearances` is the count *inside the
window*. Every in-window appearance is on a distinct show — guests with repeats
on the same show inside the window are excluded — so the number doubles as
"distinct podcasts this window."

<Note>
  This is **not** a leaderboard of perennial regulars. Recurring co-hosts and daily
  news-segment contributors are filtered out by design: a guest must show activity
  materially elevated above their own baseline, across multiple distinct shows,
  with substantive (5+ minute) interviews. For a steady-state directory, use
  [`GET /v1/podcasts/guests`](#the-guest-directory) instead.
</Note>

### Filters

| Param                    | Notes                                                                                                    |
| ------------------------ | -------------------------------------------------------------------------------------------------------- |
| `since`                  | ISO 8601 date. Inclusive lower bound of the window. Default: 30 days ago.                                |
| `min_distinct_podcasts`  | Minimum distinct shows inside the window. Minimum 2, default 2.                                          |
| `first_appearance_since` | Restrict to guests whose earliest-ever appearance is on or after this date — the "new on the scene" cut. |
| `topic_id`               | Restrict to in-window appearances on episodes under this topic.                                          |
| `suitability_tier_max`   | `SAFE`, `LIMITED`, `SENSITIVE`, `UNSAFE`.                                                                |

## Brand-suitability exposure

`GET /v1/podcasts/guests/{id}/suitability` returns the distribution of IAB Tech
Lab brand-suitability tiers across the shows a guest has appeared on, plus the
categories most often flagged in those shows.

```bash theme={"dark"}
curl "https://api.particle.pro/v1/podcasts/guests/brad-gerstner/suitability" \
  -H "X-API-Key: $PARTICLE_API_KEY"
```

```json Response (truncated) theme={"dark"}
{
  "lifetime": {
    "tier_distribution": [
      { "tier": "SAFE", "episodes": 28, "distinct_podcasts": 6 },
      { "tier": "LIMITED", "episodes": 5, "distinct_podcasts": 2 },
      { "tier": "SENSITIVE", "episodes": 2, "distinct_podcasts": 2 }
    ]
  },
  "recent_90d": {
    "window_start": "2026-03-03T02:50:50Z",
    "tier_distribution": [
      { "tier": "SAFE", "episodes": 11, "distinct_podcasts": 4 }
    ]
  },
  "top_categories": [
    { "code": "death_injury_military_conflict", "prevalence": "FREQUENT", "treatment": "DOCUMENTARY", "podcasts": 6 },
    { "code": "debated_social_issues", "prevalence": "FREQUENT", "treatment": "EDITORIAL", "podcasts": 4 }
  ],
  "notes": "This response measures the guest's exposure across the shows they have appeared on. The brand-safety tier of a show reflects the show's overall content profile and is not a verdict on any individual guest. Appearing on a SENSITIVE- or UNSAFE-tier show does not imply the guest is unsuitable."
}
```

Both a `lifetime` and a trailing `recent_90d` window are returned; each buckets
the guest's appearances by tier with episode and distinct-podcast counts.
`top_categories` lists the most-flagged IAB categories with their `prevalence`
(`INCIDENTAL`, `OCCASIONAL`, `FREQUENT`, `PERVASIVE`) and dominant `treatment`.

<Warning>
  This endpoint measures *exposure*, not a verdict on the guest. A show's
  brand-safety tier reflects the show's overall content profile — appearing on a
  `SENSITIVE`- or `UNSAFE`-tier show does not imply the guest is unsuitable. The
  `notes` field restates this in every response.
</Warning>

## Recommended podcasts for a guest

`GET /v1/podcasts/guests/{id}/recommendations/podcasts` returns shows the person has
**not** appeared on, ranked by how related they are to the shows the person **has**
appeared on. It is the pitch list: where could this person plausibly go next, and
which of their past venues make the case.

Each recommendation is derived from the precomputed related set of the person's own
shows (see [Related Podcasts](/podcasts/related)) and carries a score in (0, 1), a
`band` (`strong`, `moderate`, `weak`), and with `include=via` the person's shows that
led to it. Circuit regulars are discounted upstream, so the list reflects fit rather
than fame.

```bash theme={"dark"}
curl "https://api.particle.pro/v1/podcasts/guests/brad-gerstner/recommendations/podcasts?include=via&limit=3" \
  -H "X-API-Key: $PARTICLE_API_KEY"
```

```json Response (truncated) theme={"dark"}
{
  "data": [
    {
      "podcast": { "id": "…", "title": "Invest Like the Best", "slug": "invest-like-the-best" },
      "score": 0.87,
      "band": "strong",
      "via": [
        { "id": "…", "title": "All-In with Chamath, Jason, Sacks & Friedberg", "slug": "all-in" },
        { "id": "…", "title": "BG2Pod", "slug": "bg2pod" }
      ]
    }
  ],
  "has_more": true,
  "cursor": "r.…"
}
```

| Parameter         | Meaning                                                                            |
| ----------------- | ---------------------------------------------------------------------------------- |
| `include`         | `via` attaches the person's own shows behind each recommendation, strongest first. |
| `limit`, `cursor` | Standard pagination over the ranked list (at most 200 recommendations per person). |

A person with no identified appearances, or whose shows have no computed related set
yet, gets `200` with an empty `data` array. The shows a person has already been on are
at [`GET /v1/podcasts/guests/{id}/podcasts`](#podcasts-a-guest-has-joined).

## Recommended guests for a podcast

`GET /v1/podcasts/{id}/recommendations/guests` returns people who have guested on the
show's related shows but never on this one, ranked by how related those venues are
and how established the person is on them. It is a booking pipeline, not a
prediction: the right reading is "guests your peer shows book that you have not."
The podcast detail embeds the first five with `include=recommended_guests` on
[`GET /v1/podcasts/{id}`](/podcasts/related#the-five-most-related-shows-inline).

Guests who appear everywhere (the podcast circuit's regulars) are excluded, since
recommending them says nothing about this show. Each row carries the person, a
score and band, `shared_show_count` (how many related shows booked them), and with
`include=via` which shows.

```bash theme={"dark"}
curl "https://api.particle.pro/v1/podcasts/all-in/recommendations/guests?include=via&limit=3" \
  -H "X-API-Key: $PARTICLE_API_KEY"
```

```json Response (truncated) theme={"dark"}
{
  "data": [
    {
      "person": { "id": "…", "name": "…", "slug": "…" },
      "score": 0.62,
      "band": "moderate",
      "shared_show_count": 3,
      "via": [
        { "id": "…", "title": "Invest Like the Best", "slug": "invest-like-the-best" }
      ]
    }
  ],
  "has_more": true,
  "cursor": "r.…"
}
```

| Parameter         | Meaning                                                                    |
| ----------------- | -------------------------------------------------------------------------- |
| `include`         | `via` attaches the related shows that booked each person, strongest first. |
| `limit`, `cursor` | Standard pagination (at most 200 recommendations per show).                |

A show whose related set has not been computed yet gets `200` with an empty `data`
array. The show's existing roster is at [`GET /v1/podcasts/{id}/guests`](#guest-roster-for-a-podcast).

## Pagination

The list endpoints use the standard envelope: `limit` (1–100, default 25) plus an
opaque `cursor`, returning `{ data, has_more, cursor }`. Pass the `cursor` from
one response back as `?cursor=…` to fetch the next page. The single-item
endpoints — the profile and the suitability exposure — are not paginated.

## Related

* [Mentions](/podcasts/mentions) — every line where a person or company is named, host or guest.
* [Brand Suitability](/podcasts/suitability) — the per-show assessment behind a guest's exposure profile.
* [Episodes](/podcasts/episodes) — episode discovery, including `entity_id` recall by speaker.
* [Knowledge graph entities](/knowledge-graph/entities) — the optional `knowledge_graph_entity` cross-reference attached to some guests.
