Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.vigolium.com/llms.txt

Use this file to discover all available pages before exploring further.

Project Scoping

All scan endpoints support multi-tenancy via the X-Project-UUID header. When provided, scans are created and queried within the specified project. Responses include the project_uuid field to confirm the project context.
# Scope a request to a specific project
curl -s -X POST http://localhost:9002/api/scans/run \
  -H "Content-Type: application/json" \
  -H "X-Project-UUID: my-project-uuid" \
  -d '{}' | jq .
If the header is omitted, the default project is used.

Single-Target Scans

POST /api/scan-url — Scan a URL

Starts an asynchronous scan of a single URL. Equivalent to the CLI scan-url command. Returns 202 Accepted immediately with a scan ID. Request body:
FieldTypeRequiredDescription
urlstringYesTarget URL to scan
methodstringNoHTTP method (default: GET)
bodystringNoRequest body
headersmap[string]stringNoCustom request headers
modulesstringNoComma-separated module IDs to run
no_passiveboolNoSkip passive modules
# Simple GET scan
curl -s -X POST http://localhost:9002/api/scan-url \
  -H "Content-Type: application/json" \
  -H "X-Project-UUID: my-project-uuid" \
  -d '{
    "url": "https://example.com/api/users?id=1"
  }' | jq .

# POST with body and specific modules
curl -s -X POST http://localhost:9002/api/scan-url \
  -H "Content-Type: application/json" \
  -H "X-Project-UUID: my-project-uuid" \
  -d '{
    "url": "https://example.com/api/login",
    "method": "POST",
    "body": "{\"user\":\"admin\",\"pass\":\"test\"}",
    "headers": {
      "Content-Type": "application/json"
    },
    "modules": "xss-scanner,sqli-error-based"
  }' | jq .
Response (202):
{
  "project_uuid": "my-project-uuid",
  "scan_id": "550e8400-e29b-41d4-a716-446655440000",
  "status": "running",
  "message": "scan-url started for https://example.com/api/users?id=1"
}

POST /api/scan-request — Scan a Raw HTTP Request

Starts an asynchronous scan from a base64-encoded raw HTTP request. Equivalent to the CLI scan-request command. Returns 202 Accepted immediately with a scan ID. Request body:
FieldTypeRequiredDescription
raw_requeststringYesBase64-encoded raw HTTP request
target_urlstringNoOverride target URL (scheme://host) for the request
modulesstringNoComma-separated module IDs to run
no_passiveboolNoSkip passive modules
# Base64-encode a raw HTTP request
REQ_B64=$(echo -n "POST /api/login HTTP/1.1\r\nHost: example.com\r\nContent-Type: application/json\r\n\r\n{\"user\":\"admin\"}" | base64)

curl -s -X POST http://localhost:9002/api/scan-request \
  -H "Content-Type: application/json" \
  -H "X-Project-UUID: my-project-uuid" \
  -d "{
    \"raw_request\": \"$REQ_B64\",
    \"target_url\": \"https://example.com\"
  }" | jq .
Response (202):
{
  "project_uuid": "my-project-uuid",
  "scan_id": "661f9511-f3ac-52e5-b827-557766551111",
  "status": "running",
  "message": "scan-request started for https://example.com/api/login"
}
Error responses (both endpoints):
CodeCondition
400Missing required fields or invalid input
Use GET /api/scan/status to check the progress of the scan.

Scan Management

POST /api/scans/run — Run Target Scan

