{"name":"Vibe Check Scan","description":"Passive web security scanner. Analyzes HTTP headers, TLS/SSL, CORS policy, API surface exposure, server-secret material in client bundles, and React/Next RSC CVEs for any public URL. Returns an A-F grade scorecard. No authentication required.","api_version":"2026-09-12","site_url":"https://vibecheckscan.com","auth":{"required":false,"description":"No authentication needed. All endpoints are public."},"auth_discovery":{"published":false,"reason":"OAuth/OIDC discovery metadata is intentionally omitted because the public scan API does not currently use authenticated routes or access tokens."},"protocols":{"rest":true,"mcp":false,"mcp_note":"No MCP server is published for this service and none is planned. Use the REST API. /.well-known/mcp/server-card.json returns 410 Gone.","webmcp_in_page":true,"cors":"Cross-origin browser reads are not enabled in production. Use same-origin calls or server-to-server REST requests."},"execution":{"preferred":"rest","description":"Use the REST endpoints directly. Scanning is asynchronous — start a scan, poll status, and take the final result from the terminal status response.","workflow":[{"step":1,"action":"POST /api/scan/start","body":{"url":"https://example.com"},"returns":"scanId"},{"step":2,"action":"GET /api/scan/status?id={scanId}&format=agent","description":"Poll every 2-3 seconds until top-level status is \"completed\" or \"error\". Final response includes result payload."}]},"rate_limits":{"scanEndpoints":"5 requests per IP per minute (POST /api/scan/start, POST /api/cve-2025-55182/check)","pageRoutes":"100 requests per IP per minute (HTML page routes; API routes under /api/ are not subject to this limit)","polling":"Status polling is not rate limited. Poll every 2-3 seconds; do not poll faster.","onLimit":"429 with Retry-After header (seconds) and code: \"rate_limit_exceeded\""},"scan_modules":[{"name":"headers","label":"Security Headers","description":"CSP, HSTS, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy. Each finding reports presence separately from assessment, so \"absent\" is distinguished from \"misconfigured\".","weight":"26.25%"},{"name":"tls","label":"TLS/SSL","description":"Protocol version, certificate expiry, trust chain, cipher strength.","weight":"22.5%"},{"name":"cors","label":"CORS Policy","description":"Wildcard origins, credentials policy, localhost/null origin exposure.","weight":"15%"},{"name":"apiSurface","label":"API Surface","description":"Classifies probed paths into confirmedExposure, needsReview, protectedSurface, expectedPublicEndpoint and hardeningOpportunity. Server-secret material and exposed .env files are confirmedExposure. Public client config is informational. Only confirmedExposure findings affect the score.","weight":"11.25%"},{"name":"cve","label":"React / Next CVEs","description":"Passively detects React Server Components and the React version, then checks that version against the OSV.dev advisory database for react-server-dom-* packages. No vulnerable-version list is maintained server-side. Only a confirmed advisory match (status confirmed_vulnerable) affects the grade; not_vulnerable and uncertain are informational and excluded from the weighted average.","weight":"25% (confirmed matches only)"}],"grading":{"scale":{"A":"90-100","B":"80-89","C":"70-79","D":"60-69","F":"<60"},"note":"Grade is a weighted average across the modules that produced a gradeable result. A module with affectsGrade false is excluded from the average entirely."},"result_ttl":"24 hours — scan results and share links are deleted after 24 hours","result_formats":{"full":"GET /api/scan/result?id={scanId} — Complete scan report with all findings. The default.","summary":"GET /api/scan/result?id={scanId}&format=summary — Condensed JSON with scores and counts only.","agent":"GET /api/scan/result?id={scanId}&format=agent — JSON containing text, markdown, remediationBrief and summary.","text":"GET /api/scan/result?id={scanId}&format=text — Plain text for chat delivery.","markdown":"GET /api/scan/result?id={scanId}&format=markdown — Markdown for chat delivery.","telegram":"GET /api/scan/result?id={scanId}&format=telegram — Alias of markdown.","whatsapp":"GET /api/scan/result?id={scanId}&format=whatsapp — Alias of markdown.","fix":"GET /api/scan/result?id={scanId}&format=fix — Markdown task list for a coding agent to investigate and fix the findings. Evidence is redacted.","remediation":"GET /api/scan/result?id={scanId}&format=remediation — Alias of fix."},"terminal_status_shortcut":"GET /api/scan/status?id={scanId}&format=agent returns the final result inline when complete, so the separate result fetch is usually unnecessary.","error_codes":{"missing_url":"No URL provided.","invalid_url":"URL failed validation (format, TLD, SSRF check, or unreachable).","rate_limit_exceeded":"Too many requests from this IP. Honour Retry-After.","scan_not_found":"scanId not found. Results are held per instance, so a poll can reach an instance that never ran the scan. When \"retryable\" is true, retry a few times before giving up.","invalid_scan_id":"scanId format is invalid."},"safety":"Passive only. Uses GET/HEAD/OPTIONS requests. No fuzzing, brute-force, or POST requests during scanning.","contracts":{"capability_registry":"https://vibecheckscan.com/api/agent/capabilities","openapi_spec":"https://vibecheckscan.com/api/openapi.json","agent_card":"https://vibecheckscan.com/api/agent/card","skill":"https://vibecheckscan.com/api/agent/skill","interpret":"https://vibecheckscan.com/api/agent/interpret","llms_txt":"https://vibecheckscan.com/llms.txt","api_catalog":"https://vibecheckscan.com/.well-known/api-catalog","agent_skills_index":"https://vibecheckscan.com/.well-known/agent-skills/index.json"},"skill_installation":{"required":false,"description":"An optional skill file is available for agent runtimes that support it.","skill_url":"https://vibecheckscan.com/api/agent/skill"}}