{"openapi":"3.1.0","info":{"title":"Advantage API","version":"1.0.0","description":"Scan how AI assistants read a live URL (Get Found), whether a first-time visitor would convert (Convert), and what the page shipped that it shouldn't have (Ship Verified). Every result is an observed measurement at scan time — never a verdict, certification, or guarantee. The public API is free to try without a key at a per-IP rate; an API key (Authorization: Bearer adv_live_…) raises the rate to your plan's tier and returns live model output on a paid plan."},"servers":[{"url":"https://getadvantage.app","description":"This deployment"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"An Advantage API key, created at /app/api-keys. Send as `Authorization: Bearer adv_live_…`. Optional — without it, requests use the keyless free tier (per-IP limited, sampled output)."}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"string","description":"Human-readable error message."},"code":{"type":"string","description":"Stable error code, when present (e.g. invalid_key)."}},"required":["error"]},"ScoreBlock":{"type":"object","properties":{"score":{"type":"integer","minimum":0,"maximum":100,"description":"0–100, measured by the engine. Never blended with other engines' scores."},"grade":{"type":"string","enum":["A","B","C","D","F"]},"summary":{"type":"object","properties":{"pass":{"type":"integer"},"warn":{"type":"integer"},"fail":{"type":"integer"}}},"percentile":{"type":["integer","null"],"description":"Percentile vs the apps we've checked, or null when not computed for this dimension."},"benchCount":{"type":"integer","description":"How many apps the benchmark has measured."}}}}},"paths":{"/api/analyze":{"get":{"summary":"Get Found — AI-readability scan (9 signals)","description":"Fetches the page and scores how legible it is to AI engines (ChatGPT, Perplexity, Gemini) across 9 signals, returns a per-signal breakdown, paste-ready fixes, and a generated starter llms.txt. No LLM is required for the score. Observed at scan time.","security":[{},{"bearerAuth":[]}],"parameters":[{"name":"url","in":"query","required":true,"schema":{"type":"string","format":"uri"},"description":"The live URL to scan."},{"name":"source","in":"query","required":false,"schema":{"type":"string","pattern":"^[a-z_]{1,24}$"},"description":"Optional funnel attribution tag."}],"responses":{"200":{"description":"Scan result","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Missing/invalid url","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached (retry-after header set)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/verify-convert":{"get":{"summary":"Convert — conversion-readiness scan + 5-second cold-read","description":"Fetches the landing page and scores the signals that decide whether a first-time visitor understands it and signs up (value prop, primary CTA, social proof, signup friction, mobile viewport, page weight, headline clarity). With a paid key it also runs an agentic 5-second first-impression test. Returns checks, fixes, a benchmark percentile, and a shareable /v report. Observed at scan time.","security":[{},{"bearerAuth":[]}],"parameters":[{"name":"url","in":"query","required":true,"schema":{"type":"string","format":"uri"},"description":"The live URL to check (alias: domain)."},{"name":"source","in":"query","required":false,"schema":{"type":"string","pattern":"^[a-z_]{1,24}$"}}],"responses":{"200":{"description":"Convert result","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Missing/invalid url","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/verify-safety":{"get":{"summary":"Ship Verified — shipped-safety checks + badge record","description":"Fetches the app and runs deterministic checks for common vibe-coded exposures (secrets in the client bundle, backend config, exposed files, security headers, CORS, transport, source maps). A passing check means we did NOT find that specific issue — never that the app is secure or certified. Returns checks, fixes, a benchmark percentile, a shareable /v report, and a 'Checked by Advantage' badge. Observed at scan time.","security":[{},{"bearerAuth":[]}],"parameters":[{"name":"url","in":"query","required":true,"schema":{"type":"string","format":"uri"},"description":"The live URL to check (alias: domain)."},{"name":"source","in":"query","required":false,"schema":{"type":"string","pattern":"^[a-z_]{1,24}$"}}],"responses":{"200":{"description":"Ship Verified result","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Missing/invalid url","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/scan/combined":{"post":{"summary":"Combined scan — all three engines, one call","description":"Runs Get Found, Convert, and Ship Verified over one URL and returns one payload: three independent score blocks (never averaged), an intersection summary naming the weakest dimension and the single biggest next move, and one permalink (the Ship Verified /v report). Consumes one rate-limit tick at your plan's per-engine rate. Observed at scan time.","security":[{},{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri","description":"The live URL to scan."},"source":{"type":"string","pattern":"^[a-z_]{1,24}$","description":"Optional funnel attribution tag."}},"required":["url"]}}}},"responses":{"200":{"description":"Combined result","content":{"application/json":{"schema":{"type":"object","properties":{"host":{"type":"string"},"finalUrl":{"type":"string"},"found":{"$ref":"#/components/schemas/ScoreBlock"},"convert":{"$ref":"#/components/schemas/ScoreBlock"},"safety":{"$ref":"#/components/schemas/ScoreBlock"},"intersection":{"type":"object","properties":{"summary":{"type":"string"},"weakest":{"type":"string","enum":["found","convert","safety"]},"topPriority":{"type":"string"}}},"permalink":{"type":["string","null"],"description":"Path to the shareable /v report, or null."},"mode":{"type":"string","enum":["live","sample"]}}}}}},"400":{"description":"Missing/invalid body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}