> ## 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.

# List and search podcasts

> Returns a paginated list of podcasts, with filters for topic, language, suitability tier, popularity, and format. The `q` parameter searches by name and is kept for backwards compatibility — `GET /v1/podcasts/search` is the canonical way to search podcasts, and `q` here may be removed in a future version.



## OpenAPI

````yaml /openapi.json get /v1/podcasts
openapi: 3.1.0
info:
  description: Public API for Particle — news intelligence, financial data, and analysis.
  title: Particle API
  version: 0.1.0
  x-guidance: >-
    Podcast, people, company and topic intelligence. Authenticate with a pp_ API
    key (X-API-Key header) or pay per request with x402: a keyless call to a
    billable endpoint returns 402 with the payment requirements in the
    PAYMENT-REQUIRED header; sign the USDC transfer and repeat the request with
    PAYMENT-SIGNATURE. Start with GET /v1/podcasts/search?q=<show name>; the
    slugs in responses are the inputs to the other endpoints. Docs:
    https://docs.particle.pro; setup playbook:
    https://api.particle.pro/agents.md; endpoint and tool map with prices:
    https://api.particle.pro/llms.txt; credential recipe:
    https://api.particle.pro/auth.md.
servers:
  - url: https://api.particle.pro
security:
  - ApiKeyHeader: []
  - BearerAuth: []
