Skip to main content

API Reference

The Guardimesh web console exposes a JSON API that powers the UI. These endpoints can be used for programmatic access to scan results, configuration management, and automation.

Authentication

The web console API supports two authentication methods:

  1. Authenticate via POST /login with email and password (or use OAuth)
  2. The response sets an HTTP-only session cookie
  3. Include the cookie in subsequent requests
# Example: authenticate and query scans
curl -c cookies.txt -X POST https://console.guardimesh.com/login \
-H "Content-Type: application/json" \
-d '{"email": "user@example.com", "password": "your-password"}'

curl -b cookies.txt https://console.guardimesh.com/api/scans

API Key (Programmatic Access)

Read-only data endpoints also accept Bearer token authentication using an API key with console:read scope. This is ideal for AI agents, SOAR integrations, and automation pipelines.

curl -H "Authorization: Bearer YOUR_API_KEY" \
https://console.guardimesh.com/api/scans

API key access requires Startup tier or above. See the Customer API Access guide for full documentation, Python examples, and AI agent integration best practices.

TOTP (Two-Factor Authentication)

If TOTP is enabled on the account, a two-step login is required:

# Step 1: Submit credentials
curl -c cookies.txt -X POST https://console.guardimesh.com/login \
-d '{"email": "user@example.com", "password": "your-password"}'
# Response: {"totp_required": true}

# Step 2: Submit TOTP code
curl -b cookies.txt -c cookies.txt -X POST https://console.guardimesh.com/login/verify-totp \
-d '{"code": "123456"}'

Scan Results

List Scan Results

GET /api/scans

Returns paginated scan results from BigQuery.

Query Parameters:

ParameterTypeDescription
startDatestringISO 8601 start date filter
endDatestringISO 8601 end date filter
limitintegerResults per page (default: 50, max: 1000)
offsetintegerPagination offset
clusterstringFilter by cluster ID
namespacestringFilter by namespace
podNamestringFilter by pod name (partial match)
imageNamestringFilter by container image name (partial match)
findingsOnlybooleanOnly return scans with malware findings
findingTypestringFilter by finding type: malware, drift, runtime
orderBystringSort field (default: StartTime)
orderDescbooleanSort descending (default: true)

Response:

{
"scanResults": [
{
"APIVersion": "1.0",
"ContainerID": "abc123def456",
"ImageID": "sha256:...",
"ImageName": "nginx:1.25",
"Namespace": "default",
"PodName": "web-app-7d8f9c6b4-x2k9p",
"UserName": "user@example.com",
"UUID": "uuid-string",
"Results": [
{
"Description": "Trojan detected",
"FilePath": "/var/tmp/payload.bin",
"ScannerName": "ClamAV",
"ScannerVersion": "1.3.0",
"SignatureName": "Trojan.Linux.Generic",
"Timestamp": 1716710400,
"ScanSource": "runtime"
}
],
"PodIP": "10.244.0.42",
"HostIP": "10.0.1.15",
"StartTime": 1716710400,
"ClusterID": "production-us-east-1"
}
],
"totalCount": 142
}

Finding Types:

ValueDescription
malwareClamAV signature match
driftExecutable not present in original image
runtimeDeleted binary, memfd, or deleted library detection

Get Scan Filters

GET /api/filters/clusters

Returns distinct cluster IDs for filter dropdowns.

GET /api/filters/namespaces

Returns distinct namespaces for filter dropdowns.


Pod Logs

List Pod Logs

GET /api/pods

Returns paginated pod creation/metadata logs.

Query Parameters:

ParameterTypeDescription
startDatestringISO 8601 start date
endDatestringISO 8601 end date
limitintegerResults per page
offsetintegerPagination offset
clusterstringFilter by cluster ID
namespacestringFilter by namespace
podNamestringFilter by pod name

Response:

{
"podLogs": [
{
"PodName": "web-app-7d8f9c6b4-x2k9p",
"UUID": "uuid-string",
"Namespace": "default",
"HostIP": "10.0.1.15",
"PodIP": "10.244.0.42",
"StartTime": 1716710400,
"ClusterID": "production-us-east-1",
"NodeName": "worker-node-3",
"OwnerKind": "ReplicaSet",
"OwnerName": "web-app-7d8f9c6b4",
"ImageNames": ["nginx:1.25", "sidecar:latest"]
}
],
"totalCount": 5280
}

Scan Configuration

Get Scan Configuration

GET /api/scan-config

Returns the current scan configuration that is pushed to scanners via remote config.

Response:

{
"activeScan": true,
"scheduledScan": false,
"scanDays": [],
"minContainerAge": 1,
"skipNamespaces": ["kube-system", "guardimesh-system"],
"skipNamespacePrefixes": ["openshift-"],
"scanDeduplicationTTL": 300,
"includeDatabases": ["main", "daily", "bytecode", "guardimesh-custom"],
"featureFlags": {
"fanotify": false
},
"configVersion": 5
}

