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

# Estimate a keyword update

> What `PATCH /v1/keywords/{id}` would do with this body, **without changing anything or charging anything**. Same validation as the patch, so `valid: false` carries the refusal it would answer. A valid body comes back with the keyword's monthly credits after the patch, before it (`previousMonthlyCredits`) and the difference, and with `resetSearches`: the searches the patch **would** start over, computed by the same code the patch runs. An unknown or foreign id is still a 404. Free: does not charge credits. Price it first with the matching `estimate` operation, which runs the same validation and writes nothing. Send its `estimateToken` back in the `Nephia-Estimate-Token` header with the **same** body: the write then refuses a body that is not the one priced. The header is optional for an API key and required from the MCP server.



## OpenAPI

````yaml /openapi.json post /v1/keywords/{id}/estimate
openapi: 3.1.0
info:
  title: Nephia API
  description: >-
    The brand-monitoring API. Create a **keyword** and it polls the live Sources
    (X, Reddit, Youtube, TikTok, Bluesky, Hacker News, Mastodon, Lemmy, GitHub,
    Product Hunt, Stack Overflow, RSS, AI answers and Vinted) on an interval,
    keeps what matches, reads each mention for sentiment and intent, sorts it
    into your buckets and answers your own agent step over it. Read the result
    back as **mentions** (`GET /v1/mentions` across the whole Account, or per
    keyword), or have it pushed to you as signed webhook events and delivery
    channels. A search can carry several terms at once, OR'd into one upstream
    request at one tick's cost. Authenticate with an API key on your Account.
    Monitoring is sold as a subscription (keywords, terms, freshness and AI)
    with credits as the meter underneath; credit packs are overflow and never
    change a limit. Reading your own mentions is free; the semantic search mode
    and the AI passes are what meter. Request quota is per Account (all API keys
    share one bucket), by Plan: Free 60/min, Solo 350/min, Growth 700/min, Pro
    1200/min.
  version: 1.0.0
servers:
  - url: https://api.nephia.cc
    description: Production
security:
  - ApiKeyAuth: []
tags:
  - name: Account
    description: Account balance
  - name: Mentions
    description: Everything your keywords caught, across every Source
  - name: Keywords
    description: >-
      What you monitor. A keyword carries its terms, its Sources and its
      settings. Read, create, edit and pause them here.
  - name: Explore
    description: >-
      One question asked of the Sources once, priced first, without creating a
      keyword
  - name: AI
    description: Group, classify, agent and summarise passes over items you name
  - name: Vinted analytics
    description: Observed price history and per-day market statistics
