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

# Refine an AI Finder preview

> **What it does.** Takes an existing `previewId` plus a natural-language `feedback` string (e.g. *"exclude agencies"*, *"only US companies"*, *"narrow to 50–500 employees"*) and runs a NEW AI search that combines the original query with your refinement. Returns a brand-new `previewId`; the original preview is untouched and still valid.

**When to use.** Call this after you've reviewed the result of a preview and want to tighten the filters before importing. You can chain iterations — each iterate call returns a new `previewId` you can iterate on again.

**Provider.** The new preview uses the SAME provider as the one being refined — you don't re-pick the provider. If the original preview used `AUTO`, the refined one also uses `AUTO` (the AI may still route to the same or a different provider, based on the combined query).

**What you get back.** Same shape as `POST /v1/ai-finder/previews`, plus a `previousPreviewId` field pointing at the preview you refined. Use this new `previewId` with the iterate or import endpoint.

    > **Required scope:** `ACTIONS_WRITE`
    >
    > **Rate limit:** 10 requests per minute



## OpenAPI

````yaml https://openapi.enginy.ai/definitions.json post /v1/ai-finder/previews/{previewId}/iterate
openapi: 3.1.0
info:
  title: Enginy API
  version: 1.0.0
  description: Public API for Enginy platform
servers:
  - url: https://openapi.enginy.ai
    description: Configured server
security: []
tags:
  - name: AI Variables
    description: >-
      Manage AI variables and discover the entity fields you can reference in
      prompts and entity requests.
  - name: Inbox
    description: >-
      Inbox endpoints for listing contact threads, reading thread messages,
      managing tags, and sending manual replies.
  - name: Workflows
    description: >-
      Build, validate, publish, run, and inspect advanced (graph) workflows,
      plus the block/condition catalog needed to author a workflow plan.
