{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/serpkite-com/json-schema/serpkite-com-monitor-update-request-schema.json",
  "title": "MonitorUpdateRequest",
  "description": "Only the fields sent change. Search fields are merged into the saved search; a changed search (or endpoint) makes the next run report every result as new.",
  "x-generated": "2026-10-31",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/serpkite-com-openapi.yaml#/components/schemas/MonitorUpdateRequest",
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "maxLength": 200
    },
    "interval": {
      "type": "string",
      "enum": [
        "hourly",
        "daily",
        "weekly"
      ]
    },
    "interval_seconds": {
      "type": "integer",
      "minimum": 3600,
      "maximum": 2592000
    },
    "webhook_url": {
      "type": "string",
      "description": "A webhook URL, or an empty string to remove it"
    },
    "active": {
      "type": "boolean",
      "description": "true resumes a paused monitor (due now, failure streak cleared)"
    },
    "metadata": {
      "type": [
        "object",
        "null"
      ],
      "additionalProperties": true,
      "description": "Replaces the metadata (null clears it)"
    },
    "endpoint": {
      "type": "string",
      "enum": [
        "search",
        "news",
        "webpage",
        "chatgpt",
        "gemini",
        "copilot",
        "ai_mode",
        "brave_ai"
      ],
      "description": "Switching between a search, a page and an AI prompt drops the other kinds' fields"
    },
    "q": {
      "type": "string",
      "minLength": 1,
      "maxLength": 2048
    },
    "prompt": {
      "type": "string",
      "minLength": 1,
      "maxLength": 4000
    },
    "web_search": {
      "type": "boolean"
    },
    "track": {
      "$ref": "#/$defs/TrackList"
    },
    "url": {
      "type": "string",
      "format": "uri",
      "description": "endpoint=webpage only"
    },
    "country": {
      "type": "string"
    },
    "language": {
      "type": "string"
    },
    "location": {
      "type": "string"
    },
    "time": {
      "type": "string",
      "enum": [
        "hour",
        "day",
        "week",
        "month",
        "year"
      ]
    },
    "num": {
      "type": "integer",
      "minimum": 1,
      "maximum": 100
    },
    "device": {
      "type": "string",
      "enum": [
        "desktop",
        "mobile"
      ]
    },
    "safe": {
      "type": "string",
      "enum": [
        "active",
        false
      ]
    },
    "include_domains": {
      "$ref": "#/$defs/DomainList"
    },
    "exclude_domains": {
      "$ref": "#/$defs/DomainList"
    },
    "engine": {
      "$ref": "#/$defs/EngineParam"
    }
  },
  "$defs": {
    "DomainList": {
      "description": "Domains as an array or a comma-separated string, at most 20: a host (`example.com`, subdomains match), a host with a path prefix (`github.com/org`) or a TLD (`.gov`).",
      "oneOf": [
        {
          "type": "string"
        },
        {
          "type": "array",
          "maxItems": 20,
          "items": {
            "type": "string"
          }
        }
      ]
    },
    "EngineParam": {
      "description": "Which search providers may answer. `google` (the default) is Google only; Google requests are retried internally before failing. `auto` allows falling back to other enabled providers, in route order, when Google is blocked or times out. A single other provider (`brave`) or a list (`[\"google\",\"brave\"]`, or `google,brave` in a query string) restricts the request to those providers. `meta.engine` always names the provider that answered and credits follow that provider's price. A key with \"Allow fallback to other search engines\" on treats a request without `engine` as `auto`. `consensus` (`/v1/search` only; 400 elsewhere, and it can't be combined with other names) queries several independent search indexes in parallel (at most one Bing-backed provider, so Yahoo or DuckDuckGo never count as agreeing with Bing), merges the results by URL and ranks them by how many providers returned each one. Each result lists its `sources`; `meta.engine` is `consensus` and `meta.route` lists every provider attempt. Up to three providers answer: a provider that fails or comes back empty hands its turn to the next one in the route. It stops once `num` unique results are in hand or after a few seconds, and costs the sum of one page at each provider that returned results (providers that failed, came back empty or were never started are free). `yandex` serves `/v1/search` from Yandex web search (no `time` filter or `safe: active`: a request naming it gets a 400 with them) and `/v1/maps`, `/v1/places` and `/v1/place` from Yandex Maps, where the deployment enables it (otherwise a 503 `unavailable`, not charged); with `auto` it is the last fallback there.",
      "oneOf": [
        {
          "type": "string",
          "default": "google"
        },
        {
          "type": "array",
          "items": {
            "$ref": "#/$defs/Provider"
          },
          "minItems": 1
        }
      ]
    },
    "Provider": {
      "type": "string",
      "description": "A search provider (docs/providers). Which verticals each serves depends on the deployment.",
      "enum": [
        "google",
        "brave",
        "bing",
        "yahoo",
        "duckduckgo",
        "mojeek",
        "wikipedia",
        "yandex"
      ]
    },
    "TrackList": {
      "type": "array",
      "maxItems": 20,
      "items": {
        "type": "string",
        "maxLength": 100
      },
      "description": "Brands (\"Acme\") and domains (\"acme.com\", subdomains match) to check the answer for; each comes back in `mentions`"
    }
  }
}