Appearance
Scans
Run security scans and view the command center dashboard. Scans analyze your URLs for security vulnerabilities, performance issues, and accessibility problems.
Base URL: https://app.krafter.dev/api/v1
Run Scan
Trigger a new security scan for a given URL. The scan is queued and processed asynchronously.
POST /orgs/:org_id/projects/:project_id/audit/scans/runRequired scope: audit:write
Rate limit (strict)
This endpoint uses the strict bucket — 30 requests / 60 seconds per team, shared with flags/{evaluate,bootstrap,track} and push subscriber registration. Exceeding the limit returns 429 Too Many Requests with the headers retry-after, x-ratelimit-limit, x-ratelimit-remaining, and x-ratelimit-reset, and a body of { "error": "Rate limit exceeded", "retry_after": <seconds> }. Note that this body is not wrapped in the standard Audit response envelope.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
url | string | Yes | URL to scan. Must be http/https and target a public host. See URL validation below. |
trigger | string | No | What triggered the scan. One of manual, scheduled, post_deploy. Defaults to manual. |
URL validation (SSRF protection)
url must use the http or https scheme. Requests targeting any of the following are rejected with 422 Unprocessable Entity and error.code: "invalid_params":
localhost,127.0.0.1,::1,0.0.0.0- Hosts ending in
.localor.internal - IPv4 private ranges:
10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 - IPv4 link-local:
169.254.0.0/16 - IPv6 unique-local:
fd00::/8 - IPv6 link-local:
fe80::/10
Example Request
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"
}'Example Response
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-10T14:30:00Z",
"finished_at": null,
"inserted_at": "2025-06-10T14:30:00Z",
"updated_at": "2025-06-10T14:30:00Z"
},
"meta": {
"request_id": "F-mxbAQk6m9lXeQAAATj"
},
"error": null
}status is one of queued, running, completed, failed. trigger is one of manual, scheduled, post_deploy. The summary map is populated once the scan finishes and contains aggregated finding counts by domain and severity. The url you submitted is not echoed back in the response — track scans by id.
Error Response
json
// 422 Unprocessable Entity
{
"data": null,
"meta": {
"request_id": "F-mxbAQk6m9lXeQAAATj"
},
"error": {
"code": "invalid_params"
}
}Command Center
Retrieve the command center dashboard overview with finding summaries, trending issues, and overall health status.
GET /orgs/:org_id/projects/:project_id/audit/command-center?date_from=...&date_to=...Required scope: audit:read
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
date_from | string | No | Start date for the dashboard period (ISO 8601). |
date_to | string | No | End date for the dashboard period (ISO 8601). |
Example Request
bash
curl "https://app.krafter.dev/api/v1/orgs/:org_id/projects/:project_id/audit/command-center?date_from=2025-06-01T00:00:00Z&date_to=2025-06-10T23:59:59Z" \
-H "Authorization: Bearer kr_live_abc123def456"Example Response
json
{
"data": {
"org_id": "11111111-1111-1111-1111-111111111111",
"project_id": "production-website",
"period": {
"from": "2025-06-04",
"to": "2025-06-10"
},
"health_score": 67,
"unresolved_findings": 11,
"critical_findings": 2,
"top_priorities": [
{
"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-10T14:30:00Z",
"updated_at": "2025-06-10T14:30:00Z"
}
],
"expected_impact": {
"cwv_improvement_pct": 14,
"security_risk_reduction_pct": 27,
"regression_risk_pct": 16
}
},
"meta": {
"request_id": "F-mxbAQk6m9lXeQAAATj"
},
"error": null
}health_score is computed from unresolved + critical counts (100 minus a penalty, capped at 95 penalty). top_priorities returns up to 5 unresolved findings ordered by priority.score then by created_at. expected_impact is a projected impact estimate, not a measurement. period defaults to the last 7 days when date_from/date_to are omitted.