{
  "openapi": "3.1.0",
  "info": {
    "title": "Foglift Public API",
    "version": "1.0.0",
    "description": "Public Technical Audit, AI Visibility, prompt, monitoring, and Sensor operations. See https://foglift.io/docs for guides and examples.",
    "contact": {
      "name": "Foglift",
      "url": "https://foglift.io/contact"
    }
  },
  "servers": [
    {
      "url": "https://foglift.io",
      "description": "Production"
    }
  ],
  "tags": [
    {
      "name": "Technical Audit"
    },
    {
      "name": "AI Visibility"
    },
    {
      "name": "Prompts"
    },
    {
      "name": "Sensor"
    }
  ],
  "paths": {
    "/api/v1/scan": {
      "get": {
        "operationId": "scanUrl",
        "summary": "Run a Technical Audit",
        "description": "Anonymous requests receive a limited report. API-key requests receive the full report and consume one scan token plus one API request.",
        "tags": [
          "Technical Audit"
        ],
        "security": [
          {},
          {
            "apiKey": []
          },
          {
            "bearerApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "url",
            "in": "query",
            "required": true,
            "description": "Absolute HTTP or HTTPS URL to audit.",
            "schema": {
              "type": "string",
              "format": "uri"
            }
          },
          {
            "name": "format",
            "in": "query",
            "required": false,
            "description": "Response format.",
            "schema": {
              "type": "string",
              "enum": [
                "json",
                "text"
              ],
              "default": "json"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "description": "Bypass a recent cached result.",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "force",
            "in": "query",
            "required": false,
            "description": "Legacy alias for refresh.",
            "schema": {
              "type": "boolean",
              "default": false,
              "deprecated": true
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Technical Audit result.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScanResponse"
                }
              },
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Request limit for the active window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in the active window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Used": {
                "description": "Requests used in the active window when emitted by this operation.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp when the active window resets when emitted by this operation.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request or brand disambiguation is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Invalid request or brand disambiguation is required.",
                  "code": "invalid_request_or_brand_required",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Missing or invalid API key.",
                  "code": "invalid_api_key",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "402": {
            "description": "The account has insufficient tokens.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "The account has insufficient tokens.",
                  "code": "insufficient_tokens",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "403": {
            "description": "The key cannot access this brand.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "The key cannot access this brand.",
                  "code": "workspace_access_denied",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "422": {
            "description": "The target blocked or could not be reached by the audit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "The target blocked or could not be reached by the audit.",
                  "code": "scan_unreachable",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "429": {
            "description": "API request limit exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "API request limit exceeded.",
                  "code": "rate_limit_exceeded",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Request limit for the active window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in the active window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Used": {
                "description": "Requests used in the active window when emitted by this operation.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp when the active window resets when emitted by this operation.",
                "schema": {
                  "type": "integer"
                }
              },
              "Retry-After": {
                "description": "Seconds until the request can be retried.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Foglift could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Foglift could not complete the request.",
                  "code": "internal_error",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "503": {
            "description": "The audit service is temporarily unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "The audit service is temporarily unavailable.",
                  "code": "service_unavailable",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/scan/batch": {
      "post": {
        "operationId": "scanUrlBatch",
        "summary": "Audit up to 10 URLs",
        "tags": [
          "Technical Audit"
        ],
        "security": [
          {
            "apiKey": []
          },
          {
            "bearerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "urls"
                ],
                "properties": {
                  "urls": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 10,
                    "items": {
                      "type": "string",
                      "format": "uri"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Per-URL results and a success/failure summary.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BatchScanResponse"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Request limit for the active window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in the active window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Used": {
                "description": "Requests used in the active window when emitted by this operation.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp when the active window resets when emitted by this operation.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request or brand disambiguation is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Invalid request or brand disambiguation is required.",
                  "code": "invalid_request_or_brand_required",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Missing or invalid API key.",
                  "code": "invalid_api_key",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include batch audits.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "The plan does not include batch audits.",
                  "code": "plan_upgrade_required",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "403": {
            "description": "The key cannot access this brand.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "The key cannot access this brand.",
                  "code": "workspace_access_denied",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "429": {
            "description": "API request limit exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "API request limit exceeded.",
                  "code": "rate_limit_exceeded",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Request limit for the active window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in the active window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Used": {
                "description": "Requests used in the active window when emitted by this operation.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp when the active window resets when emitted by this operation.",
                "schema": {
                  "type": "integer"
                }
              },
              "Retry-After": {
                "description": "Seconds until the request can be retried.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Foglift could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Foglift could not complete the request.",
                  "code": "internal_error",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/scan/sitemap": {
      "post": {
        "operationId": "scanSitemap",
        "summary": "Audit pages discovered from a sitemap",
        "tags": [
          "Technical Audit"
        ],
        "security": [
          {
            "bearerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "url"
                ],
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri"
                  },
                  "limit": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 25,
                    "default": 25
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Sitemap audit rollup and page results.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SitemapScanResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request or brand disambiguation is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Invalid request or brand disambiguation is required.",
                  "code": "invalid_request_or_brand_required",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Missing or invalid API key.",
                  "code": "invalid_api_key",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not include sitemap audits.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "The plan does not include sitemap audits.",
                  "code": "plan_upgrade_required",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "403": {
            "description": "The key cannot access this brand.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "The key cannot access this brand.",
                  "code": "workspace_access_denied",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "404": {
            "description": "No sitemap could be discovered.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "No sitemap could be discovered.",
                  "code": "sitemap_not_found",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "429": {
            "description": "API request limit exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "API request limit exceeded.",
                  "code": "rate_limit_exceeded",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Request limit for the active window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in the active window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Used": {
                "description": "Requests used in the active window when emitted by this operation.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp when the active window resets when emitted by this operation.",
                "schema": {
                  "type": "integer"
                }
              },
              "Retry-After": {
                "description": "Seconds until the request can be retried.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Foglift could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Foglift could not complete the request.",
                  "code": "internal_error",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/ai-visibility": {
      "post": {
        "operationId": "runAiVisibilityCheck",
        "summary": "Run an AI Visibility Check",
        "description": "Costs prompt count × the sum of selected engine token costs and consumes one API request. Omit prompts to use saved prompts.",
        "tags": [
          "AI Visibility"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "prompts": {
                    "type": "array",
                    "maxItems": 20,
                    "items": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 1000
                    }
                  },
                  "prompt": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 1000
                  },
                  "models": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/EngineId"
                    },
                    "uniqueItems": true
                  },
                  "domain": {
                    "type": "string"
                  },
                  "brand": {
                    "type": "string"
                  },
                  "brand_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "workspace_id": {
                    "type": "string",
                    "format": "uuid",
                    "deprecated": true
                  },
                  "dry_run": {
                    "type": "boolean",
                    "default": false
                  },
                  "persist_unmatched_prompts": {
                    "type": "boolean",
                    "default": false
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Completed AI Visibility Check.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AiVisibilityResponse"
                }
              }
            }
          },
          "202": {
            "description": "The provider work is still in flight.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AsyncAcceptedResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request or brand disambiguation is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Invalid request or brand disambiguation is required.",
                  "code": "invalid_request_or_brand_required",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Missing or invalid API key.",
                  "code": "invalid_api_key",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "402": {
            "description": "The account has insufficient tokens for prompt count × selected engine costs.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "The account has insufficient tokens for prompt count × selected engine costs.",
                  "code": "insufficient_tokens",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "403": {
            "description": "The key cannot access this brand.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "The key cannot access this brand.",
                  "code": "workspace_access_denied",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "429": {
            "description": "API request limit exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "API request limit exceeded.",
                  "code": "rate_limit_exceeded",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Request limit for the active window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in the active window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Used": {
                "description": "Requests used in the active window when emitted by this operation.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp when the active window resets when emitted by this operation.",
                "schema": {
                  "type": "integer"
                }
              },
              "Retry-After": {
                "description": "Seconds until the request can be retried.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Foglift could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Foglift could not complete the request.",
                  "code": "internal_error",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "503": {
            "description": "A provider or spend guard is temporarily unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "A provider or spend guard is temporarily unavailable.",
                  "code": "service_unavailable",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/ai-visibility/results": {
      "get": {
        "operationId": "listAiVisibilityResults",
        "summary": "List AI Visibility results",
        "tags": [
          "AI Visibility"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "brand_id",
            "in": "query",
            "required": false,
            "description": "Brand workspace ID. Required when the account has multiple brands.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "workspace_id",
            "in": "query",
            "required": false,
            "description": "Legacy alias for brand_id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "deprecated": true
            }
          },
          {
            "name": "days",
            "in": "query",
            "required": false,
            "description": "Lookback window.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 90,
              "default": 7
            }
          },
          {
            "name": "model",
            "in": "query",
            "required": false,
            "description": "Filter by engine.",
            "schema": {
              "$ref": "#/components/schemas/EngineId"
            }
          },
          {
            "name": "prompt",
            "in": "query",
            "required": false,
            "description": "Case-insensitive prompt substring.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "include",
            "in": "query",
            "required": false,
            "description": "Comma-separated optional fields. Use response_text to include answer text.",
            "schema": {
              "type": "string",
              "example": "response_text"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum records to return.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "Zero-based result offset.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Results, rollups, and pagination.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedResultsResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request or brand disambiguation is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Invalid request or brand disambiguation is required.",
                  "code": "invalid_request_or_brand_required",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Missing or invalid API key.",
                  "code": "invalid_api_key",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "403": {
            "description": "The key cannot access this brand.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "The key cannot access this brand.",
                  "code": "workspace_access_denied",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "500": {
            "description": "Foglift could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Foglift could not complete the request.",
                  "code": "internal_error",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/results/{result_id}/trace": {
      "get": {
        "operationId": "getSearchTrace",
        "summary": "Get a result's Search Trace",
        "description": "Returns tenant-scoped search evidence retained for 90 days. ChatGPT can expose ordered queries, retrieved pages, citation labels, answer brands, and a coverage-aware 30-day prompt rollup. Claude, Perplexity, and Google AI Overview expose ordered returned queries without page evidence. Gemini does not support Search Trace. Free API keys receive only the result status and captured step count; Launch and higher plans receive the full trace. Reading a stored trace does not start an AI Visibility Check.",
        "tags": [
          "AI Visibility"
        ],
        "security": [
          {
            "apiKey": []
          },
          {
            "bearerApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "result_id",
            "in": "path",
            "required": true,
            "description": "AI Visibility result UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "brand_id",
            "in": "query",
            "required": false,
            "description": "Brand workspace ID. Required when the account has multiple brands.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "workspace_id",
            "in": "query",
            "required": false,
            "description": "Legacy alias for brand_id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "deprecated": true
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Search Trace evidence or the Free locked preview.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SearchTraceResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request or brand disambiguation is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Invalid request or brand disambiguation is required.",
                  "code": "invalid_request_or_brand_required",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Missing or invalid API key.",
                  "code": "invalid_api_key",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "403": {
            "description": "The key cannot access this brand.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "The key cannot access this brand.",
                  "code": "workspace_access_denied",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "404": {
            "description": "The result does not exist for the resolved brand.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "The result does not exist for the resolved brand.",
                  "code": "not_found",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "500": {
            "description": "Foglift could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Foglift could not complete the request.",
                  "code": "internal_error",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/prompts": {
      "get": {
        "operationId": "listPrompts",
        "summary": "List tracked prompts",
        "tags": [
          "Prompts"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "brand_id",
            "in": "query",
            "required": false,
            "description": "Brand workspace ID. Required when the account has multiple brands.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "workspace_id",
            "in": "query",
            "required": false,
            "description": "Legacy alias for brand_id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "deprecated": true
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Tracked prompts and effective cadence.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PromptListResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request or brand disambiguation is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Invalid request or brand disambiguation is required.",
                  "code": "invalid_request_or_brand_required",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Missing or invalid API key.",
                  "code": "invalid_api_key",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "403": {
            "description": "The key cannot access this brand.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "The key cannot access this brand.",
                  "code": "workspace_access_denied",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "500": {
            "description": "Foglift could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Foglift could not complete the request.",
                  "code": "internal_error",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "createPrompts",
        "summary": "Create tracked prompts",
        "tags": [
          "Prompts"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Optional replay-safe request key.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "prompts"
                ],
                "properties": {
                  "prompts": {
                    "type": "array",
                    "maxItems": 50,
                    "items": {
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "text"
                      ],
                      "properties": {
                        "text": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 500
                        },
                        "category": {
                          "type": "string",
                          "enum": [
                            "brand",
                            "product",
                            "comparison",
                            "industry",
                            "review",
                            "local"
                          ]
                        },
                        "analysis_type": {
                          "type": "string",
                          "enum": [
                            "visibility",
                            "sentiment"
                          ]
                        },
                        "language": {
                          "type": "string",
                          "description": "BCP-47 language tag."
                        },
                        "region": {
                          "type": "string",
                          "maxLength": 80
                        },
                        "engine_set": {
                          "type": [
                            "array",
                            "null"
                          ],
                          "items": {
                            "$ref": "#/components/schemas/EngineId"
                          },
                          "uniqueItems": true
                        },
                        "tags": {
                          "oneOf": [
                            {
                              "type": "array",
                              "maxItems": 12,
                              "items": {
                                "type": "string"
                              }
                            },
                            {
                              "type": "string",
                              "description": "Comma-separated tags (maximum 12)."
                            }
                          ]
                        }
                      }
                    }
                  },
                  "brand_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "workspace_id": {
                    "type": "string",
                    "format": "uuid",
                    "deprecated": true
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created and de-duplicated prompts.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PromptMutationResponse"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Request limit for the active window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in the active window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Used": {
                "description": "Requests used in the active window when emitted by this operation.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp when the active window resets when emitted by this operation.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request or brand disambiguation is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Invalid request or brand disambiguation is required.",
                  "code": "invalid_request_or_brand_required",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Missing or invalid API key.",
                  "code": "invalid_api_key",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "403": {
            "description": "The key cannot access this brand.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "The key cannot access this brand.",
                  "code": "workspace_access_denied",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency key conflict.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Idempotency key conflict.",
                  "code": "idempotency_conflict",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "429": {
            "description": "API request limit exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "API request limit exceeded.",
                  "code": "rate_limit_exceeded",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Request limit for the active window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in the active window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Used": {
                "description": "Requests used in the active window when emitted by this operation.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp when the active window resets when emitted by this operation.",
                "schema": {
                  "type": "integer"
                }
              },
              "Retry-After": {
                "description": "Seconds until the request can be retried.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Foglift could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Foglift could not complete the request.",
                  "code": "internal_error",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deletePrompt",
        "summary": "Soft-delete a tracked prompt",
        "tags": [
          "Prompts"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "prompt_id"
                ],
                "properties": {
                  "prompt_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "brand_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "workspace_id": {
                    "type": "string",
                    "format": "uuid",
                    "deprecated": true
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Prompt deleted.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "deleted",
                    "prompt_id"
                  ],
                  "properties": {
                    "deleted": {
                      "const": true
                    },
                    "prompt_id": {
                      "type": "string",
                      "format": "uuid"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request or brand disambiguation is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Invalid request or brand disambiguation is required.",
                  "code": "invalid_request_or_brand_required",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Missing or invalid API key.",
                  "code": "invalid_api_key",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "403": {
            "description": "The key cannot access this brand.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "The key cannot access this brand.",
                  "code": "workspace_access_denied",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "404": {
            "description": "Prompt not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Prompt not found.",
                  "code": "prompt_not_found",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "500": {
            "description": "Foglift could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Foglift could not complete the request.",
                  "code": "internal_error",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/models": {
      "get": {
        "operationId": "listModels",
        "summary": "List enabled AI engines",
        "tags": [
          "AI Visibility"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Enabled and available engine configuration.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ModelsResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request or brand disambiguation is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Invalid request or brand disambiguation is required.",
                  "code": "invalid_request_or_brand_required",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Missing or invalid API key.",
                  "code": "invalid_api_key",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "403": {
            "description": "The key cannot access this brand.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "The key cannot access this brand.",
                  "code": "workspace_access_denied",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "500": {
            "description": "Foglift could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Foglift could not complete the request.",
                  "code": "internal_error",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "updateModels",
        "summary": "Update enabled AI engines",
        "tags": [
          "AI Visibility"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "enabled_models": {
                    "type": "object",
                    "additionalProperties": false,
                    "properties": {
                      "chatgpt": {
                        "type": "boolean"
                      },
                      "ai-overview": {
                        "type": "boolean"
                      },
                      "gemini": {
                        "type": "boolean"
                      },
                      "claude": {
                        "type": "boolean"
                      },
                      "perplexity": {
                        "type": "boolean"
                      }
                    }
                  },
                  "monitoring_frequency": {
                    "type": "string",
                    "enum": [
                      "manual",
                      "monthly",
                      "weekly",
                      "daily",
                      "twice_daily",
                      "hourly"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated engine configuration.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ModelsUpdateResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request or brand disambiguation is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Invalid request or brand disambiguation is required.",
                  "code": "invalid_request_or_brand_required",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Missing or invalid API key.",
                  "code": "invalid_api_key",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "403": {
            "description": "The key cannot access this brand.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "The key cannot access this brand.",
                  "code": "workspace_access_denied",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "500": {
            "description": "Foglift could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Foglift could not complete the request.",
                  "code": "internal_error",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/sentiment": {
      "get": {
        "operationId": "getSentiment",
        "summary": "Get brand sentiment",
        "tags": [
          "AI Visibility"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "brand_id",
            "in": "query",
            "required": false,
            "description": "Brand workspace ID. Required when the account has multiple brands.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "workspace_id",
            "in": "query",
            "required": false,
            "description": "Legacy alias for brand_id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "deprecated": true
            }
          },
          {
            "name": "days",
            "in": "query",
            "required": false,
            "description": "Lookback window.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 90,
              "default": 30
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sentiment summary and evidence.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SentimentResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request or brand disambiguation is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Invalid request or brand disambiguation is required.",
                  "code": "invalid_request_or_brand_required",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Missing or invalid API key.",
                  "code": "invalid_api_key",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "403": {
            "description": "The key cannot access this brand.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "The key cannot access this brand.",
                  "code": "workspace_access_denied",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "500": {
            "description": "Foglift could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Foglift could not complete the request.",
                  "code": "internal_error",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/history": {
      "get": {
        "operationId": "listHistory",
        "summary": "List historical AI answers",
        "tags": [
          "AI Visibility"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "brand_id",
            "in": "query",
            "required": false,
            "description": "Brand workspace ID. Required when the account has multiple brands.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "workspace_id",
            "in": "query",
            "required": false,
            "description": "Legacy alias for brand_id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "deprecated": true
            }
          },
          {
            "name": "prompt_id",
            "in": "query",
            "required": false,
            "description": "Filter by tracked prompt.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "model",
            "in": "query",
            "required": false,
            "description": "Filter by engine.",
            "schema": {
              "$ref": "#/components/schemas/EngineId"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum records.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "Zero-based offset.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Historical result rows and pagination.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HistoryResponse"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Request limit for the active window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in the active window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Used": {
                "description": "Requests used in the active window when emitted by this operation.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp when the active window resets when emitted by this operation.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request or brand disambiguation is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Invalid request or brand disambiguation is required.",
                  "code": "invalid_request_or_brand_required",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Missing or invalid API key.",
                  "code": "invalid_api_key",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "403": {
            "description": "The key cannot access this brand.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "The key cannot access this brand.",
                  "code": "workspace_access_denied",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "429": {
            "description": "API request limit exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "API request limit exceeded.",
                  "code": "rate_limit_exceeded",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Request limit for the active window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in the active window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Used": {
                "description": "Requests used in the active window when emitted by this operation.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp when the active window resets when emitted by this operation.",
                "schema": {
                  "type": "integer"
                }
              },
              "Retry-After": {
                "description": "Seconds until the request can be retried.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Foglift could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Foglift could not complete the request.",
                  "code": "internal_error",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/monitor": {
      "get": {
        "operationId": "getMonitorSummary",
        "summary": "Get monitoring summary",
        "tags": [
          "AI Visibility"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "brand_id",
            "in": "query",
            "required": false,
            "description": "Brand workspace ID. Required when the account has multiple brands.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "workspace_id",
            "in": "query",
            "required": false,
            "description": "Legacy alias for brand_id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "deprecated": true
            }
          },
          {
            "name": "period",
            "in": "query",
            "required": false,
            "description": "Summary period.",
            "schema": {
              "type": "string",
              "enum": [
                "7d",
                "14d",
                "30d"
              ],
              "default": "7d"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Monitoring trends and summary.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MonitorResponse"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Request limit for the active window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in the active window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Used": {
                "description": "Requests used in the active window when emitted by this operation.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp when the active window resets when emitted by this operation.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request or brand disambiguation is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Invalid request or brand disambiguation is required.",
                  "code": "invalid_request_or_brand_required",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Missing or invalid API key.",
                  "code": "invalid_api_key",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "403": {
            "description": "The key cannot access this brand.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "The key cannot access this brand.",
                  "code": "workspace_access_denied",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "429": {
            "description": "API request limit exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "API request limit exceeded.",
                  "code": "rate_limit_exceeded",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Request limit for the active window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in the active window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Used": {
                "description": "Requests used in the active window when emitted by this operation.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp when the active window resets when emitted by this operation.",
                "schema": {
                  "type": "integer"
                }
              },
              "Retry-After": {
                "description": "Seconds until the request can be retried.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Foglift could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Foglift could not complete the request.",
                  "code": "internal_error",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/sensor/verify": {
      "get": {
        "operationId": "verifySensor",
        "summary": "Verify Sensor installation",
        "tags": [
          "Sensor"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Installation and receiving-data signals.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SensorVerifyResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request or brand disambiguation is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Invalid request or brand disambiguation is required.",
                  "code": "invalid_request_or_brand_required",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Missing or invalid API key.",
                  "code": "invalid_api_key",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "403": {
            "description": "The key cannot access this brand.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "The key cannot access this brand.",
                  "code": "workspace_access_denied",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "500": {
            "description": "Foglift could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Foglift could not complete the request.",
                  "code": "internal_error",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/crawler-analytics": {
      "get": {
        "operationId": "getCrawlerAnalytics",
        "summary": "Get AI crawler analytics",
        "tags": [
          "Sensor"
        ],
        "security": [
          {
            "apiKey": []
          },
          {
            "bearerApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "brand_id",
            "in": "query",
            "required": false,
            "description": "Brand workspace ID. Required when the account has multiple brands.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "workspace_id",
            "in": "query",
            "required": false,
            "description": "Legacy alias for brand_id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "deprecated": true
            }
          },
          {
            "name": "days",
            "in": "query",
            "required": false,
            "description": "Lookback window.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 365,
              "default": 30
            }
          },
          {
            "name": "range",
            "in": "query",
            "required": false,
            "description": "Use hourly buckets for the last 24 hours.",
            "schema": {
              "type": "string",
              "enum": [
                "24h"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Crawler analytics grouped by agent, path, and time.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CrawlerAnalyticsResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request or brand disambiguation is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Invalid request or brand disambiguation is required.",
                  "code": "invalid_request_or_brand_required",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Missing or invalid API key.",
                  "code": "invalid_api_key",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "403": {
            "description": "The key cannot access this brand.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "The key cannot access this brand.",
                  "code": "workspace_access_denied",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "500": {
            "description": "Foglift could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Foglift could not complete the request.",
                  "code": "internal_error",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "ingestCrawlerVisit",
        "summary": "Record a recognized crawler visit",
        "description": "Use X-API-Key, or provide the workspace-bound public token as brand_id (legacy workspace_id) together with a matching hostname and a timestamp no more than 24 hours old.",
        "tags": [
          "Sensor"
        ],
        "security": [
          {
            "apiKey": []
          },
          {
            "sensorPublicToken": []
          }
        ],
        "parameters": [
          {
            "name": "brand_id",
            "in": "query",
            "required": false,
            "description": "Public Sensor token. The same value may be supplied in the JSON body.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "workspace_id",
            "in": "query",
            "required": false,
            "description": "Legacy alias for brand_id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "deprecated": true
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "path",
                  "userAgent"
                ],
                "properties": {
                  "brand_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "workspace_id": {
                    "type": "string",
                    "format": "uuid",
                    "deprecated": true
                  },
                  "hostname": {
                    "type": "string"
                  },
                  "path": {
                    "type": "string"
                  },
                  "userAgent": {
                    "type": "string"
                  },
                  "source": {
                    "type": "string",
                    "enum": [
                      "crawler",
                      "referrer"
                    ]
                  },
                  "crawler": {
                    "type": "string"
                  },
                  "engine": {
                    "type": "string"
                  },
                  "category": {
                    "type": "string"
                  },
                  "referrerEngine": {
                    "type": "string"
                  },
                  "referrerHost": {
                    "type": "string"
                  },
                  "source_hint": {
                    "type": "string",
                    "enum": [
                      "utm"
                    ]
                  },
                  "timestamp": {
                    "type": "string",
                    "format": "date-time"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Visit accepted or de-duplicated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SensorIngestResponse"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Request limit for the active window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in the active window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Used": {
                "description": "Requests used in the active window when emitted by this operation.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp when the active window resets when emitted by this operation.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request or brand disambiguation is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Invalid request or brand disambiguation is required.",
                  "code": "invalid_request_or_brand_required",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Missing or invalid API key.",
                  "code": "invalid_api_key",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "403": {
            "description": "The key cannot access this brand.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "The key cannot access this brand.",
                  "code": "workspace_access_denied",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "429": {
            "description": "API request limit exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "API request limit exceeded.",
                  "code": "rate_limit_exceeded",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Request limit for the active window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in the active window.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Used": {
                "description": "Requests used in the active window when emitted by this operation.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp when the active window resets when emitted by this operation.",
                "schema": {
                  "type": "integer"
                }
              },
              "Retry-After": {
                "description": "Seconds until the request can be retried.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Foglift could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Foglift could not complete the request.",
                  "code": "internal_error",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "503": {
            "description": "Sensor persistence is temporarily unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Sensor persistence is temporarily unavailable.",
                  "code": "service_unavailable",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/referrer-analytics": {
      "get": {
        "operationId": "getReferrerAnalytics",
        "summary": "Get AI referral analytics",
        "tags": [
          "Sensor"
        ],
        "security": [
          {
            "apiKey": []
          },
          {
            "bearerApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "brand_id",
            "in": "query",
            "required": false,
            "description": "Brand workspace ID. Required when the account has multiple brands.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "workspace_id",
            "in": "query",
            "required": false,
            "description": "Legacy alias for brand_id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "deprecated": true
            }
          },
          {
            "name": "days",
            "in": "query",
            "required": false,
            "description": "Lookback window.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 365,
              "default": 30
            }
          },
          {
            "name": "range",
            "in": "query",
            "required": false,
            "description": "Use hourly buckets for the last 24 hours.",
            "schema": {
              "type": "string",
              "enum": [
                "24h"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "AI referral visits grouped by engine, landing page, and time.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReferrerAnalyticsResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request or brand disambiguation is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Invalid request or brand disambiguation is required.",
                  "code": "invalid_request_or_brand_required",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Missing or invalid API key.",
                  "code": "invalid_api_key",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "403": {
            "description": "The key cannot access this brand.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "The key cannot access this brand.",
                  "code": "workspace_access_denied",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          },
          "500": {
            "description": "Foglift could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": "Foglift could not complete the request.",
                  "code": "internal_error",
                  "docs_url": "https://foglift.io/docs/api-errors",
                  "request_id": "req_example"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "apiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key",
        "description": "Foglift API key beginning with sk_fog_."
      },
      "bearerApiKey": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "sk_fog_…",
        "description": "Foglift API key in the Authorization header."
      },
      "sensorPublicToken": {
        "type": "apiKey",
        "in": "query",
        "name": "brand_id",
        "description": "Workspace-bound public Sensor token. JSON-body brand_id is also accepted when hostname and timestamp validation succeeds."
      }
    },
    "schemas": {
      "EngineId": {
        "type": "string",
        "enum": [
          "chatgpt",
          "perplexity",
          "ai-overview",
          "gemini",
          "claude"
        ]
      },
      "ModelConfiguration": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "name",
          "enabled"
        ],
        "properties": {
          "id": {
            "$ref": "#/components/schemas/EngineId"
          },
          "name": {
            "type": "string"
          },
          "enabled": {
            "type": "boolean"
          }
        }
      },
      "ModelsResponse": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "models",
          "monitoring_frequency",
          "available_frequencies"
        ],
        "properties": {
          "models": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ModelConfiguration"
            }
          },
          "monitoring_frequency": {
            "type": "string"
          },
          "available_frequencies": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          }
        }
      },
      "ModelsUpdateResponse": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "updated",
          "models",
          "monitoring_frequency"
        ],
        "properties": {
          "updated": {
            "const": true
          },
          "models": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ModelConfiguration"
            }
          },
          "monitoring_frequency": {
            "type": "string"
          }
        }
      },
      "WorkspaceSummary": {
        "type": "object",
        "required": [
          "id",
          "domain"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "domain": {
            "type": "string"
          }
        }
      },
      "SearchTraceWorkspace": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "name",
          "domain"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "domain": {
            "type": "string"
          }
        }
      },
      "SearchTraceLockedAccess": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "locked",
          "required_plan",
          "upgrade_url"
        ],
        "properties": {
          "locked": {
            "const": true
          },
          "required_plan": {
            "const": "launch"
          },
          "upgrade_url": {
            "type": "string",
            "format": "uri",
            "const": "https://foglift.io/pricing"
          }
        }
      },
      "SearchTraceUnlockedAccess": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "locked",
          "required_plan"
        ],
        "properties": {
          "locked": {
            "const": false
          },
          "required_plan": {
            "const": "launch"
          }
        }
      },
      "SearchTracePreview": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "status",
          "step_count"
        ],
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "available",
              "unavailable",
              "expired"
            ]
          },
          "step_count": {
            "type": "integer",
            "minimum": 0
          }
        }
      },
      "SearchTraceSource": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "url",
          "domain",
          "rank",
          "cited",
          "is_own_site",
          "page_type"
        ],
        "properties": {
          "url": {
            "type": "string",
            "format": "uri"
          },
          "domain": {
            "type": "string"
          },
          "rank": {
            "type": "integer",
            "minimum": 1
          },
          "cited": {
            "type": "boolean"
          },
          "is_own_site": {
            "type": "boolean"
          },
          "page_type": {
            "type": "string",
            "enum": [
              "first_party",
              "community_review",
              "listicle_comparison",
              "other"
            ]
          }
        }
      },
      "SearchTraceStep": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "step",
          "search_call_index",
          "search_call_id",
          "queries",
          "sources"
        ],
        "properties": {
          "step": {
            "type": "integer",
            "minimum": 1
          },
          "search_call_index": {
            "type": "integer",
            "minimum": 0
          },
          "search_call_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "queries": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SearchTraceSource"
            }
          }
        }
      },
      "SearchTraceResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "prompt_id",
          "prompt",
          "engine",
          "run_at"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "prompt_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "prompt": {
            "type": [
              "string",
              "null"
            ]
          },
          "engine": {
            "type": "string"
          },
          "run_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "SearchTraceAnswer": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "text",
          "citations",
          "brands_named"
        ],
        "properties": {
          "text": {
            "type": [
              "string",
              "null"
            ]
          },
          "citations": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uri"
            }
          },
          "brands_named": {
            "type": "array",
            "uniqueItems": true,
            "items": {
              "type": "string"
            }
          }
        }
      },
      "SearchTraceRunRollup": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "pages_read",
          "own_pages_read",
          "own_pages_cited",
          "step_one_brands"
        ],
        "properties": {
          "pages_read": {
            "type": "integer",
            "minimum": 0
          },
          "own_pages_read": {
            "type": "integer",
            "minimum": 0
          },
          "own_pages_cited": {
            "type": "integer",
            "minimum": 0
          },
          "step_one_brands": {
            "type": "array",
            "uniqueItems": true,
            "items": {
              "type": "string"
            }
          }
        }
      },
      "SearchTrace": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "status",
          "retention_days",
          "expires_at",
          "result",
          "steps",
          "answer",
          "rollup"
        ],
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "available",
              "unavailable",
              "expired"
            ]
          },
          "retention_days": {
            "const": 90
          },
          "expires_at": {
            "type": "string",
            "format": "date-time"
          },
          "result": {
            "$ref": "#/components/schemas/SearchTraceResult"
          },
          "steps": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SearchTraceStep"
            }
          },
          "answer": {
            "$ref": "#/components/schemas/SearchTraceAnswer"
          },
          "rollup": {
            "$ref": "#/components/schemas/SearchTraceRunRollup"
          }
        }
      },
      "SearchTracePromptRollup": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "status",
          "window_days",
          "since",
          "through",
          "prompt_id",
          "coverage",
          "step_one_competitors",
          "top_domains",
          "own_site"
        ],
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "available",
              "unavailable"
            ]
          },
          "window_days": {
            "const": 30
          },
          "since": {
            "type": "string",
            "format": "date-time"
          },
          "through": {
            "type": "string",
            "format": "date-time"
          },
          "prompt_id": {
            "type": "string",
            "format": "uuid"
          },
          "coverage": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "chatgpt_runs",
              "trace_runs",
              "step_one_query_runs"
            ],
            "properties": {
              "chatgpt_runs": {
                "type": "integer",
                "minimum": 0
              },
              "trace_runs": {
                "type": "integer",
                "minimum": 0
              },
              "step_one_query_runs": {
                "type": "integer",
                "minimum": 0
              }
            }
          },
          "step_one_competitors": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "competitor",
                "run_count",
                "run_rate"
              ],
              "properties": {
                "competitor": {
                  "type": "string"
                },
                "run_count": {
                  "type": "integer",
                  "minimum": 0
                },
                "run_rate": {
                  "type": "number",
                  "minimum": 0,
                  "maximum": 1
                }
              }
            }
          },
          "top_domains": {
            "type": "array",
            "maxItems": 10,
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "domain",
                "pages_read",
                "cited_pages",
                "cite_rate"
              ],
              "properties": {
                "domain": {
                  "type": "string"
                },
                "pages_read": {
                  "type": "integer",
                  "minimum": 0
                },
                "cited_pages": {
                  "type": "integer",
                  "minimum": 0
                },
                "cite_rate": {
                  "type": "number",
                  "minimum": 0,
                  "maximum": 1
                }
              }
            }
          },
          "own_site": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "read_and_named_runs",
              "read_not_named_runs",
              "not_read_named_runs",
              "not_read_not_named_runs"
            ],
            "properties": {
              "read_and_named_runs": {
                "type": "integer",
                "minimum": 0
              },
              "read_not_named_runs": {
                "type": "integer",
                "minimum": 0
              },
              "not_read_named_runs": {
                "type": "integer",
                "minimum": 0
              },
              "not_read_not_named_runs": {
                "type": "integer",
                "minimum": 0
              }
            }
          }
        }
      },
      "SearchTraceLockedResponse": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "workspace",
          "access",
          "preview",
          "trace",
          "prompt_rollup"
        ],
        "properties": {
          "workspace": {
            "$ref": "#/components/schemas/SearchTraceWorkspace"
          },
          "access": {
            "$ref": "#/components/schemas/SearchTraceLockedAccess"
          },
          "preview": {
            "$ref": "#/components/schemas/SearchTracePreview"
          },
          "trace": {
            "type": "null"
          },
          "prompt_rollup": {
            "type": "null"
          }
        }
      },
      "SearchTraceUnlockedResponse": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "workspace",
          "access",
          "preview",
          "trace",
          "prompt_rollup"
        ],
        "properties": {
          "workspace": {
            "$ref": "#/components/schemas/SearchTraceWorkspace"
          },
          "access": {
            "$ref": "#/components/schemas/SearchTraceUnlockedAccess"
          },
          "preview": {
            "type": "null"
          },
          "trace": {
            "$ref": "#/components/schemas/SearchTrace"
          },
          "prompt_rollup": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/SearchTracePromptRollup"
              },
              {
                "type": "null"
              }
            ]
          }
        }
      },
      "SearchTraceResponse": {
        "oneOf": [
          {
            "$ref": "#/components/schemas/SearchTraceUnlockedResponse"
          },
          {
            "$ref": "#/components/schemas/SearchTraceLockedResponse"
          }
        ]
      },
      "SentimentResponse": {
        "type": "object",
        "required": [
          "workspace",
          "has_data",
          "overall_sentiment",
          "overall_label",
          "daily_trend",
          "by_engine",
          "by_prompt",
          "alerts"
        ],
        "properties": {
          "workspace": {
            "$ref": "#/components/schemas/WorkspaceSummary"
          },
          "has_data": {
            "type": "boolean"
          },
          "overall_sentiment": {
            "type": "number",
            "minimum": -1,
            "maximum": 1
          },
          "overall_label": {
            "type": "string"
          },
          "daily_trend": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "by_engine": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "by_prompt": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "alerts": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "competitor_sentiment": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "total_analyzed": {
            "type": "integer",
            "minimum": 0
          },
          "date_range": {
            "type": "object",
            "additionalProperties": true
          },
          "enriched": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": true
          }
        }
      },
      "SensorVerifyResponse": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "valid",
          "workspace",
          "tier",
          "crawlers_tracked"
        ],
        "properties": {
          "valid": {
            "const": true
          },
          "workspace": {
            "type": "string"
          },
          "tier": {
            "type": "string"
          },
          "crawlers_tracked": {
            "type": "integer",
            "minimum": 0
          }
        }
      },
      "AnalyticsResponseBase": {
        "type": "object",
        "required": [
          "period",
          "totalVisits",
          "pageCount",
          "pageCountByEngine",
          "byEngine",
          "topPaths",
          "timeline"
        ],
        "properties": {
          "period": {
            "type": "string"
          },
          "totalVisits": {
            "type": "integer",
            "minimum": 0
          },
          "pageCount": {
            "type": "integer",
            "minimum": 0
          },
          "pageCountByEngine": {
            "type": "object",
            "additionalProperties": {
              "type": "integer",
              "minimum": 0
            }
          },
          "byEngine": {
            "type": "object",
            "additionalProperties": {
              "type": "integer",
              "minimum": 0
            }
          },
          "topPaths": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "timeline": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "trackedSince": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "lastSeen": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "message": {
            "type": "string"
          }
        }
      },
      "CrawlerAnalyticsResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/AnalyticsResponseBase"
          },
          {
            "type": "object",
            "required": [
              "engines"
            ],
            "properties": {
              "engines": {
                "type": "integer",
                "minimum": 0
              },
              "byCategory": {
                "type": "object",
                "additionalProperties": {
                  "type": "integer",
                  "minimum": 0
                }
              },
              "categoryBreakdown": {
                "type": "object",
                "additionalProperties": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          }
        ]
      },
      "ReferrerAnalyticsResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/AnalyticsResponseBase"
          }
        ]
      },
      "ApiError": {
        "anyOf": [
          {
            "type": "object",
            "required": [
              "error"
            ],
            "properties": {
              "error": {
                "type": "string"
              },
              "code": {
                "type": "string"
              },
              "docs_url": {
                "type": "string",
                "format": "uri"
              },
              "request_id": {
                "type": "string"
              },
              "details": {}
            }
          },
          {
            "type": "object",
            "required": [
              "error",
              "error_code",
              "next_action"
            ],
            "properties": {
              "error": {
                "type": "string"
              },
              "error_code": {
                "type": "string"
              },
              "next_action": {
                "type": "object",
                "required": [
                  "type",
                  "url",
                  "label"
                ],
                "properties": {
                  "type": {
                    "type": "string"
                  },
                  "url": {
                    "type": "string"
                  },
                  "label": {
                    "type": "string"
                  }
                }
              }
            }
          }
        ]
      },
      "ScanResponse": {
        "type": "object",
        "required": [
          "url",
          "scores",
          "cached",
          "scannedAt"
        ],
        "properties": {
          "url": {
            "type": "string",
            "format": "uri"
          },
          "scores": {
            "type": "object",
            "additionalProperties": {
              "type": "number"
            }
          },
          "issues": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "topIssues": {
            "type": "array",
            "maxItems": 3,
            "items": {
              "type": "object"
            }
          },
          "totalIssues": {
            "type": "integer"
          },
          "cached": {
            "type": "boolean"
          },
          "scannedAt": {
            "type": "string",
            "format": "date-time"
          },
          "scoreContractVersion": {
            "type": "string"
          },
          "scanId": {
            "type": [
              "string",
              "null"
            ]
          },
          "fullReport": {
            "type": "string",
            "format": "uri"
          }
        }
      },
      "BatchScanResponse": {
        "type": "object",
        "required": [
          "summary",
          "results",
          "usage"
        ],
        "properties": {
          "summary": {
            "type": "object",
            "required": [
              "total",
              "successful",
              "failed"
            ],
            "properties": {
              "total": {
                "type": "integer"
              },
              "successful": {
                "type": "integer"
              },
              "failed": {
                "type": "integer"
              }
            }
          },
          "results": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "usage": {
            "type": "object",
            "additionalProperties": {
              "type": "integer"
            }
          }
        }
      },
      "SitemapScanResponse": {
        "type": "object",
        "required": [
          "site",
          "pagesScanned",
          "results"
        ],
        "properties": {
          "site": {
            "type": "string",
            "format": "uri"
          },
          "totalPagesInSitemap": {
            "type": "integer"
          },
          "pagesScanned": {
            "type": "integer"
          },
          "successful": {
            "type": "integer"
          },
          "failed": {
            "type": "integer"
          },
          "averageScores": {
            "type": "object",
            "additionalProperties": {
              "type": "number"
            }
          },
          "worstPages": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "results": {
            "type": "array",
            "items": {
              "type": "object"
            }
          }
        }
      },
      "AiVisibilityResponse": {
        "type": "object",
        "required": [
          "success",
          "outcome",
          "code",
          "summary",
          "results"
        ],
        "properties": {
          "success": {
            "type": "boolean"
          },
          "outcome": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "message": {
            "type": "string"
          },
          "summary": {
            "type": "object",
            "additionalProperties": true
          },
          "results": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          }
        }
      },
      "AsyncAcceptedResponse": {
        "type": "object",
        "required": [
          "success",
          "outcome",
          "code",
          "scan_run_id"
        ],
        "properties": {
          "success": {
            "type": "boolean"
          },
          "outcome": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "message": {
            "type": "string"
          },
          "scan_run_id": {
            "type": "string",
            "format": "uuid"
          }
        }
      },
      "PaginatedResultsResponse": {
        "type": "object",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "pagination": {
            "type": "object",
            "required": [
              "limit",
              "offset",
              "total",
              "has_more"
            ],
            "properties": {
              "limit": {
                "type": "integer"
              },
              "offset": {
                "type": "integer"
              },
              "total": {
                "type": "integer"
              },
              "has_more": {
                "type": "boolean"
              }
            }
          }
        }
      },
      "HistoryResponse": {
        "type": "object",
        "required": [
          "results",
          "total",
          "limit",
          "offset"
        ],
        "properties": {
          "workspace": {
            "type": "object",
            "additionalProperties": true
          },
          "results": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "total": {
            "type": "integer"
          },
          "limit": {
            "type": "integer"
          },
          "offset": {
            "type": "integer"
          },
          "hasMore": {
            "type": "boolean"
          },
          "visibilityRate": {
            "type": "number"
          },
          "byModel": {
            "type": "object",
            "additionalProperties": true
          }
        }
      },
      "MonitorResponse": {
        "type": "object",
        "required": [
          "workspace",
          "period",
          "summary",
          "model_breakdown",
          "sentiment",
          "top_citations",
          "recent_scores"
        ],
        "properties": {
          "workspace": {
            "type": "object",
            "additionalProperties": true
          },
          "period": {
            "type": "string"
          },
          "summary": {
            "type": "object",
            "additionalProperties": true
          },
          "model_breakdown": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "sentiment": {
            "type": "object",
            "additionalProperties": true
          },
          "top_citations": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "recent_scores": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          }
        }
      },
      "SensorIngestResponse": {
        "type": "object",
        "required": [
          "logged"
        ],
        "properties": {
          "logged": {
            "type": "boolean"
          },
          "deduplicated": {
            "type": "boolean"
          },
          "firstIngest": {
            "type": "boolean"
          },
          "verificationProbe": {
            "type": "boolean"
          },
          "source": {
            "type": "string",
            "enum": [
              "crawler",
              "referrer"
            ]
          },
          "crawler": {
            "type": "string"
          },
          "engine": {
            "type": "string"
          },
          "category": {
            "type": "string"
          },
          "host": {
            "type": "string"
          },
          "workspace": {
            "type": "string"
          },
          "reason": {
            "type": "string"
          }
        }
      },
      "PromptListResponse": {
        "type": "object",
        "required": [
          "workspace",
          "prompts",
          "count"
        ],
        "properties": {
          "workspace": {
            "type": "object",
            "additionalProperties": true
          },
          "prompts": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "count": {
            "type": "integer"
          },
          "effective_cadence": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": true
          }
        }
      },
      "PromptMutationResponse": {
        "type": "object",
        "required": [
          "created",
          "inserted",
          "deduped",
          "prompts"
        ],
        "properties": {
          "created": {
            "type": "integer"
          },
          "inserted": {
            "type": "integer"
          },
          "deduped": {
            "type": "integer"
          },
          "prompts": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          }
        }
      }
    }
  },
  "x-foglift-token-costs": {
    "chatgpt": 3,
    "perplexity": 5,
    "ai-overview": 3,
    "gemini": 3,
    "claude": 5
  },
  "x-foglift-api-limits": {
    "free": {
      "daily": 10,
      "monthly": 100
    },
    "launch": {
      "daily": 50,
      "monthly": 1000
    },
    "growth": {
      "daily": 200,
      "monthly": 5000
    },
    "enterprise": {
      "daily": "Custom",
      "monthly": "Custom"
    }
  }
}
