Developer API · v1
Security scans, scriptable.
Start scans from CI, poll results, and pull audit reports — everything the dashboard does for scanning and reporting, over plain HTTPS + JSON.
Authentication
Create an API key in dashboard settings → API keys. The full key (vg_live_…) is shown exactly once — we store only its hash. Send it on every request as the X-API-Key header.
curl "$VIBEGUARD_API/v1/scans/$SCAN_ID" \ -H "X-API-Key: vg_live_…"
Keys carry three scopes: scans:read, scans:write, and reports:read. Revoking a key (settings, one click) disables it immediately.
Base URL
All v1 endpoints live on the VibeGuard API origin — the same https://api.… host your dashboard talks to. The examples below use $VIBEGUARD_API as a stand-in for that origin. Requests are HTTPS-only; bodies and responses are JSON (UTF-8).
Endpoints
Five endpoints, all ownership-scoped to the account that owns the key. The typical flow: create a scan → upload the ZIP → start → poll until complete → (purchase an audit in the dashboard) → poll the audit → fetch the report.
/v1/scansscans:writeCreate a project + scan. For ZIP sources the response includes a signed upload URL — PUT your archive there, then call start. Counts toward the per-key daily scan limit.
Parameters
project_name(body · string, required) — Display name, 1–200 chars.source_type(body · string, required) — "zip" or "github".github_repo_full_name(body · string, optional) — For "github" sources, e.g. "acme/storefront". The repo must have the VibeGuard GitHub App installed (done once from the dashboard).
Response
201 Created
{
"scan_id": "8b6c…",
"project_id": "f1d2…",
"upload_url": "https://…signed…", // null for github sources
"upload_storage_path": "raw-uploads/…/….zip", // null for github
"upload_expires_at": "2026-06-12T10:15:00Z" // 15 minutes
}Example
curl -X POST "$VIBEGUARD_API/v1/scans" \
-H "X-API-Key: $VIBEGUARD_API_KEY" \
-H "Content-Type: application/json" \
-d '{"project_name": "my-mvp", "source_type": "zip"}'
# then upload the archive (ZIP sources only):
curl -X PUT "$UPLOAD_URL" \
-H "Content-Type: application/zip" \
--data-binary @my-mvp.zipCreating an API key constitutes your standing authorization to scan code you own or are authorized to scan — the same commitment the dashboard checkbox records. Your account email must be verified.
/v1/scans/{scan_id}/startscans:writeQueue the scan for processing. Call after the ZIP upload completes (or immediately for GitHub sources). Returns 409 if the scan already left the queued state.
Parameters
scan_id(path · uuid) — From the create response.
Response
202 Accepted
{
"scan_id": "8b6c…",
"status": "queued"
}Example
curl -X POST "$VIBEGUARD_API/v1/scans/$SCAN_ID/start" \ -H "X-API-Key: $VIBEGUARD_API_KEY"
/v1/scans/{scan_id}scans:readScan status plus the full findings list once complete — the same shape the dashboard polls. Findings are empty until status is complete.
Parameters
scan_id(path · uuid) — The scan to inspect.
Response
200 OK
{
"id": "8b6c…",
"status": "queued | extracting | scanning | complete | failed",
"source_type": "zip | github",
"project_id": "f1d2…",
"total_files": 412, "included_files": 268, "ignored_files": 144,
"risky_skipped_files": 0, "total_bytes": 9182733, "included_bytes": 4201554,
"complexity_score": 42.5, "complexity_label": "moderate",
"launch_readiness_score": 61.0,
"free_findings_summary": { "findings_by_severity": { "critical": 1, … } },
"created_at": "…", "completed_at": "… | null", "error_message": null,
"findings": [
{
"id": "…", "severity": "critical", "category": "secret",
"rule_id": "…", "title": "…", "description": "…",
"recommendation": "… | null", "file_path": "src/db.ts",
"line_start": 12, "line_end": 14,
"masked_evidence": "sk_live_****", "confidence": "high"
}
]
}Example
curl "$VIBEGUARD_API/v1/scans/$SCAN_ID" \ -H "X-API-Key: $VIBEGUARD_API_KEY"
/v1/audits/{audit_job_id}reports:readStatus of a purchased audit run, including the security-fix pull request URL once it opens. Audits are purchased in the dashboard; this endpoint observes them.
Parameters
audit_job_id(path · uuid) — Shown in the dashboard after purchase.
Response
200 OK
{
"audit_job_id": "c9a1…",
"status": "queued | running | … | completed | failed",
"tier": "launch_check | founder_shield | elite_audit",
"pr_url": "https://github.com/acme/storefront/pull/42" // null until open
}Example
curl "$VIBEGUARD_API/v1/audits/$AUDIT_JOB_ID" \ -H "X-API-Key: $VIBEGUARD_API_KEY"
/v1/audits/{audit_job_id}/reportreports:readThe full report payload — markdown, severity overview, signed download URLs (PDF, fixed-files bundle), and the PR link. Identical to the dashboard report viewer response.
Parameters
audit_job_id(path · uuid) — The purchased audit run.
Response
200 OK
{
"audit_job_id": "c9a1…",
"status": "ready | pending | failed",
"title": "…", "tier": "founder_shield",
"report_markdown": "# VibeGuard audit…",
"files": { "pdf": { "name": "VIBEGUARD_REPORT.pdf", "url": "https://…signed…" } },
"fixed_files_url": "https://…signed… | null", // patch bundle (folder uploads)
"pr_url": "https://github.com/… | null", // GitHub deliveries
"findings_by_severity": { "critical": 1, "high": 4, "medium": 9, "low": 3, "info": 2 },
"total_findings": 19,
"launch_readiness_score": 61.0,
"fix_count": 14
}Example
curl "$VIBEGUARD_API/v1/audits/$AUDIT_JOB_ID/report" \ -H "X-API-Key: $VIBEGUARD_API_KEY"
Signed URLs in the response expire after about an hour — fetch the report again for fresh links rather than storing them.
Rate limits
- 60 requests / minute per key — every v1 endpoint counts toward this bucket.
- 20 scans / day per key — only
POST /v1/scanscounts.
Exceeding a limit returns 429 with the bucket name in the detail. Windows are fixed (UTC minute / UTC day), so a simple retry after the window boundary is enough — no jittered backoff required. Account-level abuse protections (per-user and per-IP scan limits) also still apply.
Errors
Errors are JSON with a single detail string (FastAPI convention). Validation failures on request bodies return 422 with field-level details.
401Missing, malformed, invalid, or revoked X-API-Key.{ "detail": "Invalid or revoked API key." }403Key lacks the required scope, or email verification / IP checks failed.{ "detail": "This API key is missing the required scope 'scans:write'." }404The resource does not exist or is not owned by your account (we never reveal which).{ "detail": "Scan not found" }429A per-key rate limit was exceeded. Back off and retry after the window resets.{ "detail": "Rate limit exceeded (v1_requests_per_key_per_minute: 61/60). Try again later." }Payments stay in the dashboard
There are deliberately no checkout, quote, or payment endpoints in v1. Purchasing an audit is an interactive, PayPal-approved step that happens in the dashboard — an API key can observe scans and fetch reports, but it can never spend your money.
Key hygiene
Treat keys like passwords: keep them in your CI secret store, never commit them, and rotate by creating a new key and revoking the old one. Key creation, usage timestamps, and revocation are all recorded in your account's activity log.
The cheapest time to fix security is before launch.
Run a free scan in under two minutes. See your launch-readiness score, top risks, and dynamic audit options instantly.
No credit card required for the free scan. Paid quotes generated only after the scan completes.