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

# Search premium financial newsletter and podcast posts by topic.



## OpenAPI

````yaml https://dripstack.xyz/openapi.json get /api/v1/search
openapi: 3.1.0
info:
  title: Drip
  summary: Premium financial newsletter and podcast API with micropayment access.
  version: 0.1.0
  description: >
    Paid API for searching and browsing Drip's premium financial newsletters and
    podcasts, resolving publications and direct post links, and purchasing
    synthesized post summaries for investing research and market analysis.


    ## Payment Flow


    Paid routes return HTTP 402 with a dual challenge. Use an x402 or MPP
    payment-aware client.


    1. Plain request returns 402 with `WWW-Authenticate` (MPP) and
    `PAYMENT-REQUIRED` (x402) headers.

    2. Retry the same request through a payment-aware client, or manually with
    `Authorization: Payment <credential>` (MPP) or `PAYMENT-SIGNATURE` header
    (x402).

    3. On success (200), response includes `synthesizedSummary` and
    `paymentInfo`.


    **Pricing:** Discovery `x-payment-info.offers[]` is advisory. Runtime 402
    challenge is authoritative. Price may scale with content (e.g. stock-picks
    by source article count).


    **Error codes:** 402 = payment required, do not retry without payment. 503 =
    summary not ready, retry later. 404 = content not found, do not pay.
  contact:
    name: Drip
    email: support@dripstack.com
    url: https://dripstack.xyz
  license:
    name: Proprietary
    url: https://dripstack.xyz/terms
  x-guidance: >
    # Drip API Reference


    ## Discovery


    Prefer `GET /openapi.json` (OpenAPI 3.1) for route shapes, JSON schemas, and
    paid-route `x-payment-info.offers[]` metadata. If OpenAPI is unavailable,
    use `GET /.well-known/x402` for the paid resource list in `METHOD /path`
    form.


    Root `x-discovery.ownershipProofs` is a Drip vendor extension, not part of
    core MPP discovery.


    ## Routes


    ### `GET /api/v1/search`


    Searches imported premium financial newsletters and podcasts by topic. Use
    this as the default discovery route for topic browsing rather than loading
    the whole publication catalog.


    Query parameters:


    - `q` (required): natural-language search query

    - `limit` (optional): number of article results to return, from 1-30; use
    `10` by default

    - `mode` (optional): `hybrid` by default; `fts` is lexical only


    Response includes `items[]`, ranked post candidates with `publicationSlug`,
    `slug`, `title`, `subtitle`, `publishedAt`, `snippet`, `whyMatched`, and
    relevance fields. Use `publicationSlug` + `slug` from a selected item to
    fetch the paid article or podcast post.


    For user-facing search options, render `{title} ({publicationSlug},
    {YYYY-MM-DD})` when `publishedAt` is present, or `{title}
    ({publicationSlug})` when no date is available. Convert ISO timestamps to
    date-only `YYYY-MM-DD`. Do not show `slug`, `subtitle`, `snippet`,
    `whyMatched`, relevance scores, or other internal metadata in user-facing
    menus. Treat search results as candidates, not evidence; answer substantive
    questions only from fetched paid summaries.


    ### `GET /api/v1/publications`


    Lists every indexed newsletter, podcast, and publication with `slug`,
    `title`, `description`, `siteUrl`, and `lastSyncedAt`. Use this only when
    the user explicitly wants to browse the full catalog or asks what
    publications are available.


    ### `GET /api/v1/publications/search`


    Searches indexed publications by slug, title, author, podcast show,
    newsletter, or site URL. Required query parameter: `q` (minimum 2
    characters). Returns up to 3 matches with `publicationSlug`, `title`,
    `author`, and `siteUrl`.


    ### `GET /api/v1/publications/{publicationSlug}`


    Returns publication metadata plus `posts`: post summaries with `slug`,
    `title`, `subtitle`, `publishedAt`, and `priceCents`. Returns `404` if the
    publication is not in the database.


    Optional post-list query parameter: `limit` (1-100).


    ### `GET /api/v1/publications/{publicationSlug}/{postSlug}` (paid)


    Returns post metadata and `synthesizedSummary` after payment. Returns `404`
    if the publication or post is not found, `503` with code `summary_not_ready`
    when the summary is not ready yet (retry later; no payment challenge), and
    `402` if payment is required.


    Unpaid responses include a dual payment challenge: MPP in `WWW-Authenticate:
    Payment ...` and x402 v2 in `PAYMENT-REQUIRED`. Retry the same request with
    `Authorization: Payment ...` for MPP or `PAYMENT-SIGNATURE` for x402 v2.


    ### `GET /api/v1/stock-picks`


    Returns stock-picker calls for AI-agent consumption after x402/MPP payment.
    This is a specialized paid route for ticker-level picks, analyst calls,
    recommendations, and investment ideas; it is not part of the normal
    newsletter/podcast search, selection, and paid-summary workflow.


    This endpoint always returns one effective UTC calendar day, not a rolling
    date range. By default, it returns the latest day that has stock picks. Pass
    `date=YYYY-MM-DD` to request one effective UTC day. Optional `period=latest`
    is an explicit alias for the default. Do not send `date` and `period`
    together. Optional `limit` is 1-500 and defaults to 200.


    The effective day is based on article `publishedAt`; when publication time
    is missing, the server may use extraction time internally. Returned items do
    not include extraction time, so treat `publishedAt` as source article
    context only and omit date context when it is null.


    Response includes `dateUsed`, `startDate`, `endDate`, `asOf`, `count`, and
    `items[]`. `dateUsed` is the canonical returned day; `startDate` and
    `endDate` are the same as `dateUsed` for this single-day response. Each item
    includes `ticker`, `tickerExchange`, `instrumentType`, `action`,
    `direction`, `authorConviction`, `convictionLabel`, `activePick`,
    `evidenceQuote`, `rationaleSnippet`, `articleTitle`, `articleUrl`, `author`,
    `publishedAt`, `publicationSlug`, and `postSlug`.


    Returns `404` when no stock picks exist for the requested or resolved day —
    do not pay on `404`. Plain requests return `402` only when matching paid
    picks exist. Runtime price is based on the number of distinct attributed
    source articles in the returned picks. After settlement, the server records
    a sale for each distinct attributed source article.


    ## Payment


    Paid post routes return HTTP `402` with a dual challenge: MPP in
    `WWW-Authenticate: Payment ...` and x402 v2 in `PAYMENT-REQUIRED`. Use an
    x402 or MPP payment-aware client. If plain HTTP returns `402`, retry the
    same request through the payment-aware client instead of treating it as a
    final failure.


    Infer the live price from the paid endpoint response or payment challenge.
    OpenAPI `x-payment-info.offers[]` is advisory and may show Base USDC x402,
    Tempo, and Stripe charges or catalog floor prices; per-post pricing comes
    from the runtime challenge. Always trust the live `402` challenge over
    discovery offers.


    ## Agent flows


    ### Topic search


    Use when the user asks a general finance question, asks what writers or
    podcasts are saying, or wants article/podcast post recommendations.


    1. Call `GET /api/v1/search?q={query}&limit=10`.

    2. Present returned `items[]` as candidates using only title, publication
    slug, and date.

    3. Keep each candidate's `publicationSlug` and `slug` for the paid fetch
    URL.

    4. Fetch selected article summaries with `GET
    /api/v1/publications/{publicationSlug}/{postSlug}` through a payment-aware
    client.

    5. Summarize or synthesize only from fetched `synthesizedSummary` text.


    ### Specific publication


    Use when the user names a publication, author, podcast show, newsletter, or
    shares a Substack publication URL.


    1. Call `GET /api/v1/publications/search?q={query}` unless the normalized
    slug is obvious.

    2. If one match is clearly right, call `GET
    /api/v1/publications/{publicationSlug}`.

    3. Present 3-5 recent post titles from `posts[]`.

    4. Fetch selected post summaries through the paid post route.


    ### Browse catalog


    Use when the user asks to see available newsletters, podcasts, or
    publications before choosing one.


    1. Call `GET /api/v1/publications`.

    2. Present publications as `Publication Title (slug) — short description`.

    3. After the user chooses a publication, call `GET
    /api/v1/publications/{publicationSlug}`.

    4. Fetch selected post bodies through the paid post route.


    ### Stock picks


    Use when the user asks for stock-picker calls, stock recommendations, recent
    investment picks, analyst calls, or ticker-level long/short ideas.


    1. Call `GET /api/v1/stock-picks` through an x402 or MPP payment-aware
    client for the latest UTC effective day with picks. Read `dateUsed` and
    `asOf` from the response.

    2. Call `GET /api/v1/stock-picks?date={YYYY-MM-DD}` when the user asks for a
    specific day.

    3. Use `period=latest` only when an explicit latest-period parameter is
    useful; it is equivalent to omitting `date`.

    4. If the response is `404`, no picks exist for that day — do not pay; try
    another date or tell the user none are available.

    5. Present picks with ticker, action, direction, conviction, active/inactive
    status, evidence quote, rationale snippet, article title, source
    publication, and source URL.

    6. Treat `publishedAt` as the article publication time; if it is null, omit
    date context rather than inventing one.

    7. Keep `publicationSlug` and `postSlug` for optional follow-up paid
    article-summary fetches.


    ### Direct article


    Use when the user shares a direct article URL, podcast post URL, or a
    specific post slug.


    1. Resolve `publicationSlug` and `postSlug` from the URL or context.

    2. Probe the paid endpoint first when needed to inspect the live `402`
    challenge and price.

    3. Call `GET /api/v1/publications/{publicationSlug}/{postSlug}` through a
    payment-aware client after the user has clearly asked to read, buy,
    summarize, or use that post.

    4. Return a curated summary by default; include raw/full content only when
    explicitly requested.


    ## Fetched article response handling


    For one fetched article, return a curated summary with synthesis, notable
    claims, caveats, implications, and source context. For multiple fetched
    articles, compare the relevant claims, tensions, mechanisms, caveats, and
    implications across sources.


    Append source references for fetched articles with title, publication, date
    when available, and source URL when available.


    If a paid fetch fails, surface the failure rather than substituting model
    knowledge. If some selected articles succeed and others fail, synthesize
    only from successfully fetched articles and name the failed fetches.


    Runtime pricing note: paid post challenges use the stored per-post USD price
    when present, else at least $0.1.
