{
  "openapi": "3.1.0",
  "info": {
    "title": "xSeek API",
    "version": "1.0.0",
    "summary": "Measure and improve how AI assistants cite a brand.",
    "description": "xSeek tracks how AI assistants (ChatGPT, Perplexity, Claude, Gemini, Copilot and others)\nanswer questions about a brand: which pages they cite, which competitors they name instead,\nand which crawlers fetch the site.\n\n## Two surfaces\n\n**Free tools** need no credentials. Send a URL, get a report. Use these to audit any site.\n\n**The v1 API** is authenticated and scoped to one organization. Send\n`Authorization: Bearer <API_KEY>`. Keys are created in Settings > API keys and carry explicit\nscopes; a key only ever gets the scopes it was issued with, so request the narrowest set that\ncovers the work.\n\n## Errors\n\nEvery error is JSON with a stable `error.code` to branch on, a `message`, and a `hint` naming\nthe next step. Never parse the message: it is written for humans and may be reworded.",
    "contact": {
      "name": "xSeek",
      "url": "https://www.xseek.io/contact"
    },
    "license": {
      "name": "Proprietary",
      "url": "https://www.xseek.io/terms"
    }
  },
  "servers": [
    {
      "url": "https://www.xseek.io",
      "description": "Production"
    }
  ],
  "tags": [
    {
      "name": "Free tools",
      "description": "No credentials required. Audit any URL."
    },
    {
      "name": "Account",
      "description": "The organization behind the API key."
    },
    {
      "name": "Websites",
      "description": "Sites tracked by the organization."
    },
    {
      "name": "Articles",
      "description": "Content Studio drafts and published articles."
    },
    {
      "name": "Prompts",
      "description": "Tracked questions run against the AI engines."
    },
    {
      "name": "Metrics",
      "description": "Visibility, citations and AI-referred traffic."
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "paths": {
    "/api/health": {
      "get": {
        "operationId": "getHealth",
        "summary": "Service health",
        "tags": [
          "Free tools"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "The service is reachable."
          }
        }
      }
    },
    "/api/tools/agent-ready": {
      "get": {
        "operationId": "checkAgentReadyByQuery",
        "summary": "Score a URL on agent readiness",
        "description": "Checks whether an AI agent can read and act on the page: server-rendered content, machine-readable metadata, crawler access.",
        "tags": [
          "Free tools"
        ],
        "security": [],
        "parameters": [
          {
            "name": "url",
            "in": "query",
            "required": true,
            "description": "Absolute URL to analyze.",
            "schema": {
              "type": "string",
              "format": "uri"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Agent-readiness report."
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "post": {
        "operationId": "checkAgentReady",
        "summary": "Score a URL on agent readiness",
        "description": "Same report as the GET form, for callers that prefer a body.",
        "tags": [
          "Free tools"
        ],
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "url"
                ],
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Absolute URL of the page to analyze.",
                    "example": "https://example.com"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Score a URL on agent readiness"
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/tools/ai-readable": {
      "post": {
        "operationId": "checkAiReadable",
        "summary": "Check whether a page is readable without JavaScript",
        "description": "Fetches the page without executing scripts and reports what an AI crawler actually sees.",
        "tags": [
          "Free tools"
        ],
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "url"
                ],
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Absolute URL of the page to analyze.",
                    "example": "https://example.com"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Check whether a page is readable without JavaScript"
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/tools/page-weight": {
      "post": {
        "operationId": "checkPageWeight",
        "summary": "Measure page weight",
        "description": "Reports transfer size and what is inflating it. Heavy pages are truncated by crawlers.",
        "tags": [
          "Free tools"
        ],
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "url"
                ],
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Absolute URL of the page to analyze.",
                    "example": "https://example.com"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Measure page weight"
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/tools/robots-check": {
      "post": {
        "operationId": "checkRobotsTxt",
        "summary": "Check robots.txt against AI crawlers",
        "description": "Reports which AI crawlers (GPTBot, ClaudeBot, PerplexityBot, and others) the site allows or blocks.",
        "tags": [
          "Free tools"
        ],
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "url"
                ],
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Absolute URL of the page to analyze.",
                    "example": "https://example.com"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Check robots.txt against AI crawlers"
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/robots-checker": {
      "post": {
        "operationId": "checkRobotsDetailed",
        "summary": "Detailed robots.txt analysis",
        "description": "Per-user-agent breakdown of robots.txt directives.",
        "tags": [
          "Free tools"
        ],
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "url"
                ],
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Absolute URL of the page to analyze.",
                    "example": "https://example.com"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Detailed robots.txt analysis"
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/aeo-preview": {
      "post": {
        "operationId": "previewAeo",
        "summary": "Preview AI visibility for a domain",
        "description": "Runs a sample of questions against the AI engines and reports whether the domain is cited.",
        "tags": [
          "Free tools"
        ],
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "url"
                ],
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Absolute URL of the page to analyze.",
                    "example": "https://example.com"
                  },
                  "locale": {
                    "type": "string",
                    "enum": [
                      "en",
                      "fr"
                    ],
                    "default": "en",
                    "description": "Language of the insight titles and descriptions. The type, impact and icon fields are codes and never translate. An unrecognized value falls back to English."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Preview AI visibility for a domain"
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/competitor-leaderboard": {
      "post": {
        "operationId": "getCompetitorLeaderboard",
        "summary": "Rank a brand against its competitors in AI answers",
        "description": "Returns who the AI engines name for this market, and how often.",
        "tags": [
          "Free tools"
        ],
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "url"
                ],
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Absolute URL of the page to analyze.",
                    "example": "https://example.com"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Rank a brand against its competitors in AI answers"
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/llms-generator": {
      "get": {
        "operationId": "generateLlmsTxt",
        "summary": "Generate an llms.txt for a site",
        "description": "Crawls the site and returns a proposed llms.txt describing it to AI assistants.",
        "tags": [
          "Free tools"
        ],
        "security": [],
        "parameters": [
          {
            "name": "url",
            "in": "query",
            "required": true,
            "description": "Absolute URL of the site root.",
            "schema": {
              "type": "string",
              "format": "uri"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Proposed llms.txt."
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/track-ai-bot": {
      "post": {
        "operationId": "trackAiBot",
        "summary": "Report an AI crawler visit",
        "description": "Records that an AI crawler fetched a URL. Called by the xSeek tracking snippet or edge worker.",
        "tags": [
          "Free tools"
        ],
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "websiteId",
                  "url"
                ],
                "properties": {
                  "websiteId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "url": {
                    "type": "string",
                    "format": "uri"
                  },
                  "userAgent": {
                    "type": "string"
                  },
                  "botName": {
                    "type": "string",
                    "example": "GPTBot"
                  },
                  "referer": {
                    "type": "string"
                  },
                  "ip": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Visit accepted."
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/account": {
      "get": {
        "operationId": "getAccount",
        "summary": "The organization behind the API key",
        "description": "Use this to confirm a key works and to discover which organization it belongs to.",
        "tags": [
          "Account"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Organization and connected keys."
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/api-keys": {
      "get": {
        "operationId": "listApiKeys",
        "summary": "List the organization API keys",
        "tags": [
          "Account"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Keys, with their scopes."
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/robots": {
      "get": {
        "operationId": "getRobotsGuidance",
        "summary": "Recommended robots.txt directives for AI crawlers",
        "tags": [
          "Account"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Recommended directives."
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/websites": {
      "get": {
        "operationId": "listWebsites",
        "summary": "List tracked websites",
        "tags": [
          "Websites"
        ],
        "security": [
          {
            "bearerAuth": [
              "websites:read"
            ]
          }
        ],
        "responses": {
          "200": {
            "description": "Websites in the organization."
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "post": {
        "operationId": "createWebsite",
        "summary": "Track a new website",
        "tags": [
          "Websites"
        ],
        "security": [
          {
            "bearerAuth": [
              "websites:create"
            ]
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "url"
                ],
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri"
                  },
                  "companyName": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Website created."
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/websites/{websiteId}": {
      "get": {
        "operationId": "getWebsite",
        "summary": "Get one website",
        "tags": [
          "Websites"
        ],
        "security": [
          {
            "bearerAuth": [
              "websites:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "websiteId",
            "in": "path",
            "required": true,
            "description": "The website UUID, from GET /api/v1/websites.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The website."
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "patch": {
        "operationId": "updateWebsite",
        "summary": "Update website settings",
        "tags": [
          "Websites"
        ],
        "security": [
          {
            "bearerAuth": [
              "websites:update"
            ]
          }
        ],
        "parameters": [
          {
            "name": "websiteId",
            "in": "path",
            "required": true,
            "description": "The website UUID, from GET /api/v1/websites.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated website."
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/websites/{websiteId}/brand-context": {
      "get": {
        "operationId": "getBrandContext",
        "summary": "Brand voice, audiences and knowledge base",
        "tags": [
          "Websites"
        ],
        "security": [
          {
            "bearerAuth": [
              "websites:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "websiteId",
            "in": "path",
            "required": true,
            "description": "The website UUID, from GET /api/v1/websites.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Brand voice, audiences and knowledge base"
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/websites/{websiteId}/products": {
      "get": {
        "operationId": "listProducts",
        "summary": "Products described for this brand",
        "tags": [
          "Websites"
        ],
        "security": [
          {
            "bearerAuth": [
              "websites:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "websiteId",
            "in": "path",
            "required": true,
            "description": "The website UUID, from GET /api/v1/websites.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Products described for this brand"
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/websites/{websiteId}/topics": {
      "get": {
        "operationId": "listTopics",
        "summary": "Topics tracked for this website",
        "tags": [
          "Websites"
        ],
        "security": [
          {
            "bearerAuth": [
              "prompts:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "websiteId",
            "in": "path",
            "required": true,
            "description": "The website UUID, from GET /api/v1/websites.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Topics tracked for this website"
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/websites/{websiteId}/external-profiles": {
      "get": {
        "operationId": "listExternalProfiles",
        "summary": "Off-site profiles the brand controls",
        "tags": [
          "Websites"
        ],
        "security": [
          {
            "bearerAuth": [
              "websites:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "websiteId",
            "in": "path",
            "required": true,
            "description": "The website UUID, from GET /api/v1/websites.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Off-site profiles the brand controls"
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/websites/{websiteId}/sitemap-pages": {
      "get": {
        "operationId": "listSitemapPages",
        "summary": "Pages discovered in the sitemap",
        "tags": [
          "Websites"
        ],
        "security": [
          {
            "bearerAuth": [
              "websites:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "websiteId",
            "in": "path",
            "required": true,
            "description": "The website UUID, from GET /api/v1/websites.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Pages discovered in the sitemap"
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/websites/{websiteId}/keywords": {
      "get": {
        "operationId": "listKeywords",
        "summary": "Keyword data for this website",
        "tags": [
          "Websites"
        ],
        "security": [
          {
            "bearerAuth": [
              "websites:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "websiteId",
            "in": "path",
            "required": true,
            "description": "The website UUID, from GET /api/v1/websites.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Keyword data for this website"
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/websites/{websiteId}/images": {
      "post": {
        "operationId": "uploadImage",
        "summary": "Upload an image for use in an article",
        "tags": [
          "Articles"
        ],
        "security": [
          {
            "bearerAuth": [
              "images:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "websiteId",
            "in": "path",
            "required": true,
            "description": "The website UUID, from GET /api/v1/websites.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Hosted image URL."
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/websites/{websiteId}/ai-visits": {
      "get": {
        "operationId": "listAiVisits",
        "summary": "AI crawler visits recorded for this website",
        "tags": [
          "Websites"
        ],
        "security": [
          {
            "bearerAuth": [
              "ai_visits:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "websiteId",
            "in": "path",
            "required": true,
            "description": "The website UUID, from GET /api/v1/websites.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "AI crawler visits recorded for this website"
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/websites/{websiteId}/robots-scans": {
      "get": {
        "operationId": "listRobotsScans",
        "summary": "History of robots.txt scans",
        "tags": [
          "Websites"
        ],
        "security": [
          {
            "bearerAuth": [
              "websites:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "websiteId",
            "in": "path",
            "required": true,
            "description": "The website UUID, from GET /api/v1/websites.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "History of robots.txt scans"
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/websites/{websiteId}/robots-scans/latest": {
      "get": {
        "operationId": "getLatestRobotsScan",
        "summary": "Most recent robots.txt scan",
        "tags": [
          "Websites"
        ],
        "security": [
          {
            "bearerAuth": [
              "websites:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "websiteId",
            "in": "path",
            "required": true,
            "description": "The website UUID, from GET /api/v1/websites.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Most recent robots.txt scan"
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/websites/{websiteId}/prompts": {
      "get": {
        "operationId": "listPrompts",
        "summary": "List tracked prompts",
        "description": "The questions xSeek runs against the AI engines on this website’s behalf.",
        "tags": [
          "Prompts"
        ],
        "security": [
          {
            "bearerAuth": [
              "prompts:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "websiteId",
            "in": "path",
            "required": true,
            "description": "The website UUID, from GET /api/v1/websites.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Tracked prompts."
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "post": {
        "operationId": "createPrompt",
        "summary": "Track a new prompt",
        "tags": [
          "Prompts"
        ],
        "security": [
          {
            "bearerAuth": [
              "prompts:create"
            ]
          }
        ],
        "parameters": [
          {
            "name": "websiteId",
            "in": "path",
            "required": true,
            "description": "The website UUID, from GET /api/v1/websites.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "prompt"
                ],
                "properties": {
                  "prompt": {
                    "type": "string",
                    "minLength": 1
                  },
                  "mainCompany": {
                    "type": "string"
                  },
                  "isActive": {
                    "type": "boolean",
                    "default": true
                  },
                  "frequency": {
                    "type": "string",
                    "enum": [
                      "daily",
                      "weekly",
                      "monthly"
                    ],
                    "default": "daily"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Prompt created."
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/websites/{websiteId}/prompts/{promptId}": {
      "patch": {
        "operationId": "updatePrompt",
        "summary": "Update or deactivate a prompt",
        "description": "Deleting is soft. Deactivating keeps every past measurement; a hard delete would remove the results the trends are computed from.",
        "tags": [
          "Prompts"
        ],
        "security": [
          {
            "bearerAuth": [
              "prompts:update"
            ]
          }
        ],
        "parameters": [
          {
            "name": "websiteId",
            "in": "path",
            "required": true,
            "description": "The website UUID, from GET /api/v1/websites.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "promptId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated prompt."
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/websites/{websiteId}/prompts/{promptId}/runs": {
      "get": {
        "operationId": "listPromptRuns",
        "summary": "Results of one prompt, run by run",
        "tags": [
          "Prompts"
        ],
        "security": [
          {
            "bearerAuth": [
              "prompts:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "websiteId",
            "in": "path",
            "required": true,
            "description": "The website UUID, from GET /api/v1/websites.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "promptId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Runs, with the engines that answered."
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/websites/{websiteId}/prompts/visibility": {
      "get": {
        "operationId": "getPromptVisibility",
        "summary": "How often the brand is named across tracked prompts",
        "tags": [
          "Websites"
        ],
        "security": [
          {
            "bearerAuth": [
              "prompts:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "websiteId",
            "in": "path",
            "required": true,
            "description": "The website UUID, from GET /api/v1/websites.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "How often the brand is named across tracked prompts"
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/websites/{websiteId}/prompts/leaderboard": {
      "get": {
        "operationId": "getPromptLeaderboard",
        "summary": "Brand versus competitors across tracked prompts",
        "tags": [
          "Websites"
        ],
        "security": [
          {
            "bearerAuth": [
              "prompts:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "websiteId",
            "in": "path",
            "required": true,
            "description": "The website UUID, from GET /api/v1/websites.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Brand versus competitors across tracked prompts"
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/websites/{websiteId}/prompt-web-searches": {
      "get": {
        "operationId": "listPromptWebSearches",
        "summary": "The web searches engines ran while answering",
        "tags": [
          "Websites"
        ],
        "security": [
          {
            "bearerAuth": [
              "prompts:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "websiteId",
            "in": "path",
            "required": true,
            "description": "The website UUID, from GET /api/v1/websites.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The web searches engines ran while answering"
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/websites/{websiteId}/sources": {
      "get": {
        "operationId": "listSources",
        "summary": "Pages the engines cited, own and external",
        "tags": [
          "Websites"
        ],
        "security": [
          {
            "bearerAuth": [
              "prompts:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "websiteId",
            "in": "path",
            "required": true,
            "description": "The website UUID, from GET /api/v1/websites.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Pages the engines cited, own and external"
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/websites/{websiteId}/sentiment/prompts": {
      "get": {
        "operationId": "getPromptSentiment",
        "summary": "How the engines speak of the brand, per tracked prompt, worst first",
        "tags": [
          "Websites"
        ],
        "security": [
          {
            "bearerAuth": [
              "prompts:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "websiteId",
            "in": "path",
            "required": true,
            "description": "The website UUID, from GET /api/v1/websites.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "days",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 30,
              "maximum": 365
            },
            "description": "Window, in days."
          },
          {
            "name": "label",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "positive",
                "neutral",
                "mixed",
                "negative"
              ]
            },
            "description": "Only prompts with at least one answer carrying this label."
          },
          {
            "name": "company",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "A tracked competitor name or alias, to read its sentiment instead of the brand's."
          },
          {
            "name": "minRead",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 1
            },
            "description": "Only prompts with at least this many read answers."
          }
        ],
        "responses": {
          "200": {
            "description": "How the engines speak of the brand, per tracked prompt, worst first"
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/websites/{websiteId}/sentiment/runs": {
      "get": {
        "operationId": "listSentimentRuns",
        "summary": "The answers behind a sentiment label, each with its evidence sentence and cited sources",
        "tags": [
          "Websites"
        ],
        "security": [
          {
            "bearerAuth": [
              "prompts:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "websiteId",
            "in": "path",
            "required": true,
            "description": "The website UUID, from GET /api/v1/websites.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "label",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "positive",
                "neutral",
                "mixed",
                "negative"
              ]
            },
            "description": "Filter by label; omit for every read answer."
          },
          {
            "name": "promptId",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Only answers to this prompt."
          },
          {
            "name": "company",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "A tracked competitor name or alias, instead of the brand."
          },
          {
            "name": "days",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 30,
              "maximum": 365
            }
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 1
            }
          },
          {
            "name": "pageSize",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 20,
              "maximum": 100
            }
          },
          {
            "name": "includeAnswer",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            },
            "description": "Return the full answer text on each run."
          }
        ],
        "responses": {
          "200": {
            "description": "The answers behind a sentiment label, each with its evidence sentence and cited sources"
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/websites/{websiteId}/llm-queries": {
      "get": {
        "operationId": "listLlmQueries",
        "summary": "Queries that sent AI traffic to the site",
        "tags": [
          "Websites"
        ],
        "security": [
          {
            "bearerAuth": [
              "llm_queries:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "websiteId",
            "in": "path",
            "required": true,
            "description": "The website UUID, from GET /api/v1/websites.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Queries that sent AI traffic to the site"
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/websites/{websiteId}/llm-queries/by-page": {
      "get": {
        "operationId": "listLlmQueriesByPage",
        "summary": "AI queries grouped by landing page",
        "tags": [
          "Websites"
        ],
        "security": [
          {
            "bearerAuth": [
              "llm_queries:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "websiteId",
            "in": "path",
            "required": true,
            "description": "The website UUID, from GET /api/v1/websites.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "AI queries grouped by landing page"
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/websites/{websiteId}/metrics/ai-clicks": {
      "get": {
        "operationId": "getAiClicks",
        "summary": "Sessions referred by AI assistants",
        "tags": [
          "Websites"
        ],
        "security": [
          {
            "bearerAuth": [
              "llm_queries:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "websiteId",
            "in": "path",
            "required": true,
            "description": "The website UUID, from GET /api/v1/websites.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sessions referred by AI assistants"
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/websites/{websiteId}/metrics/share-of-voice": {
      "get": {
        "operationId": "getShareOfVoice",
        "summary": "Share of AI answers naming this brand",
        "tags": [
          "Websites"
        ],
        "security": [
          {
            "bearerAuth": [
              "prompts:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "websiteId",
            "in": "path",
            "required": true,
            "description": "The website UUID, from GET /api/v1/websites.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Share of AI answers naming this brand"
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/websites/{websiteId}/metrics/top-pages": {
      "get": {
        "operationId": "getTopPages",
        "summary": "Pages earning the most AI citations",
        "tags": [
          "Websites"
        ],
        "security": [
          {
            "bearerAuth": [
              "websites:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "websiteId",
            "in": "path",
            "required": true,
            "description": "The website UUID, from GET /api/v1/websites.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Pages earning the most AI citations"
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/websites/{websiteId}/search-metrics": {
      "get": {
        "operationId": "getSearchMetrics",
        "summary": "Traditional search impressions and clicks",
        "tags": [
          "Websites"
        ],
        "security": [
          {
            "bearerAuth": [
              "websites:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "websiteId",
            "in": "path",
            "required": true,
            "description": "The website UUID, from GET /api/v1/websites.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Traditional search impressions and clicks"
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/websites/{websiteId}/search-queries": {
      "get": {
        "operationId": "listSearchQueries",
        "summary": "Google Search Console queries of 60+ characters from the last 30 days, with impressions and position per query",
        "tags": [
          "Websites"
        ],
        "security": [
          {
            "bearerAuth": [
              "llm_queries:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "websiteId",
            "in": "path",
            "required": true,
            "description": "The website UUID, from GET /api/v1/websites.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Google Search Console queries of 60+ characters from the last 30 days, with impressions and position per query"
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/websites/{websiteId}/cannibalization": {
      "get": {
        "operationId": "getCannibalization",
        "summary": "Pages competing with each other for the same query",
        "tags": [
          "Websites"
        ],
        "security": [
          {
            "bearerAuth": [
              "websites:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "websiteId",
            "in": "path",
            "required": true,
            "description": "The website UUID, from GET /api/v1/websites.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Pages competing with each other for the same query"
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/websites/{websiteId}/content/search": {
      "get": {
        "operationId": "searchContent",
        "summary": "Search this site content: does a page already cover this question?",
        "tags": [
          "Websites"
        ],
        "security": [
          {
            "bearerAuth": [
              "articles:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "websiteId",
            "in": "path",
            "required": true,
            "description": "The website UUID, from GET /api/v1/websites.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Search this site content: does a page already cover this question?"
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/websites/{websiteId}/content/keyword-conflicts": {
      "get": {
        "operationId": "getKeywordConflicts",
        "summary": "Articles given the same primary keyword",
        "tags": [
          "Websites"
        ],
        "security": [
          {
            "bearerAuth": [
              "articles:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "websiteId",
            "in": "path",
            "required": true,
            "description": "The website UUID, from GET /api/v1/websites.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Articles given the same primary keyword"
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/websites/{websiteId}/opportunities": {
      "get": {
        "operationId": "listOpportunities",
        "summary": "The current action plan: the actions already recommended for this site",
        "tags": [
          "Websites"
        ],
        "security": [
          {
            "bearerAuth": [
              "websites:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "websiteId",
            "in": "path",
            "required": true,
            "description": "The website UUID, from GET /api/v1/websites.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The current action plan: the actions already recommended for this site"
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/websites/{websiteId}/opportunities/{opportunityId}": {
      "get": {
        "operationId": "getOpportunity",
        "summary": "One content gap, with its evidence",
        "tags": [
          "Metrics"
        ],
        "security": [
          {
            "bearerAuth": [
              "websites:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "websiteId",
            "in": "path",
            "required": true,
            "description": "The website UUID, from GET /api/v1/websites.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "opportunityId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The opportunity."
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/websites/{websiteId}/recommendations": {
      "get": {
        "operationId": "listRecommendations",
        "summary": "The action plan: what to write, rewrite or fix next",
        "tags": [
          "Websites"
        ],
        "security": [
          {
            "bearerAuth": [
              "websites:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "websiteId",
            "in": "path",
            "required": true,
            "description": "The website UUID, from GET /api/v1/websites.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The action plan: what to write, rewrite or fix next"
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/websites/{websiteId}/articles": {
      "get": {
        "operationId": "listArticles",
        "summary": "List Content Studio articles",
        "tags": [
          "Articles"
        ],
        "security": [
          {
            "bearerAuth": [
              "articles:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "websiteId",
            "in": "path",
            "required": true,
            "description": "The website UUID, from GET /api/v1/websites.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "status",
            "in": "query",
            "description": "Filter by workflow state.",
            "schema": {
              "type": "string",
              "enum": [
                "draft",
                "ready",
                "published",
                "archived"
              ]
            }
          },
          {
            "name": "language",
            "in": "query",
            "description": "Return only articles in this language, for a localised blog. A bare code matches any market of that language (\"fr\" finds \"fr-CA\"); a full tag matches exactly. Articles written before the language column have none and are returned for the site's own language. Every article keeps its full \"alternates\" array whatever the filter, so hreflang stays complete.",
            "schema": {
              "type": "string",
              "example": "fr-CA"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Articles."
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "post": {
        "operationId": "createArticle",
        "summary": "Create or upsert an article",
        "description": "Upserts by slug, so pushing the same slug twice updates rather than duplicating. A slug is never regenerated from a changed title, because that would orphan a live URL.",
        "tags": [
          "Articles"
        ],
        "security": [
          {
            "bearerAuth": [
              "articles:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "websiteId",
            "in": "path",
            "required": true,
            "description": "The website UUID, from GET /api/v1/websites.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "title",
                  "contentMarkdown"
                ],
                "properties": {
                  "title": {
                    "type": "string"
                  },
                  "slug": {
                    "type": "string",
                    "description": "Optional. Derived from the title when absent."
                  },
                  "contentMarkdown": {
                    "type": "string"
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "draft",
                      "ready",
                      "published"
                    ],
                    "default": "draft"
                  },
                  "keywordTerms": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Primary keyword first."
                  },
                  "tags": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Article created or updated."
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/websites/{websiteId}/articles/{articleId}": {
      "get": {
        "operationId": "getArticle",
        "summary": "Get one article",
        "tags": [
          "Articles"
        ],
        "security": [
          {
            "bearerAuth": [
              "articles:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "websiteId",
            "in": "path",
            "required": true,
            "description": "The website UUID, from GET /api/v1/websites.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "articleId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The article."
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "patch": {
        "operationId": "updateArticle",
        "summary": "Update content, status or quality",
        "tags": [
          "Articles"
        ],
        "security": [
          {
            "bearerAuth": [
              "articles:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "websiteId",
            "in": "path",
            "required": true,
            "description": "The website UUID, from GET /api/v1/websites.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "articleId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated article."
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/websites/{websiteId}/articles/by-slug/{slug}": {
      "get": {
        "operationId": "getArticleBySlug",
        "summary": "Get an article by slug",
        "tags": [
          "Articles"
        ],
        "security": [
          {
            "bearerAuth": [
              "articles:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "websiteId",
            "in": "path",
            "required": true,
            "description": "The website UUID, from GET /api/v1/websites.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The article."
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/websites/{websiteId}/articles/{articleId}/comments": {
      "get": {
        "operationId": "listArticleComments",
        "summary": "Review comments on an article",
        "tags": [
          "Articles"
        ],
        "security": [
          {
            "bearerAuth": [
              "articles:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "websiteId",
            "in": "path",
            "required": true,
            "description": "The website UUID, from GET /api/v1/websites.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "articleId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Comments."
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/tools/robots-txt": {
      "get": {
        "operationId": "scanRobotsTxtAuthenticated",
        "summary": "Scan a robots.txt and store the result",
        "tags": [
          "Account"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "url",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uri"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Scan result."
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/tools/llms-txt": {
      "get": {
        "operationId": "scanLlmsTxtAuthenticated",
        "summary": "Fetch and analyze a site llms.txt",
        "tags": [
          "Account"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "url",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uri"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Analysis."
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Send `Authorization: Bearer <API_KEY>`.\n\nKeys are created in Settings > API keys and carry explicit scopes, listed below. A key\ncannot gain a scope after it is issued: to widen access, issue a new key. Requesting an\nendpoint without its scope returns 403 with `error.code = \"insufficient_scope\"` and the\nexact scopes required."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "error",
          "documentation_url"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message",
              "hint"
            ],
            "properties": {
              "code": {
                "type": "string",
                "description": "Stable identifier. Branch on this, never on the message.",
                "enum": [
                  "missing_authorization",
                  "invalid_api_key",
                  "insufficient_scope",
                  "not_found",
                  "invalid_request",
                  "plan_required",
                  "rate_limited",
                  "internal_error"
                ]
              },
              "message": {
                "type": "string",
                "description": "Human-readable. May be reworded at any time."
              },
              "hint": {
                "type": "string",
                "description": "The next concrete step to resolve this."
              },
              "fields": {
                "type": "object",
                "additionalProperties": {
                  "type": "string"
                },
                "description": "For invalid_request: which fields failed, keyed by field path."
              }
            }
          },
          "documentation_url": {
            "type": "string",
            "format": "uri"
          }
        },
        "example": {
          "error": {
            "code": "insufficient_scope",
            "message": "This endpoint requires the scope articles:write.",
            "hint": "Issue a new key that carries the required scopes. Scopes are granted per key, so an existing key cannot gain one after the fact."
          },
          "documentation_url": "https://www.xseek.io/openapi.json"
        }
      }
    },
    "responses": {
      "Error": {
        "description": "Structured error. See the Error schema for the codes.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      }
    }
  },
  "x-scopes": {
    "ai_visits:push": "Report AI crawler visits for a website you own.",
    "ai_visits:read": "Read recorded AI crawler visits.",
    "llm_queries:read": "Read the queries AI assistants used to reach a site.",
    "websites:create": "Add a website to the organization.",
    "websites:read": "Read websites and their settings.",
    "websites:update": "Update website settings.",
    "prompts:create": "Create tracked prompts.",
    "prompts:read": "Read tracked prompts and their results.",
    "prompts:update": "Update or deactivate tracked prompts.",
    "articles:read": "Read Content Studio articles.",
    "articles:write": "Create and update Content Studio articles.",
    "images:write": "Upload images used by articles.",
    "brand:write": "Edit the brand profile, competitors, audiences and notes.",
    "integrations:write": "Connect Google and set up tracking.",
    "articles:publish": "Publish articles to the website. API keys with articles:write also publish."
  }
}