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

# Preview a source classification rule change

> What a rule change (`create`, `update`, `delete` or `remove_all`) would do if saved now: how many stored citations would change Source Type, in how many AI answers, and the moves from type to type. Writes nothing, so it takes no `Idempotency-Key`. It refuses what the save would refuse, with the same codes. Requires the `source:classify` capability, and your own project role must allow managing the project (otherwise 403 `forbidden`). A pitch project that is not currently active refuses with 409 `INACTIVE_PITCH_PROMPT_MUTATION`.



## OpenAPI

````yaml /api-reference/openapi.json post /api/mcp/projects/{projectId}/sources/rules/preview
openapi: 3.1.0
info:
  title: Searchable REST API
  version: 1.0.0
  summary: >-
    Query AI visibility, sources, sentiment, traffic, and content data, and
    trigger audits/reports/sitemap syncs.
  description: >-
    The Searchable REST API (`/api/mcp/*` and
    `/api/v1/projects/{projectId}/audits`) exposes the same data and actions
    available in the Searchable dashboard and MCP server, over plain HTTP with a
    bearer API key. It is a **read-mostly** surface — 75 of its 91 operations
    are GET. The mutating ones are capability-gated (a bare `write` scope does
    not satisfy a capability such as `prompt:draft`), and those listed under
    [Idempotency](/api-reference/introduction#idempotency) support
    `Idempotency-Key` replay.


    See **[Getting started](/api-reference/introduction)** for auth, rate
    limits, idempotency, and pagination conventions, and the **[error
    reference](/api/errors)** for every error `code` this API returns.


    `/api/mcp/*` is a frozen v1 contract — see the [changelog](/changelog) for
    the deprecation policy.
  contact:
    name: Searchable Support
    email: support@searchable.com
    url: https://docs.searchable.com/api-reference/introduction
servers:
  - url: https://app.searchable.com
    description: Production
security:
  - bearerAuth: []
tags:
  - name: Projects
    description: List and inspect the projects an API key can reach.
  - name: Visibility
    description: >-
      AI visibility score, platform/topic/prompt/location breakdowns, and
      historical trend.
  - name: Share of Voice
    description: Brand vs. competitor mention-share ranking and its daily trend.
  - name: Competitors
    description: >-
      The project's tracked competitor roster — share of voice, sentiment, and
      mention/citation counts.
  - name: Sources
    description: >-
      Domains and URLs cited by AI answers — citation share, trend, and cached
      page content.
  - name: Sentiment
    description: Brand sentiment summary, trend, and head-to-head competitor comparison.
  - name: Query Fanout
    description: The sub-queries AI models generate when answering tracked prompts.
  - name: Traffic
    description: >-
      First-party AI-crawler and AI-referral traffic sourced from the
      tracker/CDN pipeline.
  - name: Shopping
    description: AI shopping/product-carousel visibility.
  - name: Ads
    description: >-
      Sponsored ads surfaced in AI answers — advertisers, individual creatives,
      ad-heavy prompts, and the frequency trend.
  - name: Answers
    description: Raw, per-response AI-answer data for a single prompt.
  - name: GSC
    description: Live Google Search Console performance data for the project's linked site.
  - name: GA4
    description: Live Google Analytics 4 traffic and AI-referral data.
  - name: Audits & Issues
    description: >-
      Page audits (technical + AEO), site issues, monitored pages, and sitemap
      sync.
  - name: Reports
    description: Generate and list shareable visibility/sentiment reports.
  - name: Articles
    description: Content pieces (articles) created in Searchable.
  - name: Opportunities
    description: >-
      Actionable, prioritized suggestions Searchable has surfaced for the
      project.
  - name: Brand
    description: Brand profile (knowledge base + AI-observed facts) and domain authority.
  - name: Prompts
    description: >-
      The project's prompt catalog (tracked, untracked, and AI-suggested
      prompts).
paths:
  /api/mcp/projects/{projectId}/sources/rules/preview:
    post:
      tags:
        - Sources
      summary: Preview a source classification rule change
      description: >-
        What a rule change (`create`, `update`, `delete` or `remove_all`) would
        do if saved now: how many stored citations would change Source Type, in
        how many AI answers, and the moves from type to type. Writes nothing, so
        it takes no `Idempotency-Key`. It refuses what the save would refuse,
        with the same codes. Requires the `source:classify` capability, and your
        own project role must allow managing the project (otherwise 403
        `forbidden`). A pitch project that is not currently active refuses with
        409 `INACTIVE_PITCH_PROMPT_MUTATION`.
      operationId: previewSourceClassificationRuleChange
      parameters:
        - $ref: '#/components/parameters/projectId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SourceClassificationRuleChange'
      responses:
        '200':
          description: The change's impact.
          headers:
            X-Request-Id:
              $ref: '#/components/headers/XRequestId'
            RateLimit:
              $ref: '#/components/headers/RateLimit'
            RateLimit-Policy:
              $ref: '#/components/headers/RateLimitPolicy'
            X-RateLimit-Limit:
              $ref: '#/components/headers/XRateLimitLimit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/XRateLimitRemaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/XRateLimitReset'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SourceClassificationImpactResponse'
        '400':
          $ref: '#/components/responses/defaultError'
        '401':
          $ref: '#/components/responses/defaultError'
        '403':
          $ref: '#/components/responses/defaultError'
        '404':
          $ref: '#/components/responses/defaultError'
        '409':
          $ref: '#/components/responses/defaultError'
        '429':
          $ref: '#/components/responses/rateLimited'
