{
  "openapi": "3.0.1",
  "info": {
    "title": "AI Brand Watch - ChatGPT & LLM Brand Monitoring, AI Visibility",
    "description": "Know the day AI stops recommending you. AI visibility tracker and AI brand monitoring across ChatGPT, Claude, Perplexity & Gemini: share of voice vs competitors, brand visibility monitor, alerts only on real change (signed webhook). GEO/AEO audit, visibilityScore 0-100. $0.08/query, no subscription",
    "version": "0.1",
    "x-build-id": "YCdqoLsl7wTYZdRE5"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/desvela~brand-watch/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-desvela-brand-watch",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/acts/desvela~brand-watch/runs": {
      "post": {
        "operationId": "runs-sync-desvela-brand-watch",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor and returns information about the initiated run in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/runsResponseSchema"
                }
              }
            }
          }
        }
      }
    },
    "/acts/desvela~brand-watch/run-sync": {
      "post": {
        "operationId": "run-sync-desvela-brand-watch",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "inputSchema": {
        "type": "object",
        "required": [
          "brandName"
        ],
        "properties": {
          "brandName": {
            "title": "Brand name",
            "type": "string",
            "description": "The brand to track. Required."
          },
          "domain": {
            "title": "Own domain",
            "type": "string",
            "description": "Your brand's domain, e.g. \"desvela.ai\". Used to detect citations to your own site (ownDomainRate), to match the domain as a mention, and to feed the own-URL component of the visibility score. Optional."
          },
          "brandAliases": {
            "title": "Brand aliases",
            "type": "array",
            "description": "Other ways AI engines may refer to your brand (domain, alternative spellings).",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "competitors": {
            "title": "Competitors",
            "type": "array",
            "description": "Competitor brand names to track alongside yours.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "ownSources": {
            "title": "Your other sources (optional)",
            "type": "array",
            "description": "Pages that also count as your own when an AI cites them, besides your domain. A path works for shared platforms: \"apify.com/yourname\" counts apify.com/yourname/... as yours and not other people's pages on apify.com. E.g. your Store listing, GitHub org or docs site.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "competitorDomains": {
            "title": "Competitor domains",
            "type": "object",
            "description": "Competitor name → domain, e.g. {\"Coda\":\"coda.io\",\"ClickUp\":\"clickup.com\"}. Enables competitorCitationRate: which competitor the AI cites by URL (same matching as your own domain: www, subdomains, and an optional path such as apify.com/name). Without it the field is null.",
            "default": {}
          },
          "queries": {
            "title": "Category queries (optional)",
            "maxItems": 30,
            "type": "array",
            "description": "The 5-30 questions that define your category, e.g. \"best CRM for small business in Spain\". These are asked to each AI engine. Leave empty for zero-config: the actor reuses the frozen question set of a previous run, or discovers a new one for you.",
            "items": {
              "type": "string"
            }
          },
          "autoGenerateQueries": {
            "title": "Auto-generate extra queries",
            "type": "boolean",
            "description": "Only applies when you provide queries: also discover additional category questions and combine them (deduplicated, max 30). Without queries this is ignored — zero-config mode already discovers. Discovery is charged as one 'prompt-discovery' event ($0.04) only when it actually runs.",
            "default": false
          },
          "engines": {
            "title": "AI engines",
            "type": "array",
            "description": "Which AI answer engines to check.",
            "items": {
              "type": "string",
              "enum": [
                "openai",
                "perplexity",
                "anthropic",
                "gemini"
              ],
              "enumTitles": [
                "ChatGPT (OpenAI)",
                "Perplexity",
                "Claude (Anthropic)",
                "Gemini (Google)"
              ]
            },
            "default": [
              "openai",
              "perplexity"
            ]
          },
          "samplesPerQuery": {
            "title": "Samples per query",
            "minimum": 1,
            "maximum": 5,
            "type": "integer",
            "description": "AI answers vary between runs. We ask each question several times and report the mention rate (fraction of samples where the brand appeared) across samples. Example: present/absent/present → mentionRate = 0.67; a single sample would have given 0% or 100% arbitrarily. The price per query×engine covers all samples of the cell. IMPORTANT: 4 and 5 apply to Gemini only. ChatGPT and Claude are always measured at 3 samples, because they bill each web search separately and charge the page content they read as input tokens, which makes them roughly four times more expensive per sample at the same cell price. Perplexity is always measured with 1 sample: its repeated samples return the same web search (identical sources in 85 of 91 cells we measured), so more samples add cost, not information, and its alerts fire when that one answer starts or stops naming you. Every row reports the samples it actually used, and the run summary lists them per engine.",
            "default": 3
          },
          "webhookUrl": {
            "title": "Webhook URL (optional)",
            "type": "string",
            "description": "POST endpoint that receives a signed event when your brand visibility changes. Leave empty to only use the dataset."
          },
          "notifyOnlyOnChange": {
            "title": "Notify only on change",
            "type": "boolean",
            "description": "If enabled, the webhook fires only when something changed vs the previous run.",
            "default": true
          },
          "includeRecommendations": {
            "title": "GEO recommendations (paid add-on)",
            "type": "boolean",
            "description": "Generate 3-5 concrete GEO actions from this run's data (which sources each engine cites, where competitors win). Charged as one 'recommendation' event ($0.04) only when delivered.",
            "default": false
          },
          "includeSentiment": {
            "title": "Sentiment (paid add-on)",
            "type": "boolean",
            "description": "Label each measured cell as positive/neutral/negative toward your brand (one Claude Haiku call per cell, fed with the verbatim evidence). Charged as one 'sentiment' event ($0.04) per delivered cell — e.g. 20 cells add $0.80. Default off: existing runs cost exactly the same. Descriptor only, never triggers change alerts.",
            "default": false
          },
          "checkCitedPages": {
            "title": "Check cited pages (free, no AI calls)",
            "type": "boolean",
            "description": "After measuring, fetch the unique pages the engines cited or returned as sources (up to 400 per run, most-cited first) and report, per page, whether it names your brand (brandName, brandAliases or domain) and whether the cited source is dead (redirects to a different site or the domain no longer resolves). Per question you get how many third-party pages the engines rely on that do not name you: that is where to act. No extra charge and no AI API calls: only plain HTTP requests, which run after everything else is delivered and add up to 10 minutes. Requests identify as DesvelaCiteCheck and respect robots.txt, including rules written for DesvelaBot (desvela.dev/bot). Limitation: no browser, so content rendered by JavaScript is not seen; near-empty pages, errors and blocks are reported as unreadable, not as 'does not name you'. Default off: existing runs are unchanged.",
            "default": false
          },
          "citedPagesLanguage": {
            "title": "Language for cited-page checks",
            "type": "string",
            "description": "Accept-Language sent when fetching cited pages, so sites that vary by language serve your market's version, e.g. \"es-ES,es;q=0.9\". Only used with 'Check cited pages'. Default: en-US."
          },
          "promptSetAction": {
            "title": "Prompt set",
            "enum": [
              "keep",
              "renew"
            ],
            "type": "string",
            "description": "How to treat the frozen question set for this brand. 'keep' (default) reuses the previous run's questions and compares against them — the watch mode. 'renew' deliberately starts a fresh baseline with the questions you provide now; that run establishes a new baseline and produces no change alerts.",
            "default": "keep"
          }
        }
      },
      "runsResponseSchema": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "actId": {
                "type": "string"
              },
              "userId": {
                "type": "string"
              },
              "startedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "finishedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "status": {
                "type": "string",
                "example": "READY"
              },
              "meta": {
                "type": "object",
                "properties": {
                  "origin": {
                    "type": "string",
                    "example": "API"
                  },
                  "userAgent": {
                    "type": "string"
                  }
                }
              },
              "stats": {
                "type": "object",
                "properties": {
                  "inputBodyLen": {
                    "type": "integer",
                    "example": 2000
                  },
                  "rebootCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "restartCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "resurrectCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "computeUnits": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "options": {
                "type": "object",
                "properties": {
                  "build": {
                    "type": "string",
                    "example": "latest"
                  },
                  "timeoutSecs": {
                    "type": "integer",
                    "example": 300
                  },
                  "memoryMbytes": {
                    "type": "integer",
                    "example": 1024
                  },
                  "diskMbytes": {
                    "type": "integer",
                    "example": 2048
                  }
                }
              },
              "buildId": {
                "type": "string"
              },
              "defaultKeyValueStoreId": {
                "type": "string"
              },
              "defaultDatasetId": {
                "type": "string"
              },
              "defaultRequestQueueId": {
                "type": "string"
              },
              "buildNumber": {
                "type": "string",
                "example": "1.0.0"
              },
              "containerUrl": {
                "type": "string"
              },
              "usage": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "integer",
                    "example": 1
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "usageTotalUsd": {
                "type": "number",
                "example": 0.00005
              },
              "usageUsd": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "number",
                    "example": 0.00005
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}