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:
Session Cookie (Web Console UI)
- Authenticate via
POST /loginwith email and password (or use OAuth) - The response sets an HTTP-only session cookie
- 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:
| Parameter | Type | Description |
|---|---|---|
startDate | string | ISO 8601 start date filter |
endDate | string | ISO 8601 end date filter |
limit | integer | Results per page (default: 50, max: 1000) |
offset | integer | Pagination offset |
cluster | string | Filter by cluster ID |
namespace | string | Filter by namespace |
podName | string | Filter by pod name (partial match) |
imageName | string | Filter by container image name (partial match) |
findingsOnly | boolean | Only return scans with malware findings |
findingType | string | Filter by finding type: malware, drift, runtime |
orderBy | string | Sort field (default: StartTime) |
orderDesc | boolean | Sort 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:
| Value | Description |
|---|---|
malware | ClamAV signature match |
drift | Executable not present in original image |
runtime | Deleted 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:
| Parameter | Type | Description |
|---|---|---|
startDate | string | ISO 8601 start date |
endDate | string | ISO 8601 end date |
limit | integer | Results per page |
offset | integer | Pagination offset |
cluster | string | Filter by cluster ID |
namespace | string | Filter by namespace |
podName | string | Filter 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 Status | Error Code | Description |
|---|---|---|
| 401 | unauthorized | Session expired or not authenticated |
| 403 | forbidden | Insufficient permissions or tier |
| 404 | not_found | Resource does not exist |
| 429 | rate_limited | API rate limit exceeded |
| 500 | internal_error | Server error |
Rate Limiting
API rate limits are enforced per tier:
| Tier | Rate Limit |
|---|---|
| Trial | 2 requests/sec |
| Individual | 10 requests/sec |
| Startup | 10 requests/sec |
| Team | 10 requests/sec |
| Enterprise | 100 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:
| Endpoint | Method | Purpose |
|---|---|---|
/api/v1/log/scanresult | POST | Submit scan results (protobuf) |
/api/v1/log/podlog | POST | Submit pod metadata (protobuf) |
/api/v1/scan/config | GET | Fetch remote scan config (JSON) |
/api/v1/custom-signatures | GET | List custom signature databases |
/api/v1/custom-signatures/:id/download | GET | Download signature file |
Next Steps
- Customer API Access — Bearer token authentication, Python examples, and AI agent integration
- Integrations — Notification channel setup guides
- Configuration Reference — All settings
- Troubleshooting — Common issues