Trigger an Audit
This guide shows the full lifecycle of programmatically triggering an audit — start, poll, fetch results.
Start a crawl
Section titled “Start a crawl”curl -X POST https://visibilityiq365.com/api/v1/projects/proj_abc123/audits \ -H "Authorization: Bearer vis_live_YOUR_KEY_HERE" \ -H "Content-Type: application/json" \ -d '{ "crawlDepth": null, "renderMode": "html", "botSimulation": ["Googlebot", "GPTBot", "ClaudeBot"] }'Response:
{ "ok": true, "data": { "auditId": "audit_xyz789", "status": "running", "startedAt": "2026-06-15T14:23:00Z" }}Poll for completion
Section titled “Poll for completion”Poll the audit status endpoint until status is completed or failed:
async function waitForAudit(projectId: string, auditId: string, apiKey: string) { const maxWaitMs = 30 * 60 * 1000; // 30 minutes const pollInterval = 15_000; // 15 seconds const start = Date.now();
while (Date.now() - start < maxWaitMs) { const res = await fetch( `https://visibilityiq365.com/api/v1/projects/${projectId}/audits/${auditId}`, { headers: { Authorization: `Bearer ${apiKey}` } } ); const { data } = await res.json();
if (data.status === 'completed') return data; if (data.status === 'failed') throw new Error(`Audit failed: ${data.error}`);
await new Promise(r => setTimeout(r, pollInterval)); }
throw new Error('Audit timed out');}Typical completion times:
- Small site (< 100 pages): 1–3 minutes
- Medium site (100–1,000 pages): 5–15 minutes
- Large site (1,000–10,000 pages): 15–60 minutes
Using webhooks instead of polling is strongly recommended for production integrations — see Webhooks.
Fetch findings after completion
Section titled “Fetch findings after completion”# All Critical findings, paginatedcurl "https://visibilityiq365.com/api/v1/projects/proj_abc123/issues?severity=critical&auditId=audit_xyz789&limit=50" \ -H "Authorization: Bearer vis_live_YOUR_KEY_HERE"# All findings regardless of severitycurl "https://visibilityiq365.com/api/v1/projects/proj_abc123/issues?auditId=audit_xyz789&limit=50&offset=0" \ -H "Authorization: Bearer vis_live_YOUR_KEY_HERE"Query parameters for findings
Section titled “Query parameters for findings”| Parameter | Type | Description |
|---|---|---|
severity | critical|high|medium|low|info | Filter by severity |
scope | page|template|site|cluster | Filter by scope |
checkId | string | Filter by specific check (e.g., canonical.loop) |
auditId | string | Filter to a specific audit run (defaults to latest) |
limit | number | Results per page (max 1000, default 50) |
offset | number | Pagination offset |
Response structure
Section titled “Response structure”{ "ok": true, "data": { "findings": [ /* AuditFinding[] */ ], "total": 142, "page": 1, "limit": 50, "auditId": "audit_xyz789", "completedAt": "2026-06-15T14:38:00Z", "pagesCrawled": 847 }}CI/CD integration
Section titled “CI/CD integration”For CI/CD pipelines, the typical pattern is:
- Trigger audit after deployment
- Poll (or use webhook) until complete
- Fetch Critical + High findings
- Fail the pipeline if any Critical findings are new (not present in previous audit)
- Post finding summary as a PR comment or CI annotation
See CI Integration guide for a complete working example.