{
 "openapi": "3.1.0",
 "info": {
  "title": "AEO Lookup free AEO tools",
  "version": "1.0.0",
  "description": "Free, keyless answer engine optimisation checks for any public web page. Documentation: https://aeolookup.com/aeo-tools/api/. MCP server: https://aeolookup.com/mcp."
 },
 "servers": [
  {
   "url": "https://aeolookup.com"
  }
 ],
 "paths": {
  "/api/aeo/ai-crawlers": {
   "get": {
    "operationId": "check_ai_crawler_access",
    "summary": "AI crawler checker",
    "description": "Checks whether the crawlers behind ChatGPT, Claude, Perplexity, Google AI Overviews, Copilot and 14 more may read a page: robots.txt rules (RFC 9309), robots meta and X-Robots-Tag directives, and whether the site's firewall refuses each crawler's user agent. Separates search and user crawlers (which decide whether you can be cited) from training crawlers (which do not).",
    "parameters": [
     {
      "name": "url",
      "in": "query",
      "required": true,
      "description": "The page or site to check, for example https://example.co.uk/ (https:// is added if missing).",
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "path",
      "in": "query",
      "required": false,
      "description": "Optional path to test instead of the URL's own path, for example /blog/.",
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The result, as JSON."
     },
     "400": {
      "description": "A bad or private address."
     },
     "502": {
      "description": "The site could not be reached."
     }
    }
   },
   "post": {
    "operationId": "check_ai_crawler_access_post",
    "summary": "AI crawler checker",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "url": {
          "type": "string",
          "description": "The page or site to check, for example https://example.co.uk/ (https:// is added if missing)."
         },
         "path": {
          "type": "string",
          "description": "Optional path to test instead of the URL's own path, for example /blog/."
         }
        },
        "required": [
         "url"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The result, as JSON."
     }
    }
   }
  },
  "/api/aeo/schema": {
   "get": {
    "operationId": "check_structured_data",
    "summary": "Schema checker",
    "description": "Extracts every JSON-LD block on a page, lists the schema.org types it describes, flags missing required and recommended properties (Organization, LocalBusiness, Article, FAQPage, Product, Service, Person, BreadcrumbList, Event) and scores entity signals: a named organisation, sameAs links to other profiles, a logo and an @id.",
    "parameters": [
     {
      "name": "url",
      "in": "query",
      "required": true,
      "description": "The page or site to check, for example https://example.co.uk/ (https:// is added if missing).",
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The result, as JSON."
     },
     "400": {
      "description": "A bad or private address."
     },
     "502": {
      "description": "The site could not be reached."
     }
    }
   },
   "post": {
    "operationId": "check_structured_data_post",
    "summary": "Schema checker",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "url": {
          "type": "string",
          "description": "The page or site to check, for example https://example.co.uk/ (https:// is added if missing)."
         }
        },
        "required": [
         "url"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The result, as JSON."
     }
    }
   }
  },
  "/api/aeo/llms-txt": {
   "get": {
    "operationId": "validate_llms_txt",
    "summary": "llms.txt validator",
    "description": "Fetches /llms.txt (or the llms.txt address given), validates it against the llmstxt.org proposal (one H1, optional summary, H2 sections of [name](url): notes links), tests up to eight of its links and reports whether llms-full.txt exists. States the evidence on how little the file is read.",
    "parameters": [
     {
      "name": "url",
      "in": "query",
      "required": true,
      "description": "The page or site to check, for example https://example.co.uk/ (https:// is added if missing).",
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "check_links",
      "in": "query",
      "required": false,
      "description": "Test up to eight of the file's links that are on its own site (default true).",
      "schema": {
       "type": "boolean"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The result, as JSON."
     },
     "400": {
      "description": "A bad or private address."
     },
     "502": {
      "description": "The site could not be reached."
     }
    }
   },
   "post": {
    "operationId": "validate_llms_txt_post",
    "summary": "llms.txt validator",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "url": {
          "type": "string",
          "description": "The page or site to check, for example https://example.co.uk/ (https:// is added if missing)."
         },
         "check_links": {
          "type": "boolean",
          "description": "Test up to eight of the file's links that are on its own site (default true)."
         }
        },
        "required": [
         "url"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The result, as JSON."
     }
    }
   }
  },
  "/api/aeo/llms-txt-generate": {
   "get": {
    "operationId": "generate_llms_txt",
    "summary": "llms.txt generator",
    "description": "Drafts an llms.txt for a site: the name and summary from its home page, then its pages from the sitemap grouped by section, with titles and descriptions read from up to 24 pages. Returns the file as text, for a person to edit before publishing.",
    "parameters": [
     {
      "name": "url",
      "in": "query",
      "required": true,
      "description": "The page or site to check, for example https://example.co.uk/ (https:// is added if missing).",
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "max_links",
      "in": "query",
      "required": false,
      "description": "Roughly how many links to include (default 40).",
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The result, as JSON."
     },
     "400": {
      "description": "A bad or private address."
     },
     "502": {
      "description": "The site could not be reached."
     }
    }
   },
   "post": {
    "operationId": "generate_llms_txt_post",
    "summary": "llms.txt generator",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "url": {
          "type": "string",
          "description": "The page or site to check, for example https://example.co.uk/ (https:// is added if missing)."
         },
         "max_links": {
          "type": "integer",
          "minimum": 5,
          "maximum": 100,
          "description": "Roughly how many links to include (default 40)."
         }
        },
        "required": [
         "url"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The result, as JSON."
     }
    }
   }
  },
  "/api/aeo/answer-readiness": {
   "get": {
    "operationId": "score_answer_readiness",
    "summary": "Answer-readiness checker",
    "description": "Scores a page out of 100 on 14 published checks: indexable, title and description, one H1, question headings, direct first-sentence answers, structured data, dates, a named author, lists and tables, source links, specific figures, length, declared language and stock AI phrasing. Returns each check's points, what it found and the fix, ordered by points available.",
    "parameters": [
     {
      "name": "url",
      "in": "query",
      "required": true,
      "description": "The page or site to check, for example https://example.co.uk/ (https:// is added if missing).",
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The result, as JSON."
     },
     "400": {
      "description": "A bad or private address."
     },
     "502": {
      "description": "The site could not be reached."
     }
    }
   },
   "post": {
    "operationId": "score_answer_readiness_post",
    "summary": "Answer-readiness checker",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "url": {
          "type": "string",
          "description": "The page or site to check, for example https://example.co.uk/ (https:// is added if missing)."
         }
        },
        "required": [
         "url"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The result, as JSON."
     }
    }
   }
  },
  "/api/aeo/audit": {
   "get": {
    "operationId": "run_aeo_audit",
    "summary": "Full AEO audit",
    "description": "Runs all four checks on one address (AI crawler access, structured data, llms.txt, answer readiness) and returns each result plus an overall score: the mean of the crawler, schema and answer-readiness scores. llms.txt is reported but not scored, because the evidence says few systems read it.",
    "parameters": [
     {
      "name": "url",
      "in": "query",
      "required": true,
      "description": "The page or site to check, for example https://example.co.uk/ (https:// is added if missing).",
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The result, as JSON."
     },
     "400": {
      "description": "A bad or private address."
     },
     "502": {
      "description": "The site could not be reached."
     }
    }
   },
   "post": {
    "operationId": "run_aeo_audit_post",
    "summary": "Full AEO audit",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "url": {
          "type": "string",
          "description": "The page or site to check, for example https://example.co.uk/ (https:// is added if missing)."
         }
        },
        "required": [
         "url"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The result, as JSON."
     }
    }
   }
  }
 }
}