Shield API

Manage Shield sites, rules, virtual patches, and analytics programmatically. Same API the dashboard uses.

Authentication

All Shield API endpoints accept an API key with scope shield:read. Generate at Settings → API Keys. Write operations (creating sites, editing rules, changing mode) are dashboard-only today; they happen via your authenticated browser session at /shield/sites, not via API key.

curl -H "Authorization: Bearer sect_live_..." \
  https://api.sectora.io/api/v1/shield/sites

Site management

# List sites
GET    /api/v1/shield/sites

# Get one
GET    /api/v1/shield/sites/:id

# Create
POST   /api/v1/shield/sites
{
  "domain": "example.com",
  "origin_url": "https://my-app.run.app",
  "mode": "log"
}

# Update mode (log / block / challenge)
PATCH  /api/v1/shield/sites/:id
{ "mode": "block" }

# Delete
DELETE /api/v1/shield/sites/:id

Virtual patches

# List patches for a site
GET    /api/v1/shield/sites/:id/virtual-patches

# Create from a finding
POST   /api/v1/vulnerabilities/:id/virtual-patch
{ "auto_remove": true }

# Or define manually
POST   /api/v1/shield/sites/:id/virtual-patches
{
  "url_pattern": "/api/users/search",
  "method": "POST",
  "match_param": "name",
  "match_regex": "['\"]\s*(OR|UNION|;|--)",
  "action": "block",
  "expires_in_days": 30
}

# Delete
DELETE /api/v1/shield/sites/:id/virtual-patches/:patch_id

IP access

# Add an IP rule
POST   /api/v1/shield/sites/:id/ip-access
{
  "type": "ip",
  "value": "203.0.113.42",
  "action": "deny",
  "note": "credential stuffing 2026-05",
  "expires_at": "2026-06-25T00:00:00Z"
}

# Bulk import
POST   /api/v1/shield/sites/:id/ip-access/import
Content-Type: text/csv
type,value,action,note
ip,203.0.113.42,deny,credstuffing
asn,AS14061,deny,DigitalOcean droplets

Rate limits

POST   /api/v1/shield/sites/:id/rate-limits
{
  "identity": "ip",
  "url_pattern": "/login",
  "method": "POST",
  "budget": 5,
  "window_seconds": 60,
  "action": "block",
  "escalate_to_deny_minutes": 5
}

Analytics + live tail

# Aggregate stats
GET    /api/v1/shield/sites/:id/analytics?from=2026-05-01&to=2026-05-25

# Live decisions (SSE stream)
GET    /api/v1/shield/sites/:id/live
Accept: text/event-stream

Schema enforcement

# Upload OpenAPI spec
PUT    /api/v1/shield/sites/:id/schema
Content-Type: application/yaml
--data-binary @openapi.yaml

# Set strictness
PATCH  /api/v1/shield/sites/:id/schema-config
{ "strictness": "standard" }

Rate limits on the Shield API itself

100 requests/minute per API key. Analytics endpoints separately rate-limited to 30/minute due to higher backend cost. Exceeding returns 429 with a Retry-After header.

Idempotency

All mutating endpoints accept an Idempotency-Key header. Repeat requests within 24h with the same key return the original response without re-applying — safe to retry on network errors.

What's next