{"openapi":"3.0.3","info":{"title":"RulerIQ API","version":"0.1.0","description":"Public + account-gated API for the RulerIQ AI search visibility instrument. For AI agents, prefer the MCP server at /api/mcp (tools/list, tools/call)."},"servers":[{"url":"https://ruleriq.com"}],"paths":{"/api/grade":{"post":{"summary":"Check a domain","description":"Runs the site check (Agent Readiness) immediately; with an email, runs the full 4-engine check with a 90% margin of error.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string","example":"acme.com"},"runEngines":{"type":"boolean","example":true},"forceRefresh":{"type":"boolean"},"background":{"type":"boolean","description":"Enqueue a background scan and return a jobId."},"turnstileToken":{"type":"string"},"byok":{"type":"object","description":"Optional bring-your-own engine keys."}},"required":["domain"]}}}},"responses":{"200":{"description":"Readiness-only or full-probe result (GradeApiResponse)."},"202":{"description":"Background job queued; { jobId }."},"429":{"description":"Rate limited."}}}},"/api/leads":{"post":{"summary":"Capture a lead","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","format":"email"},"domain":{"type":"string"},"note":{"type":"string"}},"required":["email","domain"]}}}},"responses":{"200":{"description":"{ ok, id }"}}}},"/api/track":{"post":{"summary":"Start weekly tracking","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string"},"email":{"type":"string"},"plan":{"type":"string"}},"required":["domain"]}}}},"responses":{"200":{"description":"{ ok, id }"}}}},"/api/fix-status":{"get":{"summary":"List fix status for a domain (auth)","parameters":[{"name":"domain","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"{ rows }"}}},"post":{"summary":"Set fix status (auth)","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string"},"fixId":{"type":"string"},"status":{"type":"string","enum":["shipped","still_missing","in_progress"]},"note":{"type":"string"}},"required":["domain","fixId","status"]}}}},"responses":{"200":{"description":"{ ok }"}}}},"/api/gsc":{"post":{"summary":"Import a GSC CSV and convert to buyer prompts","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"csv":{"type":"string"},"brandName":{"type":"string"},"trackedBrandId":{"type":"string","description":"Save the parsed rows to this tracked brand (auth, owner only)."},"siteUrl":{"type":"string","description":"Search Console property; defaults to sc-domain:<brand domain>."}},"required":["csv"]}}}},"responses":{"200":{"description":"{ queryCount, prompts, stored, siteUrl }"}}}},"/api/gsc/sites":{"get":{"summary":"Search Console properties the caller's own connected Google account can read (auth; ?domain= filters)","responses":{"200":{"description":"{ sites: [{ siteUrl, permissionLevel }] }"}}}},"/api/gsc/fetch":{"post":{"summary":"Fetch GSC Search Analytics (auth)","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"siteUrl":{"type":"string"},"startDate":{"type":"string","format":"date"},"endDate":{"type":"string","format":"date"},"rowLimit":{"type":"integer"},"trackedBrandId":{"type":"string","description":"Save the fetched rows to this tracked brand (auth, owner only)."}},"required":["siteUrl","startDate","endDate"]}}}},"responses":{"200":{"description":"{ rows, stored }"}}}},"/api/gsc/queries":{"get":{"summary":"Stored Search Console query set for a tracked brand (auth, owner only)","parameters":[{"name":"trackedBrandId","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"{ rows, fetchedAtMs, siteUrl }"}}}},"/api/mcp":{"post":{"summary":"MCP server (Streamable HTTP, JSON-RPC 2.0)","description":"Supports initialize, tools/list, tools/call, ping. Optional Authorization: Bearer <personal access key> adds the read tools for your own tracked brands to tools/list; a key created with write access also lists ruleriq_mark_fix_done. An invalid or revoked key returns 401 with WWW-Authenticate: Bearer.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"jsonrpc":{"type":"string"},"id":{},"method":{"type":"string"},"params":{}},"required":["jsonrpc","method"]}}}},"responses":{"200":{"description":"JSON-RPC response."},"401":{"description":"Invalid or revoked access key."}}}},"/api/report/{id}":{"get":{"summary":"White-label HTML report for a completed scan","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"text/html report"}}}},"/api/export":{"get":{"summary":"CSV export of leads or tracked brands (signed-in user, or Authorization: Bearer admin token)","parameters":[{"name":"type","in":"query","schema":{"type":"string","enum":["leads","brands"]}}],"responses":{"200":{"description":"text/csv"}}}},"/api/health":{"get":{"summary":"Health check","responses":{"200":{"description":"{ ok, service }"}}}}}}