paths:
  /v1/podcasts:
    get:
      tags:
        - Podcasts
        - tier:standard
      summary: List and search podcasts
      description: >-
        Returns a paginated list of podcasts, with filters for topic, language,
        suitability tier, popularity, and format. The `q` parameter searches by
        name and is kept for backwards compatibility — `GET /v1/podcasts/search`
        is the canonical way to search podcasts, and `q` here may be removed in
        a future version.
      operationId: list-podcasts
      parameters:
        - description: Results per page
          explode: false
          in: query
          name: limit
          schema:
            default: 25
            description: Results per page
            format: int64
            maximum: 100
            minimum: 1
            type: integer
        - description: Opaque pagination cursor from previous response
          explode: false
          in: query
          name: cursor
          schema:
            description: Opaque pagination cursor from previous response
            type: string
        - description: >-
            Search the catalog by podcast name. GET /v1/podcasts/search is the
            canonical search endpoint and accepts the same parameters. The
            search is forgiving: it handles typos, missing or extra words
            ('offline jon favreau' finds Offline with Jon Favreau), a name plus
            qualifiers ('equity techcrunch'), and pasted episode titles
            ('Ferrari | Acquired' finds Acquired). The best matches come first,
            and each result's match_quality tells you how confident the match is
            — including when a show matched only through its description
            (match_quality=description) rather than its name.
          explode: false
          in: query
          name: q
          schema:
            description: >-
              Search the catalog by podcast name. GET /v1/podcasts/search is the
              canonical search endpoint and accepts the same parameters. The
              search is forgiving: it handles typos, missing or extra words
              ('offline jon favreau' finds Offline with Jon Favreau), a name
              plus qualifiers ('equity techcrunch'), and pasted episode titles
              ('Ferrari | Acquired' finds Acquired). The best matches come
              first, and each result's match_quality tells you how confident the
              match is — including when a show matched only through its
              description (match_quality=description) rather than its name.
            maxLength: 200
            type: string
        - description: >-
            Result ordering. relevance — the default whenever q is present —
            ranks by how well each podcast matches the query, breaking ties by
            popularity. popularity orders purely by the global popularity
            percentile (most popular first; podcasts not currently charting sort
            last), and also overrides topic_id's concentration ordering. Without
            q or topic_id, results are popularity-ordered either way.
          explode: false
          in: query
          name: sort
          schema:
            description: >-
              Result ordering. relevance — the default whenever q is present —
              ranks by how well each podcast matches the query, breaking ties by
              popularity. popularity orders purely by the global popularity
              percentile (most popular first; podcasts not currently charting
              sort last), and also overrides topic_id's concentration ordering.
              Without q or topic_id, results are popularity-ordered either way.
            enum:
              - relevance
              - popularity
            type: string
        - description: >-
            Filter by exact podcast slug (e.g., 'all-in'). Slugs are stable,
            human-readable identifiers returned on every podcast object.
          explode: false
          in: query
          name: slug
          schema:
            description: >-
              Filter by exact podcast slug (e.g., 'all-in'). Slugs are stable,
              human-readable identifiers returned on every podcast object.
            maxLength: 200
            type: string
        - description: >-
            Filter by topic ID, ancestry slug (e.g.,
            technology/artificial-intelligence), or ancestry path hash. Matches
            podcasts where the topic accounts for at least 20% of the show's
            episodes, ranked by topic concentration — not merely podcasts that
            mention it once.
          explode: false
          in: query
          name: topic_id
          schema:
            description: >-
              Filter by topic ID, ancestry slug (e.g.,
              technology/artificial-intelligence), or ancestry path hash.
              Matches podcasts where the topic accounts for at least 20% of the
              show's episodes, ranked by topic concentration — not merely
              podcasts that mention it once.
            type: string
        - description: >-
            Filter by the podcast's language (ISO 639-1 code, e.g. 'en', 'fr').
            Matches the primary language subtag, so 'fr' covers 'fr-FR'.
          explode: false
          in: query
          name: language
          schema:
            description: >-
              Filter by the podcast's language (ISO 639-1 code, e.g. 'en',
              'fr'). Matches the primary language subtag, so 'fr' covers
              'fr-FR'.
            examples:
              - fr
            type: string
        - description: >-
            Filter by brand-suitability tier (IAB Tech Lab Brand Safety &
            Suitability Framework, formerly GARM). Only returns podcasts whose
            most recent suitability analysis assigned this tier. Podcasts
            without a suitability analysis are excluded when this filter is set.
          explode: false
          in: query
          name: suitability_tier
          schema:
            description: >-
              Filter by brand-suitability tier (IAB Tech Lab Brand Safety &
              Suitability Framework, formerly GARM). Only returns podcasts whose
              most recent suitability analysis assigned this tier. Podcasts
              without a suitability analysis are excluded when this filter is
              set.
            enum:
              - SAFE
              - LIMITED
              - SENSITIVE
              - UNSAFE
            type: string
        - description: >-
            Restrict results to podcasts whose global popularity percentile is
            at least this value (accepted range [0,1]). Omitting the parameter
            or passing 0 disables the filter; only a value greater than 0
            activates it. Popularity is always global — a cume_dist ranking over
            all currently-charting podcasts (Apple Podcasts) — never scoped to
            topic_id or any other filter. When the filter is active (threshold >
            0), podcasts not currently charting have no percentile and are
            excluded, so a high threshold combined with a narrow topic_id may
            return zero results; lower or remove the threshold to widen the set.
          explode: false
          in: query
          name: popularity_threshold
          schema:
            description: >-
              Restrict results to podcasts whose global popularity percentile is
              at least this value (accepted range [0,1]). Omitting the parameter
              or passing 0 disables the filter; only a value greater than 0
              activates it. Popularity is always global — a cume_dist ranking
              over all currently-charting podcasts (Apple Podcasts) — never
              scoped to topic_id or any other filter. When the filter is active
              (threshold > 0), podcasts not currently charting have no
              percentile and are excluded, so a high threshold combined with a
              narrow topic_id may return zero results; lower or remove the
              threshold to widen the set.
            format: double
            maximum: 1
            minimum: 0
            type: number
        - description: >-
            Filter by how often episodes feature a guest. Pass a comma-separated
            list to match any of several buckets — e.g. regular,always for
            interview-driven shows, or never for shows that don't host guests.
            Only matches podcasts with enough analyzed episodes to judge; values
            mirror the format.guest_frequency field on podcast responses.
          explode: false
          in: query
          name: guest_frequency
          schema:
            description: >-
              Filter by how often episodes feature a guest. Pass a
              comma-separated list to match any of several buckets — e.g.
              regular,always for interview-driven shows, or never for shows that
              don't host guests. Only matches podcasts with enough analyzed
              episodes to judge; values mirror the format.guest_frequency field
              on podcast responses.
            examples:
              - - regular
                - always
            items:
              enum:
                - never
                - rare
                - occasional
                - regular
                - always
              type: string
            maxItems: 5
            type:
              - array
              - 'null'
        - description: >-
            Filter by detected production format. Pass a comma-separated list to
            match any of several formats — e.g. panel,call_in. Values mirror the
            format.signals field on podcast responses; a show can carry several
            signals.
          explode: false
          in: query
          name: format_signal
          schema:
            description: >-
              Filter by detected production format. Pass a comma-separated list
              to match any of several formats — e.g. panel,call_in. Values
              mirror the format.signals field on podcast responses; a show can
              carry several signals.
            examples:
              - - interview
            items:
              enum:
                - interview
                - panel
                - call_in
                - solo_narrated
              type: string
            maxItems: 4
            type:
              - array
              - 'null'
        - description: >-
            Filter by advertiser presence. Pass false to find ad-free shows — an
            assertion that requires the show to have enough analyzed episodes,
            so sparsely-analyzed podcasts are excluded rather than presumed
            ad-free.
          explode: false
          in: query
          name: has_ads
          schema:
            description: >-
              Filter by advertiser presence. Pass false to find ad-free shows —
              an assertion that requires the show to have enough analyzed
              episodes, so sparsely-analyzed podcasts are excluded rather than
              presumed ad-free.
            enum:
              - 'true'
              - 'false'
            type: string
        - description: >-
            Filter by whether episodes have discovered video versions (e.g.
            YouTube releases).
          explode: false
          in: query
          name: has_video
          schema:
            description: >-
              Filter by whether episodes have discovered video versions (e.g.
              YouTube releases).
            enum:
              - 'true'
              - 'false'
            type: string
        - description: >-
            Only podcasts whose average episode runs at least this many minutes.
            Combine with max_avg_episode_minutes to target a length band (e.g.
            20–40 minute commute shows).
          explode: false
          in: query
          name: min_avg_episode_minutes
          schema:
            description: >-
              Only podcasts whose average episode runs at least this many
              minutes. Combine with max_avg_episode_minutes to target a length
              band (e.g. 20–40 minute commute shows).
            format: int64
            maximum: 10080
            minimum: 0
            type: integer
        - description: Only podcasts whose average episode runs at most this many minutes.
          explode: false
          in: query
          name: max_avg_episode_minutes
          schema:
            description: >-
              Only podcasts whose average episode runs at most this many
              minutes.
            format: int64
            maximum: 10080
            minimum: 0
            type: integer
        - description: >-
            Only podcasts publishing at least this many episodes per week on
            average (e.g. 5 for weekday dailies). Cadence is measured over the
            trailing 90 days; podcasts tracked too briefly to measure are
            excluded.
          explode: false
          in: query
          name: min_episodes_per_week
          schema:
            description: >-
              Only podcasts publishing at least this many episodes per week on
              average (e.g. 5 for weekday dailies). Cadence is measured over the
              trailing 90 days; podcasts tracked too briefly to measure are
              excluded.
            format: double
            minimum: 0
            type: number
        - description: >-
            Only podcasts publishing at most this many episodes per week on
            average (e.g. 0.5 for fortnightly-or-slower shows).
          explode: false
          in: query
          name: max_episodes_per_week
          schema:
            description: >-
              Only podcasts publishing at most this many episodes per week on
              average (e.g. 0.5 for fortnightly-or-slower shows).
            format: double
            minimum: 0
            type: number
        - description: >-
            Filter by publishing activity: active shows have released an episode
            within the last 90 days; dormant shows have not.
          explode: false
          in: query
          name: publishing_status
          schema:
            description: >-
              Filter by publishing activity: active shows have released an
              episode within the last 90 days; dormant shows have not.
            enum:
              - active
              - dormant
            type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PagePodcast'
          description: OK
        '402':
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/PlatformError'
          description: >-
            Payment Required. Read error_code. payment_required is the x402
            path: either a keyless request being challenged — pay $0.01 in USDC
            per request (requirements in the PAYMENT-REQUIRED header) or send a
            pp_ API key — or a supplied payment that failed settlement (details
            in the PAYMENT-RESPONSE header; retry the same signature before
            signing a new one). See https://docs.particle.pro/x402. Any other
            code means the credential was accepted but does not cover this
            request (a plan or session gate such as premium_required or
            paid_plan_confirmation_required); its resolve says how to obtain
            access, and no payment header is sent.
        default:
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/PlatformError'
          description: Error
      x-codeSamples:
        - label: cURL
          lang: curl
          source: |-
            curl -H "X-API-Key: $PARTICLE_API_KEY" \
              "https://api.particle.pro/v1/podcasts?limit=25"
