BETA
Skip to content

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/current

Required 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/current

Required scope: audit:write

Request Body

FieldTypeRequiredDescription
namestringNoHuman-readable policy name. Defaults to "Default Audit Policy" when omitted.
configobjectYesFree-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/test

Required scope: audit:write

Request Body

FieldTypeRequiredDescription
configobjectNoFree-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 at critical severity in the project.
  • config_preview — the config you submitted, echoed back unchanged.

Built by Krafter Studio