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

# Get a single alert match

> Returns one match with full hydration — transcript Windows, source-episode metadata, and the deliveries that included this match. The URL is keyed only by the match ID so a result link can be shared publicly without leaking the alert identifier. Use this for per-match landing pages opened from a digest or results list. URL possession is the access factor; authenticated org members see the full payload while unauthenticated and non-member callers see a reduced public payload (entity + episode, no transcript dialogue). Single-match only: digests (daily/weekly) embed many matches and should be fetched via GET /v1/alerts/deliveries/{id}?view=detailed.



## OpenAPI

````yaml /openapi.json get /v1/alerts/matches/{id}
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/alerts/matches/{id}:
    get:
      tags:
        - Alerts
        - tier:free
      summary: Get a single alert match
      description: >-
        Returns one match with full hydration — transcript Windows,
        source-episode metadata, and the deliveries that included this match.
        The URL is keyed only by the match ID so a result link can be shared
        publicly without leaking the alert identifier. Use this for per-match
        landing pages opened from a digest or results list. URL possession is
        the access factor; authenticated org members see the full payload while
        unauthenticated and non-member callers see a reduced public payload
        (entity + episode, no transcript dialogue). Single-match only: digests
        (daily/weekly) embed many matches and should be fetched via GET
        /v1/alerts/deliveries/{id}?view=detailed.
      operationId: get-alert-match
      parameters:
        - description: Match ID
          in: path
          name: id
          required: true
          schema:
            description: Match ID
            type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AlertMatch'
          description: OK
        default:
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/PlatformError'
          description: Error
      security: []
      x-codeSamples:
        - label: cURL
          lang: curl
          source: curl "https://api.particle.pro/v1/alerts/matches/{id}"