components:
  schemas:
    PagePodcast:
      additionalProperties: false
      properties:
        cursor:
          description: Pass to next request for more results
          type: string
        data:
          description: List of results
          items:
            $ref: '#/components/schemas/Podcast'
          type:
            - array
            - 'null'
        has_more:
          description: Whether more results exist
          type: boolean
      required:
        - data
        - has_more
      type: object
    PlatformError:
      additionalProperties: false
      properties:
        detail:
          description: >-
            A human-readable explanation specific to this occurrence of the
            problem.
          examples:
            - Property foo is required but is missing.
          type: string
        error_code:
          type: string
        errors:
          description: Optional list of individual error details
          items:
            $ref: '#/components/schemas/ErrorDetail'
          type:
            - array
            - 'null'
        instance:
          description: >-
            A URI reference that identifies the specific occurrence of the
            problem.
          examples:
            - https://example.com/error-log/abc123
          format: uri
          type: string
        resolve:
          $ref: '#/components/schemas/ErrorResolve'
        status:
          description: HTTP status code
          examples:
            - 400
          format: int64
          type: integer
        title:
          description: >-
            A short, human-readable summary of the problem type. This value
            should not change between occurrences of the error.
          examples:
            - Bad Request
          type: string
        type:
          default: about:blank
          description: A URI reference to human-readable documentation for the error.
          examples:
            - https://example.com/errors/example
          format: uri
          type: string
      type: object
    Podcast:
      additionalProperties: false
      properties:
        bias:
          description: >-
            Political bias rating for the podcast: EXTREME_LEFT, LEANS_LEFT,
            LEFT, CENTER, RIGHT, LEANS_RIGHT, or EXTREME_RIGHT. Empty when the
            podcast is not substantively political or has not been evaluated
            yet. Fetch GET /v1/podcasts/{id}/bias for the full analysis
            including reasoning and evidence.
          type: string
        description:
          description: Podcast description
          type: string
        episode_count:
          description: Total number of episodes
          format: int64
          type: integer
        explicit:
          description: Whether the podcast contains explicit content
          type: boolean
        format:
          $ref: '#/components/schemas/PodcastFormat'
          description: >-
            Production format attributes derived from episode analysis: guest
            frequency, detected formats (interview, panel, call_in,
            solo_narrated), ad and video presence, episode length, publishing
            cadence, and activity status. Every field doubles as a GET
            /v1/podcasts filter. Omitted for podcasts with no tracked episodes
            yet; within the object, the speaker-derived fields (guest_frequency,
            signals, has_ads) are additionally omitted until enough episodes
            have been analyzed to judge. Fetch GET /v1/podcasts/{id}/format for
            the full breakdown including exact rates, duration percentiles, and
            the publish-day histogram.
        id:
          description: Unique identifier
          type: string
        image_url:
          description: Cover image URL
          type: string
        language:
          description: ISO 639-1 language code
          type: string
        match_quality:
          description: >-
            How confidently this result matches your q search, strongest first.
            exact: this is the show with that name. partial: the name matches
            your search strongly (your search may have included extra words).
            fuzzy: the name is similar but not the same — it may be the show you
            meant with a typo, or a different show with a near-identical name;
            verify before relying on it. description: your search text appears
            in the show's description rather than its name. speculative: a loose
            suggestion, listed last. When resolving a show programmatically, act
            on exact or partial results and treat anything weaker as candidates
            to confirm. Present only when q was provided.
          enum:
            - exact
            - partial
            - fuzzy
            - description
            - speculative
          type: string
        political_context:
          description: >-
            Political framework the bias rating is calibrated against: US, UK,
            EU, CANADA, AUSTRALIA, INDIA, OTHER. Omitted when the latest
            analysis returned NOT_POLITICAL or when no analysis has been run
            yet.
          type: string
        popularity:
          description: >-
            Global popularity percentile in (0,1], a cume_dist ranking over all
            currently-charting podcasts (Apple Podcasts charts). Higher is more
            popular; the most popular podcast is 1.0. Always global — never
            scoped to a topic_id or other filter. Omitted when the podcast is
            not currently charting. Pair with the popularity_threshold query
            parameter on GET /v1/podcasts to filter the catalog by this value.
          format: double
          type: number
        publisher:
          $ref: '#/components/schemas/PodcastPublisherCompact'
          description: >-
            Publisher attributed to this podcast. Available on detail responses;
            absent on list responses and on podcasts whose publisher attribution
            is not yet known.
        recommended_guests:
          description: >-
            The five guests the show could plausibly book next (lean form, no
            via). Present only on GET /v1/podcasts/{id} with
            include=recommended_guests; the paged list is GET
            /v1/podcasts/{id}/recommendations/guests.
          items:
            $ref: '#/components/schemas/RecommendedGuest'
          type:
            - array
            - 'null'
        recommended_sponsors:
          description: >-
            The five advertisers most active on shows like this one that do not
            buy it yet (lean form, no via). Premium-grade: present only on GET
            /v1/podcasts/{id} with include=recommended_sponsors for plans that
            include premium endpoints; the paged list is GET
            /v1/podcasts/{id}/recommendations/sponsors.
          items:
            $ref: '#/components/schemas/RecommendedSponsor'
          type:
            - array
            - 'null'
        related:
          description: >-
            The five most related podcasts (lean form: podcast, score, band).
            Present only on GET /v1/podcasts/{id} with include=related, and
            omitted when the show's related set has not been computed yet. Fetch
            GET /v1/podcasts/{id}/related for the full ranked list with
            pagination and the basis (why) behind each result.
          items:
            $ref: '#/components/schemas/RelatedPodcast'
          type:
            - array
            - 'null'
        slug:
          description: Human-readable slug identifier
          type: string
        speakers:
          description: Top recurring speakers
          items:
            $ref: '#/components/schemas/PodcastSpeaker'
          type:
            - array
            - 'null'
        suitability_tier:
          description: >-
            High-level brand-suitability verdict from the IAB Tech Lab Brand
            Safety & Suitability Framework (formerly GARM): SAFE, LIMITED,
            SENSITIVE, or UNSAFE. Empty when the podcast has not been evaluated
            yet. Per-category breakdown, evidence, and methodology are gated to
            GET /v1/podcasts/{id}/suitability.
          type: string
        title:
          description: Podcast title
          type: string
        topics:
          description: >-
            Top topics discussed across episodes, ordered by frequency. Absent
            when the rollup exceeds its time budget.
          items:
            $ref: '#/components/schemas/Topic'
          type:
            - array
            - 'null'
        url:
          description: RSS feed URL
          type: string
      required:
        - id
        - title
        - explicit
      type: object
    ErrorDetail:
      additionalProperties: false
      properties:
        location:
          description: >-
            Where the error occurred, e.g. 'body.items[3].tags' or
            'path.thing-id'
          type: string
        message:
          description: Error message text
          type: string
        value:
          description: The value at the given location
      type: object
    ErrorResolve:
      additionalProperties: false
      properties:
        action:
          type: string
        endpoint:
          type: string
        message:
          type: string
        method:
          type: string
        url:
          type: string
      required:
        - message
      type: object
    PodcastFormat:
      additionalProperties: false
      properties:
        avg_episode_minutes:
          description: >-
            Average episode length in minutes. Omitted when no episode durations
            are known.
          format: int64
          type: integer
        episodes_per_week:
          description: >-
            Publishing cadence over the trailing 90 days, in episodes per week
            (e.g. 5.0 for a weekday daily, 0.5 for a fortnightly show). Omitted
            until the show has been tracked long enough to measure reliably.
          format: double
          type: number
        guest_frequency:
          description: >-
            How often episodes feature a guest: never, rare, occasional,
            regular, or always. Derived from the share of analyzed episodes with
            at least one guest speaker. Omitted when too few episodes have been
            analyzed to judge. Filter the catalog with the guest_frequency query
            parameter on GET /v1/podcasts.
          type: string
        has_ads:
          description: >-
            Whether episodes carry advertiser reads. Omitted when too few
            episodes have been analyzed to judge. The full advertising profile
            (sponsors, read types, ad load) is served by GET
            /v1/podcasts/{id}/advertising.
          type: boolean
        has_video:
          description: >-
            Whether any episode has a discovered video version (e.g. a YouTube
            release).
          type: boolean
        publishing_status:
          description: >-
            Whether the show is still releasing episodes: active (published
            within the last 90 days) or dormant. Omitted when no publish dates
            are known.
          type: string
        signals:
          description: >-
            Production formats detected from the show's speaker-role mix:
            interview, panel, call_in, and/or solo_narrated. A show can carry
            several (a panel show with call-in segments). Omitted when too few
            episodes have been analyzed to judge.
          items:
            type: string
          type:
            - array
            - 'null'
      required:
        - has_video
      type: object
    PodcastPublisherCompact:
      additionalProperties: false
      properties:
        id:
          description: Publisher ID
          type: string
        name:
          description: Publisher name
          type: string
        slug:
          description: >-
            Human-readable slug identifier (e.g., 'goalhanger',
            'iheartpodcasts'). When present, accepted in place of the ID
            anywhere a publisher reference is taken in the API. Occasionally
            absent on publishers whose name doesn't slugify (e.g., scripts not
            representable in ASCII URL slugs).
          type: string
      required:
        - id
        - name
      type: object
    RecommendedGuest:
      additionalProperties: false
      properties:
        band:
          description: Coarse class of the score.
          enum:
            - strong
            - moderate
            - weak
          type: string
        person:
          $ref: '#/components/schemas/PersonCompact'
          description: The recommended guest.
        score:
          description: >-
            Strength of the recommendation in (0,1): how related the shows that
            booked this person are, counted once per publisher and damped for
            how widely the person already circulates. Recurring on any one show
            does not raise it, and circuit regulars who appear everywhere are
            excluded.
          format: double
          type: number
        shared_show_count:
          description: How many of the show's related shows have booked this person.
          format: int64
          type: integer
        via:
          description: The related shows that booked this person, strongest first.
          items:
            $ref: '#/components/schemas/PodcastCompact'
          type:
            - array
            - 'null'
      required:
        - person
        - score
        - band
        - shared_show_count
      type: object
    RecommendedSponsor:
      additionalProperties: false
      properties:
        band:
          description: >-
            Coarse class of the score; branch on this rather than on exact
            thresholds.
          enum:
            - strong
            - moderate
            - weak
          type: string
        company_contested:
          description: >-
            Whether the company link is disputed: true when the recent majority
            is under 60%, when the declared domain does not map to a company,
            when a mapped domain is contradicted by an ad majority of 60% or
            more, and for every all-time fallback; a weak disagreement with a
            mapped domain is not contested. A contested company is the best
            available guess — it is still served, but contacts are withheld.
          type: boolean
        contacts:
          description: >-
            Up to three people at the sponsor's company most likely to own a
            podcast sponsorship decision (marketing, partnerships, brand, media,
            communications, growth, then other executives), each with the role
            class and a LinkedIn URL when known. Present only with
            include=contacts, only when the sponsor resolves to a company, and
            never when company_contested is true.
          items:
            $ref: '#/components/schemas/RecommendedContact'
          type:
            - array
            - 'null'
        last_ad_at:
          description: Publish date of the sponsor's most recent ad across those shows.
          format: date-time
          type: string
        score:
          description: >-
            Strength of the recommendation in (0,1): how related the shows that
            run this sponsor are, counted once per publisher, weighted by
            whether it is still buying there and how much (saturating after
            about twenty reads). Compounds across publishers.
          format: double
          type: number
        shared_show_count:
          description: How many of the show's related shows run this sponsor.
          format: int64
          type: integer
        sponsor:
          $ref: '#/components/schemas/SponsorCompact'
          description: >-
            The recommended sponsor, with its linked company when known — the
            company record is the path to people to contact. Sponsor records
            that resolve to the same company (or the same name) are one row,
            named by the strongest of them. The link is resolved from the
            sponsor's declared domain when it maps to one live company, else the
            company most of its ads that aired in the last 180 days were
            attributed to, else the all-time majority.
        total_ads:
          description: >-
            The sponsor's ad reads summed over those related shows (network
            promos excluded).
          format: int64
          type: integer
        via:
          description: >-
            The related shows that run this sponsor, most related first (at most
            three) — the peer set to cite in a pitch.
          items:
            $ref: '#/components/schemas/PodcastCompact'
          type:
            - array
            - 'null'
      required:
        - sponsor
        - score
        - band
        - shared_show_count
        - total_ads
      type: object
    RelatedPodcast:
      additionalProperties: false
      properties:
        band:
          description: >-
            Coarse class of the score: strong (same beat and audience), moderate
            (overlapping subject or audience), weak (a loose connection). Branch
            on this rather than on exact score thresholds.
          enum:
            - strong
            - moderate
            - weak
          type: string
        basis:
          $ref: '#/components/schemas/RelatedPodcastBasis'
          description: Why the shows are related. Present only with include=basis.
        podcast:
          $ref: '#/components/schemas/PodcastCompact'
          description: The related podcast.
        score:
          description: >-
            Fused relatedness in (0,1], calibrated so that higher values are
            more likely to be judged related. Comparable across shows.
          format: double
          type: number
      required:
        - podcast
        - score
        - band
      type: object
    PodcastSpeaker:
      additionalProperties: false
      properties:
        entity:
          $ref: '#/components/schemas/EntityCompact'
          description: Linked knowledge graph entity, when this speaker is identified
        name:
          description: Speaker name
          type: string
        occurrences:
          description: Number of episodes featuring this speaker
          format: int64
          type: integer
        role:
          description: >-
            Speaker role, drawn from the same canonical set as the episode
            speakers. This show-level view surfaces the podcast's recurring
            hosts, so expect HOST here; read the per-episode speakers for
            guests, advertisers, and the rest of the role range.
          type: string
      required:
        - name
      type: object
    Topic:
      additionalProperties: false
      properties:
        ancestry:
          description: Human-readable breadcrumb path (e.g. Business > Technology > AI)
          type: string
        ancestry_path:
          description: Hash-based ancestry path for programmatic filtering
          type: string
        episode_count:
          description: >-
            Number of episodes in this podcast that cover this topic (only
            populated for /v1/podcasts/{id} topic lists)
          format: int64
          type: integer
        id:
          description: Unique identifier
          type: string
        name:
          description: Topic name
          type: string
        slug:
          description: >-
            Ancestry-based slug (e.g., technology/artificial-intelligence). Can
            be used as topic_id.
          type: string
      required:
        - id
        - name
        - slug
      type: object
    PersonCompact:
      additionalProperties: false
      properties:
        description:
          description: Short description (e.g. current role), when known.
          type: string
        id:
          description: Encoded Person identifier
          type: string
        image_url:
          description: Canonical headshot URL when one is known for the Person
          type: string
        name:
          description: Display name
          type: string
        slug:
          description: >-
            Stable human-readable handle (e.g. 'satya-nadella'). Recommended
            canonical identifier on every Particle Pro person surface.
          type: string
      required:
        - id
        - name
      type: object
    PodcastCompact:
      additionalProperties: false
      properties:
        best_rank:
          $ref: '#/components/schemas/PodcastRankingHandle'
          description: >-
            The single best (lowest-numbered) chart position this podcast
            currently holds across all charts. Omitted when the podcast holds no
            current chart appearances, and on endpoints that do not attach it.
            Reading a full chart (with country/category/source filters and
            history) remains premium; a single show's own placement is available
            on every plan.
        id:
          description: Podcast ID
          type: string
        image_url:
          description: Cover image URL
          type: string
        popularity:
          description: >-
            Global popularity percentile in (0,1], a cume_dist ranking over all
            currently-charting podcasts (Apple Podcasts charts). Higher is more
            popular. Omitted when the podcast is not currently charting, and on
            endpoints that build this resource from a projection rather than the
            full podcast row.
          format: double
          type: number
        publisher:
          $ref: '#/components/schemas/PodcastPublisherCompact'
          description: >-
            Publisher (network) attributed to this podcast. Present only when
            the embedding endpoint preloads publisher attribution and the
            podcast's publisher is known.
        slug:
          description: Human-readable slug identifier
          type: string
        title:
          description: Podcast title
          type: string
      required:
        - id
        - title
      type: object
    RecommendedContact:
      additionalProperties: false
      properties:
        linkedin_url:
          description: >-
            The person's LinkedIn profile when known — an InMail path even
            without an email.
          type: string
        person:
          $ref: '#/components/schemas/PersonCompact'
          description: The person; the slug feeds GET /v1/people/{id}.
        role:
          description: >-
            Contact role class derived from the title; contacts are ordered by
            how likely the class is to own a sponsorship decision.
          enum:
            - marketing
            - brand
            - partnerships
            - media_advertising
            - communications
            - growth
            - executive
            - other
          type: string
        title:
          description: Current title at the company, as recorded.
          type: string
      required:
        - person
        - role
      type: object
    SponsorCompact:
      additionalProperties: false
      properties:
        company:
          $ref: '#/components/schemas/CompanyCompact'
          description: Linked company record
        id:
          description: Unique identifier
          type: string
        name:
          description: Sponsor name
          type: string
      required:
        - id
        - name
      type: object
    RelatedPodcastBasis:
      additionalProperties: false
      properties:
        content_similarity:
          description: >-
            Cosine similarity of the two shows' content centroids in [0,1];
            omitted when either show has too few embedded episodes.
          format: double
          type: number
        same_publisher:
          description: Both shows belong to the same multi-show publisher (network).
          type: boolean
        shared_category_count:
          description: Number of directory categories the shows share.
          format: int64
          type: integer
        shared_guest_count:
          description: Number of guests who appeared on both shows.
          format: int64
          type: integer
        shared_guests:
          description: Up to three of the shared guests, most significant first.
          items:
            $ref: '#/components/schemas/PersonCompact'
          type:
            - array
            - 'null'
        shared_sponsor_count:
          description: Number of advertisers both shows have carried.
          format: int64
          type: integer
        shared_topics:
          description: Up to three topics that contribute most to the overlap.
          items:
            $ref: '#/components/schemas/Topic'
          type:
            - array
            - 'null'
        topic_overlap:
          description: Overlap of the shows' topic profiles in [0,1].
          format: double
          type: number
      required:
        - shared_guest_count
        - same_publisher
        - shared_sponsor_count
        - shared_category_count
      type: object
    EntityCompact:
      additionalProperties: false
      properties:
        company:
          $ref: '#/components/schemas/EntityCompany'
          description: Linked company record, if this entity is a known company
        description:
          description: Short description
          type: string
        id:
          description: Entity ID
          type: string
        image_url:
          description: Entity image URL
          type: string
        name:
          description: Entity name
          type: string
        person:
          $ref: '#/components/schemas/EntityPerson'
          description: Linked person record, if this entity is a known person
        slug:
          description: Human-readable slug identifier
          type: string
        type:
          $ref: '#/components/schemas/EntityType'
          description: Category. Omitted when the entity falls outside the supported set.
        wikipedia_url:
          description: Wikipedia URL
          type: string
      required:
        - id
        - slug
        - name
      type: object
    PodcastRankingHandle:
      additionalProperties: false
      properties:
        captured_at:
          format: date-time
          type: string
        category_slug:
          type: string
        chart_type:
          enum:
            - top_podcasts
          type: string
        country:
          type: string
        rank:
          format: int64
          type: integer
        source:
          enum:
            - apple
            - spotify
          type: string
      required:
        - source
        - chart_type
        - rank
        - captured_at
      type: object
    CompanyCompact:
      additionalProperties: false
      properties:
        description:
          description: Short company description, when known.
          type: string
        domain:
          description: Primary website domain (e.g. 'nvidia.com'), when known.
          type: string
        id:
          description: Company identifier (domain, slug, or encoded ID)
          type: string
        image_mode:
          description: >-
            Image presentation policy. AUTOMATIC permits client fallbacks,
            CUSTOM requires image_url, and NONE suppresses all image fallbacks.
          enum:
            - AUTOMATIC
            - CUSTOM
            - NONE
          type: string
        image_url:
          description: Company logo or image URL
          type: string
        name:
          description: Company name
          type: string
        slug:
          description: >-
            Stable human-readable handle (the linked knowledge-graph slug, e.g.
            'nvidia'), when known. Companies have no slug of their own; prefer
            this for display and pass it (or id) to /v1/companies.
          type: string
        ticker:
          description: Primary stock ticker symbol, when listed.
          type: string
      required:
        - id
        - name
      type: object
    EntityCompany:
      additionalProperties: false
      properties:
        domain:
          description: Company website domain
          type: string
        id:
          description: Company identifier
          type: string
        ticker:
          description: Primary stock ticker symbol
          type: string
      required:
        - id
      type: object
    EntityPerson:
      additionalProperties: false
      properties:
        company:
          description: Current company name
          type: string
        id:
          description: Person identifier
          type: string
        image_url:
          description: Person headshot URL
          type: string
        title:
          description: Current role title
          type: string
      required:
        - id
      type: object
    EntityType:
      additionalProperties: false
      properties:
        name:
          description: Human-friendly display label (e.g. 'Company').
          type: string
        slug:
          description: >-
            Stable identifier, safe to pass to the type query parameter (e.g.
            'company').
          type: string
      required:
        - slug
        - name
      type: object
  securitySchemes:
    ApiKeyHeader:
      description: Pass your API key in the X-API-Key header (recommended).
      in: header
      name: X-API-Key
      type: apiKey
    BearerAuth:
      description: Pass your API key as a Bearer token in the Authorization header.
      scheme: bearer
      type: http

````