Skip to content

Discovery API

The Discovery API enables automated rule discovery from project artifacts such as configuration files, linter configs, and documentation.

Endpoints

Start a discovery scan

POST /api/v1/discover/scan

Request body:

{
  "sources": ["policy_document", "claude_md", "linter_config", "code_patterns"],
  "file_contents": {
    "CLAUDE.md": "# CLAUDE.md\n\n## Coding Conventions\n- Use snake_case...",
    ".eslintrc.json": "{\"rules\": {\"no-console\": \"error\"}}"
  },
  "repository": "my-org/my-project"
}
Field Type Required Description
sources array of strings Yes Analyzer types to run. Values: policy_document, claude_md, linter_config, code_patterns.
file_contents object Yes Map of file paths to their contents.
repository string No Repository identifier for provenance tracking.

Response (202 Accepted):

{
  "scan_id": "a1b2c3d4-...",
  "status": "pending",
  "created_at": "2026-04-26T10:00:00Z"
}

Get scan status

GET /api/v1/discover/scans/{scan_id}

Response:

{
  "scan_id": "a1b2c3d4-...",
  "status": "completed",
  "candidates_count": 12,
  "created_at": "2026-04-26T10:00:00Z",
  "completed_at": "2026-04-26T10:00:15Z"
}

Status values: pending, running, completed, failed.

List candidates

GET /api/v1/discover/scans/{scan_id}/candidates

Query parameters:

Param Type Default Description
status string all Filter by pending, approved, dismissed.
min_confidence float 0.0 Minimum confidence score (0.0 -- 1.0).

Response:

{
  "candidates": [
    {
      "id": "c1d2e3f4-...",
      "statement": "All public API functions must have type hints.",
      "confidence": 0.92,
      "source_file": "CLAUDE.md",
      "source_line": 45,
      "suggested_metadata": {
        "scope": "backend",
        "modality": "MUST",
        "severity": "medium",
        "tags": ["typing", "api"]
      },
      "status": "pending"
    }
  ],
  "total": 12
}

Approve a candidate

POST /api/v1/discover/candidates/{candidate_id}/approve

Request body (optional):

{
  "statement": "All public API functions must have type hints and Google-style docstrings.",
  "metadata_overrides": {
    "severity": "high"
  }
}

Approving a candidate creates a rule through the standard rule creation flow. The response returns the created rule.

Response (201 Created):

{
  "rule_id": "r1s2t3u4-...",
  "candidate_id": "c1d2e3f4-...",
  "status": "approved"
}

Dismiss a candidate

POST /api/v1/discover/candidates/{candidate_id}/dismiss

Request body (optional):

{
  "reason": "Too specific to be a general rule"
}

Response (200 OK):

{
  "candidate_id": "c1d2e3f4-...",
  "status": "dismissed"
}