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

# Search podcast episode content

> To find podcasts (shows) by name or topic, use `/v1/podcasts/search?q=…`. This endpoint searches *inside* episode dialogue — by meaning (`semantic_search`), by exact phrase (`keyword_search`), or both at once (hybrid). Each result is a segment of an episode, returned with bounded preview windows of dialogue and any highlight clips that overlap the segment.

For "every line about a person or company" use `/v1/podcasts/mentions` instead — that endpoint returns episode-grouped mention windows with line-level highlights and is shaped for the read-everything-about-X use case. `entity_id` and `company_id` here narrow the result set to episodes featuring the resolved entity, but the ranking still comes from `semantic_search` / `keyword_search`.



## OpenAPI

````yaml /openapi.json get /v1/podcasts/episodes/search
openapi: 3.1.0
info:
  description: Public API for Particle — news intelligence, financial data, and analysis.
  title: Particle API
  version: 0.1.0
servers:
  - url: https://api.particle.pro
security:
  - ApiKeyHeader: []
  - BearerAuth: []
paths:
  /v1/podcasts/episodes/search:
    get:
      tags:
        - Podcast Episode Search
        - tier:standard
      summary: Search podcast episode content
      description: >-
        To find podcasts (shows) by name or topic, use
        `/v1/podcasts/search?q=…`. This endpoint searches *inside* episode
        dialogue — by meaning (`semantic_search`), by exact phrase
        (`keyword_search`), or both at once (hybrid). Each result is a segment
        of an episode, returned with bounded preview windows of dialogue and any
        highlight clips that overlap the segment.


        For "every line about a person or company" use `/v1/podcasts/mentions`
        instead — that endpoint returns episode-grouped mention windows with
        line-level highlights and is shaped for the read-everything-about-X use
        case. `entity_id` and `company_id` here narrow the result set to
        episodes featuring the resolved entity, but the ranking still comes from
        `semantic_search` / `keyword_search`.
      operationId: search-episodes
      parameters:
        - description: >-
            Vector-similarity search by meaning. Express the query the way you'd
            describe the topic to a colleague — paraphrase tolerant, finds
            segments that express the same idea in different vocabulary. Combine
            with keyword_search for hybrid ranking. Describe a topic, not a
            name: to find a specific person or company, filter with entity_id /
            company_id (or use /v1/podcasts/mentions for every line about them)
            — and for an exact token like a ticker, use keyword_search.
          explode: false
          in: query
          name: semantic_search
          schema:
            description: >-
              Vector-similarity search by meaning. Express the query the way
              you'd describe the topic to a colleague — paraphrase tolerant,
              finds segments that express the same idea in different vocabulary.
              Combine with keyword_search for hybrid ranking. Describe a topic,
              not a name: to find a specific person or company, filter with
              entity_id / company_id (or use /v1/podcasts/mentions for every
              line about them) — and for an exact token like a ticker, use
              keyword_search.
            maxLength: 500
            type: string
        - description: >-
            BM25 lexical search over dialogue. Use when an exact token must
            appear verbatim — tickers, drug names, product codes. Wrap any token
            sequence in double quotes (e.g. "machine learning") to require an
            exact ordered phrase match. Multiple quoted phrases AND together
            (e.g. "central bank" "interest rates"); unquoted tokens still
            contribute to BM25 ranking.
          explode: false
          in: query
          name: keyword_search
          schema:
            description: >-
              BM25 lexical search over dialogue. Use when an exact token must
              appear verbatim — tickers, drug names, product codes. Wrap any
              token sequence in double quotes (e.g. "machine learning") to
              require an exact ordered phrase match. Multiple quoted phrases AND
              together (e.g. "central bank" "interest rates"); unquoted tokens
              still contribute to BM25 ranking.
            maxLength: 500
            type: string
        - description: >-
            Optional entity slug or ID. Filters results to episodes featuring
            this entity. For 'every line about X', use /v1/podcasts/mentions
            instead.
          explode: false
          in: query
          name: entity_id
          schema:
            description: >-
              Optional entity slug or ID. Filters results to episodes featuring
              this entity. For 'every line about X', use /v1/podcasts/mentions
              instead.
            type: string
        - description: >-
            Optional entity category slug. Filters to episodes that *mention*
            any entity in that category (e.g. 'company', 'school', 'book').
            Speakers are always people, so this filter only narrows mentioned
            entities. Cannot be combined with 'role'. Ignored when entity_id
            resolves to a specific entity. See GET /v1/entities/types for the
            available slugs.
          explode: false
          in: query
          name: entity_type
          schema:
            description: >-
              Optional entity category slug. Filters to episodes that *mention*
              any entity in that category (e.g. 'company', 'school', 'book').
              Speakers are always people, so this filter only narrows mentioned
              entities. Cannot be combined with 'role'. Ignored when entity_id
              resolves to a specific entity. See GET /v1/entities/types for the
              available slugs.
            type: string
        - description: >-
            Optional company slug, domain, or ID. Resolves to the company's
            linked entity and applies as a filter.
          explode: false
          in: query
          name: company_id
          schema:
            description: >-
              Optional company slug, domain, or ID. Resolves to the company's
              linked entity and applies as a filter.
            type: string
        - description: Filter to a specific episode by slug or ID.
          explode: false
          in: query
          name: episode_id
          schema:
            description: Filter to a specific episode by slug or ID.
            type: string
        - description: Podcast slug, internal ID, or numeric iTunes ID.
          explode: false
          in: query
          name: podcast_id
          schema:
            description: Podcast slug, internal ID, or numeric iTunes ID.
            type: string
        - description: Segment type filter.
          explode: false
          in: query
          name: type
          schema:
            description: Segment type filter.
            enum:
              - INTRO
              - PERSONAL_BANTER
              - TOPIC_DISCUSSION
              - INTERVIEW
              - TRANSITION
              - AD
              - OUTRO
            type: string
        - description: Speaker/mention role filter on the entity_id / company_id filter.
          explode: false
          in: query
          name: role
          schema:
            description: Speaker/mention role filter on the entity_id / company_id filter.
            enum:
              - guest
              - host
              - panelist
              - correspondent
              - mention
            type: string
        - description: Only segments from episodes published after this date.
          explode: false
          in: query
          name: since
          schema:
            description: Only segments from episodes published after this date.
            examples:
              - '2024-01-01'
            type: string
        - description: >-
            Only segments from episodes published on or before this date. A bare
            date includes that whole day.
          explode: false
          in: query
          name: until
          schema:
            description: >-
              Only segments from episodes published on or before this date. A
              bare date includes that whole day.
            examples:
              - '2024-06-01'
            type: string
        - description: Sort order. Defaults to relevance.
          explode: false
          in: query
          name: sort
          schema:
            description: Sort order. Defaults to relevance.
            enum:
              - relevance
              - recency
            type: string
        - description: >-
            Lines of surrounding dialogue around each matched line (1-15,
            default 1). Widens each match's transcript window in place — request
            more context instead of fetching the full transcript. Window size
            stays bounded even at the maximum.
          explode: false
          in: query
          name: context
          schema:
            default: 1
            description: >-
              Lines of surrounding dialogue around each matched line (1-15,
              default 1). Widens each match's transcript window in place —
              request more context instead of fetching the full transcript.
              Window size stays bounded even at the maximum.
            format: int64
            maximum: 15
            minimum: 1
            type: integer
        - description: Results per page (1-100, default 25).
          explode: false
          in: query
          name: limit
          schema:
            default: 25
            description: Results per page (1-100, default 25).
            format: int64
            maximum: 100
            minimum: 1
            type: integer
        - description: Opaque cursor from a previous response.
          explode: false
          in: query
          name: cursor
          schema:
            description: Opaque cursor from a previous response.
            type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PodcastSearchPage'
          description: OK
        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/episodes/search?context=1&limit=25"
