Automation API Reference
This page documents the currently exposed local API endpoints. Use it to confirm auth behavior, request shape, and operational notes before wiring the API into internal tooling.
Need stable error semantics first? Start with API Errors Catalog, then return to endpoint contracts here.
Docs > API & Automation > API Reference
Use this page when you need endpoint-level contracts, request examples, and Kubernetes/container API coverage.
Base URL and Security
http(s)://<api_bind_host>:<api_port>- Default settings:
api_bind_host=0.0.0.0,api_port=9123. - If
api_tls_enabled=true, usehttps://; self-signed mode requires client trust orcurl -kfor local testing. GET /statusis public and does not require a bearer token.- All other routes require
Authorization: Bearer <api_access_token>, including loopback calls. - Invalid or missing token returns
401with{"error":"..."}envelope.
Token generation and rotation guidance: Token & Access Guide.
Validated Runtime Notes
- Validated on March 2, 2026 against
https://192.168.1.4:9098(self-signed TLS), contract suite result: 14 passed. notification_trigger_modemust bescan_completeorwaste_only. Empty strings from legacy local state should be normalized beforePATCH.GET /v1/settings/licensemay take several seconds on first call while local license state initializes.POST /v1/cloud-accounts/testfor unsupported providers runs format validation only and can returnok=truewith a “deep verify not implemented” message.
Cursor Pagination Envelope
List endpoints keep legacy array responses by default. Add envelope=true or provide cursor to receive an AI- and SDK-friendly page envelope.
GET /v1/findings?envelope=true&limit=50
{
"items": [],
"page": {
"limit": 50,
"next_cursor": "50",
"has_more": true
}
}Current envelope support covers /v1/scans, /v1/findings, /v1/scan-history, /v1/reports, and /v1/events.
Find a route
Search by method, path, or endpoint purpose before jumping into the full reference section below.
Showing all indexed routes.
Runtime & Settings
Status, metadata, and runtime policy endpoints.
12 routes
Runtime & Settings
Status, metadata, and runtime policy endpoints.
/status
Health and runtime metadata.
/v1/meta/capabilities
Current API capability groups and route inventory.
/v1/openapi.json
Machine-readable OpenAPI 3.1 route contract.
/v1/meta/error-model
Error envelope compatibility and status semantics.
/v1/meta/compatibility
Versioning, pagination, webhook signing, and deprecation policy.
/v1/settings/general
General runtime settings snapshot.
/v1/settings/general
Update general runtime settings.
/v1/settings/network
Network/proxy/API listener settings snapshot.
/v1/settings/network
Update network and local API listener settings.
/v1/settings/scan-policy
Global/provider scan policy settings snapshot.
/v1/settings/scan-policy
Update scan thresholds and provider policy overrides.
/v1/settings/license
Local license-derived policy snapshot.
Scans & Findings
Scan creation, progress, findings, and history endpoints.
13 routes
Scans & Findings
Scan creation, progress, findings, and history endpoints.
/scan
Legacy alias for creating a scan job.
/api/scan
Legacy alias for creating a scan job.
/v1/scans
List scan jobs with optional status filter.
/v1/scans
Create asynchronous scan job.
/v1/scans/:scan_id
Get scan job state and result summary.
/v1/scans/:scan_id/progress
Get progress snapshot for one scan job.
/v1/scans/:scan_id/cancel
Cancel a queued scan job.
/v1/findings
List current findings dataset.
/v1/findings/handled
List handled resource IDs.
/v1/findings/:resource_id/handled
Mark one resource as handled.
/v1/scan-history
List scan history summaries.
/v1/scan-history/:history_id
Get one scan history record detail.
/v1/scan-history/:history_id
Delete one scan history record.
Reports & Events
Report artifacts, event feed, and event type discovery.
6 routes
Reports & Events
Report artifacts, event feed, and event type discovery.
/v1/reports/generate
Generate report artifact (json/csv/pdf).
/v1/reports
List generated report artifacts.
/v1/reports/:report_id
Get one report artifact metadata.
/v1/reports/:report_id/download
Download report file bytes.
/v1/events
List recent local API/audit events.
/v1/events/types
List supported event type names.
Kubernetes & Containers
Local-first Kubernetes scan, inventory, governance reports, and MCP tool endpoints.
13 routes
Kubernetes & Containers
Local-first Kubernetes scan, inventory, governance reports, and MCP tool endpoints.
/v1/k8s/contextsList contexts from a local kubeconfig path.
/v1/k8s/scansRun a Kubernetes-only local kubectl scan.
/v1/k8s/findingsReturn Kubernetes waste findings.
/v1/k8s/nodesReturn scanned node inventory.
/v1/k8s/podsReturn pod inventory across namespaces.
/v1/k8s/workloadsReturn deployment, StatefulSet, and DaemonSet inventory.
/v1/k8s/persistent-volumesReturn PersistentVolume inventory.
/v1/k8s/persistent-volume-claimsReturn PersistentVolumeClaim inventory.
/v1/k8s/servicesReturn Service inventory and exposure signals.
/v1/reports/k8s-governanceReturn Kubernetes governance report summary.
/v1/reports/k8s-action-planReturn Kubernetes cleanup action plan.
/v1/mcp/tools/k8s-governanceMCP tool payload for Kubernetes governance context.
/v1/mcp/tools/k8s-action-planMCP tool payload for Kubernetes action planning.
Accounts & Proxies
Cloud account inventory, account CRUD, and proxy profile endpoints.
13 routes
Accounts & Proxies
Cloud account inventory, account CRUD, and proxy profile endpoints.
/v1/accounts
List selectable account IDs.
/v1/cloud-accounts
List cloud account records (masked credentials).
/v1/cloud-accounts
Create cloud account record.
/v1/cloud-accounts/:account_id
Read one cloud account record.
/v1/cloud-accounts/:account_id
Update one cloud account record.
/v1/cloud-accounts/:account_id
Delete one cloud account record.
/v1/cloud-accounts/test
Run provider credential connectivity test.
/v1/proxies
List proxy profiles.
/v1/proxies
Create proxy profile.
/v1/proxies/:proxy_id
Read one proxy profile.
/v1/proxies/:proxy_id
Update proxy profile.
/v1/proxies/:proxy_id
Delete proxy profile.
/v1/proxies/test
Run proxy connectivity diagnostics.
Notifications & Schedules
Notification channels, dispatch policy, and recurring scan schedules.
12 routes
Notifications & Schedules
Notification channels, dispatch policy, and recurring scan schedules.
/v1/notifications/channels
List notification channels.
/v1/notifications/channels
Create notification channel.
/v1/notifications/channels/:channel_id
Update notification channel.
/v1/notifications/channels/:channel_id
Delete notification channel.
/v1/notifications/channels/test
Run notification channel delivery diagnostics.
/v1/notifications/policy
Get scan notification trigger mode.
/v1/notifications/policy
Update scan notification trigger mode.
/v1/schedules
List persisted schedules.
/v1/schedules
Create schedule with embedded scan payload.
/v1/schedules/:schedule_id
Get one schedule.
/v1/schedules/:schedule_id
Delete one schedule.
/v1/schedules/:schedule_id/run-now
Trigger immediate run for an existing schedule.
Webhooks & MCP
Webhook subscriptions and MCP tool surface.
12 routes
Webhooks & MCP
Webhook subscriptions and MCP tool surface.
/v1/webhooks
List webhook subscriptions.
/v1/webhooks
Create webhook subscription.
/v1/webhooks/:webhook_id
Delete webhook subscription.
/v1/webhooks/:webhook_id/test
Send webhook test event.
/v1/mcp/capabilities
Get MCP beta tool capability map.
/v1/mcp/tools/run-scan
MCP beta: trigger scan tool.
/v1/mcp/tools/get-scan/:scan_id
MCP beta: query scan tool state.
/v1/mcp/tools/settingsMCP beta: read settings snapshot.
/v1/mcp/tools/settings/generalMCP beta: update general settings.
/v1/mcp/tools/scan-policyMCP beta: update scan policy.
/v1/mcp/tools/reportsMCP beta: list report artifacts.
/v1/mcp/tools/reports/:report_idMCP beta: retrieve one report artifact.
GET /status
Health endpoint for liveness checks and runtime metadata.
Auth: Not required.
curl -k "https://127.0.0.1:9123/status"{
"status": "running",
"version": "2.3.9",
"api_version": "v1",
"listen_host": "0.0.0.0",
"transport": "https",
"remote_auth": "bearer_token_required",
"loopback_without_token": false
}Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k "https://127.0.0.1:9123/status"
import json
import ssl
import urllib.request
req = urllib.request.Request(
"https://127.0.0.1:9123/status",
data=None,
headers={ },
method="GET"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const res = await fetch("https://127.0.0.1:9123/status", {
method: "GET",
});
console.log(await res.text());
})();
GET /v1/meta/capabilities
Returns current capability groups and active route inventory for this runtime.
Auth: Bearer token required.
curl -H "Authorization: Bearer YOUR_API_TOKEN" "http://127.0.0.1:9123/v1/meta/capabilities"Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k "https://127.0.0.1:9123/v1/meta/capabilities" -H "Authorization: Bearer YOUR_API_TOKEN"
import json
import ssl
import urllib.request
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/meta/capabilities",
data=None,
headers={ "Authorization": "Bearer YOUR_API_TOKEN" },
method="GET"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const res = await fetch("https://127.0.0.1:9123/v1/meta/capabilities", {
method: "GET",
headers: {
Authorization: "Bearer YOUR_API_TOKEN"
},
});
console.log(await res.text());
})();
GET /v1/openapi.json
Return the current OpenAPI 3.1 route contract generated from the active local API surface.
Auth: Bearer token required.
curl -k "https://127.0.0.1:9123/v1/openapi.json" -H "Authorization: Bearer YOUR_API_TOKEN"Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k "https://127.0.0.1:9123/v1/openapi.json" -H "Authorization: Bearer YOUR_API_TOKEN"
import json
import ssl
import urllib.request
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/openapi.json",
data=None,
headers={ "Authorization": "Bearer YOUR_API_TOKEN" },
method="GET"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const res = await fetch("https://127.0.0.1:9123/v1/openapi.json", {
method: "GET",
headers: {
Authorization: "Bearer YOUR_API_TOKEN"
}
});
console.log(await res.text());
})();
GET /v1/meta/compatibility
Return the v1 compatibility policy for versioning, deprecation windows, pagination behavior, webhook signing, and error envelope stability.
Auth: Bearer token required.
curl -k "https://127.0.0.1:9123/v1/meta/compatibility" -H "Authorization: Bearer YOUR_API_TOKEN"Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k "https://127.0.0.1:9123/v1/meta/compatibility" -H "Authorization: Bearer YOUR_API_TOKEN"
import json
import ssl
import urllib.request
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/meta/compatibility",
data=None,
headers={ "Authorization": "Bearer YOUR_API_TOKEN" },
method="GET"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const res = await fetch("https://127.0.0.1:9123/v1/meta/compatibility", {
method: "GET",
headers: {
Authorization: "Bearer YOUR_API_TOKEN"
}
});
console.log(await res.text());
})();
GET /v1/meta/error-model
Documents response envelope compatibility for errors and common status codes.
Auth: Bearer token required.
curl -H "Authorization: Bearer YOUR_API_TOKEN" "http://127.0.0.1:9123/v1/meta/error-model"Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k "https://127.0.0.1:9123/v1/meta/error-model" -H "Authorization: Bearer YOUR_API_TOKEN"
import json
import ssl
import urllib.request
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/meta/error-model",
data=None,
headers={ "Authorization": "Bearer YOUR_API_TOKEN" },
method="GET"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const res = await fetch("https://127.0.0.1:9123/v1/meta/error-model", {
method: "GET",
headers: {
Authorization: "Bearer YOUR_API_TOKEN"
},
});
console.log(await res.text());
})();
GET /v1/settings/general
Returns general runtime settings such as currency, timeout, and notification trigger mode.
Auth: Bearer token required.
Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k "https://127.0.0.1:9123/v1/settings/general" -H "Authorization: Bearer YOUR_API_TOKEN"
import json
import ssl
import urllib.request
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/settings/general",
data=None,
headers={ "Authorization": "Bearer YOUR_API_TOKEN" },
method="GET"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const res = await fetch("https://127.0.0.1:9123/v1/settings/general", {
method: "GET",
headers: {
Authorization: "Bearer YOUR_API_TOKEN"
},
});
console.log(await res.text());
})();
PATCH /v1/settings/general
Updates one or more general settings. Allowed fields: currency, api_timeout_seconds, notification_trigger_mode.
Validation note: notification_trigger_mode must be scan_complete or waste_only.
Auth: Bearer token required.
curl -X PATCH "http://127.0.0.1:9123/v1/settings/general" -H "Authorization: Bearer YOUR_API_TOKEN" -H "Content-Type: application/json" -d '{"currency":"EUR","api_timeout_seconds":15}'Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k -X PATCH "https://127.0.0.1:9123/v1/settings/general" -H "Authorization: Bearer YOUR_API_TOKEN" -H "Content-Type: application/json" -d '{"currency":"USD","api_timeout_seconds":15}'
import json
import ssl
import urllib.request
payload = {"currency":"USD","api_timeout_seconds":15}
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/settings/general",
data=json.dumps(payload).encode("utf-8"),
headers={ "Authorization": "Bearer YOUR_API_TOKEN", "Content-Type": "application/json" },
method="PATCH"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const payload = {"currency":"USD","api_timeout_seconds":15};
const res = await fetch("https://127.0.0.1:9123/v1/settings/general", {
method: "PATCH",
headers: {
Authorization: "Bearer YOUR_API_TOKEN",
"Content-Type": "application/json"
},
body: JSON.stringify(payload)
});
console.log(await res.text());
})();
GET /v1/settings/network
Returns proxy mode, masked proxy endpoint, and local API network listener settings.
Auth: Bearer token required.
Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k "https://127.0.0.1:9123/v1/settings/network" -H "Authorization: Bearer YOUR_API_TOKEN"
import json
import ssl
import urllib.request
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/settings/network",
data=None,
headers={ "Authorization": "Bearer YOUR_API_TOKEN" },
method="GET"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const res = await fetch("https://127.0.0.1:9123/v1/settings/network", {
method: "GET",
headers: {
Authorization: "Bearer YOUR_API_TOKEN"
},
});
console.log(await res.text());
})();
PATCH /v1/settings/network
Updates proxy runtime and local API listener settings. When proxy_mode=custom, a valid proxy_url is required.
Auth: Bearer token required.
curl -X PATCH "http://127.0.0.1:9123/v1/settings/network" -H "Authorization: Bearer YOUR_API_TOKEN" -H "Content-Type: application/json" -d '{"proxy_mode":"none","api_tls_enabled":false}'Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k -X PATCH "https://127.0.0.1:9123/v1/settings/network" -H "Authorization: Bearer YOUR_API_TOKEN" -H "Content-Type: application/json" -d '{"proxy_mode":"none","api_tls_enabled":true}'
import json
import ssl
import urllib.request
payload = {"proxy_mode":"none","api_tls_enabled":true}
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/settings/network",
data=json.dumps(payload).encode("utf-8"),
headers={ "Authorization": "Bearer YOUR_API_TOKEN", "Content-Type": "application/json" },
method="PATCH"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const payload = {"proxy_mode":"none","api_tls_enabled":true};
const res = await fetch("https://127.0.0.1:9123/v1/settings/network", {
method: "PATCH",
headers: {
Authorization: "Bearer YOUR_API_TOKEN",
"Content-Type": "application/json"
},
body: JSON.stringify(payload)
});
console.log(await res.text());
})();
GET /v1/settings/scan-policy
Returns global scan thresholds and provider-specific policy overrides.
Auth: Bearer token required.
Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k "https://127.0.0.1:9123/v1/settings/scan-policy" -H "Authorization: Bearer YOUR_API_TOKEN"
import json
import ssl
import urllib.request
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/settings/scan-policy",
data=None,
headers={ "Authorization": "Bearer YOUR_API_TOKEN" },
method="GET"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const res = await fetch("https://127.0.0.1:9123/v1/settings/scan-policy", {
method: "GET",
headers: {
Authorization: "Bearer YOUR_API_TOKEN"
},
});
console.log(await res.text());
})();
PATCH /v1/settings/scan-policy
Updates global thresholds and provider policy map. Body accepts partial updates.
Auth: Bearer token required.
curl -X PATCH "http://127.0.0.1:9123/v1/settings/scan-policy" -H "Authorization: Bearer YOUR_API_TOKEN" -H "Content-Type: application/json" -d '{"global":{"cpu_percent":3.0,"network_mb":8.0,"lookback_days":14}}'Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k -X PATCH "https://127.0.0.1:9123/v1/settings/scan-policy" -H "Authorization: Bearer YOUR_API_TOKEN" -H "Content-Type: application/json" -d '{"global":{"cpu_percent":3.0,"network_mb":8.0,"lookback_days":14}}'
import json
import ssl
import urllib.request
payload = {"global":{"cpu_percent":3.0,"network_mb":8.0,"lookback_days":14}}
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/settings/scan-policy",
data=json.dumps(payload).encode("utf-8"),
headers={ "Authorization": "Bearer YOUR_API_TOKEN", "Content-Type": "application/json" },
method="PATCH"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const payload = {"global":{"cpu_percent":3.0,"network_mb":8.0,"lookback_days":14}};
const res = await fetch("https://127.0.0.1:9123/v1/settings/scan-policy", {
method: "PATCH",
headers: {
Authorization: "Bearer YOUR_API_TOKEN",
"Content-Type": "application/json"
},
body: JSON.stringify(payload)
});
console.log(await res.text());
})();
GET /v1/settings/license
Returns local license policy snapshot including plan type, trial status, and API availability.
Performance note: first request can be slower than other settings endpoints while runtime reads local license state.
Auth: Bearer token required.
Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k "https://127.0.0.1:9123/v1/settings/license" -H "Authorization: Bearer YOUR_API_TOKEN"
import json
import ssl
import urllib.request
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/settings/license",
data=None,
headers={ "Authorization": "Bearer YOUR_API_TOKEN" },
method="GET"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const res = await fetch("https://127.0.0.1:9123/v1/settings/license", {
method: "GET",
headers: {
Authorization: "Bearer YOUR_API_TOKEN"
},
});
console.log(await res.text());
})();
POST /scan (Legacy Alias)
Backward-compatible alias for creating scan jobs. Behavior matches POST /v1/scans.
Auth: Bearer token required.
curl -X POST "http://127.0.0.1:9123/scan" -H "Authorization: Bearer YOUR_API_TOKEN" -H "Content-Type: application/json" -d '{"selected_accounts":["profile_abc123"]}'Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k -X POST "https://127.0.0.1:9123/scan" -H "Authorization: Bearer YOUR_API_TOKEN" -H "Content-Type: application/json" -d '{"selected_accounts":["profile_abc123"]}'
import json
import ssl
import urllib.request
payload = {"selected_accounts":["profile_abc123"]}
req = urllib.request.Request(
"https://127.0.0.1:9123/scan",
data=json.dumps(payload).encode("utf-8"),
headers={ "Authorization": "Bearer YOUR_API_TOKEN", "Content-Type": "application/json" },
method="POST"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const payload = {"selected_accounts":["profile_abc123"]};
const res = await fetch("https://127.0.0.1:9123/scan", {
method: "POST",
headers: {
Authorization: "Bearer YOUR_API_TOKEN",
"Content-Type": "application/json"
},
body: JSON.stringify(payload)
});
console.log(await res.text());
})();
POST /api/scan (Legacy Alias)
Legacy path retained for older integrations. Response contract is identical to POST /v1/scans.
Auth: Bearer token required.
curl -X POST "http://127.0.0.1:9123/api/scan" -H "Authorization: Bearer YOUR_API_TOKEN"Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k -X POST "https://127.0.0.1:9123/api/scan" -H "Authorization: Bearer YOUR_API_TOKEN" -H "Content-Type: application/json" -d '{"selected_accounts":["profile_abc123"]}'
import json
import ssl
import urllib.request
payload = {"selected_accounts":["profile_abc123"]}
req = urllib.request.Request(
"https://127.0.0.1:9123/api/scan",
data=json.dumps(payload).encode("utf-8"),
headers={ "Authorization": "Bearer YOUR_API_TOKEN", "Content-Type": "application/json" },
method="POST"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const payload = {"selected_accounts":["profile_abc123"]};
const res = await fetch("https://127.0.0.1:9123/api/scan", {
method: "POST",
headers: {
Authorization: "Bearer YOUR_API_TOKEN",
"Content-Type": "application/json"
},
body: JSON.stringify(payload)
});
console.log(await res.text());
})();
GET /v1/scans
List in-memory scan jobs. Optional query params: status, limit (1-250, default 50).
Auth: Bearer token required.
Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k "https://127.0.0.1:9123/v1/scans" -H "Authorization: Bearer YOUR_API_TOKEN"
import json
import ssl
import urllib.request
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/scans",
data=None,
headers={ "Authorization": "Bearer YOUR_API_TOKEN" },
method="GET"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const res = await fetch("https://127.0.0.1:9123/v1/scans", {
method: "GET",
headers: {
Authorization: "Bearer YOUR_API_TOKEN"
},
});
console.log(await res.text());
})();
POST /v1/scans
Create an asynchronous scan job and return a scan_id immediately.
Body is optional: if omitted, runtime enqueues a full scan of configured cloud profiles.
Auth: Bearer token required.
Request body (all fields optional):
aws_profile,aws_region: legacy local AWS selector (applied only whenselected_accountsis omitted).selected_accounts: list of account IDs from/v1/accountsplus optionalaws_local:<profile>.demo_mode: if true, runs demo flow and skips report email sending.report_emails: recipients for post-scan summary delivery (up to 5 emails).
selected_accounts behavior:
- Omitted or
null: scan all configured cloud profiles. []: scan all configured cloud profiles.- Non-empty array: scan only listed IDs. Add
aws_local:<profile>entries when local AWS profiles must be included. - Validation limits: max 64 IDs, max 128 ASCII chars per ID, empty IDs are rejected.
Full scan examples:
# Option A: no body (recommended for full cloud-profile scan)
curl -X POST "http://127.0.0.1:9123/v1/scans" -H "Authorization: Bearer YOUR_API_TOKEN"
# Option B: explicit empty JSON (same behavior)
curl -X POST "http://127.0.0.1:9123/v1/scans" -H "Authorization: Bearer YOUR_API_TOKEN" -H "Content-Type: application/json" -d '{}'Targeted scan example:
curl -X POST "http://127.0.0.1:9123/v1/scans" -H "Authorization: Bearer YOUR_API_TOKEN" -H "Content-Type: application/json" -d '{
"selected_accounts": ["aws_local:prod", "profile_abc123"],
"demo_mode": false,
"report_emails": ["finops@company.com", "ops@company.com"]
}'Success response:
{
"scan_id": "f6a58c53-52ae-4cee-abf4-0f33a6d15ad9",
"status": "queued",
"message": "Scan job accepted"
}Error semantics: immediate validation/auth errors return non-2xx; runtime scan failures appear later when querying /v1/scans/:scan_id with status=failed and error text.
Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k -X POST "https://127.0.0.1:9123/v1/scans" -H "Authorization: Bearer YOUR_API_TOKEN" -H "Content-Type: application/json" -d '{"selected_accounts":["profile_abc123"],"report_emails":["ops@example.com"]}'
import json
import ssl
import urllib.request
payload = {"selected_accounts":["profile_abc123"],"report_emails":["ops@example.com"]}
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/scans",
data=json.dumps(payload).encode("utf-8"),
headers={ "Authorization": "Bearer YOUR_API_TOKEN", "Content-Type": "application/json" },
method="POST"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const payload = {"selected_accounts":["profile_abc123"],"report_emails":["ops@example.com"]};
const res = await fetch("https://127.0.0.1:9123/v1/scans", {
method: "POST",
headers: {
Authorization: "Bearer YOUR_API_TOKEN",
"Content-Type": "application/json"
},
body: JSON.stringify(payload)
});
console.log(await res.text());
})();
GET /v1/scans/:scan_id
Return current state and summary fields for one scan job.
Auth: Bearer token required.
curl -H "Authorization: Bearer YOUR_API_TOKEN" "http://127.0.0.1:9123/v1/scans/f6a58c53-52ae-4cee-abf4-0f33a6d15ad9"Response example (completed):
{
"id": "f6a58c53-52ae-4cee-abf4-0f33a6d15ad9",
"status": "completed",
"trigger_source": "api:manual",
"created_at": 1765351200,
"started_at": 1765351201,
"finished_at": 1765351260,
"resources_found": 42,
"estimated_monthly_savings": 817.35,
"selected_accounts": ["profile_abc123"],
"error": null,
"report_email_status": "sent"
}- Possible
statusvalues:queued,running,completed,failed,canceled. - If
report_emailsis set,report_email_statusmay besent,failed: ..., orskipped: .... - Unknown scan ID returns
404with{"error":"scan_id not found"}.
Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k "https://127.0.0.1:9123/v1/scans/f6a58c53-52ae-4cee-abf4-0f33a6d15ad9" -H "Authorization: Bearer YOUR_API_TOKEN"
import json
import ssl
import urllib.request
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/scans/f6a58c53-52ae-4cee-abf4-0f33a6d15ad9",
data=None,
headers={ "Authorization": "Bearer YOUR_API_TOKEN" },
method="GET"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const res = await fetch("https://127.0.0.1:9123/v1/scans/f6a58c53-52ae-4cee-abf4-0f33a6d15ad9", {
method: "GET",
headers: {
Authorization: "Bearer YOUR_API_TOKEN"
},
});
console.log(await res.text());
})();
GET /v1/scans/:scan_id/progress
Return progress snapshot for one scan, including phase and percent.
Auth: Bearer token required.
Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k "https://127.0.0.1:9123/v1/scans/f6a58c53-52ae-4cee-abf4-0f33a6d15ad9/progress" -H "Authorization: Bearer YOUR_API_TOKEN"
import json
import ssl
import urllib.request
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/scans/f6a58c53-52ae-4cee-abf4-0f33a6d15ad9/progress",
data=None,
headers={ "Authorization": "Bearer YOUR_API_TOKEN" },
method="GET"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const res = await fetch("https://127.0.0.1:9123/v1/scans/f6a58c53-52ae-4cee-abf4-0f33a6d15ad9/progress", {
method: "GET",
headers: {
Authorization: "Bearer YOUR_API_TOKEN"
},
});
console.log(await res.text());
})();
POST /v1/scans/:scan_id/cancel
Cancel a queued scan job. Running jobs currently return conflict.
Auth: Bearer token required.
Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k -X POST "https://127.0.0.1:9123/v1/scans/f6a58c53-52ae-4cee-abf4-0f33a6d15ad9/cancel" -H "Authorization: Bearer YOUR_API_TOKEN"
import json
import ssl
import urllib.request
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/scans/f6a58c53-52ae-4cee-abf4-0f33a6d15ad9/cancel",
data=None,
headers={ "Authorization": "Bearer YOUR_API_TOKEN" },
method="POST"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const res = await fetch("https://127.0.0.1:9123/v1/scans/f6a58c53-52ae-4cee-abf4-0f33a6d15ad9/cancel", {
method: "POST",
headers: {
Authorization: "Bearer YOUR_API_TOKEN"
},
});
console.log(await res.text());
})();
GET /v1/findings
Return current scan findings (same data family as Resources view).
Auth: Bearer token required.
Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k "https://127.0.0.1:9123/v1/findings" -H "Authorization: Bearer YOUR_API_TOKEN"
import json
import ssl
import urllib.request
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/findings",
data=None,
headers={ "Authorization": "Bearer YOUR_API_TOKEN" },
method="GET"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const res = await fetch("https://127.0.0.1:9123/v1/findings", {
method: "GET",
headers: {
Authorization: "Bearer YOUR_API_TOKEN"
},
});
console.log(await res.text());
})();
GET /v1/findings/handled
List handled resource IDs persisted in local state.
Auth: Bearer token required.
Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k "https://127.0.0.1:9123/v1/findings/handled" -H "Authorization: Bearer YOUR_API_TOKEN"
import json
import ssl
import urllib.request
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/findings/handled",
data=None,
headers={ "Authorization": "Bearer YOUR_API_TOKEN" },
method="GET"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const res = await fetch("https://127.0.0.1:9123/v1/findings/handled", {
method: "GET",
headers: {
Authorization: "Bearer YOUR_API_TOKEN"
},
});
console.log(await res.text());
})();
POST /v1/findings/:resource_id/handled
Mark a resource as handled with optional note and provider context.
Auth: Bearer token required.
Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k -X POST "https://127.0.0.1:9123/v1/findings/resource_vm_123/handled" -H "Authorization: Bearer YOUR_API_TOKEN"
import json
import ssl
import urllib.request
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/findings/resource_vm_123/handled",
data=None,
headers={ "Authorization": "Bearer YOUR_API_TOKEN" },
method="POST"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const res = await fetch("https://127.0.0.1:9123/v1/findings/resource_vm_123/handled", {
method: "POST",
headers: {
Authorization: "Bearer YOUR_API_TOKEN"
},
});
console.log(await res.text());
})();
GET /v1/scan-history
List historical scan summaries. Optional query params: status, limit.
Auth: Bearer token required.
Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k "https://127.0.0.1:9123/v1/scan-history" -H "Authorization: Bearer YOUR_API_TOKEN"
import json
import ssl
import urllib.request
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/scan-history",
data=None,
headers={ "Authorization": "Bearer YOUR_API_TOKEN" },
method="GET"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const res = await fetch("https://127.0.0.1:9123/v1/scan-history", {
method: "GET",
headers: {
Authorization: "Bearer YOUR_API_TOKEN"
},
});
console.log(await res.text());
})();
GET /v1/scan-history/:history_id
Get detailed history record payload including parsed results JSON.
Auth: Bearer token required.
Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k "https://127.0.0.1:9123/v1/scan-history/history_20260302_001" -H "Authorization: Bearer YOUR_API_TOKEN"
import json
import ssl
import urllib.request
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/scan-history/history_20260302_001",
data=None,
headers={ "Authorization": "Bearer YOUR_API_TOKEN" },
method="GET"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const res = await fetch("https://127.0.0.1:9123/v1/scan-history/history_20260302_001", {
method: "GET",
headers: {
Authorization: "Bearer YOUR_API_TOKEN"
},
});
console.log(await res.text());
})();
DELETE /v1/scan-history/:history_id
Delete one history record by ID.
Auth: Bearer token required.
Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k -X DELETE "https://127.0.0.1:9123/v1/scan-history/history_20260302_001" -H "Authorization: Bearer YOUR_API_TOKEN"
import json
import ssl
import urllib.request
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/scan-history/history_20260302_001",
data=None,
headers={ "Authorization": "Bearer YOUR_API_TOKEN" },
method="DELETE"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const res = await fetch("https://127.0.0.1:9123/v1/scan-history/history_20260302_001", {
method: "DELETE",
headers: {
Authorization: "Bearer YOUR_API_TOKEN"
},
});
console.log(await res.text());
})();
POST /v1/reports/generate
Generate a report artifact. Supported formats: json, csv, pdf.
Auth: Bearer token required.
Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k -X POST "https://127.0.0.1:9123/v1/reports/generate" -H "Authorization: Bearer YOUR_API_TOKEN" -H "Content-Type: application/json" -d '{"format":"pdf","include_esg":true}'
import json
import ssl
import urllib.request
payload = {"format":"pdf","include_esg":true}
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/reports/generate",
data=json.dumps(payload).encode("utf-8"),
headers={ "Authorization": "Bearer YOUR_API_TOKEN", "Content-Type": "application/json" },
method="POST"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const payload = {"format":"pdf","include_esg":true};
const res = await fetch("https://127.0.0.1:9123/v1/reports/generate", {
method: "POST",
headers: {
Authorization: "Bearer YOUR_API_TOKEN",
"Content-Type": "application/json"
},
body: JSON.stringify(payload)
});
console.log(await res.text());
})();
GET /v1/reports
List generated report artifacts from current runtime state. Optional query params: format, limit.
Auth: Bearer token required.
Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k "https://127.0.0.1:9123/v1/reports" -H "Authorization: Bearer YOUR_API_TOKEN"
import json
import ssl
import urllib.request
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/reports",
data=None,
headers={ "Authorization": "Bearer YOUR_API_TOKEN" },
method="GET"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const res = await fetch("https://127.0.0.1:9123/v1/reports", {
method: "GET",
headers: {
Authorization: "Bearer YOUR_API_TOKEN"
},
});
console.log(await res.text());
})();
GET /v1/reports/:report_id
Get one report artifact metadata record.
Auth: Bearer token required.
Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k "https://127.0.0.1:9123/v1/reports/report_20260302_001" -H "Authorization: Bearer YOUR_API_TOKEN"
import json
import ssl
import urllib.request
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/reports/report_20260302_001",
data=None,
headers={ "Authorization": "Bearer YOUR_API_TOKEN" },
method="GET"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const res = await fetch("https://127.0.0.1:9123/v1/reports/report_20260302_001", {
method: "GET",
headers: {
Authorization: "Bearer YOUR_API_TOKEN"
},
});
console.log(await res.text());
})();
GET /v1/reports/:report_id/download
Download generated report file bytes with content-type/disposition headers.
Auth: Bearer token required.
Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k "https://127.0.0.1:9123/v1/reports/report_20260302_001/download" -H "Authorization: Bearer YOUR_API_TOKEN"
import json
import ssl
import urllib.request
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/reports/report_20260302_001/download",
data=None,
headers={ "Authorization": "Bearer YOUR_API_TOKEN" },
method="GET"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const res = await fetch("https://127.0.0.1:9123/v1/reports/report_20260302_001/download", {
method: "GET",
headers: {
Authorization: "Bearer YOUR_API_TOKEN"
},
});
console.log(await res.text());
})();
GET /v1/events
List recent event/audit records (paginated by page, trimmed by limit).
Auth: Bearer token required.
Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k "https://127.0.0.1:9123/v1/events" -H "Authorization: Bearer YOUR_API_TOKEN"
import json
import ssl
import urllib.request
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/events",
data=None,
headers={ "Authorization": "Bearer YOUR_API_TOKEN" },
method="GET"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const res = await fetch("https://127.0.0.1:9123/v1/events", {
method: "GET",
headers: {
Authorization: "Bearer YOUR_API_TOKEN"
},
});
console.log(await res.text());
})();
GET /v1/events/types
Return supported event type labels for webhook and automation mapping.
Auth: Bearer token required.
Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k "https://127.0.0.1:9123/v1/events/types" -H "Authorization: Bearer YOUR_API_TOKEN"
import json
import ssl
import urllib.request
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/events/types",
data=None,
headers={ "Authorization": "Bearer YOUR_API_TOKEN" },
method="GET"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const res = await fetch("https://127.0.0.1:9123/v1/events/types", {
method: "GET",
headers: {
Authorization: "Bearer YOUR_API_TOKEN"
},
});
console.log(await res.text());
})();
GET /v1/webhooks
List configured webhook subscriptions stored in local settings.
Auth: Bearer token required.
Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k "https://127.0.0.1:9123/v1/webhooks" -H "Authorization: Bearer YOUR_API_TOKEN"
import json
import ssl
import urllib.request
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/webhooks",
data=None,
headers={ "Authorization": "Bearer YOUR_API_TOKEN" },
method="GET"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const res = await fetch("https://127.0.0.1:9123/v1/webhooks", {
method: "GET",
headers: {
Authorization: "Bearer YOUR_API_TOKEN"
},
});
console.log(await res.text());
})();
POST /v1/webhooks
Create webhook subscription with URL, event filters, active state, and optional HMAC signing secret.
Auth: Bearer token required.
Webhook signing contract
When secret is configured, deliveries include X-CWS-Event, X-CWS-Timestamp, and X-CWS-Signature. Verify sha256=<hex> with HMAC-SHA256(secret, "<timestamp>.<raw_json_body>") and reject payloads outside a 300-second replay window.
Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k -X POST "https://127.0.0.1:9123/v1/webhooks" -H "Authorization: Bearer YOUR_API_TOKEN" -H "Content-Type: application/json" -d '{"url":"https://example.com/cws-webhook","events":["scan.completed"],"is_active":true,"secret":"shared-secret"}'
import json
import ssl
import urllib.request
payload = {"url":"https://example.com/cws-webhook","events":["scan.completed"],"is_active":true,"secret":"shared-secret"}
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/webhooks",
data=json.dumps(payload).encode("utf-8"),
headers={ "Authorization": "Bearer YOUR_API_TOKEN", "Content-Type": "application/json" },
method="POST"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const payload = {"url":"https://example.com/cws-webhook","events":["scan.completed"],"is_active":true,"secret":"shared-secret"};
const res = await fetch("https://127.0.0.1:9123/v1/webhooks", {
method: "POST",
headers: {
Authorization: "Bearer YOUR_API_TOKEN",
"Content-Type": "application/json"
},
body: JSON.stringify(payload)
});
console.log(await res.text());
})();
DELETE /v1/webhooks/:webhook_id
Delete webhook subscription by ID.
Auth: Bearer token required.
Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k -X DELETE "https://127.0.0.1:9123/v1/webhooks/webhook_123" -H "Authorization: Bearer YOUR_API_TOKEN"
import json
import ssl
import urllib.request
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/webhooks/webhook_123",
data=None,
headers={ "Authorization": "Bearer YOUR_API_TOKEN" },
method="DELETE"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const res = await fetch("https://127.0.0.1:9123/v1/webhooks/webhook_123", {
method: "DELETE",
headers: {
Authorization: "Bearer YOUR_API_TOKEN"
},
});
console.log(await res.text());
})();
POST /v1/webhooks/:webhook_id/test
Send one test payload to configured webhook endpoint.
Auth: Bearer token required.
Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k -X POST "https://127.0.0.1:9123/v1/webhooks/webhook_123/test" -H "Authorization: Bearer YOUR_API_TOKEN"
import json
import ssl
import urllib.request
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/webhooks/webhook_123/test",
data=None,
headers={ "Authorization": "Bearer YOUR_API_TOKEN" },
method="POST"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const res = await fetch("https://127.0.0.1:9123/v1/webhooks/webhook_123/test", {
method: "POST",
headers: {
Authorization: "Bearer YOUR_API_TOKEN"
},
});
console.log(await res.text());
})();
GET /v1/mcp/capabilities
MCP beta capability listing for local tool integrations.
Auth: Bearer token required.
Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k "https://127.0.0.1:9123/v1/mcp/capabilities" -H "Authorization: Bearer YOUR_API_TOKEN"
import json
import ssl
import urllib.request
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/mcp/capabilities",
data=None,
headers={ "Authorization": "Bearer YOUR_API_TOKEN" },
method="GET"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const res = await fetch("https://127.0.0.1:9123/v1/mcp/capabilities", {
method: "GET",
headers: {
Authorization: "Bearer YOUR_API_TOKEN"
},
});
console.log(await res.text());
})();
POST /v1/mcp/tools/run-scan
MCP beta tool endpoint for scan trigger orchestration.
Auth: Bearer token required.
Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k -X POST "https://127.0.0.1:9123/v1/mcp/tools/run-scan" -H "Authorization: Bearer YOUR_API_TOKEN" -H "Content-Type: application/json" -d '{"demo_mode":true}'
import json
import ssl
import urllib.request
payload = {"demo_mode":true}
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/mcp/tools/run-scan",
data=json.dumps(payload).encode("utf-8"),
headers={ "Authorization": "Bearer YOUR_API_TOKEN", "Content-Type": "application/json" },
method="POST"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const payload = {"demo_mode":true};
const res = await fetch("https://127.0.0.1:9123/v1/mcp/tools/run-scan", {
method: "POST",
headers: {
Authorization: "Bearer YOUR_API_TOKEN",
"Content-Type": "application/json"
},
body: JSON.stringify(payload)
});
console.log(await res.text());
})();
GET /v1/mcp/tools/get-scan/:scan_id
MCP beta tool endpoint for scan state retrieval.
Auth: Bearer token required.
Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k "https://127.0.0.1:9123/v1/mcp/tools/get-scan/f6a58c53-52ae-4cee-abf4-0f33a6d15ad9" -H "Authorization: Bearer YOUR_API_TOKEN"
import json
import ssl
import urllib.request
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/mcp/tools/get-scan/f6a58c53-52ae-4cee-abf4-0f33a6d15ad9",
data=None,
headers={ "Authorization": "Bearer YOUR_API_TOKEN" },
method="GET"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const res = await fetch("https://127.0.0.1:9123/v1/mcp/tools/get-scan/f6a58c53-52ae-4cee-abf4-0f33a6d15ad9", {
method: "GET",
headers: {
Authorization: "Bearer YOUR_API_TOKEN"
},
});
console.log(await res.text());
})();
GET /v1/accounts
List configured cloud profiles that can be used in selected_accounts.
Auth: Bearer token required.
curl -H "Authorization: Bearer YOUR_API_TOKEN" "http://127.0.0.1:9123/v1/accounts"[
{"id":"profile_abc123","provider":"aws","name":"prod"},
{"id":"profile_xyz987","provider":"azure","name":"shared-services"}
]Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k "https://127.0.0.1:9123/v1/accounts" -H "Authorization: Bearer YOUR_API_TOKEN"
import json
import ssl
import urllib.request
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/accounts",
data=None,
headers={ "Authorization": "Bearer YOUR_API_TOKEN" },
method="GET"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const res = await fetch("https://127.0.0.1:9123/v1/accounts", {
method: "GET",
headers: {
Authorization: "Bearer YOUR_API_TOKEN"
},
});
console.log(await res.text());
})();
GET /v1/cloud-accounts
List all cloud account records with masked credential fields.
Auth: Bearer token required.
Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k "https://127.0.0.1:9123/v1/cloud-accounts" -H "Authorization: Bearer YOUR_API_TOKEN"
import json
import ssl
import urllib.request
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/cloud-accounts",
data=None,
headers={ "Authorization": "Bearer YOUR_API_TOKEN" },
method="GET"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const res = await fetch("https://127.0.0.1:9123/v1/cloud-accounts", {
method: "GET",
headers: {
Authorization: "Bearer YOUR_API_TOKEN"
},
});
console.log(await res.text());
})();
POST /v1/cloud-accounts
Create a cloud account profile for non-AWS providers.
Auth: Bearer token required.
curl -X POST "http://127.0.0.1:9123/v1/cloud-accounts" -H "Authorization: Bearer YOUR_API_TOKEN" -H "Content-Type: application/json" -d '{"provider":"alibaba","name":"prod-cn","credentials":"{\"access_key_id\":\"***\",\"access_key_secret\":\"***\"}"}'Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k -X POST "https://127.0.0.1:9123/v1/cloud-accounts" -H "Authorization: Bearer YOUR_API_TOKEN" -H "Content-Type: application/json" -d '{"provider":"alibaba","name":"prod-cn","credentials":"{\"access_key_id\":\"ALI_ACCESS_KEY_ID\",\"access_key_secret\":\"ALI_ACCESS_KEY_SECRET\"}"}'
import json
import ssl
import urllib.request
payload = {"provider":"alibaba","name":"prod-cn","credentials":"{\"access_key_id\":\"ALI_ACCESS_KEY_ID\",\"access_key_secret\":\"ALI_ACCESS_KEY_SECRET\"}"}
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/cloud-accounts",
data=json.dumps(payload).encode("utf-8"),
headers={ "Authorization": "Bearer YOUR_API_TOKEN", "Content-Type": "application/json" },
method="POST"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const payload = {"provider":"alibaba","name":"prod-cn","credentials":"{\"access_key_id\":\"ALI_ACCESS_KEY_ID\",\"access_key_secret\":\"ALI_ACCESS_KEY_SECRET\"}"};
const res = await fetch("https://127.0.0.1:9123/v1/cloud-accounts", {
method: "POST",
headers: {
Authorization: "Bearer YOUR_API_TOKEN",
"Content-Type": "application/json"
},
body: JSON.stringify(payload)
});
console.log(await res.text());
})();
GET /v1/cloud-accounts/:account_id
Get one cloud account record by ID with masked credentials.
Auth: Bearer token required.
Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k "https://127.0.0.1:9123/v1/cloud-accounts/account_123" -H "Authorization: Bearer YOUR_API_TOKEN"
import json
import ssl
import urllib.request
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/cloud-accounts/account_123",
data=None,
headers={ "Authorization": "Bearer YOUR_API_TOKEN" },
method="GET"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const res = await fetch("https://127.0.0.1:9123/v1/cloud-accounts/account_123", {
method: "GET",
headers: {
Authorization: "Bearer YOUR_API_TOKEN"
},
});
console.log(await res.text());
})();
PATCH /v1/cloud-accounts/:account_id
Update one or more cloud account fields. AWS provider is rejected by design.
Auth: Bearer token required.
Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k -X PATCH "https://127.0.0.1:9123/v1/cloud-accounts/account_123" -H "Authorization: Bearer YOUR_API_TOKEN" -H "Content-Type: application/json" -d '{"name":"prod-cn-finops","timeout_seconds":20}'
import json
import ssl
import urllib.request
payload = {"name":"prod-cn-finops","timeout_seconds":20}
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/cloud-accounts/account_123",
data=json.dumps(payload).encode("utf-8"),
headers={ "Authorization": "Bearer YOUR_API_TOKEN", "Content-Type": "application/json" },
method="PATCH"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const payload = {"name":"prod-cn-finops","timeout_seconds":20};
const res = await fetch("https://127.0.0.1:9123/v1/cloud-accounts/account_123", {
method: "PATCH",
headers: {
Authorization: "Bearer YOUR_API_TOKEN",
"Content-Type": "application/json"
},
body: JSON.stringify(payload)
});
console.log(await res.text());
})();
DELETE /v1/cloud-accounts/:account_id
Delete one cloud account profile by ID.
Auth: Bearer token required.
Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k -X DELETE "https://127.0.0.1:9123/v1/cloud-accounts/account_123" -H "Authorization: Bearer YOUR_API_TOKEN"
import json
import ssl
import urllib.request
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/cloud-accounts/account_123",
data=None,
headers={ "Authorization": "Bearer YOUR_API_TOKEN" },
method="DELETE"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const res = await fetch("https://127.0.0.1:9123/v1/cloud-accounts/account_123", {
method: "DELETE",
headers: {
Authorization: "Bearer YOUR_API_TOKEN"
},
});
console.log(await res.text());
})();
POST /v1/cloud-accounts/test
Run a connectivity/auth test using provider credentials and optional proxy profile binding.
Behavior note: unsupported providers currently run format validation only and may return ok=true with an implementation note.
Auth: Bearer token required.
Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k -X POST "https://127.0.0.1:9123/v1/cloud-accounts/test" -H "Authorization: Bearer YOUR_API_TOKEN" -H "Content-Type: application/json" -d '{"provider":"unsupported-provider","credentials":"{\"foo\":\"bar\"}"}'
import json
import ssl
import urllib.request
payload = {"provider":"unsupported-provider","credentials":"{\"foo\":\"bar\"}"}
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/cloud-accounts/test",
data=json.dumps(payload).encode("utf-8"),
headers={ "Authorization": "Bearer YOUR_API_TOKEN", "Content-Type": "application/json" },
method="POST"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const payload = {"provider":"unsupported-provider","credentials":"{\"foo\":\"bar\"}"};
const res = await fetch("https://127.0.0.1:9123/v1/cloud-accounts/test", {
method: "POST",
headers: {
Authorization: "Bearer YOUR_API_TOKEN",
"Content-Type": "application/json"
},
body: JSON.stringify(payload)
});
console.log(await res.text());
})();
GET /v1/proxies
List stored proxy profiles (username shown, password presence exposed as boolean).
Auth: Bearer token required.
Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k "https://127.0.0.1:9123/v1/proxies" -H "Authorization: Bearer YOUR_API_TOKEN"
import json
import ssl
import urllib.request
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/proxies",
data=None,
headers={ "Authorization": "Bearer YOUR_API_TOKEN" },
method="GET"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const res = await fetch("https://127.0.0.1:9123/v1/proxies", {
method: "GET",
headers: {
Authorization: "Bearer YOUR_API_TOKEN"
},
});
console.log(await res.text());
})();
POST /v1/proxies
Create a proxy profile with protocol, host, port, and optional auth credentials.
Auth: Bearer token required.
Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k -X POST "https://127.0.0.1:9123/v1/proxies" -H "Authorization: Bearer YOUR_API_TOKEN" -H "Content-Type: application/json" -d '{"name":"corp-egress-1","protocol":"http","host":"10.0.0.15","port":8080}'
import json
import ssl
import urllib.request
payload = {"name":"corp-egress-1","protocol":"http","host":"10.0.0.15","port":8080}
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/proxies",
data=json.dumps(payload).encode("utf-8"),
headers={ "Authorization": "Bearer YOUR_API_TOKEN", "Content-Type": "application/json" },
method="POST"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const payload = {"name":"corp-egress-1","protocol":"http","host":"10.0.0.15","port":8080};
const res = await fetch("https://127.0.0.1:9123/v1/proxies", {
method: "POST",
headers: {
Authorization: "Bearer YOUR_API_TOKEN",
"Content-Type": "application/json"
},
body: JSON.stringify(payload)
});
console.log(await res.text());
})();
GET /v1/proxies/:proxy_id
Read a single proxy profile by ID.
Auth: Bearer token required.
Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k "https://127.0.0.1:9123/v1/proxies/proxy_123" -H "Authorization: Bearer YOUR_API_TOKEN"
import json
import ssl
import urllib.request
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/proxies/proxy_123",
data=None,
headers={ "Authorization": "Bearer YOUR_API_TOKEN" },
method="GET"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const res = await fetch("https://127.0.0.1:9123/v1/proxies/proxy_123", {
method: "GET",
headers: {
Authorization: "Bearer YOUR_API_TOKEN"
},
});
console.log(await res.text());
})();
PATCH /v1/proxies/:proxy_id
Update one or more proxy profile fields with validation on protocol/host/port.
Auth: Bearer token required.
Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k -X PATCH "https://127.0.0.1:9123/v1/proxies/proxy_123" -H "Authorization: Bearer YOUR_API_TOKEN" -H "Content-Type: application/json" -d '{"host":"10.0.0.25","port":8081}'
import json
import ssl
import urllib.request
payload = {"host":"10.0.0.25","port":8081}
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/proxies/proxy_123",
data=json.dumps(payload).encode("utf-8"),
headers={ "Authorization": "Bearer YOUR_API_TOKEN", "Content-Type": "application/json" },
method="PATCH"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const payload = {"host":"10.0.0.25","port":8081};
const res = await fetch("https://127.0.0.1:9123/v1/proxies/proxy_123", {
method: "PATCH",
headers: {
Authorization: "Bearer YOUR_API_TOKEN",
"Content-Type": "application/json"
},
body: JSON.stringify(payload)
});
console.log(await res.text());
})();
DELETE /v1/proxies/:proxy_id
Delete one proxy profile by ID.
Auth: Bearer token required.
Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k -X DELETE "https://127.0.0.1:9123/v1/proxies/proxy_123" -H "Authorization: Bearer YOUR_API_TOKEN"
import json
import ssl
import urllib.request
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/proxies/proxy_123",
data=None,
headers={ "Authorization": "Bearer YOUR_API_TOKEN" },
method="DELETE"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const res = await fetch("https://127.0.0.1:9123/v1/proxies/proxy_123", {
method: "DELETE",
headers: {
Authorization: "Bearer YOUR_API_TOKEN"
},
});
console.log(await res.text());
})();
POST /v1/proxies/test
Run proxy diagnostics by explicit proxy URL or by referencing a stored proxy profile ID.
Auth: Bearer token required.
Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k -X POST "https://127.0.0.1:9123/v1/proxies/test" -H "Authorization: Bearer YOUR_API_TOKEN" -H "Content-Type: application/json" -d '{"proxy_url":"http://user:pass@10.0.0.15:8080"}'
import json
import ssl
import urllib.request
payload = {"proxy_url":"http://user:pass@10.0.0.15:8080"}
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/proxies/test",
data=json.dumps(payload).encode("utf-8"),
headers={ "Authorization": "Bearer YOUR_API_TOKEN", "Content-Type": "application/json" },
method="POST"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const payload = {"proxy_url":"http://user:pass@10.0.0.15:8080"};
const res = await fetch("https://127.0.0.1:9123/v1/proxies/test", {
method: "POST",
headers: {
Authorization: "Bearer YOUR_API_TOKEN",
"Content-Type": "application/json"
},
body: JSON.stringify(payload)
});
console.log(await res.text());
})();
GET /v1/notifications/channels
List all notification channels configured in local storage.
Auth: Bearer token required.
Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k "https://127.0.0.1:9123/v1/notifications/channels" -H "Authorization: Bearer YOUR_API_TOKEN"
import json
import ssl
import urllib.request
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/notifications/channels",
data=None,
headers={ "Authorization": "Bearer YOUR_API_TOKEN" },
method="GET"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const res = await fetch("https://127.0.0.1:9123/v1/notifications/channels", {
method: "GET",
headers: {
Authorization: "Bearer YOUR_API_TOKEN"
},
});
console.log(await res.text());
})();
POST /v1/notifications/channels
Create a notification channel (method + config + activation state).
Auth: Bearer token required.
Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k -X POST "https://127.0.0.1:9123/v1/notifications/channels" -H "Authorization: Bearer YOUR_API_TOKEN" -H "Content-Type: application/json" -d '{"name":"ops-email","method":"email","config":{"to":["ops@example.com"]},"enabled":true}'
import json
import ssl
import urllib.request
payload = {"name":"ops-email","method":"email","config":{"to":["ops@example.com"]},"enabled":true}
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/notifications/channels",
data=json.dumps(payload).encode("utf-8"),
headers={ "Authorization": "Bearer YOUR_API_TOKEN", "Content-Type": "application/json" },
method="POST"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const payload = {"name":"ops-email","method":"email","config":{"to":["ops@example.com"]},"enabled":true};
const res = await fetch("https://127.0.0.1:9123/v1/notifications/channels", {
method: "POST",
headers: {
Authorization: "Bearer YOUR_API_TOKEN",
"Content-Type": "application/json"
},
body: JSON.stringify(payload)
});
console.log(await res.text());
})();
PATCH /v1/notifications/channels/:channel_id
Update one or more fields of an existing notification channel.
Auth: Bearer token required.
Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k -X PATCH "https://127.0.0.1:9123/v1/notifications/channels/channel_123" -H "Authorization: Bearer YOUR_API_TOKEN" -H "Content-Type: application/json" -d '{"enabled":false}'
import json
import ssl
import urllib.request
payload = {"enabled":false}
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/notifications/channels/channel_123",
data=json.dumps(payload).encode("utf-8"),
headers={ "Authorization": "Bearer YOUR_API_TOKEN", "Content-Type": "application/json" },
method="PATCH"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const payload = {"enabled":false};
const res = await fetch("https://127.0.0.1:9123/v1/notifications/channels/channel_123", {
method: "PATCH",
headers: {
Authorization: "Bearer YOUR_API_TOKEN",
"Content-Type": "application/json"
},
body: JSON.stringify(payload)
});
console.log(await res.text());
})();
DELETE /v1/notifications/channels/:channel_id
Delete one notification channel by ID.
Auth: Bearer token required.
Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k -X DELETE "https://127.0.0.1:9123/v1/notifications/channels/channel_123" -H "Authorization: Bearer YOUR_API_TOKEN"
import json
import ssl
import urllib.request
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/notifications/channels/channel_123",
data=None,
headers={ "Authorization": "Bearer YOUR_API_TOKEN" },
method="DELETE"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const res = await fetch("https://127.0.0.1:9123/v1/notifications/channels/channel_123", {
method: "DELETE",
headers: {
Authorization: "Bearer YOUR_API_TOKEN"
},
});
console.log(await res.text());
})();
POST /v1/notifications/channels/test
Run diagnostics for a saved channel (channel_id) or an inline channel payload.
Auth: Bearer token required.
Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k -X POST "https://127.0.0.1:9123/v1/notifications/channels/test" -H "Authorization: Bearer YOUR_API_TOKEN" -H "Content-Type: application/json" -d '{"channel_id":"channel_123"}'
import json
import ssl
import urllib.request
payload = {"channel_id":"channel_123"}
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/notifications/channels/test",
data=json.dumps(payload).encode("utf-8"),
headers={ "Authorization": "Bearer YOUR_API_TOKEN", "Content-Type": "application/json" },
method="POST"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const payload = {"channel_id":"channel_123"};
const res = await fetch("https://127.0.0.1:9123/v1/notifications/channels/test", {
method: "POST",
headers: {
Authorization: "Bearer YOUR_API_TOKEN",
"Content-Type": "application/json"
},
body: JSON.stringify(payload)
});
console.log(await res.text());
})();
GET /v1/notifications/policy
Get current scan notification dispatch policy (scan_complete or waste_only).
Auth: Bearer token required.
Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k "https://127.0.0.1:9123/v1/notifications/policy" -H "Authorization: Bearer YOUR_API_TOKEN"
import json
import ssl
import urllib.request
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/notifications/policy",
data=None,
headers={ "Authorization": "Bearer YOUR_API_TOKEN" },
method="GET"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const res = await fetch("https://127.0.0.1:9123/v1/notifications/policy", {
method: "GET",
headers: {
Authorization: "Bearer YOUR_API_TOKEN"
},
});
console.log(await res.text());
})();
PATCH /v1/notifications/policy
Update scan notification policy mode.
Validation note: only scan_complete and waste_only are accepted values.
Auth: Bearer token required.
Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k -X PATCH "https://127.0.0.1:9123/v1/notifications/policy" -H "Authorization: Bearer YOUR_API_TOKEN" -H "Content-Type: application/json" -d '{"notification_trigger_mode":"scan_complete"}'
import json
import ssl
import urllib.request
payload = {"notification_trigger_mode":"scan_complete"}
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/notifications/policy",
data=json.dumps(payload).encode("utf-8"),
headers={ "Authorization": "Bearer YOUR_API_TOKEN", "Content-Type": "application/json" },
method="PATCH"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const payload = {"notification_trigger_mode":"scan_complete"};
const res = await fetch("https://127.0.0.1:9123/v1/notifications/policy", {
method: "PATCH",
headers: {
Authorization: "Bearer YOUR_API_TOKEN",
"Content-Type": "application/json"
},
body: JSON.stringify(payload)
});
console.log(await res.text());
})();
GET /v1/schedules
Return all persisted schedules (sorted by created_at).
Auth: Bearer token required.
curl -H "Authorization: Bearer YOUR_API_TOKEN" "http://127.0.0.1:9123/v1/schedules"[
{
"id": "c4b4ad7d-15a2-4cc7-a71f-d6994dba9bcb",
"name": "nightly-cost-scan",
"enabled": true,
"run_at": 1762502400,
"interval_minutes": 1440,
"timezone": "UTC",
"next_run_at": 1762588800,
"last_run_at": null,
"last_scan_id": null,
"last_error": null,
"created_at": 1762499000,
"updated_at": 1762499000,
"scan": {"selected_accounts": ["profile_abc123"]}
}
]Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k "https://127.0.0.1:9123/v1/schedules" -H "Authorization: Bearer YOUR_API_TOKEN"
import json
import ssl
import urllib.request
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/schedules",
data=None,
headers={ "Authorization": "Bearer YOUR_API_TOKEN" },
method="GET"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const res = await fetch("https://127.0.0.1:9123/v1/schedules", {
method: "GET",
headers: {
Authorization: "Bearer YOUR_API_TOKEN"
},
});
console.log(await res.text());
})();
POST /v1/schedules
Create one schedule with an embedded scan payload.
Auth: Bearer token required.
Request fields:
name(optional): defaults toschedule-<timestamp>.enabled(optional): defaults totrue.run_at(optional): Unix timestamp in seconds; defaults to now/advanced schedule time.interval_minutes(optional): must be > 0 when present.timezone(optional): defaults toUTC.scan: scan payload object forwarded to scan job creation.
curl -X POST "http://127.0.0.1:9123/v1/schedules" -H "Authorization: Bearer YOUR_API_TOKEN" -H "Content-Type: application/json" -d '{
"name": "customer-a-nightly",
"enabled": true,
"run_at": 1762502400,
"interval_minutes": 1440,
"timezone": "UTC",
"scan": {
"selected_accounts": ["profile_abc123"],
"report_emails": ["service@cloud-waste-scanner.com"]
}
}'Error example:
{"error":"interval_minutes must be > 0"}Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k -X POST "https://127.0.0.1:9123/v1/schedules" -H "Authorization: Bearer YOUR_API_TOKEN" -H "Content-Type: application/json" -d '{"name":"nightly-cost-scan","enabled":true,"run_at":1762502400,"interval_minutes":1440,"timezone":"UTC","scan":{"selected_accounts":["profile_abc123"]}}'
import json
import ssl
import urllib.request
payload = {"name":"nightly-cost-scan","enabled":true,"run_at":1762502400,"interval_minutes":1440,"timezone":"UTC","scan":{"selected_accounts":["profile_abc123"]}}
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/schedules",
data=json.dumps(payload).encode("utf-8"),
headers={ "Authorization": "Bearer YOUR_API_TOKEN", "Content-Type": "application/json" },
method="POST"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const payload = {"name":"nightly-cost-scan","enabled":true,"run_at":1762502400,"interval_minutes":1440,"timezone":"UTC","scan":{"selected_accounts":["profile_abc123"]}};
const res = await fetch("https://127.0.0.1:9123/v1/schedules", {
method: "POST",
headers: {
Authorization: "Bearer YOUR_API_TOKEN",
"Content-Type": "application/json"
},
body: JSON.stringify(payload)
});
console.log(await res.text());
})();
GET /v1/schedules/:schedule_id
Return one persisted schedule by ID.
Auth: Bearer token required.
curl -H "Authorization: Bearer YOUR_API_TOKEN" "http://127.0.0.1:9123/v1/schedules/c4b4ad7d-15a2-4cc7-a71f-d6994dba9bcb"Unknown schedule returns 404 with {"error":"schedule_id not found"}.
Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k "https://127.0.0.1:9123/v1/schedules/c4b4ad7d-15a2-4cc7-a71f-d6994dba9bcb" -H "Authorization: Bearer YOUR_API_TOKEN"
import json
import ssl
import urllib.request
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/schedules/c4b4ad7d-15a2-4cc7-a71f-d6994dba9bcb",
data=None,
headers={ "Authorization": "Bearer YOUR_API_TOKEN" },
method="GET"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const res = await fetch("https://127.0.0.1:9123/v1/schedules/c4b4ad7d-15a2-4cc7-a71f-d6994dba9bcb", {
method: "GET",
headers: {
Authorization: "Bearer YOUR_API_TOKEN"
},
});
console.log(await res.text());
})();
DELETE /v1/schedules/:schedule_id
Delete one schedule record from local persistence.
Auth: Bearer token required.
curl -X DELETE -H "Authorization: Bearer YOUR_API_TOKEN" "http://127.0.0.1:9123/v1/schedules/c4b4ad7d-15a2-4cc7-a71f-d6994dba9bcb"{"status":"deleted","schedule_id":"c4b4ad7d-15a2-4cc7-a71f-d6994dba9bcb"}Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k -X DELETE "https://127.0.0.1:9123/v1/schedules/c4b4ad7d-15a2-4cc7-a71f-d6994dba9bcb" -H "Authorization: Bearer YOUR_API_TOKEN"
import json
import ssl
import urllib.request
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/schedules/c4b4ad7d-15a2-4cc7-a71f-d6994dba9bcb",
data=None,
headers={ "Authorization": "Bearer YOUR_API_TOKEN" },
method="DELETE"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const res = await fetch("https://127.0.0.1:9123/v1/schedules/c4b4ad7d-15a2-4cc7-a71f-d6994dba9bcb", {
method: "DELETE",
headers: {
Authorization: "Bearer YOUR_API_TOKEN"
},
});
console.log(await res.text());
})();
POST /v1/schedules/:schedule_id/run-now
Immediately enqueue a scan using an existing schedule payload, without waiting for next trigger time.
Auth: Bearer token required.
curl -X POST -H "Authorization: Bearer YOUR_API_TOKEN" "http://127.0.0.1:9123/v1/schedules/c4b4ad7d-15a2-4cc7-a71f-d6994dba9bcb/run-now"{
"scan_id": "68cd5a29-7d63-4f58-845a-2f31ebdd2102",
"status": "queued",
"message": "Scan job accepted"
}Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k -X POST "https://127.0.0.1:9123/v1/schedules/c4b4ad7d-15a2-4cc7-a71f-d6994dba9bcb/run-now" -H "Authorization: Bearer YOUR_API_TOKEN"
import json
import ssl
import urllib.request
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/schedules/c4b4ad7d-15a2-4cc7-a71f-d6994dba9bcb/run-now",
data=None,
headers={ "Authorization": "Bearer YOUR_API_TOKEN" },
method="POST"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const res = await fetch("https://127.0.0.1:9123/v1/schedules/c4b4ad7d-15a2-4cc7-a71f-d6994dba9bcb/run-now", {
method: "POST",
headers: {
Authorization: "Bearer YOUR_API_TOKEN"
},
});
console.log(await res.text());
})();
GET /v1/mcp/tools/settings
Return MCP-ready settings context, including general, network, scan policy, and local license-derived policy snapshots.
Auth: Bearer token required.
curl -k "https://127.0.0.1:9123/v1/mcp/tools/settings" -H "Authorization: Bearer YOUR_API_TOKEN"Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k "https://127.0.0.1:9123/v1/mcp/tools/settings" -H "Authorization: Bearer YOUR_API_TOKEN"
import json
import ssl
import urllib.request
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/mcp/tools/settings",
data=None,
headers={ "Authorization": "Bearer YOUR_API_TOKEN" },
method="GET"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const res = await fetch("https://127.0.0.1:9123/v1/mcp/tools/settings", {
method: "GET",
headers: {
Authorization: "Bearer YOUR_API_TOKEN"
}
});
console.log(await res.text());
})();
PATCH /v1/mcp/tools/settings/general
Update general settings through the MCP tool surface using the same body contract as PATCH /v1/settings/general.
Auth: Bearer token required.
Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k -X PATCH "https://127.0.0.1:9123/v1/mcp/tools/settings/general" -H "Authorization: Bearer YOUR_API_TOKEN" -H "Content-Type: application/json" -d '{"notifications_enabled":true}'
import json
import ssl
import urllib.request
payload = {"notifications_enabled":true}
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/mcp/tools/settings/general",
data=json.dumps(payload).encode("utf-8"),
headers={ "Authorization": "Bearer YOUR_API_TOKEN", "Content-Type": "application/json" },
method="PATCH"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const payload = {"notifications_enabled":true};
const res = await fetch("https://127.0.0.1:9123/v1/mcp/tools/settings/general", {
method: "PATCH",
headers: {
Authorization: "Bearer YOUR_API_TOKEN",
"Content-Type": "application/json"
},
body: JSON.stringify(payload)
});
console.log(await res.text());
})();
PATCH /v1/mcp/tools/scan-policy
Update scan policy through the MCP tool surface using the same body contract as PATCH /v1/settings/scan-policy.
Auth: Bearer token required.
Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k -X PATCH "https://127.0.0.1:9123/v1/mcp/tools/scan-policy" -H "Authorization: Bearer YOUR_API_TOKEN" -H "Content-Type: application/json" -d '{"scan_threshold_days":30}'
import json
import ssl
import urllib.request
payload = {"scan_threshold_days":30}
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/mcp/tools/scan-policy",
data=json.dumps(payload).encode("utf-8"),
headers={ "Authorization": "Bearer YOUR_API_TOKEN", "Content-Type": "application/json" },
method="PATCH"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const payload = {"scan_threshold_days":30};
const res = await fetch("https://127.0.0.1:9123/v1/mcp/tools/scan-policy", {
method: "PATCH",
headers: {
Authorization: "Bearer YOUR_API_TOKEN",
"Content-Type": "application/json"
},
body: JSON.stringify(payload)
});
console.log(await res.text());
})();
GET /v1/mcp/tools/reports
Return MCP-ready report artifact listings. Use envelope=true for cursor pagination.
Auth: Bearer token required.
Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k "https://127.0.0.1:9123/v1/mcp/tools/reports?envelope=true&limit=50" -H "Authorization: Bearer YOUR_API_TOKEN"
import json
import ssl
import urllib.request
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/mcp/tools/reports?envelope=true&limit=50",
data=None,
headers={ "Authorization": "Bearer YOUR_API_TOKEN" },
method="GET"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const res = await fetch("https://127.0.0.1:9123/v1/mcp/tools/reports?envelope=true&limit=50", {
method: "GET",
headers: {
Authorization: "Bearer YOUR_API_TOKEN"
}
});
console.log(await res.text());
})();
GET /v1/mcp/tools/reports/:report_id
Return one MCP-ready report artifact by ID.
Auth: Bearer token required.
Quick Request Examples
Use the same route with Bash, Python, or JavaScript.
curl -k "https://127.0.0.1:9123/v1/mcp/tools/reports/report_123" -H "Authorization: Bearer YOUR_API_TOKEN"
import json
import ssl
import urllib.request
req = urllib.request.Request(
"https://127.0.0.1:9123/v1/mcp/tools/reports/report_123",
data=None,
headers={ "Authorization": "Bearer YOUR_API_TOKEN" },
method="GET"
)
with urllib.request.urlopen(req, context=ssl._create_unverified_context()) as resp:
print(resp.read().decode("utf-8"))
(async () => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const res = await fetch("https://127.0.0.1:9123/v1/mcp/tools/reports/report_123", {
method: "GET",
headers: {
Authorization: "Bearer YOUR_API_TOKEN"
}
});
console.log(await res.text());
})();
Kubernetes API Runtime Notes
- Requires
kubectlon the same machine as the Cloud Waste Scanner app. - Uses the supplied kubeconfig/context with read-only Kubernetes permissions.
- Current implementation shells out to local
kubectl; it is not a direct kube-apiserver SDK client. - Supported inventory includes pods, nodes, PVs, PVCs, services, deployments, StatefulSets, and DaemonSets.
GET /v1/k8s/contexts
List kubeconfig contexts for operator selection.
Auth: Bearer token required. Kubernetes routes run locally through kubectl; credentials and scan output stay on the operator machine.
curl -k -H "Authorization: Bearer $CWS_TOKEN" "$CWS_BASE_URL/v1/k8s/contexts?path=/home/operator/.kube/config"
api("/v1/k8s/contexts?path=/home/operator/.kube/config")
await api("/v1/k8s/contexts?path=/home/operator/.kube/config");
POST /v1/k8s/scans
Run a Kubernetes-only scan and persist the latest Kubernetes inventory and findings.
Auth: Bearer token required. Kubernetes routes run locally through kubectl; credentials and scan output stay on the operator machine.
curl -k -X POST "$CWS_BASE_URL/v1/k8s/scans" -H "Authorization: Bearer $CWS_TOKEN" -H "Content-Type: application/json" -d '{"kubeconfig_path":"/home/operator/.kube/config","kube_context":"prod"}'
api("/v1/k8s/scans", "POST", {
"kubeconfig_path": "/home/operator/.kube/config",
"kube_context": "prod"
} )
await api("/v1/k8s/scans", "POST", {
"kubeconfig_path": "/home/operator/.kube/config",
"kube_context": "prod"
});
GET /v1/k8s/findings
Return Kubernetes waste findings from the latest local scan.
Auth: Bearer token required. Kubernetes routes run locally through kubectl; credentials and scan output stay on the operator machine.
curl -k -H "Authorization: Bearer $CWS_TOKEN" "$CWS_BASE_URL/v1/k8s/findings"
api("/v1/k8s/findings")
await api("/v1/k8s/findings");
GET /v1/k8s/nodes
Return node inventory and low-request utilization signals.
Auth: Bearer token required. Kubernetes routes run locally through kubectl; credentials and scan output stay on the operator machine.
curl -k -H "Authorization: Bearer $CWS_TOKEN" "$CWS_BASE_URL/v1/k8s/nodes"
api("/v1/k8s/nodes")
await api("/v1/k8s/nodes");
GET /v1/k8s/pods
Return pod inventory across namespaces.
Auth: Bearer token required. Kubernetes routes run locally through kubectl; credentials and scan output stay on the operator machine.
curl -k -H "Authorization: Bearer $CWS_TOKEN" "$CWS_BASE_URL/v1/k8s/pods"
api("/v1/k8s/pods")
await api("/v1/k8s/pods");
GET /v1/k8s/workloads
Return deployment, StatefulSet, and DaemonSet inventory.
Auth: Bearer token required. Kubernetes routes run locally through kubectl; credentials and scan output stay on the operator machine.
curl -k -H "Authorization: Bearer $CWS_TOKEN" "$CWS_BASE_URL/v1/k8s/workloads"
api("/v1/k8s/workloads")
await api("/v1/k8s/workloads");
GET /v1/k8s/persistent-volumes
Return PersistentVolume inventory and orphan/released signals.
Auth: Bearer token required. Kubernetes routes run locally through kubectl; credentials and scan output stay on the operator machine.
curl -k -H "Authorization: Bearer $CWS_TOKEN" "$CWS_BASE_URL/v1/k8s/persistent-volumes"
api("/v1/k8s/persistent-volumes")
await api("/v1/k8s/persistent-volumes");
GET /v1/k8s/persistent-volume-claims
Return PersistentVolumeClaim inventory and binding state.
Auth: Bearer token required. Kubernetes routes run locally through kubectl; credentials and scan output stay on the operator machine.
curl -k -H "Authorization: Bearer $CWS_TOKEN" "$CWS_BASE_URL/v1/k8s/persistent-volume-claims"
api("/v1/k8s/persistent-volume-claims")
await api("/v1/k8s/persistent-volume-claims");
GET /v1/k8s/services
Return Service inventory and exposure signals.
Auth: Bearer token required. Kubernetes routes run locally through kubectl; credentials and scan output stay on the operator machine.
curl -k -H "Authorization: Bearer $CWS_TOKEN" "$CWS_BASE_URL/v1/k8s/services"
api("/v1/k8s/services")
await api("/v1/k8s/services");
GET /v1/reports/k8s-governance
Return a governance-oriented Kubernetes summary for review.
Auth: Bearer token required. Kubernetes routes run locally through kubectl; credentials and scan output stay on the operator machine.
curl -k -H "Authorization: Bearer $CWS_TOKEN" "$CWS_BASE_URL/v1/reports/k8s-governance"
api("/v1/reports/k8s-governance")
await api("/v1/reports/k8s-governance");
GET /v1/reports/k8s-action-plan
Return a Kubernetes cleanup action plan grouped by execution risk.
Auth: Bearer token required. Kubernetes routes run locally through kubectl; credentials and scan output stay on the operator machine.
curl -k -H "Authorization: Bearer $CWS_TOKEN" "$CWS_BASE_URL/v1/reports/k8s-action-plan"
api("/v1/reports/k8s-action-plan")
await api("/v1/reports/k8s-action-plan");
GET /v1/mcp/tools/k8s-governance
Return MCP-ready Kubernetes governance tool output.
Auth: Bearer token required. Kubernetes routes run locally through kubectl; credentials and scan output stay on the operator machine.
curl -k -H "Authorization: Bearer $CWS_TOKEN" "$CWS_BASE_URL/v1/mcp/tools/k8s-governance"
api("/v1/mcp/tools/k8s-governance")
await api("/v1/mcp/tools/k8s-governance");
GET /v1/mcp/tools/k8s-action-plan
Return MCP-ready Kubernetes action-plan tool output.
Auth: Bearer token required. Kubernetes routes run locally through kubectl; credentials and scan output stay on the operator machine.
curl -k -H "Authorization: Bearer $CWS_TOKEN" "$CWS_BASE_URL/v1/mcp/tools/k8s-action-plan"
api("/v1/mcp/tools/k8s-action-plan")
await api("/v1/mcp/tools/k8s-action-plan");
Shared Error and Reliability Notes
- Route-level validation/auth failures use JSON envelope:
{"error":"..."}. - For scan jobs, prefer asynchronous workflow: create job then poll
/v1/scans/:scan_iduntil terminal status. - Jobs are held in process memory; schedule definitions are persisted and restored on app restart.
- No active checks or zero-data connectivity failure can produce
failedjob status with non-consumption quota semantics.
Test the endpoints with a live local agent, not a mock.
Save your first $1,000 before the next billing cycle.