Appearance
Policies
Each project has a single active audit policy. The policy is a free-form JSON document (config) interpreted by the scanner — there is no fixed schema, and the API does not validate individual policy fields.
Base URL: https://app.krafter.dev/api/v1
Get Current Policy
Retrieve the currently active policy for a project. If the project has no active policy yet, a default one is created on the fly and returned.
GET /orgs/:org_id/projects/:project_id/audit/policies/currentRequired scope: audit:read
Example Request
bash
curl https://app.krafter.dev/api/v1/orgs/:org_id/projects/:project_id/audit/policies/current \
-H "Authorization: Bearer kr_live_abc123def456"Example Response
json
{
"data": {
"id": "b9c8d7e6-5a4f-3e2d-1c0b-9a8b7c6d5e4f",
"name": "Default Audit Policy",
"org_id": "11111111-1111-1111-1111-111111111111",
"project_id": "production-website",
"config": {
"severity_rules": {
"security": "critical",
"performance": "high",
"accessibility": "medium",
"seo": "low"
},
"sla_hours": {
"critical": 24,
"high": 72,
"medium": 168,
"low": 336
},
"alert_routing": {
"critical": ["slack", "email"],
"high": ["slack"]
}
},
"active": true,
"updated_at": "2025-06-08T12:00:00Z"
},
"meta": {
"request_id": "R-zjn9daW3girMMMPfv"
},
"error": null
}The response shape is {id, name, org_id, project_id, config, active, updated_at}. The example config above is the default policy that the API creates the first time the endpoint is hit for a project — it is not a fixed schema. Once you write your own config via Update Policy, config echoes back exactly what you sent.
Update Policy
Replace the current policy's name and config. The policy is upserted: if no active policy exists, one is created; otherwise, the existing active policy is updated in place. The config field is opaque — the API stores it as-is and does not validate its shape.
PUT /orgs/:org_id/projects/:project_id/audit/policies/currentRequired scope: audit:write
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | No | Human-readable policy name. Defaults to "Default Audit Policy" when omitted. |
config | object | Yes | Free-form policy configuration. Stored opaquely — any JSON object is accepted. |
Full replacement
The config field is replaced wholesale, not merged. Always send the complete config you want to retain.
Example Request
bash
curl -X PUT https://app.krafter.dev/api/v1/orgs/:org_id/projects/:project_id/audit/policies/current \
-H "Authorization: Bearer kr_live_abc123def456" \
-H "Content-Type: application/json" \
-d '{
"name": "Strict Production Policy",
"config": {
"severity_rules": {
"security": "critical",
"performance": "high",
"accessibility": "high",
"seo": "medium"
},
"sla_hours": {
"critical": 12,
"high": 48,
"medium": 120,
"low": 240
},
"alert_routing": {
"critical": ["slack", "email", "pagerduty"],
"high": ["slack", "email"]
}
}
}'Example Response
The response is the full policy shape (same as Get Current Policy), reflecting the applied changes.
Error Response
json
// 422 Unprocessable Entity — changeset failed (e.g. config is not a map)
{
"data": null,
"meta": {
"request_id": "S-akoaebX4hjsNNNQgw"
},
"error": {
"code": "invalid_params"
}
}Test Policy
Run a quick what-if simulation against the project's current findings. The endpoint counts findings in the project, returns how many would currently be classified as critical, and echoes the submitted config back in config_preview. The current implementation does not yet apply the supplied config to override severities — it only reports the existing project totals so callers can wire up the simulation UI without surprises.
POST /orgs/:org_id/projects/:project_id/audit/policies/testRequired scope: audit:write
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
config | object | No | Free-form policy configuration to preview. Echoed back as config_preview. |
Example Request
bash
curl -X POST https://app.krafter.dev/api/v1/orgs/:org_id/projects/:project_id/audit/policies/test \
-H "Authorization: Bearer kr_live_abc123def456" \
-H "Content-Type: application/json" \
-d '{
"config": {
"severity_rules": {
"security": "critical",
"performance": "high"
}
}
}'Example Response
json
{
"data": {
"simulated_findings": 42,
"escalated_to_critical": 3,
"config_preview": {
"severity_rules": {
"security": "critical",
"performance": "high"
}
}
},
"meta": {
"request_id": "T-blpbfcY5iktOOORhx"
},
"error": null
}simulated_findings— total finding count in the project that would be evaluated by the policy.escalated_to_critical— number of findings already atcriticalseverity in the project.config_preview— theconfigyou submitted, echoed back unchanged.