components:
  schemas:
    PodcastSearchPage:
      additionalProperties: false
      properties:
        company:
          $ref: '#/components/schemas/CompanyCompact'
          description: >-
            Resolved company, when company_id filtered the result set. Omitted
            when only entity_id was provided.
        cursor:
          description: Opaque cursor; pass back as ?cursor= for the next page
          type: string
        data:
          description: Matches on this page, ranked by relevance (default) or recency
          items:
            $ref: '#/components/schemas/PodcastSearchMatch'
          type:
            - array
            - 'null'
        entity:
          $ref: '#/components/schemas/EntityCompact'
          description: >-
            Resolved entity, when entity_id or company_id filtered the result
            set
        has_more:
          description: More results available
          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
    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_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
    PodcastSearchMatch:
      additionalProperties: false
      properties:
        clips:
          description: Highlight clips that overlap this segment, when any exist
          items:
            $ref: '#/components/schemas/Clip'
          type:
            - array
            - 'null'
        episode:
          $ref: '#/components/schemas/EpisodeCompactWithPodcast'
          description: Episode containing the match
        match:
          $ref: '#/components/schemas/MatchMetadata'
          description: Source and relevance metadata
        segment:
          $ref: '#/components/schemas/Segment'
          description: Matching segment
        windows:
          description: >-
            Bounded transcript windows highlighting the relevant lines. Always
            at least one window when the segment's transcript is loaded.
          items:
            $ref: '#/components/schemas/TranscriptWindow'
          type:
            - array
            - 'null'
      required:
        - episode
        - segment
        - windows
        - match
      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
    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
    Clip:
      additionalProperties: false
      properties:
        audio_url:
          description: Direct audio URL for this clip
          type: string
        description:
          description: AI-generated clip description
          type: string
        duration_seconds:
          description: Clip duration
          format: double
          type: number
        end_seconds:
          description: End time within the episode
          format: double
          type: number
        engagement_score:
          description: >-
            AI-predicted engagement potential (integer, 0 to 100). Values above
            70 are typical for a strong clip.
          format: double
          type: number
        episode:
          $ref: '#/components/schemas/EpisodeCompactWithPodcast'
          description: Parent episode with podcast context
        id:
          description: Unique identifier
          type: string
        intro_statement:
          description: AI-generated hook text for social sharing
          type: string
        segment:
          $ref: '#/components/schemas/SegmentCompact'
          description: Parent segment context
        speaker:
          $ref: '#/components/schemas/ClipSpeaker'
          description: Primary speaker in this clip
        start_seconds:
          description: Start time within the episode
          format: double
          type: number
        title:
          description: AI-generated clip title
          type: string
        type:
          description: Clip type
          enum:
            - SPICY
            - CONTROVERSIAL
            - EMOTIONAL
            - FUNNY
            - SHOCKING
            - INSIGHTFUL
            - INFORMATIVE
            - EDUCATIONAL
            - PHILOSOPHICAL
            - AHA_MOMENT
            - NOTABLE_LINE
            - BEST_STORY
            - DEBATE_DISAGREEMENT
          type: string
      required:
        - id
        - title
        - engagement_score
        - start_seconds
        - end_seconds
        - duration_seconds
      type: object
    EpisodeCompactWithPodcast:
      additionalProperties: false
      properties:
        id:
          description: Episode ID
          type: string
        podcast:
          $ref: '#/components/schemas/PodcastCompact'
          description: Parent podcast
        published_at:
          description: Publication date
          format: date-time
          type: string
        slug:
          description: Human-readable slug identifier
          type: string
        title:
          description: Episode title
          type: string
      required:
        - id
        - title
      type: object
    MatchMetadata:
      additionalProperties: false
      properties:
        relevance_score:
          description: >-
            Raw relevance score from the underlying ranker. For semantic this is
            cosine similarity in [-1, 1] (typically 0..1). For keyword this is
            the BM25 score (unbounded, higher = better). For hybrid this is the
            reciprocal-rank-fusion score (small positive number, higher =
            better). Compare scores within a single response, not across
            queries.
          format: double
          type: number
        source:
          description: >-
            Which ranking signal produced this result: semantic | keyword |
            hybrid
          type: string
      required:
        - source
      type: object
    Segment:
      additionalProperties: false
      properties:
        audio_url:
          description: Direct audio URL for this segment
          type: string
        description:
          description: AI-generated segment description
          type: string
        duration_seconds:
          description: Segment duration
          format: double
          type: number
        end_seconds:
          description: End time within the episode
          format: double
          type: number
        episode:
          $ref: '#/components/schemas/EpisodeCompactWithPodcast'
          description: Parent episode with podcast context
        id:
          description: Unique identifier
          type: string
        number:
          description: Segment position within the episode
          format: int64
          type: integer
        read_type:
          description: >-
            For AD segments, how the ad was delivered (HOST_READ, PRE_RECORDED,
            NETWORK_PROMO)
          type: string
        start_seconds:
          description: Start time within the episode
          format: double
          type: number
        summary:
          description: AI-generated segment summary
          type: string
        title:
          description: AI-generated segment title
          type: string
        type:
          description: >-
            Segment type (INTRO, PERSONAL_BANTER, TOPIC_DISCUSSION, INTERVIEW,
            TRANSITION, AD, OUTRO)
          type: string
      required:
        - id
        - number
        - type
        - title
        - start_seconds
        - end_seconds
        - duration_seconds
      type: object
    TranscriptWindow:
      additionalProperties: false
      properties:
        end_seconds:
          description: Window end time in seconds (episode-absolute)
          format: double
          type: number
        is_preview:
          description: >-
            True when the window is the segment's leading lines (a fallback for
            when line-level scoring couldn't pinpoint any line) rather than
            scored matches. False or absent on a scored window.
          type: boolean
        lines:
          description: Dialogue lines in this window
          items:
            $ref: '#/components/schemas/TranscriptLine'
          type:
            - array
            - 'null'
        start_seconds:
          description: Window start time in seconds (episode-absolute)
          format: double
          type: number
      required:
        - start_seconds
        - end_seconds
        - lines
      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
    SegmentCompact:
      additionalProperties: false
      properties:
        id:
          description: Segment ID
          type: string
        title:
          description: Segment title
          type: string
        type:
          description: Segment type
          type: string
      required:
        - id
        - type
        - title
      type: object
    ClipSpeaker:
      additionalProperties: false
      properties:
        entity:
          $ref: '#/components/schemas/EntityCompact'
          description: Linked knowledge graph entity, when this speaker is identified
        name:
          description: Speaker name
          type: string
        person:
          $ref: '#/components/schemas/PersonCompact'
          description: Linked first-class Person, when the speaker has been resolved
        role:
          description: Speaker role
          type: string
      required:
        - name
      type: object
    PodcastCompact:
      additionalProperties: false
      properties:
        id:
          description: Podcast ID
          type: string
        image_url:
          description: Cover image URL
          type: string
        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
    TranscriptLine:
      additionalProperties: false
      properties:
        end_seconds:
          description: End time in seconds (episode-absolute)
          format: double
          type: number
        is_match:
          description: >-
            Top-scored line within the window for the current query, on
            /v1/podcasts/episodes/search results. Not set on
            /v1/podcasts/mentions.
          type: boolean
        is_mention:
          description: >-
            Line contains a textual mention of the resolved entity. Set on
            /v1/podcasts/mentions only — /v1/podcasts/episodes/search treats
            entity_id as a filter and does not mark mention lines.
          type: boolean
        matched_terms:
          description: >-
            Terms from the query that occur in this line, longest-first, for
            clients to highlight. Locate them case-insensitively: each term is
            spelled as the query spelled it, which may differ in case from the
            line's text (query "openai" is reported for a line reading
            "OpenAI"). Whole-token matches only — a term never matches inside a
            longer word, so "AI" is not reported for "said". A multi-word query
            yields the whole phrase ("founder mode") when it occurs
            contiguously, so clients mark it as one span rather than
            highlighting each word separately; individual words appear only
            where they occur outside the phrase. Only the longest term is
            reported at any position, so terms never overlap. On
            /v1/podcasts/episodes/search this is set on any line in the window
            containing the query, not only is_match lines; on
            /v1/podcasts/mentions it is set only on is_mention lines. Absent
            when nothing matched or the query was not text-based.
          items:
            type: string
          type:
            - array
            - 'null'
        number:
          description: Line number within the episode (1-indexed)
          format: int64
          type: integer
        role:
          description: Speaker role (HOST, GUEST, etc.)
          type: string
        speaker:
          description: Speaker name or label
          type: string
        start_seconds:
          description: Start time in seconds (episode-absolute)
          format: double
          type: number
        text:
          description: Spoken text
          type: string
      required:
        - number
        - speaker
        - start_seconds
        - end_seconds
        - text
      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
    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
  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

````