Triggers a background scan against target URLs. Equivalent to vigolium scan -t <url>. At least one target URL is required — use POST /api/scan-all-records to scan existing DB records. Returns 202 Accepted on success, 200 OK for dry runs, or 409 Conflict if a scan is already running. Request body:
FieldTypeRequiredDescription
targetsstring[]Yes*Target URLs (like -t).
urlsstring[]Yes*Alias for targets. Both fields are merged if provided.
dry_runboolNoValidate params and create scan record without launching the runner
strategystringNoStrategy preset: lite, balanced, deep
onlystringNoSingle phase isolation (like --only). Accepts aliases.
skipstring[]NoSkip specific phases (like --skip). Accepts aliases.
modulesstring[]NoModule IDs with fuzzy match (like -m)
module_tagsstring[]NoFilter modules by tag (like --module-tag)
concurrencyintNoNumber of parallel workers
timeoutstringNoRequest timeout as Go duration (e.g. "30s")
max_per_hostintNoMaximum concurrent requests per host
rate_limitintNoMaximum request submissions per second
scanning_max_durationstringNoGlobal max scan duration as Go duration. Per-phase durations are derived automatically using duration_factor from the scanning pace config (e.g. spidering gets 0.15 × max_duration).
scope_originstringNoScope origin mode: all, relaxed, balanced, strict
heuristics_checkstringNoHeuristics check level: none, basic, advanced
headersmap[string]stringNoCustom HTTP headers included in all requests
scanning_profilestringNoScanning profile name or path
Source-aware whitebox analysis lives in agent mode. Use POST /api/agent/run/swarm with a source field for AI-driven route extraction + code audit + targeted scanning, POST /api/agent/run/autopilot for autonomous pentest with code context, or run vigolium agent archon standalone for a multi-phase whitebox audit.
Phase duration factors: The scanning_max_duration field sets the global max duration. Each phase derives its own limit by multiplying the global value by its duration_factor from the scanning pace config. Default factors:
PhaseDefault FactorExample (2h global)
Spidering0.1518m
External Harvester0.2024m
Dynamic-Assessment1.002h
KnownIssueScan3.006h
Per-phase max_duration overrides in the YAML config take precedence over the factor calculation. Phase names and aliases:
Canonical nameAliases
discoverydeparos, discover
spideringspitolas
dynamic-assessmentaudit, dast, assessment
extensionext
ingestion
external-harvest
known-issue-scan
Note: only and skip are mutually exclusive — providing both returns 400.
# Scan a target with default strategy
curl -s -X POST http://localhost:9002/api/scans/run \
  -H "Content-Type: application/json" \
  -H "X-Project-UUID: my-project-uuid" \
  -d '{
    "targets": ["https://example.com"]
  }' | jq .

# Using "urls" alias
curl -s -X POST http://localhost:9002/api/scans/run \
  -H "Content-Type: application/json" \
  -d '{
    "urls": ["https://example.com", "https://api.example.com"]
  }' | jq .

# Lite strategy, discovery only, with custom headers
curl -s -X POST http://localhost:9002/api/scans/run \
  -H "Content-Type: application/json" \
  -H "X-Project-UUID: my-project-uuid" \
  -d '{
    "targets": ["https://example.com"],
    "strategy": "lite",
    "only": "discovery",
    "headers": {"Authorization": "Bearer tok123"},
    "concurrency": 20,
    "timeout": "10s"
  }' | jq .

# Dry run — validate params without launching the scan
curl -s -X POST http://localhost:9002/api/scans/run \
  -H "Content-Type: application/json" \
  -H "X-Project-UUID: my-project-uuid" \
  -d '{
    "targets": ["https://example.com"],
    "strategy": "deep",
    "dry_run": true
  }' | jq .

Response (202):
{
  "project_uuid": "my-project-uuid",
  "scan_id": "550e8400-e29b-41d4-a716-446655440000",
  "status": "running",
  "message": "scan started",
  "targets_count": 1,
  "scan_mode": "target"
}
Response — dry run (200):
{
  "project_uuid": "my-project-uuid",
  "scan_id": "550e8400-e29b-41d4-a716-446655440000",
  "status": "dry_run",
  "message": "scan record created (dry run)",
  "targets_count": 1,
  "scan_mode": "target"
}
Scan Configuration output: When a scan starts (via API or CLI), the runner logs a configuration summary to stderr showing the effective settings. This is useful for verifying that scanning_max_duration and per-phase duration factors are applied correctly.
✦ Scan Configuration
  ℹ Project: my-project-uuid
  ℹ Strategy: balanced
  ℹ Phases: ✓ ExternalHarvest (24m0s, x0.2) | ✓ Spidering (18m0s, x0.2) | ✓ Discovery
            ✓ KnownIssueScan (6h0m0s, x3.0) | ✓ Dynamic-Assessment (2h0m0s, x1.0)
  ℹ Speed: concurrency=50 | rate-limit=100 | max-per-host=10
  ℹ Modules: 144 active, 91 passive