paths:
  /v1/keywords/{id}/estimate:
    post:
      tags:
        - Keywords
      summary: Estimate a keyword update
      description: >-
        What `PATCH /v1/keywords/{id}` would do with this body, **without
        changing anything or charging anything**. Same validation as the patch,
        so `valid: false` carries the refusal it would answer. A valid body
        comes back with the keyword's monthly credits after the patch, before it
        (`previousMonthlyCredits`) and the difference, and with `resetSearches`:
        the searches the patch **would** start over, computed by the same code
        the patch runs. An unknown or foreign id is still a 404. Free: does not
        charge credits. Price it first with the matching `estimate` operation,
        which runs the same validation and writes nothing. Send its
        `estimateToken` back in the `Nephia-Estimate-Token` header with the
        **same** body: the write then refuses a body that is not the one priced.
        The header is optional for an API key and required from the MCP server.
      operationId: postV1KeywordsByIdEstimate
      parameters:
        - in: path
          name: id
          schema:
            type: string
            format: uuid
          required: true
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  minLength: 1
                  maxLength: 80
                refreshIntervalSeconds:
                  type: integer
                  exclusiveMinimum: 0
                  description: >-
                    Seconds between checks. Each Source accepts its own range,
                    published as `x-source-intervals` at the root of this
                    document. Your plan may raise the floor further; the refusal
                    names the effective one.
                webhookUrl:
                  anyOf:
                    - type: string
                      const: ''
                    - type: string
                      format: uri
                    - type: 'null'
                aiEnabled:
                  type: boolean
                aiPreset:
                  type:
                    - string
                    - 'null'
                  enum:
                    - product-model
                    - theme-sentiment
                    - seller
                    - duplicates
                    - custom
                    - null
                aiPrompt:
                  type:
                    - string
                    - 'null'
                  maxLength: 400
                aiStep:
                  oneOf:
                    - $ref: '#/components/schemas/AgentStep'
                    - type: 'null'
                sentimentEnabled:
                  type: boolean
                coBrandsEnabled:
                  type: boolean
                subjectRole:
                  type: string
                  enum:
                    - own
                    - competitor
                    - topic
                muteRules:
                  type: array
                  items:
                    anyOf:
                      - type: string
                        minLength: 1
                        maxLength: 60
                      - type: object
                        properties:
                          target:
                            type: string
                            enum:
                              - text
                              - title
                              - body
                              - author
                              - community
                          value:
                            type: string
                            minLength: 1
                            maxLength: 60
                          source:
                            type:
                              - string
                              - 'null'
                            enum:
                              - x
                              - reddit
                              - youtube
                              - tiktok
                              - bluesky
                              - hackernews
                              - mastodon
                              - lemmy
                              - github
                              - producthunt
                              - stackoverflow
                              - rss
                              - ai_answers
                              - vinted
                              - null
                          match:
                            type: string
                            enum:
                              - word
                              - contains
                              - exact
                        required:
                          - value
                  maxItems: 50
                vipAuthors:
                  type: array
                  items:
                    anyOf:
                      - type: string
                        minLength: 1
                        maxLength: 60
                      - type: object
                        properties:
                          handle:
                            type: string
                            minLength: 1
                            maxLength: 60
                          source:
                            type:
                              - string
                              - 'null'
                            enum:
                              - x
                              - reddit
                              - youtube
                              - tiktok
                              - bluesky
                              - hackernews
                              - mastodon
                              - lemmy
                              - github
                              - producthunt
                              - stackoverflow
                              - rss
                              - ai_answers
                              - vinted
                              - null
                          note:
                            type:
                              - string
                              - 'null'
                            maxLength: 120
                        required:
                          - handle
                  maxItems: 100
                rules:
                  type: array
                  items:
                    type: object
                    properties:
                      id:
                        type: string
                        format: uuid
                      name:
                        type: string
                        minLength: 1
                        maxLength: 60
                      enabled:
                        type: boolean
                      source:
                        type:
                          - string
                          - 'null'
                        enum:
                          - x
                          - reddit
                          - youtube
                          - tiktok
                          - bluesky
                          - hackernews
                          - mastodon
                          - lemmy
                          - github
                          - producthunt
                          - stackoverflow
                          - rss
                          - ai_answers
                          - vinted
                          - null
                      when:
                        anyOf:
                          - type: object
                            properties:
                              kind:
                                type: string
                                const: item
                              all:
                                type: array
                                items:
                                  type: object
                                  properties:
                                    field:
                                      type: string
                                      minLength: 1
                                    op:
                                      type: string
                                      enum:
                                        - eq
                                        - neq
                                        - lt
                                        - lte
                                        - gt
                                        - gte
                                        - contains
                                        - not_contains
                                        - word
                                        - in
                                        - exists
                                        - similar_to
                                    value:
                                      anyOf:
                                        - type: string
                                        - type: number
                                        - type: boolean
                                        - type: array
                                          items:
                                            type: string
                                        - type: object
                                          properties:
                                            text:
                                              type: string
                                            threshold:
                                              type: number
                                          required:
                                            - text
                                  required:
                                    - field
                                    - op
                                    - value
                                minItems: 1
                                maxItems: 8
                            required:
                              - kind
                              - all
                          - type: object
                            properties:
                              kind:
                                type: string
                                const: volume
                              window:
                                type: string
                                enum:
                                  - 1h
                                  - 24h
                              min:
                                type: integer
                                exclusiveMinimum: 0
                              multiple:
                                type: number
                                minimum: 1
                            required:
                              - kind
                              - window
                              - min
                              - multiple
                          - type: object
                            properties:
                              kind:
                                type: string
                                const: sentiment_shift
                              window:
                                type: string
                                enum:
                                  - 1h
                                  - 24h
                              min:
                                type: integer
                                exclusiveMinimum: 0
                              multiple:
                                type: number
                                minimum: 1
                            required:
                              - kind
                              - window
                              - min
                              - multiple
                      then:
                        type: array
                        items:
                          type: object
                          properties:
                            type:
                              type: string
                              enum:
                                - notify
                                - webhook
                                - mark
                                - stop
                            channelIds:
                              type: array
                              items:
                                type: string
                                format: uuid
                            label:
                              type: string
                              enum:
                                - to_reply
                                - starred
                                - flagged
                                - hidden
                          required:
                            - type
                        minItems: 1
                        maxItems: 4
                    required:
                      - name
                      - when
                      - then
                  maxItems: 20
                webhookMode:
                  type: string
                  enum:
                    - all
                    - rules
                webhookEvents:
                  type: array
                  items:
                    type: string
                    enum:
                      - keyword.alert_fired
                      - keyword.report_ready
                      - keyword.paused
                      - keyword.resumed
                      - channel.disabled
                  maxItems: 5
                channels:
                  type: array
                  items:
                    type: object
                    properties:
                      channelId:
                        type: string
                        format: uuid
                      mode:
                        type: string
                        enum:
                          - instant
                          - hourly
                          - daily
                          - daily_brief
                          - weekly_report
                    required:
                      - channelId
                      - mode
                  maxItems: 5
                globalCriteria:
                  type: object
                  properties:
                    market:
                      type: string
                      minLength: 1
                    query:
                      type: string
                    priceMin:
                      type: number
                    priceMax:
                      type: number
                    sort:
                      type: string
                    page:
                      type: number
                    perPage:
                      type: number
                    filters:
                      type: object
                      additionalProperties: {}
                      description: >-
                        Criteria only one Source reads, by that Source's own
                        keys (`subreddit` on Reddit, `prompt` and `brands` on AI
                        answers, and so on). On Vinted: `brand_ids`, `size_ids`,
                        `catalog_ids`, `color_ids`, `status_ids`, each a list of
                        Vinted ids (`[53, 14]`, or `"53, 14"`); one of those
                        keys holding anything else is refused with a 400. Any
                        other key is stored as written and passed to the Source,
                        which ignores what it does not read. Set them in a
                        Source's search `overrides` so the other Sources do not
                        inherit them.
                    match:
                      type: string
                      enum:
                        - platform
                        - word
                        - contains
                    terms:
                      type: array
                      items:
                        type: string
                        minLength: 1
                        maxLength: 60
                      minItems: 2
                    repliesTo:
                      type: string
                      minLength: 1
                      maxLength: 16
                  required:
                    - market
                sources:
                  type: array
                  items:
                    type: object
                    properties:
                      source:
                        type: string
                        enum:
                          - x
                          - reddit
                          - youtube
                          - tiktok
                          - bluesky
                          - hackernews
                          - mastodon
                          - lemmy
                          - github
                          - producthunt
                          - stackoverflow
                          - rss
                          - ai_answers
                          - vinted
                      enabled:
                        type: boolean
                      searches:
                        type: array
                        items:
                          type: object
                          properties:
                            id:
                              type: string
                              format: uuid
                            label:
                              type:
                                - string
                                - 'null'
                              maxLength: 80
                            overridesEnabled:
                              type: boolean
                            overrides:
                              type: object
                              properties:
                                market:
                                  type: string
                                  minLength: 1
                                query:
                                  type: string
                                priceMin:
                                  type: number
                                priceMax:
                                  type: number
                                sort:
                                  type: string
                                page:
                                  type: number
                                perPage:
                                  type: number
                                filters:
                                  type: object
                                  additionalProperties: {}
                                  description: >-
                                    Criteria only one Source reads, by that
                                    Source's own keys (`subreddit` on Reddit,
                                    `prompt` and `brands` on AI answers, and so
                                    on). On Vinted: `brand_ids`, `size_ids`,
                                    `catalog_ids`, `color_ids`, `status_ids`,
                                    each a list of Vinted ids (`[53, 14]`, or
                                    `"53, 14"`); one of those keys holding
                                    anything else is refused with a 400. Any
                                    other key is stored as written and passed to
                                    the Source, which ignores what it does not
                                    read. Set them in a Source's search
                                    `overrides` so the other Sources do not
                                    inherit them.
                                match:
                                  type: string
                                  enum:
                                    - platform
                                    - word
                                    - contains
                                terms:
                                  type: array
                                  items:
                                    type: string
                                    minLength: 1
                                    maxLength: 60
                                  minItems: 2
                                repliesTo:
                                  type: string
                                  minLength: 1
                                  maxLength: 16
                      refreshIntervalSeconds:
                        type:
                          - integer
                          - 'null'
                        exclusiveMinimum: 0
                        description: >-
                          Seconds between checks. Each Source accepts its own
                          range, published as `x-source-intervals` at the root
                          of this document. Your plan may raise the floor
                          further; the refusal names the effective one.
                    required:
                      - source
                      - enabled
                  minItems: 1
                schedule:
                  type:
                    - object
                    - 'null'
                  properties:
                    startsAt:
                      type:
                        - string
                        - 'null'
                      format: date-time
                    endsAt:
                      type:
                        - string
                        - 'null'
                      format: date-time
                    timezone:
                      type: string
                      minLength: 1
                      maxLength: 64
                  required:
                    - startsAt
                    - endsAt
                    - timezone
      responses:
        '200':
          description: Estimate
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/KeywordUpdateEstimate'
        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  code:
                    type: string
                required:
                  - error
        '404':
          description: Keyword not found
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  code:
                    type: string
                required:
                  - error
        '429':
          description: >-
            Request quota exceeded. Retry after the `Retry-After` header
            (seconds). Response includes `RateLimit-*` headers (IETF draft-7).
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  code:
                    type: string
                required:
                  - error
              example:
                error: Rate limit exceeded
                code: TOO_MANY_REQUESTS
