{"openapi":"3.1.0","info":{"title":"SeeGeo API","version":"1.0.0","summary":"Audit any website for AI readability and check which AI crawlers can reach it.","description":"SeeGeo audits a website the way AI assistants read it — crawler access for 14 AI bots, technical basics, structured data, content extractability, off-site presence and entity clarity — and grades it against 107 real small-business sites. This API exposes the same engine that powers the site.\n\nAuthenticate with an API key from https://see-geo.com/account as a bearer token. Audits are asynchronous: POST one, then poll it every few seconds; most finish in 20–40 seconds. Limits: 60 requests per minute per key; audits per calendar month by plan (Free: 10/month, Starter: 100/month, Growth: 500/month, Done-For-You: 1000/month); a second audit of the same domain from the same account within ten minutes returns the first.","termsOfService":"https://see-geo.com/terms","contact":{"name":"SeeGeo","url":"https://see-geo.com/about","email":"hello@see-geo.com"}},"servers":[{"url":"https://see-geo.com"}],"security":[{"bearerAuth":[]}],"tags":[{"name":"audits","description":"Full AI-visibility audits — asynchronous, graded A–F."},{"name":"crawlers","description":"Which AI crawlers can read a site, right now."},{"name":"account","description":"The key's plan and usage."}],"paths":{"/api/v1/audits":{"post":{"tags":["audits"],"operationId":"createAudit","summary":"Start an audit of a domain","description":"Queues a crawl of the domain and returns 202 with the audit id to poll. If this account audited the same domain in the last ten minutes, returns that audit with 200 and `deduplicated: true` instead of starting another.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["domain"],"properties":{"domain":{"type":"string","description":"A public hostname or URL; the host is used.","examples":["example.com","https://www.example.com/pricing"]}}}}}},"responses":{"200":{"description":"An audit of this domain already started in the last ten minutes; returned instead.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Audit"},{"type":"object","properties":{"deduplicated":{"type":"boolean","const":true}}}]}}}},"202":{"description":"Audit queued.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Audit"},"example":{"id":"6f1c0d2e-3b4a-4c5d-8e9f-0a1b2c3d4e5f","domain":"example.com","status":"queued","createdAt":"2026-09-08T12:00:00.000Z","progress":{"phase":"queued","note":null,"done":0,"total":0},"error":null,"summary":null,"links":{"self":"https://see-geo.com/api/v1/audits/6f1c0d2e-3b4a-4c5d-8e9f-0a1b2c3d4e5f","html":"https://see-geo.com/audits/6f1c0d2e-3b4a-4c5d-8e9f-0a1b2c3d4e5f","share":null},"usage":{"used":3,"limit":100}}}}},"400":{"description":"Body is not JSON.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"422":{"description":"`domain` is not a public hostname.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_domain","message":"`domain` must be a public hostname, e.g. \"example.com\"."}}}}},"429":{"description":"Per-minute rate limit or the plan's monthly audit cap.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"monthly_cap","message":"This plan allows 10 API audits per calendar month; 10 used."}}}}},"503":{"description":"Too many audits running platform-wide; retry after the `Retry-After` seconds."}}},"get":{"tags":["audits"],"operationId":"listAudits","summary":"List this account's recent audits","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}}],"responses":{"200":{"description":"Most recent first, summaries only (no `report`).","content":{"application/json":{"schema":{"type":"object","properties":{"audits":{"type":"array","items":{"$ref":"#/components/schemas/Audit"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/v1/audits/{id}":{"get":{"tags":["audits"],"operationId":"getAudit","summary":"Poll an audit; read its report when done","description":"While `status` is `queued` or `running`, `progress` says which phase the crawl is in. When `done`, `summary` holds the grade and category scores and `report` the full graded report with every finding. Poll every 3–5 seconds.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"report","in":"query","schema":{"type":"string","enum":["0","1"],"default":"1"},"description":"`0` omits the full report and returns only the summary."}],"responses":{"200":{"description":"The audit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Audit"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"No audit with that id on this account."}}}},"/api/v1/crawler-check":{"get":{"tags":["crawlers"],"operationId":"crawlerCheck","summary":"Can AI crawlers read this domain?","description":"Reads robots.txt for each of the 14 AI crawlers, then fetches the homepage as GPTBot, OAI-SearchBot, ClaudeBot and PerplexityBot to see what a bot wall does. Synchronous, usually 2–6 seconds. 10 per minute per key.","parameters":[{"name":"domain","in":"query","required":true,"schema":{"type":"string"},"example":"example.com"}],"responses":{"200":{"description":"The verdict, a robots row per crawler and a probe row per live fetch.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrawlerCheck"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"422":{"description":"`domain` is not a public hostname."},"429":{"description":"Rate limited."}}}},"/api/v1/me":{"get":{"tags":["account"],"operationId":"getMe","summary":"The key's plan and this month's usage","responses":{"200":{"description":"Plan and usage.","content":{"application/json":{"schema":{"type":"object","properties":{"key":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}}},"plan":{"type":"string","enum":["free","starter","growth","dfy"]},"usage":{"type":"object","properties":{"apiAuditsThisMonth":{"type":"integer"},"apiAuditsPerMonth":{"type":"integer"},"requestsPerMinute":{"type":"integer"}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"sg_… API key from https://see-geo.com/account"}},"responses":{"Unauthorized":{"description":"Missing, unknown or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_key","message":"That API key is unknown or has been revoked."}}}}}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string"},"message":{"type":"string"}},"additionalProperties":true}}},"Audit":{"type":"object","required":["id","domain","status","createdAt","links"],"properties":{"id":{"type":"string","format":"uuid"},"domain":{"type":"string"},"status":{"type":"string","enum":["queued","running","done","failed"]},"createdAt":{"type":"string","format":"date-time"},"progress":{"type":["object","null"],"properties":{"phase":{"type":"string","enum":["queued","robots","crawl","checks","report"]},"note":{"type":["string","null"]},"done":{"type":"integer"},"total":{"type":"integer"}}},"error":{"type":["string","null"]},"summary":{"anyOf":[{"$ref":"#/components/schemas/AuditSummary"},{"type":"null"}]},"report":{"$ref":"#/components/schemas/AuditReport"},"links":{"type":"object","properties":{"self":{"type":"string","format":"uri"},"html":{"type":"string","format":"uri","description":"The human-readable report on see-geo.com (owner sign-in required)."},"share":{"type":["string","null"],"format":"uri","description":"Public share link, when the owner has enabled sharing."}}}}},"AuditSummary":{"type":"object","description":"Present once `status` is `done`.","properties":{"seoScore":{"type":"integer","minimum":0,"maximum":100},"geoScore":{"type":"integer","minimum":0,"maximum":100},"combined":{"type":"integer","minimum":0,"maximum":100},"grade":{"type":"string","enum":["A","B","C","D","F"]},"gated":{"type":"boolean","description":"True when the access gate failed: AI crawlers cannot read the site, so other categories are secondary."},"ungraded":{"type":["string","null"],"enum":["unreachable","moved",null],"description":"Set when no page could be reached; scores are then not meaningful."},"walled":{"type":["object","null"],"properties":{"vendor":{"type":"string"}},"description":"Set when a bot wall blocked the crawl so thoroughly that only access could be judged."},"engineVersion":{"type":["string","null"]},"categories":{"type":"array","items":{"$ref":"#/components/schemas/CategoryScore"}},"findingCount":{"type":"integer"}}},"AuditReport":{"type":"object","description":"The full graded report: every category with its score, every finding with severity, evidence and fix, plus the engine's honesty note. Shape documented at https://see-geo.com/methodology; top-level keys listed here, nested objects are additionalProperties.","properties":{"domain":{"type":"string"},"crawledAt":{"type":"string","format":"date-time"},"grade":{"type":"string"},"seoScore":{"type":"integer"},"geoScore":{"type":"integer"},"combined":{"type":"integer"},"gated":{"type":"boolean"},"blocker":{"type":["object","null"]},"categories":{"type":"array","items":{"$ref":"#/components/schemas/CategoryScore"}},"findings":{"type":"array","items":{"$ref":"#/components/schemas/Finding"}},"evidence":{"type":"object","additionalProperties":true},"coverage":{"type":"object","additionalProperties":true},"geoHonestyNote":{"type":"string"}},"additionalProperties":true},"CategoryScore":{"type":"object","required":["category","label","score","evaluated"],"properties":{"category":{"type":"string","enum":["access","technical","structured","extractability","offsite","entity"]},"label":{"type":"string"},"score":{"type":"integer","minimum":0,"maximum":100},"evaluated":{"type":"boolean","description":"False when the crawl could not reach enough of the site to judge this category."},"findingCounts":{"type":"object","description":"Findings per severity.","additionalProperties":{"type":"integer"}}}},"Finding":{"type":"object","required":["id","category","severity","title","fix"],"properties":{"id":{"type":"string","description":"Stable check id, e.g. `structured.faq-shape-no-schema`."},"category":{"type":"string"},"pillar":{"type":"string","enum":["seo","geo","shared"]},"severity":{"type":"string","enum":["critical","warning","opportunity"]},"impact":{"type":"integer","description":"Points this finding costs its category."},"title":{"type":"string"},"whyItMatters":{"type":"string"},"fix":{"type":"string","description":"What to change, in plain language."},"evidence":{"type":"array","items":{"type":"object","additionalProperties":true}}},"additionalProperties":true},"CrawlerCheck":{"type":"object","properties":{"domain":{"type":"string"},"verdict":{"type":"string","enum":["open","partially-blocked","blocked","unreachable"]},"checkedAt":{"type":"string","format":"date-time"},"robots":{"type":"object","properties":{"status":{"type":"integer","description":"HTTP status of /robots.txt; 0 when unreachable."},"found":{"type":"boolean"},"rows":{"type":"array","items":{"type":"object","properties":{"bot":{"type":"string"},"vendor":{"type":"string"},"kind":{"type":"string","enum":["ai-training","ai-search","ai-live","search"]},"status":{"type":"string","enum":["allowed","blocked","partial"]},"explicit":{"type":"boolean","description":"robots.txt names this bot specifically."}}}}}},"probes":{"type":"array","description":"Live fetches of the homepage as each crawler's user agent.","items":{"type":"object","properties":{"ua":{"type":"string"},"status":{"type":"integer"},"ok":{"type":"boolean"},"walled":{"type":["string","null"],"description":"Bot-wall vendor when one blocked the fetch."}}}}}}}}}