Error responses:
CodeCondition
400Missing targets, invalid parameters, or missing DB
409A scan is already running
500Failed to create scan runner

GET /api/scan/status — Scan Status

Returns the status of the current or most recent scan. The status field reflects pause state when applicable.
curl -s http://localhost:9002/api/scan/status \
  -H "X-Project-UUID: my-project-uuid" | jq .
Running:
{
  "project_uuid": "my-project-uuid",
  "scan_id": "scan-abc123",
  "running": true,
  "status": "running"
}
Paused:
{
  "project_uuid": "my-project-uuid",
  "scan_id": "scan-abc123",
  "running": true,
  "status": "paused"
}
Idle (no scan running):
{
  "project_uuid": "my-project-uuid",
  "running": false,
  "status": "idle"
}

DELETE /api/scan — Cancel Scan

Cancels a running scan.
curl -s -X DELETE http://localhost:9002/api/scan \
  -H "X-Project-UUID: my-project-uuid" | jq .
{
  "project_uuid": "my-project-uuid",
  "scan_id": "scan-abc123",
  "running": true,
  "status": "cancelling",
  "message": "scan cancellation requested"
}

Scan History

GET /api/scans — List Scans

Returns paginated scan history ordered by creation date (newest first). Query parameters:
ParameterTypeDefaultDescription
limitint50Number of scans to return (max 500)
offsetint0Offset for pagination
# List recent scans
curl -s http://localhost:9002/api/scans \
  -H "X-Project-UUID: my-project-uuid" | jq .

# Paginate
curl -s 'http://localhost:9002/api/scans?limit=10&offset=0' \
  -H "X-Project-UUID: my-project-uuid" | jq .
{
  "project_uuid": "my-project-uuid",
  "data": [
    {
      "uuid": "scan-abc123",
      "name": "api-scan",
      "status": "completed",
      "scan_source": "api",
      "scan_mode": "incremental",
      "modules": "all",
      "total_findings": 5,
      "processed_count": 150,
      "started_at": "2026-02-16T15:00:00Z",
      "finished_at": "2026-02-16T15:05:00Z",
      "created_at": "2026-02-16T15:00:00Z"
    }
  ],
  "total": 12,
  "limit": 50,
  "offset": 0,
  "has_more": false
}

GET /api/scans/:uuid — Get Scan Detail

Returns a single scan by UUID.
curl -s http://localhost:9002/api/scans/scan-abc123 \
  -H "X-Project-UUID: my-project-uuid" | jq .
Error responses:
CodeCondition
400Missing UUID
404Scan not found
503Database unavailable

DELETE /api/scans/:uuid — Delete Scan

Deletes a scan record by UUID.
curl -s -X DELETE http://localhost:9002/api/scans/scan-abc123 \
  -H "X-Project-UUID: my-project-uuid" | jq .
{
  "project_uuid": "my-project-uuid",
  "message": "scan deleted",
  "uuid": "scan-abc123"
}
Error responses:
CodeCondition
400Missing UUID
404Scan not found
503Database unavailable

POST /api/scans/:uuid/stop — Stop a Running Scan

Stops a specific running scan by UUID. The scan must be the currently active scan. Workers finish their current tasks before fully stopping.
curl -s -X POST http://localhost:9002/api/scans/scan-abc123/stop \
  -H "X-Project-UUID: my-project-uuid" | jq .
{
  "project_uuid": "my-project-uuid",
  "scan_id": "scan-abc123",
  "running": true,
  "status": "cancelling",
  "message": "scan stop requested, workers finishing current tasks"
}
Error responses:
CodeCondition
400Missing UUID
409No scan running, or UUID is not the active scan