components:
  parameters:
    IdempotencyKey:
      name: Idempotency-Key
      in: header
      required: false
      schema:
        type: string
        maxLength: 255
      description: >-
        Unique key (e.g. UUID) making this POST safe to retry for 24 hours.
        Replays return the original response with an `Idempotency-Replayed:
        true` header; reusing a key with a different body returns 422.
  schemas:
    AgentStep:
      type: object
      properties:
        instruction:
          type: string
          minLength: 1
          maxLength: 800
        schema:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/AgentStepField'
      required:
        - instruction
        - schema
    KeywordUpdateEstimate:
      type: object
      properties:
        valid:
          type: boolean
        refusal:
          type: object
          properties:
            status:
              type: number
            code:
              type:
                - string
                - 'null'
            message:
              type: string
          required:
            - status
            - code
            - message
        estimate:
          type: object
          properties:
            monthlyCredits:
              type: number
            checksPerMonth:
              type: number
            bySource:
              type: array
              items:
                type: object
                properties:
                  source:
                    type: string
                    enum:
                      - x
                      - reddit
                      - youtube
                      - tiktok
                      - bluesky
                      - hackernews
                      - mastodon
                      - lemmy
                      - github
                      - producthunt
                      - stackoverflow
                      - rss
                      - ai_answers
                      - vinted
                  intervalSeconds:
                    type: number
                  searches:
                    type: number
                  checksPerMonth:
                    type: number
                  monthlyCredits:
                    type: number
                required:
                  - source
                  - intervalSeconds
                  - searches
                  - checksPerMonth
                  - monthlyCredits
            bySearch:
              type: array
              items:
                type: object
                properties:
                  source:
                    type: string
                    enum:
                      - x
                      - reddit
                      - youtube
                      - tiktok
                      - bluesky
                      - hackernews
                      - mastodon
                      - lemmy
                      - github
                      - producthunt
                      - stackoverflow
                      - rss
                      - ai_answers
                      - vinted
                  searchId:
                    type:
                      - string
                      - 'null'
                  label:
                    type:
                      - string
                      - 'null'
                  creditsPerCheck:
                    type: number
                  checksPerMonth:
                    type: number
                  monthlyCredits:
                    type: number
                required:
                  - source
                  - searchId
                  - label
                  - creditsPerCheck
                  - checksPerMonth
                  - monthlyCredits
            firstScanCredits:
              type: number
            normalized:
              type: object
              properties:
                refreshIntervalSeconds:
                  type: number
                sentimentEnabled:
                  type: boolean
                coBrandsEnabled:
                  type: boolean
                sources:
                  type: array
                  items:
                    type: object
                    properties:
                      source:
                        type: string
                        enum:
                          - x
                          - reddit
                          - youtube
                          - tiktok
                          - bluesky
                          - hackernews
                          - mastodon
                          - lemmy
                          - github
                          - producthunt
                          - stackoverflow
                          - rss
                          - ai_answers
                          - vinted
                      intervalSeconds:
                        type: number
                      searches:
                        type: array
                        items:
                          type: object
                          properties:
                            id:
                              type:
                                - string
                                - 'null'
                            label:
                              type:
                                - string
                                - 'null'
                            resolvedCriteria:
                              type: object
                              additionalProperties: {}
                          required:
                            - id
                            - label
                            - resolvedCriteria
                    required:
                      - source
                      - intervalSeconds
                      - searches
              required:
                - refreshIntervalSeconds
                - sentimentEnabled
                - coBrandsEnabled
                - sources
            planAllowance:
              type: number
            creditsRemaining:
              type: number
            searchSlots:
              type:
                - object
                - 'null'
              properties:
                inUse:
                  type: number
                requested:
                  type: number
                limit:
                  type: number
              required:
                - inUse
                - requested
                - limit
            previousMonthlyCredits:
              type: number
            monthlyCreditsDelta:
              type: number
            resetSearches:
              type: array
              items:
                type: object
                properties:
                  source:
                    type: string
                    enum:
                      - x
                      - reddit
                      - youtube
                      - tiktok
                      - bluesky
                      - hackernews
                      - mastodon
                      - lemmy
                      - github
                      - producthunt
                      - stackoverflow
                      - rss
                      - ai_answers
                      - vinted
                  searchId:
                    type: string
                  label:
                    type: string
                required:
                  - source
                  - searchId
                  - label
          required:
            - monthlyCredits
            - checksPerMonth
            - bySource
            - bySearch
            - firstScanCredits
            - normalized
            - planAllowance
            - creditsRemaining
            - searchSlots
            - previousMonthlyCredits
            - monthlyCreditsDelta
            - resetSearches
        estimateToken:
          type: string
        estimateTokenExpiresAt:
          type: string
      required:
        - valid
    AgentStepField:
      type: object
      properties:
        type:
          type: string
          enum:
            - string
            - number
            - boolean
            - enum
        description:
          type: string
          maxLength: 200
        values:
          type: array
          items:
            type: string
          maxItems: 12
        maxLength:
          type: integer
          exclusiveMinimum: 0
      required:
        - type
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: API key created from the Nephia dashboard for your Account.

````