components:
  schemas:
    AlertMatch:
      additionalProperties: false
      properties:
        alert_id:
          description: ID of the parent alert.
          type: string
        deliveries:
          items:
            $ref: '#/components/schemas/AlertDeliverySummary'
          type:
            - array
            - 'null'
        detected_at:
          format: date-time
          type: string
        entity_id:
          type: string
        entity_type:
          type: string
        episode:
          $ref: '#/components/schemas/AlertMatchEpisode'
          description: >-
            Optional episode + podcast metadata embedded so a single response
            renders a card without a follow-up /v1/episodes/{id} call. Populated
            for preview-sample matches (POST
            /v1/projects/{projectId}/alerts/preview's GET response) and for the
            landing-page GETs (GET /v1/alerts/deliveries/{id} in both summary
            and detailed views, GET /v1/alerts/matches/{id}); absent on the
            paginated live matches list.
        id:
          type: string
        is_backfilled:
          description: >-
            True for matches written by the post-create historical sweep.
            Backfilled matches are real matches the live pipeline would have
            produced, with DetectedAt set to the source episode's publish time.
            They never trigger delivery (no email is sent) — the field lets the
            UI label them so users can distinguish 'past' from 'going-forward'
            matches.
          type: boolean
        kind:
          description: >-
            Inherited from the parent alert's kind so clients can render mention
            vs appearance semantics without a follow-up alert lookup. Match
            payloads from ENTITY_MENTION alerts carry mention_count and
            mention_variants; PODCAST_SPEAKER matches carry roles and a
            line-count in mention_count.
          enum:
            - ENTITY_MENTION
            - PODCAST_SPEAKER
          type: string
        llm_summary:
          description: >-
            AI-generated narrative summary of this match with prior-mention
            context from the past 7 days for the same (alert, entity). Generated
            asynchronously after match creation. Absent (field omitted) when the
            summarizer hasn't processed the row yet OR when the LLM exhausted
            its retry budget — clients should treat both states the same: no
            summary to render. Visible to both org members and the public
            landing-page tier; the summary describes the mention itself, not the
            alert configuration.
          type: string
        mention_count:
          format: int64
          type: integer
        mention_variants:
          items:
            type: string
          type:
            - array
            - 'null'
        monitor_id:
          description: Deprecated — use alert_id. ID of the parent alert.
          type: string
        relevance:
          description: >-
            How this match relates to the watched entity, classified by the
            summarizer: on_target (the entity is the mention's subject or a
            substantive reference) or incidental (a correct but passing
            reference in service of another story). Absent when unjudged. Lets a
            client tell a substantive mention from a fly-by one. (A third
            internal verdict, wrong_entity, marks knowledge-graph name
            collisions; those matches are suppressed before delivery and never
            appear here.)
          enum:
            - on_target
            - incidental
          type: string
        roles:
          description: >-
            Canonical speaker role(s) the matched entity appeared as. One of
            GUEST, PANELIST, CORRESPONDENT, or AUDIENCE (raw STT/LLM labels like
            CALLER, REPORTER, LISTENER are normalized to these buckets on
            write). Populated only for PODCAST_SPEAKER matches; sorted
            alphabetically for deterministic order.
          items:
            type: string
          type:
            - array
            - 'null'
        source_id:
          type: string
        source_type:
          type: string
        truncated:
          type: boolean
        windows:
          items:
            $ref: '#/components/schemas/AlertMatchWindow'
          type:
            - array
            - 'null'
      required:
        - id
        - monitor_id
        - alert_id
        - kind
        - entity_type
        - entity_id
        - source_type
        - source_id
        - detected_at
        - mention_count
        - deliveries
      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
    AlertDeliverySummary:
      additionalProperties: false
      properties:
        channel:
          type: string
        created_at:
          format: date-time
          type: string
        error_message:
          type: string
        id:
          type: string
        sent_at:
          format: date-time
          type: string
        status:
          description: >-
            Delivery outcome — SENT (delivered; a partial success keeps this
            status with the failure noted in error_message), FAILED (an attempt
            failed; realtime retries within its budget and digests re-select
            within their window), SKIPPED (intentionally not delivered), or
            ABANDONED (realtime webhook delivery permanently gave up after
            exhausting its retry budget, so the match was dropped for that
            channel).
          type: string
      required:
        - id
        - channel
        - status
        - created_at
      type: object
    AlertMatchEpisode:
      additionalProperties: false
      properties:
        apple_podcasts_url:
          description: >-
            Apple Podcasts deep-link for the parent podcast. Omitted when the
            podcast has no iTunes ID.
          type: string
        audio_url:
          description: >-
            CDN-fronted URL for the full episode audio, playable directly in a
            browser <audio> element without auth (the podcast's own public
            media). Clients play a specific window by loading this and seeking
            to the window's start_seconds. Omitted when the episode has no
            stored audio yet. Present on both the member and public landing-page
            tiers so a shared link can play the clip.
          type: string
        duration_seconds:
          description: Total episode duration in seconds. Omitted when unknown.
          format: double
          type: number
        explicit:
          description: >-
            Whether the episode is flagged as containing explicit content by its
            publisher.
          type: boolean
        image_url:
          description: >-
            Episode-specific image. Omitted when the episode has no dedicated
            image. Clients should fall back to podcast_image_url for a card
            thumbnail in that case.
          type: string
        podcast_bias:
          description: >-
            Political bias rating for the parent podcast. Omitted 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.
          enum:
            - EXTREME_LEFT
            - LEANS_LEFT
            - LEFT
            - CENTER
            - RIGHT
            - LEANS_RIGHT
            - EXTREME_RIGHT
          type: string
        podcast_id:
          type: string
        podcast_image_url:
          description: >-
            Parent podcast's image. Suitable as a fallback when image_url is
            absent.
          type: string
        podcast_popularity:
          description: >-
            Parent podcast's global popularity percentile in (0,1] — a cume_dist
            ranking over all currently-charting podcasts (Apple Podcasts
            charts). Higher is more popular; 1.0 is the most popular show.
            Omitted when the podcast is not currently charting.
          format: double
          type: number
        podcast_popularity_badge:
          description: >-
            Human-facing reach tier derived from podcast_popularity: Top Podcast
            (top 1%), Very Popular (top 5%), or Popular (top 10%). Omitted for
            shows outside the top 10%.
          enum:
            - Top Podcast
            - Very Popular
            - Popular
          type: string
        podcast_slug:
          type: string
        podcast_title:
          type: string
        published_at:
          format: date-time
          type: string
        slug:
          type: string
        title:
          type: string
      required:
        - title
        - podcast_id
        - podcast_title
      type: object
    AlertMatchWindow:
      additionalProperties: false
      properties:
        clip_description:
          type: string
        clip_id:
          type: string
        clip_intro_statement:
          type: string
        clip_title:
          type: string
        clip_type:
          type: string
        end_seconds:
          format: double
          type: number
        lines:
          items:
            $ref: '#/components/schemas/AlertMatchLine'
          type:
            - array
            - 'null'
        segment_description:
          type: string
        segment_id:
          type: string
        segment_summary:
          type: string
        segment_title:
          type: string
        segment_type:
          type: string
        start_seconds:
          format: double
          type: number
      required:
        - start_seconds
        - end_seconds
        - lines
      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
    AlertMatchLine:
      additionalProperties: false
      properties:
        end_seconds:
          format: double
          type: number
        is_mention:
          type: boolean
        number:
          format: int64
          type: integer
        role:
          type: string
        speaker:
          type: string
        start_seconds:
          format: double
          type: number
        text:
          type: string
      required:
        - start_seconds
        - end_seconds
        - text
      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

````