Icymango Scanner API
Programmatic access to SEO audits, WordPress security scans, and multi-tool security assessments.
Overview
The Scanner API lets you launch and monitor audits from any application. All requests return JSON. Scans run asynchronously — you launch a scan, receive a jobId, then poll the status endpoint until the job is complete.
Authentication
Protected endpoints require an API key passed in the X-API-Key header. Generate keys from the API Keys panel in the scanner UI.
# All protected requests
curl -H "X-API-Key: msk_your_key_here" https://your-scanner.com/api/...
Alternatively, use the Authorization header:
Authorization: Bearer msk_your_key_here
Base URL
Replace with your actual deployment URL. All paths below are relative to this base.
Error Responses
All errors return a JSON object with an error field and an appropriate HTTP status code.
{
"error": "Provide a valid url starting with http(s)://"
}
| Status | Meaning |
|---|---|
| 400 | Bad request — missing or invalid parameters |
| 401 | Unauthorized — missing, invalid, or revoked API key |
| 404 | Not found — unknown job ID or report not yet available |
| 500 | Server error — check server logs |
Launch Scan
Launches an asynchronous scan. Returns a jobId immediately — use it to poll status and retrieve results.
Request Body
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| url | string | required | — | Full URL to scan, including https:// |
| maxPages | number | optional | 25 | Max pages to crawl (1–200) |
| lighthouse | boolean | optional | true | Run Lighthouse performance & SEO analysis |
| wpscan | boolean | optional | false | Run WordPress security scan (CVE lookups, plugin/theme detection) |
| security-scan | boolean | optional | false | Enable full security scan suite |
| nuclei-scan | boolean | optional | false | Run Nuclei vulnerability templates |
| nmap-scan | boolean | optional | false | Run Nmap port & service scan |
| ssl-scan | boolean | optional | false | Analyse SSL/TLS configuration |
| dns-scan | boolean | optional | false | DNS security analysis (SPF, DMARC, DNSSEC) |
| cmsmap-scan | boolean | optional | false | Run CMSmap CMS vulnerability scanner |
| zap-scan | boolean | optional | false | Run OWASP ZAP active scan |
Example — SEO audit only
curl -X POST https://your-scanner.com/api/audit \
-H "Content-Type: application/json" \
-H "X-API-Key: msk_your_key_here" \
-d '{
"url": "https://example.com",
"maxPages": 10,
"lighthouse": true
}'
Example — WordPress security scan
curl -X POST https://your-scanner.com/api/audit \
-H "Content-Type: application/json" \
-H "X-API-Key: msk_your_key_here" \
-d '{
"url": "https://yourwordpresssite.com",
"maxPages": 1,
"lighthouse": false,
"wpscan": true
}'
Response
{
"id": "a1b2c3d4e5f6g7h8",
"status": "/api/status/a1b2c3d4e5f6g7h8",
"reportBase": "/reports/a1b2c3d4e5f6g7h8/"
}
Check Status
Returns the current state and live logs of a scan job. Poll this endpoint every 5–10 seconds until state is done or error.
States
| State | Meaning |
|---|---|
| queued | Job is waiting for a free worker |
| running | Scan is actively in progress |
| done | Scan completed successfully — results available |
| error | Scan failed — check the error field |
| cancelled | Job was cancelled by the user |
Example
curl https://your-scanner.com/api/status/a1b2c3d4e5f6g7h8
Response
{
"id": "a1b2c3d4e5f6g7h8",
"url": "https://example.com",
"state": "done",
"startedAt": "2026-03-26T10:00:00.000Z",
"finishedAt": "2026-03-26T10:04:32.000Z",
"files": {
"report.html": "/reports/a1b2c3d4e5f6g7h8/report.html",
"data": "/reports/a1b2c3d4e5f6g7h8/data",
"wpscan-report.html": "/reports/a1b2c3d4e5f6g7h8/wpscan-report.html"
},
"logs": ["Starting crawl...", "Page 1/10 done"]
}
Get Results
Returns the complete scan results as a JSON object. Available once state === "done".
Top-level fields
| Field | Description |
|---|---|
| origin | Scanned URL |
| totals | Pages crawled, issues found, HTTP errors, screenshots |
| pages[] | Per-page results: URL, status, issues, SEO data, screenshots |
| rollup[] | Aggregated issue counts across all pages, sorted by frequency |
| lighthouse | Performance, SEO, accessibility, best-practices scores (0–100) |
| wpscan | WordPress detection, version, plugins, themes, CVEs, security checks |
| security_scan | Results from Nuclei, Nmap, SSL, DNS, CMSmap, ZAP |
| sitewideSeoScore | Computed SEO score 0–100 |
| seoInsights | Top keywords, orphan pages, readability averages |
WPScan sub-object (when wpscan: true)
{
"wpscan": {
"url": "example.com",
"scan_results": {
"is_wordpress": true,
"wordpress_version": "6.7.5",
"plugins": [{ "slug": "woocommerce", "version": "8.0.0", "outdated": true }],
"themes": [{ "slug": "avada", "source": "html-parse" }],
"cve_check": {
"wordpress": [{ "id": "CVE-2024-xxxx", "score": 9.8, "severity": "CRITICAL" }],
"php": [],
"themes": {}
},
"security_checks": {
"readme_exposed": true,
"xmlrpc_enabled": false,
"php_version": "8.3.27",
"security_headers": { "hsts": false, "csp": false }
},
"summary": {
"total_vulnerabilities": 21,
"critical_vulnerabilities": 2,
"security_issues": ["readme.html is publicly accessible"],
"recommendations": ["Update WordPress core"]
}
}
}
}
Cancel Scan
curl -X DELETE https://your-scanner.com/api/audit/a1b2c3d4e5f6g7h8 \
-H "X-API-Key: msk_your_key_here"
{ "ok": true, "state": "cancelled" }
List Jobs
curl https://your-scanner.com/api/jobs \
-H "X-API-Key: msk_your_key_here"
[
{
"id": "a1b2c3d4e5f6g7h8",
"url": "https://example.com",
"state": "done",
"startedAt": "2026-03-26T10:00:00.000Z",
"finishedAt": "2026-03-26T10:04:32.000Z"
}
]
Delete Job
curl -X DELETE https://your-scanner.com/api/jobs/a1b2c3d4e5f6g7h8 \
-H "X-API-Key: msk_your_key_here"
{ "ok": true }
Generate AI Report
Generates a written analysis report from completed scan results. Supports three report types. If the local AI (Ollama) is unavailable, a structured data-driven report is generated automatically.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| jobId | string | required | ID of a completed scan job |
| reportType | string | optional | audit (default), wpscan, or security |
| format | string | optional | html (default) or pdf — pdf also generates HTML |
| model | string | optional | Ollama model name, default qwen3:4b |
Example — branded WordPress executive briefing PDF
curl -X POST https://your-scanner.com/api/ai-report \
-H "Content-Type: application/json" \
-H "X-API-Key: msk_your_key_here" \
-d '{
"jobId": "a1b2c3d4e5f6g7h8",
"reportType": "wpscan",
"format": "pdf"
}'
{
"ok": true,
"fallback": false,
"files": {
"markdown": "/reports/a1b2c3d4e5f6g7h8/ai-wpscan-report.md",
"html": "/reports/a1b2c3d4e5f6g7h8/ai-wpscan-report.html",
"pdf": "/reports/a1b2c3d4e5f6g7h8/ai-wpscan-report.pdf"
}
}
Health Check
{ "ok": true, "db": true }
Example: Full SEO Audit (JavaScript)
// Launch a crawl and wait for results
async function runSeoAudit(url) {
const BASE = 'https://your-scanner.com';
const KEY = 'msk_your_key_here';
const headers = { 'Content-Type': 'application/json', 'X-API-Key': KEY };
// 1. Launch
const launch = await fetch(`${BASE}/api/audit`, {
method: 'POST', headers,
body: JSON.stringify({ url, maxPages: 20, lighthouse: true })
});
const { id } = await launch.json();
// 2. Poll until done
let status;
do {
await new Promise(r => setTimeout(r, 6000));
status = await (await fetch(`${BASE}/api/status/${id}`)).json();
} while (status.state === 'running' || status.state === 'queued');
if (status.state !== 'done') throw new Error(status.error);
// 3. Fetch results
const report = await (await fetch(`${BASE}/reports/${id}/data/report.json`)).json();
return { id, report };
}
Example: WordPress Scan + AI Briefing (Python)
import requests, time
BASE = "https://your-scanner.com"
KEY = "msk_your_key_here"
H = { "X-API-Key": KEY, "Content-Type": "application/json" }
# Launch WordPress scan
r = requests.post(f"{BASE}/api/audit", headers=H,
json={ "url": "https://yoursite.com", "maxPages": 1,
"lighthouse": False, "wpscan": True })
job_id = r.json()["id"]
# Poll
while True:
time.sleep(8)
status = requests.get(f"{BASE}/api/status/{job_id}", headers=H).json()
if status["state"] not in ("running", "queued"):
break
# Generate branded PDF briefing
ai = requests.post(f"{BASE}/api/ai-report", headers=H,
json={ "jobId": job_id, "reportType": "wpscan", "format": "pdf" }).json()
print("PDF:", BASE + ai["files"]["pdf"])
Example: Full Security Scan (curl)
curl -X POST https://your-scanner.com/api/audit \
-H "Content-Type: application/json" \
-H "X-API-Key: msk_your_key_here" \
-d '{
"url": "https://target.com",
"maxPages": 1,
"lighthouse": false,
"wpscan": true,
"security-scan": true,
"nuclei-scan": true,
"nmap-scan": true,
"ssl-scan": true,
"dns-scan": true
}'
Example: Robust Poll Helper (JavaScript)
async function waitForJob(jobId, { timeout = 600_000, interval = 7000 } = {}) {
const deadline = Date.now() + timeout;
while (Date.now() < deadline) {
await new Promise(r => setTimeout(r, interval));
const s = await (await fetch(`/api/status/${jobId}`,
{ headers: { 'X-API-Key': KEY } })).json();
if (s.state === 'done') return s;
if (s.state === 'error') throw new Error(s.error || 'Scan failed');
if (s.state === 'cancelled') throw new Error('Scan was cancelled');
}
throw new Error('Timed out waiting for scan');
}