paths:
  /v1/ai-finder/previews/{previewId}/iterate:
    post:
      tags:
        - AI Finder
      summary: Refine an AI Finder preview
      description: >-
        **What it does.** Takes an existing `previewId` plus a natural-language
        `feedback` string (e.g. *"exclude agencies"*, *"only US companies"*,
        *"narrow to 50–500 employees"*) and runs a NEW AI search that combines
        the original query with your refinement. Returns a brand-new
        `previewId`; the original preview is untouched and still valid.


        **When to use.** Call this after you've reviewed the result of a preview
        and want to tighten the filters before importing. You can chain
        iterations — each iterate call returns a new `previewId` you can iterate
        on again.


        **Provider.** The new preview uses the SAME provider as the one being
        refined — you don't re-pick the provider. If the original preview used
        `AUTO`, the refined one also uses `AUTO` (the AI may still route to the
        same or a different provider, based on the combined query).


        **What you get back.** Same shape as `POST /v1/ai-finder/previews`, plus
        a `previousPreviewId` field pointing at the preview you refined. Use
        this new `previewId` with the iterate or import endpoint.

            > **Required scope:** `ACTIONS_WRITE`
            >
            > **Rate limit:** 10 requests per minute
      parameters:
        - schema:
            type: string
            description: The previewId returned by a prior preview or iterate call.
          required: true
          description: The previewId returned by a prior preview or iterate call.
          name: previewId
          in: path
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                feedback:
                  type: string
                  minLength: 1
                  maxLength: 2000
                  description: >-
                    Refinement instruction. Appended to the original query and
                    re-run through AI Finder. Examples: "focus on US only",
                    "exclude agencies", "narrow to 50-500 employees", "include
                    VP and SVP titles only". Returns a NEW `previewId`; the
                    prior preview stays cached and is still valid. 1–2000
                    characters.
              required:
                - feedback
            examples:
              narrow:
                summary: Narrow the prior preview
                value:
                  feedback: Focus on US companies only, exclude agencies
      responses:
        '201':
          description: Refined preview generated
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    enum:
                      - success
                  message:
                    type: string
                  data:
                    type: object
                    properties:
                      previewId:
                        type: string
                        format: uuid
                        description: >-
                          UUID that identifies this cached preview. Pass it as
                          the `{previewId}` path parameter on the iterate or
                          import endpoints. Valid for 24 hours after creation.
                      createdAt:
                        type: string
                        format: date-time
                        description: When this preview was generated (ISO-8601).
                      expiresAt:
                        type: string
                        format: date-time
                        description: >-
                          When this preview will be evicted from the cache (24h
                          after creation).
                      userInput:
                        type: string
                        description: >-
                          The exact preview input. For text-based previews this
                          is the natural-language query; for saved-filter
                          previews this identifies the saved filter that seeded
                          the preview. For iterated previews this includes the
                          original input plus all refinement feedback applied so
                          far.
                      requestedProvider:
                        type: string
                        enum:
                          - AUTO
                          - LINKEDIN
                          - CRM_CONTACTS
                          - CRM_COMPANIES
                          - STORELEADS
                          - CRUNCHBASE_COMPANIES
                          - CRUNCHBASE_CONTACTS
                          - CRUNCHBASE_INVESTORS
                          - THEIRSTACK_TECHNOLOGY
                          - THEIRSTACK_JOBS
                          - GOOGLE_MAPS
                        description: >-
                          The `provider` value you sent in the request (`AUTO`
                          if omitted). Useful for logging and debugging.
                      resolvedProvider:
                        type: string
                        enum:
                          - LINKEDIN
                          - CRM_CONTACTS
                          - CRM_COMPANIES
                          - STORELEADS
                          - CRUNCHBASE_COMPANIES
                          - CRUNCHBASE_CONTACTS
                          - CRUNCHBASE_INVESTORS
                          - THEIRSTACK_TECHNOLOGY
                          - THEIRSTACK_JOBS
                          - GOOGLE_MAPS
                        description: >-
                          The provider that actually ran. Always a concrete
                          value — never `AUTO`. If you passed `AUTO`, this tells
                          you which provider the router picked.
                      crmProvider:
                        type: string
                        enum:
                          - HUBSPOT
                          - SALESFORCE
                          - ZOHO
                          - DYNAMICS
                          - TRIBECRM
                          - ATTIO
                        description: >-
                          Only set when `resolvedProvider` is `CRM_CONTACTS` or
                          `CRM_COMPANIES`. The specific CRM used for the search
                          (HUBSPOT, SALESFORCE, DYNAMICS, ZOHO, TRIBECRM,
                          ATTIO), auto-detected from the client's configured
                          integrations.
                      entity:
                        type: string
                        enum:
                          - COMPANY
                          - CONTACT
                        description: >-
                          The entity (`COMPANY` or `CONTACT`) this preview
                          produced. Use this to decide which type of list to
                          pass to the import endpoint.
                      theirstackImportType:
                        type: string
                        enum:
                          - TECHNOLOGY
                          - JOBS
                        description: >-
                          Only set when `resolvedProvider` is
                          `THEIRSTACK_TECHNOLOGY` or `THEIRSTACK_JOBS`.
                          `TECHNOLOGY` = companies using a tech stack; `JOBS` =
                          companies hiring.
                      result:
                        type: object
                        additionalProperties: {}
                        description: >-
                          The generated search result. Always includes a
                          human-readable `title` and `reasoning`. The filter
                          shape depends on the provider: LinkedIn uses
                          `filtersByType` keyed by LinkedIn Sales Nav filter
                          IDs; CRM uses `filters` (an array of CRM property
                          filters); Crunchbase / StoreLeads / TheirStack /
                          Google Maps each use their own `filters` object.
                          Inspect this to understand what will be imported
                          before committing.
                      droppedFilters:
                        type: array
                        items:
                          type: string
                        description: >-
                          Qualifiers from your query that the AI explicitly said
                          it could NOT map onto the resolved provider (e.g.
                          "healthtech" when targeting Crunchbase CONTACTS, which
                          has no industry field) — extracted heuristically from
                          phrases like "omitted"/"cannot filter" in the AI
                          reasoning, and cross-checked against the values in
                          `result` so a term that WAS applied as a structured
                          filter is never listed here. If present, the returned
                          filters are less specific than your query asked for —
                          consider switching provider or tightening with the
                          iterate endpoint. Absence of this field does not
                          guarantee every qualifier was applied; it only reports
                          terms the AI reasoning called out as dropped.
                      previousPreviewId:
                        type: string
                        format: uuid
                        description: >-
                          Only set when this preview was produced via the
                          iterate endpoint. Points at the preview this one
                          refines. Builds an implicit chain you can walk back.
                      identityId:
                        type: number
                        description: >-
                          Only set for LinkedIn previews scoped to a specific
                          identity. Echoes the `identityId` you sent — the
                          import will run the LinkedIn search under this
                          identity (LinkedIn account).
                    required:
                      - previewId
                      - createdAt
                      - expiresAt
                      - userInput
                      - requestedProvider
                      - resolvedProvider
                      - result
                required:
                  - status
                  - message
                  - data
        '400':
          description: Validation error
        '404':
          description: Preview not found or expired
        '422':
          description: AI could not build a valid refined search
      security:
        - apiKey: []
components:
  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: x-api-key

````