Appearance
Quickstart
Run your first AI security scan and triage a finding in under five minutes. This guide walks you through triggering a scan, reading the command center, browsing findings, and updating a finding's status.
Prerequisites
- A Krafter account (invite-only -- request access at app.krafter.dev)
- An API key with
audit:writescope (write scope includes read access)
Step 1: Run Your First Scan
Trigger an AI-powered scan against a target URL. The scan must use http/https and must not target a private/loopback host (see Scans → SSRF protection).
bash
curl -X POST https://app.krafter.dev/api/v1/orgs/:org_id/projects/:project_id/audit/scans/run \
-H "Authorization: Bearer kr_live_abc123def456" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com",
"trigger": "manual"
}'json
// 202 Accepted
{
"data": {
"id": "a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d",
"org_id": "11111111-1111-1111-1111-111111111111",
"project_id": "production-website",
"trigger": "manual",
"status": "queued",
"summary": {},
"started_at": "2025-06-15T10:00:00Z",
"finished_at": null,
"inserted_at": "2025-06-15T10:00:00Z",
"updated_at": "2025-06-15T10:00:00Z"
},
"meta": {
"request_id": "F-mxbAQk6m9lXeQAAATj"
},
"error": null
}Track scans by ID
The scan runs asynchronously. A 202 Accepted response means it has been queued — status will move through queued → running → completed (or failed). The submitted url is not echoed back; track the scan by id and re-fetch via GET .../audit/scans/:scan_id if you need the current state.
Rate limit
The /scans/run endpoint is throttled to 30 requests per 60-second window per team. Exceeding it returns 429 Too Many Requests with retry-after, x-ratelimit-* headers and a non-enveloped body. See Scans → Rate limit.
Step 2: Check the Command Center
After the scan finishes, fetch the command center for an at-a-glance health view:
bash
curl "https://app.krafter.dev/api/v1/orgs/:org_id/projects/:project_id/audit/command-center" \
-H "Authorization: Bearer kr_live_abc123def456"json
{
"data": {
"org_id": "11111111-1111-1111-1111-111111111111",
"project_id": "production-website",
"period": { "from": "2025-06-09", "to": "2025-06-15" },
"health_score": 67,
"unresolved_findings": 11,
"critical_findings": 2,
"top_priorities": [
{
"id": "d4e5f6a7-8b9c-0d1e-2f3a-4b5c6d7e8f9a",
"title": "Missing Content-Security-Policy header",
"severity": "critical",
"status": "new",
"domain": "security",
"priority": { "impact": 80, "effort": 20, "risk": 90, "score": 88 }
}
],
"expected_impact": {
"cwv_improvement_pct": 14,
"security_risk_reduction_pct": 27,
"regression_risk_pct": 16
}
},
"meta": {
"request_id": "G-nyc8sPL2vXfRBBBEUk"
},
"error": null
}health_score (0–100) penalises critical and unresolved findings. top_priorities is up to five unresolved findings ordered by priority.score. See Scans → Command Center for the full field reference.
Step 3: Review Findings
List findings to see what the scan detected. Filter by severity, status, or domain:
bash
curl "https://app.krafter.dev/api/v1/orgs/:org_id/projects/:project_id/audit/findings?severity=critical&limit=10" \
-H "Authorization: Bearer kr_live_abc123def456"json
{
"data": [
{
"id": "d4e5f6a7-8b9c-0d1e-2f3a-4b5c6d7e8f9a",
"org_id": "11111111-1111-1111-1111-111111111111",
"project_id": "production-website",
"domain": "security",
"title": "Missing Content-Security-Policy header",
"description": "The application does not set a Content-Security-Policy header.",
"severity": "critical",
"status": "new",
"confidence": 0.95,
"priority": { "impact": 80, "effort": 20, "risk": 90, "score": 88 },
"owner_id": null,
"affected_assets": [
{ "type": "url", "value": "https://example.com" }
],
"evidence": [],
"recommended_fix": {
"summary": "Add a Content-Security-Policy header to all responses.",
"steps": ["Configure CSP at the reverse proxy", "Start with a restrictive policy", "Relax as needed"],
"estimated_minutes": 60
},
"created_at": "2025-06-15T10:05:00Z",
"updated_at": "2025-06-15T10:05:00Z"
}
],
"meta": {
"request_id": "H-pzd9tQM3wYgSCCCFVl",
"total": 1,
"next_cursor": null
},
"error": null
}Each finding carries a recommended_fix with concrete steps and an effort estimate. Use priority.score to order work and owner_id to assign findings.
Step 4: Triage a Finding
New findings start in status new. The status flow is:
new → triaged → in_progress → ready_verify → resolved
↘ dismissedMove a finding into your queue by setting status: "triaged" (or jump straight to dismissed for false positives):
bash
curl -X PATCH "https://app.krafter.dev/api/v1/orgs/:org_id/projects/:project_id/audit/findings/d4e5f6a7-8b9c-0d1e-2f3a-4b5c6d7e8f9a" \
-H "Authorization: Bearer kr_live_abc123def456" \
-H "Content-Type: application/json" \
-d '{
"status": "triaged",
"owner_id": "22222222-2222-2222-2222-222222222222"
}'The response is the full finding shape with the new status and owner_id reflected.
Don't mark "resolved" by hand
The resolved status is set automatically when an associated verification is approved. The recommended workflow is: triage → create a task → ship the fix → run a verification → approve it. Approving the verification flips the task to done, the finding to resolved, and closes any open regression for that finding.
View in the Dashboard
Open the Krafter dashboard at app.krafter.dev/audit to browse findings, manage tasks, and monitor your posture visually.
Next Steps
- Findings Guide — Severity levels, status lifecycle, filtering, bulk operations, and regression tracking
- Remediation Guide — Tasks, verifications, policies, integrations, and report generation