Update Scan Configuration

POST /api/scan-config

Updates the scan configuration. Changes are picked up by scanners on their next config poll (within 5 minutes).

Request Body:

{
"activeScan": true,
"scheduledScan": true,
"scanDays": [
{"day": "monday", "time": "02:00"},
{"day": "wednesday", "time": "02:00"},
{"day": "friday", "time": "02:00"}
],
"minContainerAge": 2,
"skipNamespaces": ["kube-system", "guardimesh-system", "monitoring"],
"skipNamespacePrefixes": ["openshift-", "istio-"],
"scanDeduplicationTTL": 600,
"featureFlags": {
"fanotify": true
}
}

Note: The fanotify feature flag is subject to tier enforcement. Setting it to true on a tier that does not support fanotify will be overridden by the backend when delivering config to scanners.


API Keys

List API Keys

GET /api/keys

Response:

{
"keys": [
{
"id": "key-uuid-123",
"name": "Production Scanner",
"prefix": "gm_live_abc...",
"created_at": "2026-01-15T10:00:00Z",
"last_used_at": "2026-05-26T08:30:00Z",
"active": true
}
]
}

Create API Key

POST /api/keys/create

Request Body:

{
"name": "Staging Scanner"
}

Response:

{
"id": "key-uuid-456",
"name": "Staging Scanner",
"key": "gm_live_full_key_shown_only_once_abc123...",
"created_at": "2026-05-26T14:00:00Z"
}

The full key value is only returned once at creation time. Store it securely.

Delete API Key

DELETE /api/keys/:id

Immediately revokes the key. Scanners using this key will receive 403 responses.


Notifications

List Notification Channels

GET /api/notifications

Response:

{
"channels": [
{
"id": "channel-uuid-1",
"type": "webhook",
"name": "Security Team Webhook",
"enabled": true,
"config": {
"url": "https://hooks.example.com/guardimesh",
"method": "POST",
"tls_verify": true
},
"filters": {
"namespaces": ["production"],
"exclude_signatures": ["Eicar-Test-Signature"],
"min_findings": 1
},
"created_at": "2026-03-01T12:00:00Z"
}
]
}

Create Notification Channel

POST /api/notifications

Request Body (webhook example):

{
"type": "webhook",
"name": "Security Team Webhook",
"enabled": true,
"config": {
"url": "https://hooks.example.com/guardimesh",
"method": "POST",
"headers": {
"Authorization": "Bearer secret-token"
},
"tls_verify": true,
"timeout": 30
},
"filters": {
"namespaces": ["production", "staging"],
"exclude_namespaces": ["kube-system"],
"min_findings": 1,
"exclude_signatures": ["Eicar-Test-Signature"],
"rate_limit": 100
}
}

Update Notification Channel

PUT /api/notifications/:id

Same body format as create. Partial updates are supported.

Delete Notification Channel

DELETE /api/notifications/:id

Test Notification Channel

POST /api/notifications/:id/test

Sends a synthetic test notification to verify connectivity.

Get Delivery History

GET /api/notifications/:id/history

Response:

{
"history": [
{
"timestamp": "2026-05-26T10:30:05Z",
"status": "success",
"http_status": 200,
"duration_ms": 145
},
{
"timestamp": "2026-05-25T22:15:00Z",
"status": "failed",
"http_status": 503,
"error": "Service Unavailable",
"duration_ms": 30000
}
]
}

Reports

Get Reports (Startup tier and above)

GET /api/reports

Returns advanced reporting data including scan coverage, finding trends, and compliance metrics.


Error Responses

All endpoints return standard error responses:

{
"error": "error_code",
"message": "Human-readable error description"
}

Common Error Codes

HTTP StatusError CodeDescription
401unauthorizedSession expired or not authenticated
403forbiddenInsufficient permissions or tier
404not_foundResource does not exist
429rate_limitedAPI rate limit exceeded
500internal_errorServer error

Rate Limiting

API rate limits are enforced per tier:

TierRate Limit
Trial2 requests/sec
Individual10 requests/sec
Startup10 requests/sec
Team10 requests/sec
Enterprise100 requests/sec

Rate-limited responses include Retry-After header.


Scanner Ingest API

The scanner-to-backend ingest API is separate from the web console API and uses API key authentication with protobuf payloads. It is not intended for direct customer use — the scanner handles this automatically. For reference:

EndpointMethodPurpose
/api/v1/log/scanresultPOSTSubmit scan results (protobuf)
/api/v1/log/podlogPOSTSubmit pod metadata (protobuf)
/api/v1/scan/configGETFetch remote scan config (JSON)
/api/v1/custom-signaturesGETList custom signature databases
/api/v1/custom-signatures/:id/downloadGETDownload signature file

Next Steps