servers:
  - url: https://dripstack.xyz
security: []
tags:
  - name: Search
    description: Search premium newsletters and podcasts by topic.
  - name: Publications
    description: List, search, and import newsletters, podcasts, and publications.
  - name: Posts
    description: Fetch, unlock, and list individual article and podcast post content.
  - name: Stock Picks
    description: Daily stock-picker calls, analyst recommendations, and investment ideas.
paths:
  /api/v1/search:
    get:
      tags:
        - Search
      summary: Search premium financial newsletter and podcast posts by topic.
      operationId: searchByTopic
      parameters:
        - name: q
          in: query
          required: true
          schema:
            type: string
            minLength: 2
          description: Natural-language query string.
        - name: limit
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 30
            default: 10
          description: Maximum number of items returned (1-30).
        - name: mode
          in: query
          required: false
          schema:
            type: string
            enum:
              - fts
              - hybrid
            default: hybrid
          description: >-
            Search mode. `fts` is lexical only; `hybrid` blends lexical and
            semantic.
      responses:
        '200':
          description: Search results.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TopicSearchResponse'
        '400':
          description: Invalid query params.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InvalidQueryResponse'
        '500':
          description: Search failed.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorMessage'
      security: []
components:
  schemas:
    TopicSearchResponse:
      type: object
      additionalProperties: false
      required:
        - mode
        - asOf
        - query
        - normalizedQuery
        - matchConfidence
        - searchTierUsed
        - timeWindow
        - freshnessCoverage
        - totalCount
        - count
        - items
      properties:
        mode:
          type: string
          enum:
            - fts
            - hybrid
          description: Search mode used.
        asOf:
          type: string
          description: Server timestamp when the response was generated.
        query:
          type: string
          description: Original search query.
        normalizedQuery:
          type: string
          description: Normalized query after preprocessing.
        matchConfidence:
          type: string
          enum:
            - strong
            - weak
            - none
          description: Overall match confidence for the query.
        searchTierUsed:
          type: string
          enum:
            - scoped
            - non_scoped
          description: Whether scoped (preferred) or non-scoped publishers were used.
        timeWindow:
          anyOf:
            - $ref: '#/components/schemas/TopicSearchTimeWindow'
            - type: 'null'
          description: Resolved time window for the search, if applicable.
        freshnessCoverage:
          anyOf:
            - $ref: '#/components/schemas/TopicSearchFreshnessCoverage'
            - type: 'null'
          description: Freshness and coverage metadata for the time window.
        totalCount:
          type: integer
          minimum: 0
          description: Total matching results before limit.
        count:
          type: integer
          minimum: 0
          description: Number of results returned.
        items:
          type: array
          description: Ranked search results.
          items:
            $ref: '#/components/schemas/TopicSearchPostItem'
      example:
        mode: hybrid
        asOf: '2026-06-15T10:30:00Z'
        query: AI infrastructure spending
        normalizedQuery: ai infrastructure spending
        matchConfidence: strong
        searchTierUsed: scoped
        timeWindow:
          label: last_week
          startIso: '2026-06-08T00:00:00Z'
          endIso: '2026-06-15T00:00:00Z'
          days: 7
        freshnessCoverage:
          requestedWindow:
            label: last_week
            startIso: '2026-06-08T00:00:00Z'
            endIso: '2026-06-15T00:00:00Z'
            days: 7
          rankedInWindow: 4
          researchCandidatesInWindow: 12
          staleFallbackMode: false
        totalCount: 4
        count: 3
        items:
          - publicationSlug: stratechery
            slug: the-ai-infrastructure-boom
            title: The AI Infrastructure Boom
            subtitle: Why hyperscalers are spending billions on GPU clusters
            isScopedPublisher: true
            relevanceScore: 0.92
            matchedTokenCount: 3
            totalTokenCount: 3
            topicCoverageRatio: 1
            whyMatched:
              - Title matches AI + infrastructure
              - Body discusses capex spending
            publishedAt: '2026-06-14T12:00:00Z'
            isInTimeWindow: true
            snippet: >-
              Nvidia's datacenter revenue hit $26B last quarter as hyperscalers
              race to build out GPU clusters...
    InvalidQueryResponse:
      type: object
      required:
        - error
        - issues
      properties:
        error:
          type: string
          description: Human-readable error message.
        issues:
          type: object
          description: Field-level validation errors keyed by parameter name.
    ErrorMessage:
      type: object
      additionalProperties: false
      required:
        - error
      properties:
        error:
          type: string
          description: Human-readable error message.
    TopicSearchTimeWindow:
      type: object
      additionalProperties: false
      required:
        - label
        - startIso
        - endIso
        - days
      properties:
        label:
          type: string
          enum:
            - this_week
            - last_week
            - last_n_days
            - last_n_weeks
            - this_month
            - past_month
            - last_month
            - today
            - yesterday
            - latest_recent
          description: Predefined time window label.
        startIso:
          type: string
          description: Window start in ISO 8601.
        endIso:
          type: string
          description: Window end in ISO 8601.
        days:
          type: integer
          minimum: 1
          description: Window duration in days.
    TopicSearchFreshnessCoverage:
      type: object
      additionalProperties: false
      required:
        - requestedWindow
        - rankedInWindow
        - researchCandidatesInWindow
        - staleFallbackMode
      properties:
        requestedWindow:
          $ref: '#/components/schemas/TopicSearchTimeWindow'
          description: The time window used for the search.
        rankedInWindow:
          type: integer
          minimum: 0
          description: Results ranked within the time window.
        researchCandidatesInWindow:
          type: integer
          minimum: 0
          description: Research candidates found in the window.
        staleFallbackMode:
          type: boolean
          description: >-
            Whether the server fell back to older results due to low in-window
            coverage.
    TopicSearchPostItem:
      type: object
      additionalProperties: false
      required:
        - publicationSlug
        - slug
        - title
        - subtitle
        - isScopedPublisher
        - relevanceScore
        - matchedTokenCount
        - totalTokenCount
        - whyMatched
        - publishedAt
      properties:
        publicationSlug:
          type: string
          description: Publication slug for building the paid fetch URL.
        slug:
          type: string
          description: Post slug for building the paid fetch URL.
        title:
          type: string
          description: Post title.
        subtitle:
          type:
            - string
            - 'null'
          description: Post subtitle or teaser.
        isScopedPublisher:
          type: boolean
          description: Whether the publication was in the user's scoped publisher set.
        relevanceScore:
          type: number
          description: Computed relevance to the query (higher is better).
        matchedTokenCount:
          type: integer
          minimum: 0
          description: Number of query tokens matched in the post.
        totalTokenCount:
          type: integer
          minimum: 0
          description: Total query token count.
        topicCoverageRatio:
          type: number
          description: Ratio of matched tokens to total tokens.
        whyMatched:
          type: array
          items:
            type: string
          description: Short explanations of why this post matched.
        publishedAt:
          type:
            - string
            - 'null'
          description: ISO publication timestamp.
        isInTimeWindow:
          type: boolean
          description: Whether the post falls within the requested time window.
        snippet:
          type:
            - string
            - 'null'
          description: Relevant text excerpt from the post.

````