API & Developer Docs
Trigger scans programmatically, integrate into CI pipelines, or let your AI agent run security checks. No API key needed.
Quick start
3-step async workflow
Scanning is asynchronous. Start a scan, poll until all modules finish, then fetch the report.
Step 1 — Start the scan
curl -X POST https://vibecheckscan.com/api/scan/start \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com"}'
# Response
{"scanId": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4", "queued": false}Step 2 — Poll status (every 2–3 seconds)
curl "https://vibecheckscan.com/api/scan/status?id=a1b2c3d4e5f6..."
# Response (while running)
{
"status": "running",
"modules": {
"headers": {"status": "done"},
"tls": {"status": "done"},
"cors": {"status": "running"},
"apiSurface": {"status": "pending"}
}
}
# Scan is complete when all 4 modules are "done" or "error"Step 3 — Fetch the result
curl "https://vibecheckscan.com/api/scan/result?id=a1b2c3d4e5f6..."
# Response
{
"scanId": "a1b2c3d4e5f6...",
"url": "https://example.com",
"status": "completed",
"overallGrade": "B",
"overallScore": 82,
"modules": { "headers": {...}, "tls": {...}, "cors": {...}, "apiSurface": {...} }
}Endpoints
API reference
/api/scan/startRate limited: 5/min per IPInitiates an asynchronous scan. Returns a scanId immediately — the actual scan runs in the background.
Request body
{
"url": "https://example.com" // Required. Must be http or https. No private IPs.
}Response
{
"scanId": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4", // 32-char hex — save this
"queued": false // true if waiting for capacity
}/api/scan/status?id={scanId}Returns the current status of each module. Poll every 2–3 seconds until all modules report done or error.
{
"status": "running",
"modules": {
"headers": {"status": "done"}, // pending | running | done | error
"tls": {"status": "running"},
"cors": {"status": "pending"},
"apiSurface": {"status": "pending"}
}
}/api/scan/result?id={scanId}&format=fullRetrieves the completed report. Add ?format=summary for a condensed version with scores and counts only. Results expire after 24 hours.
{
"scanId": "a1b2c3d4...",
"url": "https://example.com",
"status": "completed",
"overallGrade": "B", // A B C D F
"overallScore": 82, // 0–100 weighted
"modules": {
"headers": {
"score": 29, "maxScore": 35,
"findings": {
"csp": {"present": true, "score": 12},
"hsts": {"present": true, "score": 8},
"xFrameOptions": {"present": false, "score": 0},
"xContentTypeOptions":{"present": true, "score": 5},
"referrerPolicy": {"present": true, "score": 4},
"permissionsPolicy": {"present": false, "score": 0}
}
},
"tls": {
"score": 28, "maxScore": 30,
"findings": {
"protocol": {"version": "TLSv1.3", "score": 10},
"certExpiry": {"valid": true, "daysUntilExpiry": 180, "score": 8},
"trustChain": {"valid": true, "score": 5},
"cipherStrength":{"strength": "strong", "score": 5}
}
},
"cors": {
"score": 18, "maxScore": 20,
"findings": {
"wildcardOrigin": false,
"credentialsWithWildcard": false,
"safeOriginPolicy": true,
"localhostAllowed": false,
"nullOriginAllowed": false,
"dynamicAllowlistHits": [],
"probes": [...]
}
},
"apiSurface": {
"score": 9, "maxScore": 10,
"findings": [
{
"kind": "apiEndpoint",
"category": "confirmedExposure",
"path": "/api/health",
"normalizedPath": "/api/health",
"status": 200,
"contentType": "application/json",
"reason": "unauthenticated_business_data"
}
]
}
}
}/api/cve-2025-55182/checkRate limited: 5/min per IPChecks a URL for React Server Component vulnerabilities using passive probes only.
| CVE | Impact |
|---|---|
| CVE-2025-55182 | Remote code execution via malformed RSC payloads |
| CVE-2025-55183 | Source code exposure through RSC endpoint |
| CVE-2025-55184 | Denial of service via resource exhaustion |
curl -X POST https://vibecheckscan.com/api/cve-2025-55182/check \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com"}'Scoring
Grades and weights
The overall score is a weighted average across 4 modules. Each module scores 0–100 internally, then contributes to the weighted total.
headers35%Security Headers
CSP, HSTS, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy
tls30%TLS/SSL
Protocol version, cert expiry, trust chain, cipher strength
cors20%CORS Policy
Wildcard origins, credentials policy, localhost/null origin
apiSurface15%API Surface
Exposed .map files, API endpoints, sensitive files (.env, .git)
| Grade | Score range |
|---|---|
| A | 90 – 100 |
| B | 80 – 89 |
| C | 70 – 79 |
| D | 60 – 69 |
| F | below 60 |
Rate limits
Limits per IP
| Endpoint | Limit | Window |
|---|---|---|
| POST /api/scan/start | 5 requests | per minute |
| POST /api/cve-2025-55182/check | 5 requests | per minute |
| All other routes | 100 requests | per minute |
When rate limited: HTTP 429 with a Retry-After header (seconds to wait) and code: "rate_limit_exceeded" in the response body.
Errors
Error codes
All error responses include a human-readable error string, a machine-readable code, and a request_id for debugging.
{
"error": "URL is required", // human-readable, used by UI
"code": "missing_url", // machine-readable for agents
"request_id": "a1b2c3d4e5f6a1b2" // include this in bug reports
}| HTTP | code | Meaning | Fix |
|---|---|---|---|
| 400 | missing_url | No URL in request body | Add "url" field |
| 400 | invalid_url | URL failed validation | Must be http/https, public host, valid TLD |
| 400 | missing_scan_id | No id query param | Add ?id=<scanId> |
| 400 | invalid_scan_id | Malformed scanId | Use exact scanId from start response |
| 404 | scan_not_found | Scan not found or expired | Results expire after 24h; start a new scan |
| 413 | request_too_large | Body exceeds 1MB | Reduce request size |
| 429 | rate_limit_exceeded | Too many requests | Wait Retry-After seconds |
| 503 | service_unavailable | Temporary shutdown | Retry after a few seconds |
AI agents & LLMs
Machine-readable contracts
These endpoints give AI agents everything they need to discover and use the API without guessing.
Capability registry — full JSON schemas for every capability, implementation status, and polling guidance.
OpenAPI 3.1 spec — authoritative REST contract with request/response schemas for all endpoints.
Agent card — workflow description, rate limits, module weights, and links to all contracts.
Skill file (Markdown) — when to use, terminology, poll vs wait table, error recovery. For agent runtimes that support skill installation.
Plain-text overview — lightweight orientation for LLMs: what the site does, workflow summary, and links to machine contracts.
Passive by design
All scanning uses GET, HEAD, and OPTIONS requests only. No fuzzing, no POST requests, no credential testing, no endpoint enumeration. Private and internal IP ranges are blocked server-side. You see exactly what a standard browser visitor sees.