components:
  parameters:
    projectId:
      name: projectId
      in: path
      required: true
      schema:
        type: string
        format: uuid
      description: The project id.
  schemas:
    SourceClassificationRuleChange:
      description: One change to a project's rules. `remove_all` removes every rule.
      oneOf:
        - type: object
          properties:
            action:
              type: string
              enum:
                - create
            input:
              $ref: '#/components/schemas/SourceClassificationRuleInput'
          required:
            - action
            - input
        - type: object
          properties:
            action:
              type: string
              enum:
                - update
            ruleId:
              type: string
              minLength: 1
              maxLength: 128
            patch:
              $ref: '#/components/schemas/SourceClassificationRulePatch'
          required:
            - action
            - ruleId
            - patch
        - type: object
          properties:
            action:
              type: string
              enum:
                - delete
            ruleId:
              type: string
              minLength: 1
              maxLength: 128
          required:
            - action
            - ruleId
        - type: object
          properties:
            action:
              type: string
              enum:
                - remove_all
          required:
            - action
    SourceClassificationImpactResponse:
      type: object
      properties:
        rowsChanged:
          type: integer
          description: Stored citations whose Source Type (or competitor) would change.
        answersChanged:
          type: integer
          description: AI answers those citations belong to.
        transitions:
          type: array
          description: The moves from type to type, most citations first.
          items:
            type: object
            properties:
              from:
                $ref: '#/components/schemas/SourceClassificationType'
              to:
                $ref: '#/components/schemas/SourceClassificationType'
              rows:
                type: integer
            required:
              - from
              - to
              - rows
        success:
          type: boolean
          description: >-
            Always `true` — injected on every success response by this endpoint
            family's response wrapper.
      required:
        - rowsChanged
        - answersChanged
        - transitions
        - success
    SourceClassificationRuleInput:
      type: object
      properties:
        scope:
          type: string
          minLength: 1
          maxLength: 2048
          description: >-
            A subdomain or a path of a domain, like `business.linkedin.com` or
            `linkedin.com/help`, or a URL.
        withinDomain:
          type: string
          maxLength: 253
          description: The domain the scope belongs to; a scope outside it is refused.
        citationType:
          $ref: '#/components/schemas/SourceClassificationType'
        competitorId:
          type:
            - string
            - 'null'
          maxLength: 64
          description: Required for a `competitor` rule; ignored for any other type.
      required:
        - scope
        - citationType
    SourceClassificationRulePatch:
      type: object
      properties:
        citationType:
          $ref: '#/components/schemas/SourceClassificationType'
        competitorId:
          type:
            - string
            - 'null'
          maxLength: 64
          description: Required for a `competitor` rule; ignored for any other type.
      required:
        - citationType
    SourceClassificationType:
      type: string
      enum:
        - brand
        - competitor
        - editorial
        - social
        - forum
        - review
        - institutional
        - third_party
        - other
      description: A Source Type. `brand` is the app's Owned.
    Problem:
      type: object
      description: >-
        RFC 9457 `application/problem+json` error body. `error` is retained
        verbatim as a legacy compat key equal to `message`. Some codes carry
        additional fields beyond the base shape (documented per-code in the
        [error reference](/api/errors)) — always additive, never replacing
        these.
      properties:
        type:
          type: string
          format: uri
          description: >-
            A URL identifying the error kind — the error reference page,
            anchored to `code`.
        title:
          type: string
          description: Human-readable summary of `code`.
        status:
          type: integer
          description: The HTTP status code (matches the response status).
        code:
          type: string
          description: >-
            Machine-readable, stable error code — safe to branch on. See the
            [error reference](/api/errors) for the full catalog.
          enum:
            - unauthorized
            - forbidden
            - missing_scope
            - plan_upgrade_required
            - security_policy_denied
            - not_found
            - invalid_argument
            - invalid_country
            - no_domain
            - no_workspace
            - no_pages
            - bulk_limit_exceeded
            - quota_exceeded
            - project_not_runnable
            - pitch_not_supported
            - rate_limited
            - idempotency_in_flight
            - idempotency_conflict
            - query_timeout
            - gsc_not_connected
            - gsc_site_not_linked
            - gsc_access_denied
            - ga4_not_connected
            - traffic_not_connected
            - invalid_scope
            - host_outside_domain
            - invalid_citation_type
            - missing_competitor
            - unknown_competitor
            - duplicate_scope
            - rule_limit
            - internal_error
        error:
          type: string
          description: Legacy compat key. Always equal to `message`.
        message:
          type: string
          description: Human-readable error message (identical to `error`).
        howToFix:
          type: string
          description: Present on actionable errors — a concrete next step.
        requestId:
          type: string
          format: uuid
          description: This request's id. Include it when contacting support.
        requiresUpgrade:
          type: boolean
          description: Present on `plan_upgrade_required` (403).
        retryable:
          type: boolean
          description: >-
            Present on `rate_limited`, `idempotency_in_flight`, and
            `query_timeout`.
        timeout:
          type: boolean
          description: Present on `query_timeout` (504).
        quotaExceeded:
          type: boolean
          description: Present on `quota_exceeded` (403).
        current:
          type: integer
          description: Present on `quota_exceeded` — current usage.
        limit:
          type: integer
          description: Present on `quota_exceeded` — the plan's limit.
        bulkLimitExceeded:
          type: boolean
          description: Present on `bulk_limit_exceeded` (400, `POST /audits`).
        requested:
          type: integer
          description: >-
            Present on `bulk_limit_exceeded` / `quota_exceeded` — the count
            requested.
        maxAllowed:
          type: integer
          description: Present on `bulk_limit_exceeded` — the plan's per-request cap.
        details:
          description: >-
            Present on some `invalid_argument` (400) responses — a Zod
            `.flatten()` validation breakdown.
          type: object
          properties:
            formErrors:
              type: array
              items:
                type: string
            fieldErrors:
              type: object
              additionalProperties:
                type: array
                items:
                  type: string
      required:
        - type
        - title
        - status
        - code
        - error
        - message
  headers:
    XRequestId:
      description: This request's id. Include it when contacting support.
      schema:
        type: string
        format: uuid
    RateLimit:
      description: >-
        IETF draft rate-limit header:
        `"default";r=<remaining>;t=<seconds-until-reset>`. Omitted on responses
        where the limiter did not run (e.g. a pre-auth validation error, or a
        degraded limiter failing open).
      schema:
        type: string
    RateLimitPolicy:
      description: >-
        IETF draft rate-limit policy: `"default";q=<quota>;w=<window-seconds>`.
        Currently `q=600;w=60`.
      schema:
        type: string
    XRateLimitLimit:
      description: Requests allowed per window (600/minute per key).
      schema:
        type: integer
    XRateLimitRemaining:
      description: Requests remaining in the current window.
      schema:
        type: integer
    XRateLimitReset:
      description: Absolute Unix-epoch second the current window resets.
      schema:
        type: integer
    RetryAfter:
      description: >-
        Seconds to wait before retrying. Set on 429s issued by Searchable's own
        rate limiter and on `409 idempotency_in_flight`; may be absent when an
        upstream provider (e.g. Google) rate-limits.
      schema:
        type: integer
  responses:
    defaultError:
      description: >-
        Error response. `code` is the machine-readable reason — see the [error
        reference](/api/errors) for the full catalog and remediation per code.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/XRequestId'
        RateLimit:
          $ref: '#/components/headers/RateLimit'
        RateLimit-Policy:
          $ref: '#/components/headers/RateLimitPolicy'
        X-RateLimit-Limit:
          $ref: '#/components/headers/XRateLimitLimit'
        X-RateLimit-Remaining:
          $ref: '#/components/headers/XRateLimitRemaining'
        X-RateLimit-Reset:
          $ref: '#/components/headers/XRateLimitReset'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    rateLimited:
      description: >-
        Rate limited. Usually the per-API-key REST limit (600 requests/minute);
        on Google-backed endpoints it can also relay an upstream Google rate
        limit. `Retry-After` (seconds) is present when the limit was applied by
        Searchable's own rate limiter; it may be absent when an upstream
        provider rate-limits.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/XRequestId'
        RateLimit:
          $ref: '#/components/headers/RateLimit'
        RateLimit-Policy:
          $ref: '#/components/headers/RateLimitPolicy'
        X-RateLimit-Limit:
          $ref: '#/components/headers/XRateLimitLimit'
        X-RateLimit-Remaining:
          $ref: '#/components/headers/XRateLimitRemaining'
        X-RateLimit-Reset:
          $ref: '#/components/headers/XRateLimitReset'
        Retry-After:
          $ref: '#/components/headers/RetryAfter'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: sea_xxxxx
      description: >-
        A Searchable API key, created under **Manage Account → Integrations →
        API Keys**. Send as `Authorization: Bearer sea_xxxxx`. Every key carries
        one or more scopes (`read`, `write`, `admin`) and may optionally be
        bound to a single project — see [Getting
        started](/api-reference/introduction#authentication).

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.