{"openapi":"3.1.0","info":{"title":"SEO Service","description":"Generates SEO / GEO / AEO machinery: production-ready robots.txt, sitemap.xml, the page\n`<head>` block (title/description/canonical/Open Graph + schema.org JSON-LD), and llms.txt.\nSeparately audits one page. **Machinery only** — page content and keyword strategy stay\nwith the caller, and nothing is persisted.\n\n- **Auth:** `Authorization: Bearer <api key>` on every `/v1/*` call.\n- **Errors:** RFC 7807 `application/problem+json`; request content is never echoed back. A `503`\n  with `Retry-After` means auth is not judgeable yet — it is never a verdict on your key.\n- **GEO default:** generated robots.txt explicitly welcomes AI crawlers (`allow_ai: true`).\n- **Audit scope:** a *technical SEO* audit of one page — 11 deterministic checks, equally\n  weighted, of which two are AI-readiness signals (`json_ld`, `ssr_text`). It does not read your\n  llms.txt or robots.txt AI-crawler policy, so a perfect score is not a GEO/AEO verdict. Exact\n  pass conditions for every check: `GET /llms.txt`.\n- **Agent quickstart:** `GET /llms.txt`.\n","version":"1.4.0"},"servers":[{"url":"https://seo.majr.app"}],"paths":{"/":{"get":{"tags":["discovery"],"summary":"Service card: what this service is + where its contracts live","operationId":"getServiceCard","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Getservicecard"}}}}}}},"/v1/head":{"post":{"tags":["generation"],"summary":"Render the page <head> inner block (title/canonical/OG/JSON-LD)","operationId":"generateHead","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HeadRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HeadResponse"}}}},"401":{"description":"Missing or invalid bearer token","content":{"application/problem+json":{"schema":{"properties":{"type":{"type":"string","title":"Type","default":"about:blank"},"title":{"type":"string","title":"Title"},"status":{"type":"integer","title":"Status"},"detail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Detail"}},"type":"object","required":["title","status"],"title":"Problem","description":"RFC 7807 error body, served as application/problem+json."}}}},"403":{"description":"API key is valid but not scoped for this service — use a key scoped for `required_scope` (do not rotate); `granted_scopes` lists where this key works","content":{"application/problem+json":{"schema":{"properties":{"type":{"type":"string","title":"Type","default":"about:blank"},"title":{"type":"string","title":"Title"},"status":{"type":"integer","title":"Status"},"detail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Detail"},"code":{"type":"string","title":"Code","default":"insufficient_service_scope"},"required_scope":{"type":"string","title":"Required Scope"},"granted_scopes":{"items":{"type":"string"},"type":"array","title":"Granted Scopes"}},"type":"object","required":["title","status","required_scope","granted_scopes"],"title":"InsufficientScopeProblem","description":"The 403 shape (per-service key scopes): valid key, not scoped for THIS service. The\nextension members make remediation deterministic for agents — `code` to dispatch on without\nparsing English, `required_scope` = the service refusing, `granted_scopes` = where the key\ndoes work. Emitted with `WWW-Authenticate: Bearer error=\"insufficient_scope\", scope=\"...\"`.\nDistinct from 401 (rotate the key) and 503 (retry): the fix is a key scoped for this\nservice, never rotation."}}}},"422":{"description":"Request validation failed (input values are never echoed back)","content":{"application/problem+json":{"schema":{"$defs":{"ValidationErrorDetail":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Loc"},"msg":{"type":"string","title":"Msg"},"type":{"type":"string","title":"Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationErrorDetail"}},"properties":{"type":{"type":"string","title":"Type","default":"about:blank"},"title":{"type":"string","title":"Title"},"status":{"type":"integer","title":"Status"},"detail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Detail"},"errors":{"items":{"$ref":"#/$defs/ValidationErrorDetail"},"type":"array","title":"Errors"}},"type":"object","required":["title","status","errors"],"title":"ValidationProblem","description":"The 422 shape: Problem plus the pydantic error locations — with input VALUES stripped\n(never echoed back)."}}}},"503":{"description":"Service auth is not configured (a deploy problem — no Retry-After), or the key store is not judgeable yet (cold boot / plane outage — honor Retry-After). Never a verdict on your key: do not rotate on a 503.","headers":{"Retry-After":{"description":"Seconds to wait before retrying. Present only when auth is not judgeable yet (cold boot / plane outage); absent when auth is simply unconfigured (not retryable).","schema":{"type":"integer"}}},"content":{"application/problem+json":{"schema":{"properties":{"type":{"type":"string","title":"Type","default":"about:blank"},"title":{"type":"string","title":"Title"},"status":{"type":"integer","title":"Status"},"detail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Detail"}},"type":"object","required":["title","status"],"title":"Problem","description":"RFC 7807 error body, served as application/problem+json."}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/robots":{"post":{"tags":["generation"],"summary":"Render robots.txt (GEO default: AI crawlers explicitly welcomed)","operationId":"generateRobots","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RobotsRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RobotsResponse"}}}},"401":{"description":"Missing or invalid bearer token","content":{"application/problem+json":{"schema":{"properties":{"type":{"type":"string","title":"Type","default":"about:blank"},"title":{"type":"string","title":"Title"},"status":{"type":"integer","title":"Status"},"detail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Detail"}},"type":"object","required":["title","status"],"title":"Problem","description":"RFC 7807 error body, served as application/problem+json."}}}},"403":{"description":"API key is valid but not scoped for this service — use a key scoped for `required_scope` (do not rotate); `granted_scopes` lists where this key works","content":{"application/problem+json":{"schema":{"properties":{"type":{"type":"string","title":"Type","default":"about:blank"},"title":{"type":"string","title":"Title"},"status":{"type":"integer","title":"Status"},"detail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Detail"},"code":{"type":"string","title":"Code","default":"insufficient_service_scope"},"required_scope":{"type":"string","title":"Required Scope"},"granted_scopes":{"items":{"type":"string"},"type":"array","title":"Granted Scopes"}},"type":"object","required":["title","status","required_scope","granted_scopes"],"title":"InsufficientScopeProblem","description":"The 403 shape (per-service key scopes): valid key, not scoped for THIS service. The\nextension members make remediation deterministic for agents — `code` to dispatch on without\nparsing English, `required_scope` = the service refusing, `granted_scopes` = where the key\ndoes work. Emitted with `WWW-Authenticate: Bearer error=\"insufficient_scope\", scope=\"...\"`.\nDistinct from 401 (rotate the key) and 503 (retry): the fix is a key scoped for this\nservice, never rotation."}}}},"422":{"description":"Request validation failed (input values are never echoed back)","content":{"application/problem+json":{"schema":{"$defs":{"ValidationErrorDetail":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Loc"},"msg":{"type":"string","title":"Msg"},"type":{"type":"string","title":"Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationErrorDetail"}},"properties":{"type":{"type":"string","title":"Type","default":"about:blank"},"title":{"type":"string","title":"Title"},"status":{"type":"integer","title":"Status"},"detail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Detail"},"errors":{"items":{"$ref":"#/$defs/ValidationErrorDetail"},"type":"array","title":"Errors"}},"type":"object","required":["title","status","errors"],"title":"ValidationProblem","description":"The 422 shape: Problem plus the pydantic error locations — with input VALUES stripped\n(never echoed back)."}}}},"503":{"description":"Service auth is not configured (a deploy problem — no Retry-After), or the key store is not judgeable yet (cold boot / plane outage — honor Retry-After). Never a verdict on your key: do not rotate on a 503.","headers":{"Retry-After":{"description":"Seconds to wait before retrying. Present only when auth is not judgeable yet (cold boot / plane outage); absent when auth is simply unconfigured (not retryable).","schema":{"type":"integer"}}},"content":{"application/problem+json":{"schema":{"properties":{"type":{"type":"string","title":"Type","default":"about:blank"},"title":{"type":"string","title":"Title"},"status":{"type":"integer","title":"Status"},"detail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Detail"}},"type":"object","required":["title","status"],"title":"Problem","description":"RFC 7807 error body, served as application/problem+json."}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/sitemap":{"post":{"tags":["generation"],"summary":"Render sitemaps.org-valid sitemap.xml","operationId":"generateSitemap","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SitemapRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SitemapResponse"}}}},"401":{"description":"Missing or invalid bearer token","content":{"application/problem+json":{"schema":{"properties":{"type":{"type":"string","title":"Type","default":"about:blank"},"title":{"type":"string","title":"Title"},"status":{"type":"integer","title":"Status"},"detail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Detail"}},"type":"object","required":["title","status"],"title":"Problem","description":"RFC 7807 error body, served as application/problem+json."}}}},"403":{"description":"API key is valid but not scoped for this service — use a key scoped for `required_scope` (do not rotate); `granted_scopes` lists where this key works","content":{"application/problem+json":{"schema":{"properties":{"type":{"type":"string","title":"Type","default":"about:blank"},"title":{"type":"string","title":"Title"},"status":{"type":"integer","title":"Status"},"detail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Detail"},"code":{"type":"string","title":"Code","default":"insufficient_service_scope"},"required_scope":{"type":"string","title":"Required Scope"},"granted_scopes":{"items":{"type":"string"},"type":"array","title":"Granted Scopes"}},"type":"object","required":["title","status","required_scope","granted_scopes"],"title":"InsufficientScopeProblem","description":"The 403 shape (per-service key scopes): valid key, not scoped for THIS service. The\nextension members make remediation deterministic for agents — `code` to dispatch on without\nparsing English, `required_scope` = the service refusing, `granted_scopes` = where the key\ndoes work. Emitted with `WWW-Authenticate: Bearer error=\"insufficient_scope\", scope=\"...\"`.\nDistinct from 401 (rotate the key) and 503 (retry): the fix is a key scoped for this\nservice, never rotation."}}}},"422":{"description":"Request validation failed (input values are never echoed back)","content":{"application/problem+json":{"schema":{"$defs":{"ValidationErrorDetail":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Loc"},"msg":{"type":"string","title":"Msg"},"type":{"type":"string","title":"Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationErrorDetail"}},"properties":{"type":{"type":"string","title":"Type","default":"about:blank"},"title":{"type":"string","title":"Title"},"status":{"type":"integer","title":"Status"},"detail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Detail"},"errors":{"items":{"$ref":"#/$defs/ValidationErrorDetail"},"type":"array","title":"Errors"}},"type":"object","required":["title","status","errors"],"title":"ValidationProblem","description":"The 422 shape: Problem plus the pydantic error locations — with input VALUES stripped\n(never echoed back)."}}}},"503":{"description":"Service auth is not configured (a deploy problem — no Retry-After), or the key store is not judgeable yet (cold boot / plane outage — honor Retry-After). Never a verdict on your key: do not rotate on a 503.","headers":{"Retry-After":{"description":"Seconds to wait before retrying. Present only when auth is not judgeable yet (cold boot / plane outage); absent when auth is simply unconfigured (not retryable).","schema":{"type":"integer"}}},"content":{"application/problem+json":{"schema":{"properties":{"type":{"type":"string","title":"Type","default":"about:blank"},"title":{"type":"string","title":"Title"},"status":{"type":"integer","title":"Status"},"detail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Detail"}},"type":"object","required":["title","status"],"title":"Problem","description":"RFC 7807 error body, served as application/problem+json."}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/llms-txt":{"post":{"tags":["generation"],"summary":"Render an llms.txt for your site, so answer engines cite you accurately","operationId":"generateLlmsTxt","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LlmsTxtRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LlmsTxtResponse"}}}},"401":{"description":"Missing or invalid bearer token","content":{"application/problem+json":{"schema":{"properties":{"type":{"type":"string","title":"Type","default":"about:blank"},"title":{"type":"string","title":"Title"},"status":{"type":"integer","title":"Status"},"detail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Detail"}},"type":"object","required":["title","status"],"title":"Problem","description":"RFC 7807 error body, served as application/problem+json."}}}},"403":{"description":"API key is valid but not scoped for this service — use a key scoped for `required_scope` (do not rotate); `granted_scopes` lists where this key works","content":{"application/problem+json":{"schema":{"properties":{"type":{"type":"string","title":"Type","default":"about:blank"},"title":{"type":"string","title":"Title"},"status":{"type":"integer","title":"Status"},"detail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Detail"},"code":{"type":"string","title":"Code","default":"insufficient_service_scope"},"required_scope":{"type":"string","title":"Required Scope"},"granted_scopes":{"items":{"type":"string"},"type":"array","title":"Granted Scopes"}},"type":"object","required":["title","status","required_scope","granted_scopes"],"title":"InsufficientScopeProblem","description":"The 403 shape (per-service key scopes): valid key, not scoped for THIS service. The\nextension members make remediation deterministic for agents — `code` to dispatch on without\nparsing English, `required_scope` = the service refusing, `granted_scopes` = where the key\ndoes work. Emitted with `WWW-Authenticate: Bearer error=\"insufficient_scope\", scope=\"...\"`.\nDistinct from 401 (rotate the key) and 503 (retry): the fix is a key scoped for this\nservice, never rotation."}}}},"422":{"description":"Request validation failed (input values are never echoed back)","content":{"application/problem+json":{"schema":{"$defs":{"ValidationErrorDetail":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Loc"},"msg":{"type":"string","title":"Msg"},"type":{"type":"string","title":"Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationErrorDetail"}},"properties":{"type":{"type":"string","title":"Type","default":"about:blank"},"title":{"type":"string","title":"Title"},"status":{"type":"integer","title":"Status"},"detail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Detail"},"errors":{"items":{"$ref":"#/$defs/ValidationErrorDetail"},"type":"array","title":"Errors"}},"type":"object","required":["title","status","errors"],"title":"ValidationProblem","description":"The 422 shape: Problem plus the pydantic error locations — with input VALUES stripped\n(never echoed back)."}}}},"503":{"description":"Service auth is not configured (a deploy problem — no Retry-After), or the key store is not judgeable yet (cold boot / plane outage — honor Retry-After). Never a verdict on your key: do not rotate on a 503.","headers":{"Retry-After":{"description":"Seconds to wait before retrying. Present only when auth is not judgeable yet (cold boot / plane outage); absent when auth is simply unconfigured (not retryable).","schema":{"type":"integer"}}},"content":{"application/problem+json":{"schema":{"properties":{"type":{"type":"string","title":"Type","default":"about:blank"},"title":{"type":"string","title":"Title"},"status":{"type":"integer","title":"Status"},"detail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Detail"}},"type":"object","required":["title","status"],"title":"Problem","description":"RFC 7807 error body, served as application/problem+json."}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/audit":{"post":{"tags":["audit"],"summary":"Fetch one URL and score its technical SEO + AI-readiness signals (0..1 + findings)","operationId":"auditPage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditResponse"}}}},"401":{"description":"Missing or invalid bearer token","content":{"application/problem+json":{"schema":{"properties":{"type":{"type":"string","title":"Type","default":"about:blank"},"title":{"type":"string","title":"Title"},"status":{"type":"integer","title":"Status"},"detail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Detail"}},"type":"object","required":["title","status"],"title":"Problem","description":"RFC 7807 error body, served as application/problem+json."}}}},"403":{"description":"API key is valid but not scoped for this service — use a key scoped for `required_scope` (do not rotate); `granted_scopes` lists where this key works","content":{"application/problem+json":{"schema":{"properties":{"type":{"type":"string","title":"Type","default":"about:blank"},"title":{"type":"string","title":"Title"},"status":{"type":"integer","title":"Status"},"detail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Detail"},"code":{"type":"string","title":"Code","default":"insufficient_service_scope"},"required_scope":{"type":"string","title":"Required Scope"},"granted_scopes":{"items":{"type":"string"},"type":"array","title":"Granted Scopes"}},"type":"object","required":["title","status","required_scope","granted_scopes"],"title":"InsufficientScopeProblem","description":"The 403 shape (per-service key scopes): valid key, not scoped for THIS service. The\nextension members make remediation deterministic for agents — `code` to dispatch on without\nparsing English, `required_scope` = the service refusing, `granted_scopes` = where the key\ndoes work. Emitted with `WWW-Authenticate: Bearer error=\"insufficient_scope\", scope=\"...\"`.\nDistinct from 401 (rotate the key) and 503 (retry): the fix is a key scoped for this\nservice, never rotation."}}}},"422":{"description":"Request validation failed (input values are never echoed back)","content":{"application/problem+json":{"schema":{"$defs":{"ValidationErrorDetail":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Loc"},"msg":{"type":"string","title":"Msg"},"type":{"type":"string","title":"Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationErrorDetail"}},"properties":{"type":{"type":"string","title":"Type","default":"about:blank"},"title":{"type":"string","title":"Title"},"status":{"type":"integer","title":"Status"},"detail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Detail"},"errors":{"items":{"$ref":"#/$defs/ValidationErrorDetail"},"type":"array","title":"Errors"}},"type":"object","required":["title","status","errors"],"title":"ValidationProblem","description":"The 422 shape: Problem plus the pydantic error locations — with input VALUES stripped\n(never echoed back)."}}}},"503":{"description":"Service auth is not configured (a deploy problem — no Retry-After), or the key store is not judgeable yet (cold boot / plane outage — honor Retry-After). Never a verdict on your key: do not rotate on a 503.","headers":{"Retry-After":{"description":"Seconds to wait before retrying. Present only when auth is not judgeable yet (cold boot / plane outage); absent when auth is simply unconfigured (not retryable).","schema":{"type":"integer"}}},"content":{"application/problem+json":{"schema":{"properties":{"type":{"type":"string","title":"Type","default":"about:blank"},"title":{"type":"string","title":"Title"},"status":{"type":"integer","title":"Status"},"detail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Detail"}},"type":"object","required":["title","status"],"title":"Problem","description":"RFC 7807 error body, served as application/problem+json."}}}}},"security":[{"HTTPBearer":[]}]}}},"components":{"schemas":{"AuditRequest":{"properties":{"url":{"type":"string","title":"Url","examples":["https://acme.com/pricing"]},"source":{"type":"string","title":"Source","default":""}},"type":"object","required":["url"],"title":"AuditRequest"},"AuditResponse":{"properties":{"url":{"type":"string","title":"Url"},"score":{"type":"number","title":"Score"},"findings":{"items":{"$ref":"#/components/schemas/Finding"},"type":"array","title":"Findings"},"version":{"type":"string","title":"Version","default":"v1"}},"type":"object","required":["url","score"],"title":"AuditResponse"},"Finding":{"properties":{"check":{"type":"string","title":"Check"},"ok":{"type":"boolean","title":"Ok"},"detail":{"type":"string","title":"Detail","default":""}},"type":"object","required":["check","ok"],"title":"Finding"},"HeadRequest":{"properties":{"title":{"type":"string","title":"Title","description":"Page title — becomes <title> and the og:title/twitter:title fallback.","examples":["Pricing — Acme Analytics"]},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","description":"Meta description; the tag is omitted when absent.","examples":["Plans that scale with your traffic."]},"canonical_path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Canonical Path","description":"Path joined with site_url into an absolute rel=canonical.","examples":["/pricing"]},"site_url":{"type":"string","title":"Site Url","description":"Site origin used to absolutize canonical_path.","default":"","examples":["https://acme.com"]},"robots":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Robots","description":"Value for <meta name=\"robots\">, e.g. \"index,follow\"; omit for engine default."},"og":{"anyOf":[{"$ref":"#/components/schemas/OpenGraph"},{"type":"null"}],"description":"Open Graph block; when present, Twitter card tags mirror it."},"twitter_card":{"type":"string","title":"Twitter Card","description":"Twitter card type; emitted only when `og` is present.","default":"summary_large_image"},"json_ld":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Json Ld","description":"schema.org JSON-LD blocks, each serialized into its own <script> tag."},"source":{"type":"string","title":"Source","default":""}},"type":"object","required":["title"],"title":"HeadRequest"},"HeadResponse":{"properties":{"html":{"type":"string","title":"Html"},"version":{"type":"string","title":"Version","default":"v1"}},"type":"object","required":["html"],"title":"HeadResponse"},"LinkRef":{"properties":{"title":{"type":"string","title":"Title","description":"Link text."},"path":{"type":"string","title":"Path","description":"Path (or absolute URL); joined with site_url."},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","description":"Optional one-line description appended after the link."}},"type":"object","required":["title","path"],"title":"LinkRef","description":"A titled link, used in llms.txt sections and elsewhere."},"LlmsTxtRequest":{"properties":{"site_name":{"type":"string","title":"Site Name","description":"The site/product name — llms.txt's H1.","examples":["Acme Analytics"]},"summary":{"type":"string","title":"Summary","description":"One-line entity definition — the blockquote answer engines quote.","examples":["Privacy-first web analytics for indie SaaS."]},"site_url":{"type":"string","title":"Site Url","description":"Site origin link paths are absolutized against.","default":""},"key_facts":{"items":{"type":"string"},"type":"array","title":"Key Facts","description":"Short factual bullets an answer engine can cite."},"links":{"items":{"$ref":"#/components/schemas/LinkRef"},"type":"array","title":"Links","description":"The pages that matter, rendered as a titled link list."},"source":{"type":"string","title":"Source","default":""}},"type":"object","required":["site_name","summary"],"title":"LlmsTxtRequest"},"LlmsTxtResponse":{"properties":{"content":{"type":"string","title":"Content"},"version":{"type":"string","title":"Version","default":"v1"}},"type":"object","required":["content"],"title":"LlmsTxtResponse"},"OpenGraph":{"properties":{"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title","description":"og:title; falls back to the page title."},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","description":"og:description; falls back to the page description."},"type":{"type":"string","title":"Type","description":"og:type.","default":"website"},"image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image","description":"og:image — absolute URL of the share image."},"image_alt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Alt","description":"og:image:alt."},"image_width":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Image Width","description":"og:image:width, pixels."},"image_height":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Image Height","description":"og:image:height, pixels."}},"type":"object","title":"OpenGraph"},"RobotsRequest":{"properties":{"site_url":{"type":"string","title":"Site Url","description":"Site origin used to absolutize sitemap_path into the Sitemap: line.","default":"","examples":["https://acme.com"]},"sitemap_path":{"type":"string","title":"Sitemap Path","description":"Path (or absolute URL) advertised in the Sitemap: line.","default":"/sitemap.xml"},"allow_ai":{"type":"boolean","title":"Allow Ai","description":"True (the GEO default) explicitly welcomes AI crawlers (GPTBot, ClaudeBot, PerplexityBot, ...); false emits an explicit Disallow for each instead.","default":true},"disallow_paths":{"items":{"type":"string"},"type":"array","title":"Disallow Paths","description":"Paths blocked in every crawler group; include \"/\" to block the whole site."},"source":{"type":"string","title":"Source","default":""}},"type":"object","title":"RobotsRequest"},"RobotsResponse":{"properties":{"content":{"type":"string","title":"Content"},"version":{"type":"string","title":"Version","default":"v1"}},"type":"object","required":["content"],"title":"RobotsResponse"},"SitemapEntry":{"properties":{"path":{"type":"string","title":"Path","description":"Page path (or absolute URL); joined with site_url into <loc>."},"changefreq":{"anyOf":[{"type":"string","enum":["always","hourly","daily","weekly","monthly","yearly","never"]},{"type":"null"}],"title":"Changefreq","description":"sitemaps.org <changefreq> keyword."},"priority":{"anyOf":[{"type":"number","maximum":1.0,"minimum":0.0},{"type":"null"}],"title":"Priority","description":"<priority>, 0.0..1.0."},"lastmod":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lastmod","description":"<lastmod> — ISO-8601 date, e.g. 2026-07-15."}},"type":"object","required":["path"],"title":"SitemapEntry"},"SitemapRequest":{"properties":{"site_url":{"type":"string","title":"Site Url","description":"Site origin each entry path is absolutized against.","default":""},"entries":{"items":{"$ref":"#/components/schemas/SitemapEntry"},"type":"array","title":"Entries","description":"One entry per page, in the order they should appear."},"source":{"type":"string","title":"Source","default":""}},"type":"object","title":"SitemapRequest"},"SitemapResponse":{"properties":{"content":{"type":"string","title":"Content"},"version":{"type":"string","title":"Version","default":"v1"}},"type":"object","required":["content"],"title":"SitemapResponse"}},"securitySchemes":{"HTTPBearer":{"type":"http","description":"Per-product API key, minted on the platform Control Plane.","scheme":"bearer"}}},"tags":[{"name":"generation","description":"Pure artifact generation — JSON in, artifact out, no fetches, no state."},{"name":"audit","description":"Fetch one URL (SSRF-guarded) and score its technical SEO + AI-readiness signals."},{"name":"discovery","description":"Who this service is and where its contracts live."}]}