POST /api/scans/:uuid/pause — Pause a Running Scan

Pauses a running scan. Workers finish their current item then block until resumed. The scan status is set to "paused" in the database.
curl -s -X POST http://localhost:9002/api/scans/scan-abc123/pause \
  -H "X-Project-UUID: my-project-uuid" | jq .
{
  "project_uuid": "my-project-uuid",
  "scan_id": "scan-abc123",
  "running": true,
  "status": "paused",
  "message": "scan paused, workers finishing current items"
}
Error responses:
CodeCondition
400Missing UUID
409No scan running, UUID is not the active scan, or scan is already paused

POST /api/scans/:uuid/resume — Resume a Paused Scan

Resumes a previously paused scan. Blocked workers continue processing items and the scan status is set back to "running".
curl -s -X POST http://localhost:9002/api/scans/scan-abc123/resume \
  -H "X-Project-UUID: my-project-uuid" | jq .
{
  "project_uuid": "my-project-uuid",
  "scan_id": "scan-abc123",
  "running": true,
  "status": "running",
  "message": "scan resumed"
}
Error responses:
CodeCondition
400Missing UUID
409No scan running, UUID is not the active scan, or scan is not paused

GET /api/scans/:uuid/logs — Get Scan Logs

Returns log entries for a scan, ordered by creation time ascending. Logs are captured at multiple levels:
  • Structured events (info, warn, error): Phase lifecycle events (start, complete, fail, skip), scan start/finish, pause/resume, configuration snapshots, and panic recovery.
  • Raw console output (trace): Every line printed to the terminal during the scan, with ANSI color codes stripped. This includes phase headers, traffic lines (❯ spider │ [200] GET ...), progress feedback, and scan configuration banners.
Query parameters:
ParameterTypeDefaultDescription
limitint100Number of log entries to return
offsetint0Offset for pagination
levelstringFilter by log level: trace, info, warn, error. Use trace to replay raw console output.
phasestringFilter by scan phase: config, heuristics, harvest, discovery, spidering, known-issue-scan, dynamic-assessment (alias audit), seed. Use config to retrieve the scan configuration snapshot.
# Get all logs for a scan
curl -s http://localhost:9002/api/scans/scan-abc123/logs \
  -H "X-Project-UUID: my-project-uuid" | jq .

# Filter by level with pagination
curl -s 'http://localhost:9002/api/scans/scan-abc123/logs?level=error&limit=20' \
  -H "X-Project-UUID: my-project-uuid" | jq .

# Replay raw console output (terminal log)
curl -s 'http://localhost:9002/api/scans/scan-abc123/logs?level=trace' \
  -H "X-Project-UUID: my-project-uuid" | jq .

# Get only spidering phase logs
curl -s 'http://localhost:9002/api/scans/scan-abc123/logs?phase=spidering' \
  -H "X-Project-UUID: my-project-uuid" | jq .

# Get scan configuration snapshot
curl -s 'http://localhost:9002/api/scans/scan-abc123/logs?phase=config' \
  -H "X-Project-UUID: my-project-uuid" | jq .

# Combine filters: structured discovery events only
curl -s 'http://localhost:9002/api/scans/scan-abc123/logs?level=info&phase=discovery' \
  -H "X-Project-UUID: my-project-uuid" | jq .
