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

# Import prompts

> Add 1-10 validated Prompt Universe candidates to the project as tracked prompts (`isTracked: true`), as when you add prompts in the app: the project's next scheduled run checks them, within the prompt allowance. Starts no Prompt Universe run and calls no model. THE GATES AND THE ALLOWANCE ARE ALL-OR-NOTHING, THE WRITES ARE NOT: every candidate is checked before anything is written and one refusal refuses the whole batch with 422 `prompt_gates_failed` and nothing created; the whole batch is then checked against the prompt allowance, and one that does not fit is refused with 403 `quota_exceeded` and nothing created. Once writing starts each prompt commits on its own and re-checks your prompt quota, so a batch can still stop partway if another write takes the room. Every response - success or failure - carries `outcomes`, one row per submitted candidate (`created` / `failed` / `not_attempted`); on a partial failure the response keeps the underlying error's own status and code (for example 403 `quota_exceeded`) and adds `created` and `outcomes`, so retry only the rows that are not `created`. Any `topicIds` must belong to the same project as the prompt; one that does not is refused with 404 `not_found`, indistinguishable from a topic id that does not exist. Requires a connection minted with the `prompt:draft` capability (not the bare `write` scope), and your own project role must allow the write. Supports `Idempotency-Key` replay. Returns 404 where the feature is not enabled for the workspace.



## OpenAPI

````yaml /api-reference/openapi.json post /api/mcp/projects/{projectId}/prompt-generation/import
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}/prompt-generation/import:
    post:
      tags:
        - Prompts
      summary: Import prompts
      description: >-
        Add 1-10 validated Prompt Universe candidates to the project as tracked
        prompts (`isTracked: true`), as when you add prompts in the app: the
        project's next scheduled run checks them, within the prompt allowance.
        Starts no Prompt Universe run and calls no model. THE GATES AND THE
        ALLOWANCE ARE ALL-OR-NOTHING, THE WRITES ARE NOT: every candidate is
        checked before anything is written and one refusal refuses the whole
        batch with 422 `prompt_gates_failed` and nothing created; the whole
        batch is then checked against the prompt allowance, and one that does
        not fit is refused with 403 `quota_exceeded` and nothing created. Once
        writing starts each prompt commits on its own and re-checks your prompt
        quota, so a batch can still stop partway if another write takes the
        room. Every response - success or failure - carries `outcomes`, one row
        per submitted candidate (`created` / `failed` / `not_attempted`); on a
        partial failure the response keeps the underlying error's own status and
        code (for example 403 `quota_exceeded`) and adds `created` and
        `outcomes`, so retry only the rows that are not `created`. Any
        `topicIds` must belong to the same project as the prompt; one that does
        not is refused with 404 `not_found`, indistinguishable from a topic id
        that does not exist. Requires a connection minted with the
        `prompt:draft` capability (not the bare `write` scope), and your own
        project role must allow the write. Supports `Idempotency-Key` replay.
        Returns 404 where the feature is not enabled for the workspace.
      operationId: importPrompts
      parameters:
        - $ref: '#/components/parameters/projectId'
        - $ref: '#/components/parameters/idempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - candidates
              properties:
                candidates:
                  type: array
                  minItems: 1
                  maxItems: 10
                  items:
                    type: object
                    required:
                      - text
                      - stage
                    properties:
                      text:
                        type: string
                        minLength: 1
                        maxLength: 2000
                        description: The prompt's wording.
                      stage:
                        type: string
                        enum:
                          - tofu
                          - mofu
                          - bofu
                          - post_purchase
                        description: >-
                          The funnel moment: tofu (first look), mofu (compare),
                          bofu (buy), post_purchase (own).
                      kind:
                        type: string
                        enum:
                          - open
                          - sentiment
                          - competitor
                        description: >-
                          open = unbranded, sentiment = branded, competitor =
                          comparison.
                      branded:
                        type: boolean
                        description: Whether the prompt names the brand.
                      topicIds:
                        type: array
                        maxItems: 20
                        items:
                          type: string
                        description: Existing topic ids to assign to each added prompt.
                market:
                  type: string
                  description: Which spelling list to hold the set to (US or GB).
      responses:
        '200':
          description: The added prompts.
          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'
            X-Idempotent-Replay:
              $ref: '#/components/headers/XIdempotentReplay'
            X-Idempotent-Skipped:
              $ref: '#/components/headers/XIdempotentSkipped'
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/AddPromptsResponse'
                  - type: object
                    properties:
                      outcomes:
                        type: array
                        description: >-
                          One row per submitted candidate, in submission order.
                          Present on success and, alongside the error, on a
                          partial failure.
                        items:
                          type: object
                          properties:
                            index:
                              type: integer
                              description: Position in the submitted array, 0-based.
                            text:
                              type: string
                            status:
                              type: string
                              enum:
                                - created
                                - failed
                                - not_attempted
                              description: >-
                                `created` - the prompt exists. `failed` - the
                                candidate the run stopped on. `not_attempted` -
                                the run stopped before reaching it, and nothing
                                was written for it.
                            promptId:
                              type:
                                - string
                                - 'null'
        '400':
          $ref: '#/components/responses/defaultError'
        '401':
          $ref: '#/components/responses/defaultError'
        '403':
          $ref: '#/components/responses/defaultError'
        '404':
          $ref: '#/components/responses/defaultError'
        '409':
          $ref: '#/components/responses/idempotencyInFlight'
        '422':
          $ref: '#/components/responses/defaultError'
        '429':
          $ref: '#/components/responses/rateLimited'
      security:
        - bearerAuth: []
