sk-sec- key works across curl, Python, JavaScript, MCP, ChatGPT Actions, and GitHub Copilot.The common flow: trigger a scan, poll for completion, download the fix file. Takes 2-5 minutes end to end.
# 1. Trigger a scan
curl -X POST https://securityscanner.dev/v1/scan \
-H "Authorization: Bearer sk-sec-YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"host": "https://myapp.com"}'
# Response:
# {"run_id": "abc12345", "status": "started", ...}
# 2. Poll for results (scan takes 2-5 minutes)
curl https://securityscanner.dev/v1/scan/abc12345 \
-H "Authorization: Bearer sk-sec-YOUR_KEY"
# 3. Download the fix file
curl https://securityscanner.dev/v1/scan/abc12345/fix \
-H "Authorization: Bearer sk-sec-YOUR_KEY" \
-o SECURITY-FIX.mdimport httpx, time
API = "https://securityscanner.dev"
KEY = "sk-sec-YOUR_KEY"
HEADERS = {"Authorization": f"Bearer {KEY}"}
# 1. Trigger
r = httpx.post(f"{API}/v1/scan", headers=HEADERS,
json={"host": "https://myapp.com"})
run_id = r.json()["run_id"]
# 2. Poll
while True:
status = httpx.get(f"{API}/v1/scan/{run_id}", headers=HEADERS).json()
if status["status"] == "completed":
break
time.sleep(10)
print(f"Found {status['summary']['total']} findings")
for f in status["findings"]:
print(f" [{f['severity']}] {f['title']}")
# 3. Fix file
fix = httpx.get(f"{API}/v1/scan/{run_id}/fix", headers=HEADERS).text
open("SECURITY-FIX.md", "w").write(fix)const API = "https://securityscanner.dev";
const KEY = "sk-sec-YOUR_KEY";
const H = { Authorization: `Bearer ${KEY}` };
// 1. Trigger
const started = await fetch(`${API}/v1/scan`, {
method: "POST",
headers: { ...H, "Content-Type": "application/json" },
body: JSON.stringify({ host: "https://myapp.com" }),
}).then(r => r.json());
const runId = started.run_id;
// 2. Poll
let status;
while (true) {
status = await fetch(`${API}/v1/scan/${runId}`, { headers: H }).then(r => r.json());
if (status.status === "completed") break;
await new Promise(r => setTimeout(r, 10000));
}
console.log(`Found ${status.summary.total} findings`);
for (const f of status.findings) {
console.log(` [${f.severity}] ${f.title}`);
}
// 3. Fix file
const fix = await fetch(`${API}/v1/scan/${runId}/fix`, { headers: H }).then(r => r.text());
require("fs").writeFileSync("SECURITY-FIX.md", fix);GET /v1/scan/{run_id} streams partial results while the scan runs — you can start displaying findings before the scan finishes.All endpoints require a bearer token in the Authorization header. Generate keys at /keys.
Authorization: Bearer sk-sec-YOUR_KEY
Keys are scoped to your account. Every scan you trigger counts against your plan. You can have multiple keys; revoke individually at /keys.
Scans a single URL or IP. Auto-creates the target if it doesn't exist. Returns a run_id; the scan runs in the background (2-5 minutes).
| Field | Type | Required | Description |
|---|---|---|---|
host | string | yes | URL or hostname (with or without scheme) |
label | string | no | Free-text label (e.g. "production") |
curl -X POST https://securityscanner.dev/v1/scan \
-H "Authorization: Bearer sk-sec-YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"host": "https://myapp.com", "label": "production"}'import httpx
r = httpx.post(
"https://securityscanner.dev/v1/scan",
headers={"Authorization": "Bearer sk-sec-YOUR_KEY"},
json={"host": "https://myapp.com", "label": "production"},
)
print(r.json())const r = await fetch("https://securityscanner.dev/v1/scan", {
method: "POST",
headers: {
"Authorization": "Bearer sk-sec-YOUR_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({ host: "https://myapp.com", label: "production" }),
});
console.log(await r.json());{
"run_id": "abc12345",
"status": "started",
"target": "myapp.com",
"check_status_url": "https://securityscanner.dev/v1/scan/abc12345"
}
Returns status (running, completed, aborted, failed), summary counts, and every finding emitted so far.
curl https://securityscanner.dev/v1/scan/abc12345 \
-H "Authorization: Bearer sk-sec-YOUR_KEY" import httpx
r = httpx.get(
"https://securityscanner.dev/v1/scan/abc12345",
headers={"Authorization": "Bearer sk-sec-YOUR_KEY"},
)
print(r.json())const r = await fetch("https://securityscanner.dev/v1/scan/abc12345", {
headers: { "Authorization": "Bearer sk-sec-YOUR_KEY" },
});
console.log(await r.json());{
"run_id": "abc12345",
"status": "running",
"started_at": "2026-04-12T10:00:00+00:00",
"summary": {"total": 5, "critical": 1, "high": 2, "medium": 2},
"findings": [ ... partial results ... ]
}
{
"run_id": "abc12345",
"status": "completed",
"started_at": "2026-04-12T10:00:00+00:00",
"finished_at": "2026-04-12T10:03:42+00:00",
"summary": {"total": 12, "critical": 1, "high": 3, "medium": 5, "low": 3, "info": 0},
"findings": [
{
"target": "myapp.com",
"severity": "CRITICAL",
"category": "secrets",
"title": "Anthropic API key exposed at /main.js",
"description": "Secret pattern matched. Rotate immediately.",
"evidence": "Found: sk-ant-api03-...",
"tool": "secret-scan"
}
],
"fix_url": "https://securityscanner.dev/v1/scan/abc12345/fix"
}
| Field | Description |
|---|---|
severity | CRITICAL / HIGH / MEDIUM / LOW / INFO |
category | secrets, auth, baas, api, cloud, network, tls, dns, edge-infra, privacy, disclosure, ai-safety |
tool | Module that produced the finding — useful for filtering and deduplication |
evidence | Raw evidence snippet. Truncated to 200-500 bytes per finding. |
Returns a SECURITY-FIX.md with YAML frontmatter and numbered fix instructions. Drop it into your repo; Claude Code, Cursor, and Cline will read it and apply fixes.
| Name | Type | Description |
|---|---|---|
target | string | Filter to one target's findings (multi-target runs) |
format | auto | legacy | Default is auto (security-fix/v1 frontmatter) |
---
format: security-fix/v1
scanner: securityscanner.dev
scan_id: abc12345
scan_date: "2026-04-12"
targets:
- host: myapp.com
risk_grade: F
severity_counts: {critical: 1, high: 3}
---
# Security Fixes: myapp.com
## FIX-1: Rotate exposed Anthropic API key [CRITICAL]
...
Triggers a structured Sonnet analysis over the run: executive summary, attack chains, risk score (0-100), and prioritized remediation. Cached per run.
{
"content": "# Security Assessment\n\n## Executive Summary\n...",
"model": "claude-sonnet-4-6",
"risk_score": 74,
"cached": false
}
# List all targets
curl https://securityscanner.dev/v1/targets \
-H "Authorization: Bearer sk-sec-YOUR_KEY"
# Add a new target
curl -X POST https://securityscanner.dev/v1/targets \
-H "Authorization: Bearer sk-sec-YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"host": "https://staging.myapp.com", "label": "staging"}' import httpx
h = {"Authorization": "Bearer sk-sec-YOUR_KEY"}
# List
targets = httpx.get("https://securityscanner.dev/v1/targets", headers=h).json()
# Add
httpx.post("https://securityscanner.dev/v1/targets", headers=h,
json={"host": "https://staging.myapp.com", "label": "staging"})const h = { "Authorization": "Bearer sk-sec-YOUR_KEY" };
// List
const targets = await fetch("https://securityscanner.dev/v1/targets", { headers: h }).then(r => r.json());
// Add
await fetch("https://securityscanner.dev/v1/targets", {
method: "POST",
headers: { ...h, "Content-Type": "application/json" },
body: JSON.stringify({ host: "https://staging.myapp.com", label: "staging" }),
});POST /v1/targets body: {"host": "...", "label": "..."}. DELETE /api/targets/{id} removes one.
Returns up to the last 50 runs, most recent first. Each item includes run_id, target, status, started_at, finished_at, and summary counts.
curl https://securityscanner.dev/v1/runs \
-H "Authorization: Bearer sk-sec-YOUR_KEY" import httpx
runs = httpx.get(
"https://securityscanner.dev/v1/runs",
headers={"Authorization": "Bearer sk-sec-YOUR_KEY"},
).json()
for r in runs["runs"]:
print(r["id"], r["target"], r["summary"]["total"])const data = await fetch("https://securityscanner.dev/v1/runs", {
headers: { "Authorization": "Bearer sk-sec-YOUR_KEY" },
}).then(r => r.json());
data.runs.forEach(r => console.log(r.id, r.target, r.summary.total));Automate scans on a schedule. Supports email + webhook alerts on CRITICAL/HIGH findings and certificate-expiry warnings.
{
"target": "https://myapp.com",
"frequency": "daily|weekly",
"alert_email": "[email protected]",
"alert_webhook": "https://hooks.slack.com/...",
"alert_on_cert_expiry_days": 30
}
Shallow-clones a repo and scans for secrets + dependency CVEs (npm-audit, pip-audit) + Terraform IaC misconfigs.
{"repo_url": "https://github.com/owner/repo", "github_token": "ghp_..."}
Upload an IPA or APK (max 200 MB, multipart/form-data). Scans for hardcoded secrets, cleartext traffic, ATS bypass, exposed API endpoints.
curl -H "Authorization: Bearer sk-sec-YOUR_KEY" \
-F "[email protected]" \
https://securityscanner.dev/api/mobile/scan
| Status | When | Response shape |
|---|---|---|
| 200 / 201 | OK | Endpoint-specific |
| 400 | Invalid input (missing field, bad URL) | {"error": "..."} |
| 401 | Missing or invalid API key | {"error": "unauthorized"} |
| 402 | Plan limit reached | {"error": "...", "upgrade_url": "https://securityscanner.dev/billing"} |
| 404 | Not found, or not your resource | {"error": "not found"} |
| 409 | Target already exists | {"error": "target exists", "target_id": "..."} |
| 429 | Rate limit | {"error": "rate limit", "retry_after": 60} |
| 500 | Scanner-internal error | {"error": "internal"} — email [email protected] with the run_id |
| Plan | Price | Targets | Scans | AI analysis | Monitors |
|---|---|---|---|---|---|
| Free | $0 | 1 | 1 lifetime | — | — |
| Pay-as-you-go | $9 / scan | 5 | per credit | ✓ | — |
| Monthly | $29 / month | 1 | 5 per week | ✓ | ✓ |
| Pro | $99 / month | 10 | 50 per day | ✓ | ✓ |
Rate limit responses include a retry_after (seconds). The scanner batches gracefully — if you need higher throughput for a one-time backfill, email [email protected].
securityscanner into your .mcp.json. Works with Claude Code, Claude Desktop, Cursor, Cline, Windsurf./copilot endpoint), pending GitHub Marketplace approval.httpx or fetch directly — the API is 5 endpoints./v1/openapi.json into Postman, Insomnia, Bruno, or any OpenAPI viewer.