Response — structured events (level=info):
{
  "project_uuid": "my-project-uuid",
  "logs": [
    {
      "id": 1,
      "scan_uuid": "scan-abc123",
      "level": "info",
      "message": "scan started",
      "created_at": "2026-02-16T15:00:00Z"
    },
    {
      "id": 2,
      "scan_uuid": "scan-abc123",
      "level": "info",
      "phase": "config",
      "message": "scan configuration snapshot",
      "metadata": "{\"project_uuid\":\"my-project-uuid\",\"targets\":[\"https://example.com\"],\"strategy\":\"balanced\",\"concurrency\":50,\"rate_limit\":100,\"max_per_host\":10,\"active_modules\":144,\"passive_modules\":91,\"spidering_enabled\":true,\"discovery_enabled\":true,\"known_issue_scan_enabled\":false}",
      "created_at": "2026-02-16T15:00:00Z"
    },
    {
      "id": 3,
      "scan_uuid": "scan-abc123",
      "level": "info",
      "phase": "heuristics",
      "message": "phase started",
      "created_at": "2026-02-16T15:00:01Z"
    },
    {
      "id": 4,
      "scan_uuid": "scan-abc123",
      "level": "info",
      "phase": "heuristics",
      "message": "phase completed",
      "created_at": "2026-02-16T15:00:02Z"
    },
    {
      "id": 5,
      "scan_uuid": "scan-abc123",
      "level": "info",
      "phase": "spidering",
      "message": "phase started",
      "created_at": "2026-02-16T15:00:02Z"
    },
    {
      "id": 6,
      "scan_uuid": "scan-abc123",
      "level": "info",
      "phase": "spidering",
      "message": "phase completed",
      "created_at": "2026-02-16T15:01:30Z"
    },
    {
      "id": 7,
      "scan_uuid": "scan-abc123",
      "level": "info",
      "phase": "discovery",
      "message": "phase started",
      "created_at": "2026-02-16T15:01:31Z"
    },
    {
      "id": 8,
      "scan_uuid": "scan-abc123",
      "level": "info",
      "phase": "discovery",
      "message": "soft-deduplicated 42 similar records",
      "created_at": "2026-02-16T15:02:30Z"
    },
    {
      "id": 9,
      "scan_uuid": "scan-abc123",
      "level": "info",
      "phase": "discovery",
      "message": "phase completed",
      "created_at": "2026-02-16T15:03:00Z"
    },
    {
      "id": 10,
      "scan_uuid": "scan-abc123",
      "level": "info",
      "phase": "audit",
      "message": "phase started",
      "metadata": "{\"active_modules\":127,\"passive_modules\":85}",
      "created_at": "2026-02-16T15:03:01Z"
    },
    {
      "id": 11,
      "scan_uuid": "scan-abc123",
      "level": "info",
      "phase": "audit",
      "message": "phase completed",
      "created_at": "2026-02-16T15:10:00Z"
    },
    {
      "id": 12,
      "scan_uuid": "scan-abc123",
      "level": "info",
      "message": "scan finished",
      "created_at": "2026-02-16T15:10:01Z"
    }
  ],
  "total": 12
}
Response — raw console output (level=trace):
{
  "project_uuid": "my-project-uuid",
  "logs": [
    {
      "id": 100,
      "scan_uuid": "scan-abc123",
      "level": "trace",
      "phase": "heuristics",
      "message": "✦ HeuristicsCheck  probing CLI target root pages to optimize phase selection",
      "created_at": "2026-02-16T15:00:01Z"
    },
    {
      "id": 101,
      "scan_uuid": "scan-abc123",
      "level": "trace",
      "phase": "heuristics",
      "message": "◆ Level: basic | Targets: 1",
      "created_at": "2026-02-16T15:00:01Z"
    },
    {
      "id": 102,
      "scan_uuid": "scan-abc123",
      "level": "trace",
      "phase": "spider",
      "message": "✦ Spidering  browser-based crawling to discover dynamic content and API endpoints",
      "created_at": "2026-02-16T15:00:02Z"
    },
    {
      "id": 103,
      "scan_uuid": "scan-abc123",
      "level": "trace",
      "phase": "spider",
      "message": "❯ spider │ [200] GET text/html http://localhost:3000/",
      "created_at": "2026-02-16T15:00:03Z"
    },
    {
      "id": 104,
      "scan_uuid": "scan-abc123",
      "level": "trace",
      "phase": "spider",
      "message": "❯ spider │ [200] GET application/json http://localhost:9002/api/projects",
      "created_at": "2026-02-16T15:00:04Z"
    },
    {
      "id": 105,
      "scan_uuid": "scan-abc123",
      "level": "trace",
      "phase": "discovery",
      "message": "✦ Discovery  ingest input + content discovery into database",
      "created_at": "2026-02-16T15:01:31Z"
    }
  ],
  "total": 580
}
Response — configuration snapshot (phase=config):
{
  "project_uuid": "my-project-uuid",
  "logs": [
    {
      "id": 2,
      "scan_uuid": "scan-abc123",
      "level": "info",
      "phase": "config",
      "message": "scan configuration snapshot",
      "metadata": "{\"project_uuid\":\"my-project-uuid\",\"targets\":[\"https://example.com\"],\"strategy\":\"balanced\",\"scanning_profile\":\"\",\"concurrency\":50,\"rate_limit\":100,\"max_per_host\":10,\"heuristics_check\":\"basic\",\"scope_origin_mode\":\"relaxed\",\"active_modules\":144,\"passive_modules\":91,\"spidering_enabled\":true,\"discovery_enabled\":true,\"known_issue_scan_enabled\":false,\"external_harvest\":false,\"skip_dynamic\":false}",
      "created_at": "2026-02-16T15:00:00Z"
    }
  ],
  "total": 1
}
Log entry fields:
FieldTypeDescription
idintAuto-incrementing log entry ID
scan_uuidstringUUID of the scan this log belongs to
levelstringLog level: trace, info, warn, or error
phasestringScan phase (see table below), or empty for global events (scan start/finish, pause/resume)
messagestringHuman-readable log message. For trace entries, this is the raw console line with ANSI codes stripped.
metadatastringOptional JSON blob with structured context. Present on config snapshots and phase-start events.
created_atstringISO 8601 timestamp
Phase values:
PhaseDescription
configScan configuration snapshot (logged once at scan start)
heuristicsTarget root page probing to optimize phase selection
harvestExternal URL harvesting from intelligence sources
discoveryInput ingestion + content discovery
spideringBrowser-based crawling
seedCLI target seeding (when discovery is skipped)
known-issue-scanKnown issue scan (Nuclei + Kingfisher)
dynamic-assessmentActive/passive module scanning (alias: audit)
Log levels:
LevelDescription
traceRaw console output lines (ANSI-stripped). High volume — includes traffic lines, phase banners, progress feedback. Buffered and batch-inserted every 2 seconds.
infoStructured lifecycle events: phase start/complete/skip, config snapshots, scan start/finish.
warnNon-fatal issues: phase deduplication failures, heuristics warnings.
errorPhase failures, panic recovery, critical errors.
Error responses:
CodeCondition
400Missing UUID
404Scan not found
503Database unavailable