components:
  parameters:
    projectId:
      name: projectId
      in: path
      required: true
      schema:
        type: string
        format: uuid
      description: The project id.
    idempotencyKey:
      name: Idempotency-Key
      in: header
      schema:
        type: string
      description: >-
        Optional client-generated key (e.g. a UUID). Retrying with the same key
        within 24h replays the original stored response (`X-Idempotent-Replay:
        true`) instead of repeating the side effect. See
        [Idempotency](/api-reference/introduction#idempotency).
  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
    XIdempotentReplay:
      description: >-
        `true` when this response is a replay of a previously stored successful
        response for the same `Idempotency-Key`.
      schema:
        type: string
        enum:
          - 'true'
    XIdempotentSkipped:
      description: >-
        `body-too-large` when a successful response exceeded the 100KB
        idempotency-store cap and was not cached (the request still ran
        normally).
      schema:
        type: string
        enum:
          - body-too-large
    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
  schemas:
    AddPromptsResponse:
      type: object
      properties:
        prompts:
          type: array
          items:
            $ref: '#/components/schemas/AddPromptDraft'
        created:
          type: integer
        success:
          type: boolean
      required:
        - prompts
        - created
        - success
    AddPromptDraft:
      type: object
      description: >-
        The curated shape createPrompt returns for each created draft — id,
        wording, topic assignment and location, not the raw internal row.
      properties:
        id:
          type: string
          format: uuid
        text:
          type: string
        topicId:
          type:
            - string
            - 'null'
        topicName:
          type:
            - string
            - 'null'
        topics:
          type: array
          items:
            type: object
            properties:
              id:
                type: string
              name:
                type: string
            required:
              - id
              - name
        lastUpdated:
          type: string
        createdAt:
          type:
            - string
            - 'null'
          format: date-time
        isFromOnboarding:
          type:
            - boolean
            - 'null'
        isCustomized:
          type:
            - boolean
            - 'null'
        isTracked:
          type:
            - boolean
            - 'null'
          description: >-
            `false` for every draft this endpoint creates — call the tracking
            endpoint to turn it on.
        locations:
          type: array
          items:
            type: object
            properties:
              id:
                type: string
              countryCode:
                type: string
              city:
                type:
                  - string
                  - 'null'
              region:
                type:
                  - string
                  - 'null'
              latitude:
                type:
                  - number
                  - 'null'
              longitude:
                type:
                  - number
                  - 'null'
            required:
              - id
              - countryCode
        fallbackLocation:
          type: 'null'
        usesFallbackLocation:
          type: boolean
        projectId:
          type:
            - string
            - 'null'
          format: uuid
        intentCategory:
          type:
            - string
            - 'null'
        promptType:
          type:
            - string
            - 'null'
        isBranded:
          type:
            - boolean
            - 'null'
        keywordSearchVolume:
          type:
            - integer
            - 'null'
        keywordDifficulty:
          type:
            - integer
            - 'null'
        currentRevision:
          type: integer
          description: >-
            Optimistic-concurrency counter — pass as `If-Match` on a subsequent
            PATCH to detect a concurrent change without a second fetch.
        updatedAt:
          type:
            - string
            - 'null'
          format: date-time
      required:
        - id
        - text
        - topics
        - lastUpdated
        - locations
        - usesFallbackLocation
        - currentRevision
    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
            - 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
            - query_timeout
            - gsc_not_connected
            - gsc_site_not_linked
            - gsc_access_denied
            - ga4_not_connected
            - traffic_not_connected
            - 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
  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'
    idempotencyInFlight:
      description: >-
        Another request with the same `Idempotency-Key` is still executing.
        `Retry-After` (5 seconds) is always present — retry with the SAME key
        once it elapses.
      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'
    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 **Settings → Workspace →
        Integrations**. 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.