Skip to main content

API Reference

The Garnet API provides programmatic access to Issues, Policies, and Agents. Base URL: https://api.garnet.ai/v1

Authentication

All API requests require a bearer token.
curl -H "Authorization: Bearer YOUR_API_TOKEN" \
  https://api.garnet.ai/v1/issues

Get API Token

  1. Go to dashboard.garnet.ai
  2. Settings → API Tokens → Create Token
  3. Copy token (shown only once)

Issues

List Issues

GET /v1/issues
Query parameters:
ParameterTypeDescription
severitystringFilter by severity: critical, high, medium, low
verdictstringFilter by verdict: detected, blocked
sinceISO 8601Issues created after this timestamp
limitintegerMax results (default: 100, max: 1000)
cursorstringPagination cursor
Example:
curl -H "Authorization: Bearer YOUR_TOKEN" \
  "https://api.garnet.ai/v1/issues?severity=critical&limit=50"
Response:
{
  "data": [
    {
      "id": "issue_abc123",
      "title": "Unknown egress to malicious.com",
      "severity": "critical",
      "verdict": "blocked",
      "created_at": "2024-03-15T14:32:15Z",
      "micro_context": {
        "platform": "kubernetes",
        "cluster": "production",
        "node": "gke-node-123"
      },
      "details": {
        "domain": "malicious.com",
        "ip": "192.0.2.1",
        "process": "/usr/bin/curl",
        "command": "curl https://malicious.com"
      }
    }
  ],
  "pagination": {
    "next_cursor": "cursor_xyz789",
    "has_more": true
  }
}

Get Issue Details

GET /v1/issues/{issue_id}
Example:
curl -H "Authorization: Bearer YOUR_TOKEN" \
  https://api.garnet.ai/v1/issues/issue_abc123

Policies

List Policies

GET /v1/policies
Response:
{
  "data": [
    {
      "id": "policy_xyz123",
      "name": "Corporate allowlist",
      "type": "allow",
      "scope": "global",
      "rules": [
        {
          "pattern": "*.corp.example.com",
          "comment": "Internal services"
        }
      ],
      "enabled": true,
      "created_at": "2024-01-15T10:00:00Z"
    }
  ]
}

Create Policy

POST /v1/policies
Content-Type: application/yaml
Example:
curl -X POST https://api.garnet.ai/v1/policies \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/yaml" \
  --data-binary @- <<EOF
name: "Test allowlist"
type: allow
scope: global
rules:
  - pattern: "example.com"
    comment: "Test domain"
EOF
Response:
{
  "id": "policy_new123",
  "status": "created",
  "applied_at": "2024-03-15T14:35:00Z"
}

Update Policy

PUT /v1/policies/{policy_id}
Content-Type: application/yaml

Delete Policy

DELETE /v1/policies/{policy_id}
Example:
curl -X DELETE https://api.garnet.ai/v1/policies/policy_xyz123 \
  -H "Authorization: Bearer YOUR_TOKEN"

Agents

List Agents

GET /v1/agents
Query parameters:
ParameterTypeDescription
statusstringFilter by status: connected, disconnected
platformstringFilter by platform: github_actions, kubernetes
clusterstringFilter by cluster name (K8s only)
Response:
{
  "data": [
    {
      "id": "agent_abc123",
      "hostname": "gke-prod-node-123",
      "platform": "kubernetes",
      "cluster": "production",
      "status": "connected",
      "mode": "enforce",
      "version": "1.5.0",
      "last_seen": "2024-03-15T14:32:00Z"
    }
  ]
}

Update Agent Mode

PATCH /v1/agents/{agent_id}
Content-Type: application/json
Example: Switch to enforce mode
curl -X PATCH https://api.garnet.ai/v1/agents/agent_abc123 \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"mode": "enforce"}'

Events

List Events

GET /v1/events
Query parameters:
ParameterTypeDescription
typestringEvent type: dns, connect, process
agent_idstringFilter by specific agent
sinceISO 8601Events after this timestamp
limitintegerMax results (default: 100)
Example:
curl -H "Authorization: Bearer YOUR_TOKEN" \
  "https://api.garnet.ai/v1/events?type=dns&limit=100"
Response:
{
  "data": [
    {
      "id": "event_xyz789",
      "type": "dns",
      "timestamp": "2024-03-15T14:32:15Z",
      "query": "registry.npmjs.org",
      "response": ["104.16.132.229"],
      "process": {
        "pid": 1234,
        "command": "/usr/bin/npm",
        "args": ["install", "express"]
      }
    }
  ]
}

Error Handling

All errors return standard HTTP status codes and JSON error objects.

Error Response Format

{
  "error": {
    "code": "unauthorized",
    "message": "Invalid API token",
    "details": "Token has expired or been revoked"
  }
}

Common Status Codes

CodeMeaningAction
400Bad RequestCheck request parameters
401UnauthorizedVerify API token
403ForbiddenCheck token permissions
404Not FoundResource doesn’t exist
429Rate LimitWait and retry
500Server ErrorContact support

Rate Limits

EndpointLimitWindow
All endpoints1000 requestsper hour
/v1/events100 requestsper minute
Rate limit headers:
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 950
X-RateLimit-Reset: 1710511200

Webhooks

Configure webhooks to receive real-time Issue notifications.

Setup

Dashboard → Settings → Webhooks → Create Webhook Payload:
{
  "event": "issue.created",
  "timestamp": "2024-03-15T14:32:15Z",
  "issue": {
    "id": "issue_abc123",
    "title": "Unknown egress to malicious.com",
    "severity": "critical",
    "verdict": "blocked",
    "url": "https://dashboard.garnet.ai/issues/issue_abc123"
  }
}

Verify Webhook Signature

All webhook payloads include a signature header:
X-Garnet-Signature: sha256=abc123def456...
Verify:
import hmac
import hashlib

def verify_signature(payload, signature, secret):
    expected = hmac.new(
        secret.encode(),
        payload.encode(),
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(f"sha256={expected}", signature)

SDK / Client Libraries

Official SDKs (coming soon):
  • Python: pip install garnet-sdk
  • JavaScript: npm install @garnet/sdk
  • Go: go get github.com/garnet-labs/sdk-go
For now, use any HTTP client with the REST API.

Full API Spec

OpenAPI Specification

Complete OpenAPI 3.0 spec for code generation