Selective Record Scan

POST /api/scan-records — Scan Specific HTTP Records

Starts an asynchronous scan on specific HTTP records identified by UUID. Returns 202 Accepted on success or 409 Conflict if a scan is already running. Only one scan can run at a time. Request body:
FieldTypeRequiredDescription
record_uuidsstring[]YesUUIDs of HTTP records to scan
enable_modulesstring[]NoRestrict scan to specific module IDs
# Scan specific records
curl -s -X POST http://localhost:9002/api/scan-records \
  -H "Content-Type: application/json" \
  -H "X-Project-UUID: my-project-uuid" \
  -d '{
    "record_uuids": ["abc-123", "def-456", "ghi-789"]
  }' | jq .

# Scan with specific modules
curl -s -X POST http://localhost:9002/api/scan-records \
  -H "Content-Type: application/json" \
  -H "X-Project-UUID: my-project-uuid" \
  -d '{
    "record_uuids": ["abc-123"],
    "enable_modules": ["xss-scanner", "sqli-error-based"]
  }' | jq .
Response (202):
{
  "project_uuid": "my-project-uuid",
  "scan_id": "550e8400-e29b-41d4-a716-446655440000",
  "status": "running",
  "message": "selective scan started",
  "records_to_scan": 3
}
Error responses:
CodeCondition
400Missing record_uuids or no valid records found
409A scan is already running
503Database unavailable
Use GET /api/scan/status or GET /api/scans/:uuid to check scan progress.

POST /api/scan-all-records — Scan All DB Records

Scans existing HTTP records from the database with optional filtering. Equivalent to the DB-record scan mode, but as a dedicated route with rich filtering options. Returns 202 Accepted on success, 200 OK for dry runs, or 409 Conflict if a scan is already running. Request body:
FieldTypeRequiredDescription
hostnamestringNoHostname filter (supports * wildcards, e.g. *.example.com)
methodsstring[]NoHTTP methods filter (e.g. ["GET", "POST"])
pathstringNoPath filter (supports * wildcards, e.g. /api/*)
status_codesint[]NoStatus code filter (e.g. [200, 301])
sourcestringNoRecord source filter (e.g. ingest-server, scanner)
searchstringNoSearch across URL and path
min_risk_scoreintNoMinimum risk score filter
remarkstringNoRemark substring filter
forceboolNoForce full rescan (scan mode full vs incremental)
dry_runboolNoCount matching records without launching the scan
modulesstring[]NoModule IDs with fuzzy match (like -m)
module_tagsstring[]NoFilter modules by tag (like --module-tag)
concurrencyintNoNumber of parallel workers
timeoutstringNoRequest timeout as Go duration (e.g. "30s")
max_per_hostintNoMaximum concurrent requests per host
rate_limitintNoMaximum request submissions per second
scanning_max_durationstringNoGlobal max scan duration as Go duration. Per-phase durations are derived using duration_factor (see phase duration factors above).
heuristics_checkstringNoHeuristics check level: none, basic, advanced
headersmap[string]stringNoCustom HTTP headers included in all requests
scanning_profilestringNoScanning profile name or path
# Scan all records (no filters)
curl -s -X POST http://localhost:9002/api/scan-all-records \
  -H "Content-Type: application/json" \
  -H "X-Project-UUID: my-project-uuid" \
  -d '{}' | jq .

# Scan only records matching a hostname
curl -s -X POST http://localhost:9002/api/scan-all-records \
  -H "Content-Type: application/json" \
  -H "X-Project-UUID: my-project-uuid" \
  -d '{
    "hostname": "*.example.com",
    "modules": ["xss-scanner", "sqli-error-based"]
  }' | jq .

# Scan POST requests with high risk score
curl -s -X POST http://localhost:9002/api/scan-all-records \
  -H "Content-Type: application/json" \
  -d '{
    "methods": ["POST", "PUT"],
    "min_risk_score": 5,
    "force": true
  }' | jq .

# Dry run — count matching records without scanning
curl -s -X POST http://localhost:9002/api/scan-all-records \
  -H "Content-Type: application/json" \
  -d '{
    "hostname": "api.example.com",
    "dry_run": true
  }' | jq .
Response (202):
{
  "project_uuid": "my-project-uuid",
  "scan_id": "550e8400-e29b-41d4-a716-446655440000",
  "status": "running",
  "message": "all-records scan started",
  "records_to_scan": 142,
  "scan_mode": "full"
}
Response — dry run (200):
{
  "project_uuid": "my-project-uuid",
  "scan_id": "550e8400-e29b-41d4-a716-446655440000",
  "status": "dry_run",
  "message": "scan record created (dry run)",
  "records_to_scan": 142,
  "scan_mode": "incremental"
}
Error responses:
CodeCondition
400No records match filters, or invalid params
409A scan is already running
503Database unavailable

Source Code Upload

Source code uploads for AI-driven analysis (swarm, autopilot, archon) are handled via the cloud-storage API. See Storage API:
  • POST /api/storage/upload-source — upload a source archive (zip, tar.gz, tar.bz2, tar.xz)
  • GET /api/storage/source/:key — download a previously-uploaded archive
  • POST /api/storage/presign — get a presigned URL for direct client-side upload
The returned storage_url (e.g. gs://<project-uuid>/ugc/source.tar.gz) can be passed to --source (CLI) or the source field on POST /api/agent/run/{swarm,autopilot,query}.