Skip to content

Control Plane API Reference

The Control Plane API is the backend orchestration layer for the Gatez operator and developer portals. It manages tenant lifecycle, API key provisioning, rate limit configuration, analytics, health aggregation, notifications, audit trails, branding, and platform settings.

Base URL: http://localhost:4001

All endpoints require authentication. CORS is configured to allow requests from the operator portal (localhost:3003) and developer portal (localhost:3004), configurable via the ALLOWED_ORIGINS environment variable.


Health

GET /health

Health check with dependency status.

Response: 200 OK

json
{
  "status": "healthy",
  "service": "control-plane-api",
  "version": "0.1.0",
  "checks": {
    "redis": "connected"
  }
}

If Redis is unreachable, status returns "degraded" and redis returns "unreachable".

curl Example:

bash
curl http://localhost:4001/health

GET /metrics

Prometheus-format metrics endpoint.

Response: 200 OK (text/plain, Prometheus exposition format)

curl Example:

bash
curl http://localhost:4001/metrics

GET /api/health/services

Aggregate health status from all platform layers (APISIX, Redis, AI Gateway, Agent Gateway, ClickHouse, Keycloak).

Response: 200 OK

json
[
  {"layer": "L1", "service": "APISIX", "status": "healthy", "latency_ms": 12, "url": "http://gw-apisix:9180"},
  {"layer": "L1", "service": "Redis", "status": "healthy", "latency_ms": 1, "url": "redis://gw-redis:6379"},
  {"layer": "L2", "service": "AI Gateway", "status": "healthy", "latency_ms": 5, "url": "http://ai-gateway:4000"},
  {"layer": "L3", "service": "Agent Gateway", "status": "healthy", "latency_ms": 8, "url": "http://agent-gateway:5001"},
  {"layer": "L1", "service": "ClickHouse", "status": "healthy", "latency_ms": 15, "url": "http://gw-clickhouse:8123"},
  {"layer": "L1", "service": "Keycloak", "status": "healthy", "latency_ms": 45, "url": "http://gw-keycloak:8081"}
]

Each entry includes:

FieldTypeDescription
layerstringPlatform layer (L1, L2, L3)
servicestringService name
statusstringhealthy, degraded, or down
latency_msintegerProbe latency in milliseconds
urlstringInternal service URL

curl Example:

bash
curl http://localhost:4001/api/health/services \
  -H "Authorization: Bearer $TOKEN"

GET /api/health/alerts

List active alerts from Prometheus Alertmanager.

Response: 200 OK

json
[]

curl Example:

bash
curl http://localhost:4001/api/health/alerts \
  -H "Authorization: Bearer $TOKEN"

Tenants

GET /api/tenants

List all tenants with usage statistics.

Response: 200 OK

json
[
  {
    "id": "tenant-alpha",
    "name": "Alpha Corp",
    "plan": "pro",
    "status": "active",
    "rate_limit_max": 2500,
    "rate_limit_usage": 0,
    "token_budget": 2000000,
    "token_budget_used": 150000,
    "request_count_24h": 0,
    "created_at": "2026-03-21"
  }
]

curl Example:

bash
curl http://localhost:4001/api/tenants \
  -H "Authorization: Bearer $TOKEN"

POST /api/tenants

Create a new tenant. Atomically provisions across all layers: Redis metadata, rate limit bucket, token budget, APISIX consumer group.

Request Body:

json
{
  "name": "Beta Inc",
  "plan": "pro",
  "admin_email": "admin@beta.com",
  "realm_name": "beta",
  "claim_path": "tenant_id"
}
FieldTypeRequiredDescription
namestringYesTenant display name
planstringYesPlan tier: free, pro, or enterprise
idstringNoCustom tenant ID (auto-generated if omitted)
admin_emailstringNoAdmin contact email
realm_namestringNoKeycloak realm name
claim_pathstringNoJWT claim path for tenant extraction

Plan defaults:

PlanRate Limit (req/min)Token Budget
free10050,000
pro2,5002,000,000
enterprise25,00010,000,000

Response: 201 Created

json
{
  "id": "tenant-beta",
  "name": "Beta Inc",
  "plan": "pro",
  "status": "active",
  "rate_limit_max": 2500,
  "rate_limit_usage": 0,
  "token_budget": 2000000,
  "token_budget_used": 0,
  "request_count_24h": 0,
  "created_at": "2026-03-25"
}

Error Response: 409 Conflict

json
{"error": "Tenant already exists"}

curl Example:

bash
curl -X POST http://localhost:4001/api/tenants \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "Beta Inc", "plan": "pro", "admin_email": "admin@beta.com"}'

GET /api/tenants/:id

Get a specific tenant with current usage.

Path Parameters:

ParameterDescription
idTenant identifier

Response: 200 OK

json
{
  "id": "tenant-alpha",
  "name": "Alpha Corp",
  "plan": "pro",
  "status": "active",
  "rate_limit_max": 2500,
  "rate_limit_usage": 0,
  "token_budget": 2000000,
  "token_budget_used": 150000,
  "request_count_24h": 0,
  "created_at": "2026-03-21"
}

Error Response: 404 Not Found

json
{"error": "Tenant not found"}

curl Example:

bash
curl http://localhost:4001/api/tenants/tenant-alpha \
  -H "Authorization: Bearer $TOKEN"

PATCH /api/tenants/:id

Update tenant properties.

Path Parameters:

ParameterDescription
idTenant identifier

Request Body:

json
{
  "plan": "enterprise",
  "status": "active",
  "rate_limit_max": 25000,
  "token_budget": 10000000
}

All fields are optional. Only provided fields are updated.

FieldTypeDescription
planstringPlan tier
statusstringTenant status (active, suspended)
rate_limit_maxintegerMax requests per minute
token_budgetintegerToken budget (resets remaining to this value)

Response: 200 OK

json
{"status": "updated"}

curl Example:

bash
curl -X PATCH http://localhost:4001/api/tenants/tenant-alpha \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"plan": "enterprise", "rate_limit_max": 25000}'

DELETE /api/tenants/:id

Delete a tenant and all associated resources (Redis metadata, rate limit bucket, token budget).

Path Parameters:

ParameterDescription
idTenant identifier

Response: 200 OK

json
{"status": "deleted"}

curl Example:

bash
curl -X DELETE http://localhost:4001/api/tenants/tenant-alpha \
  -H "Authorization: Bearer $TOKEN"

Keys

GET /api/keys

List all API keys (masked) across all tenants.

Response: 200 OK

json
[
  {
    "id": "k-abc12345",
    "prefix": "****ab12",
    "name": "my-app-key",
    "tenant_id": "tenant-alpha",
    "routes": ["/v1/chat/completions"],
    "status": "active",
    "created_at": "2026-03-22",
    "expires_at": null,
    "request_count": 0
  }
]

curl Example:

bash
curl http://localhost:4001/api/keys \
  -H "Authorization: Bearer $TOKEN"

POST /api/keys/request

Submit an API key request (developer workflow).

Request Body:

json
{
  "name": "my-app-key",
  "tenant_id": "tenant-alpha",
  "routes": ["/v1/chat/completions", "/v1/models"],
  "reason": "Need API access for my application",
  "email": "dev@alpha.com"
}
FieldTypeRequiredDescription
namestringYesKey name (becomes APISIX consumer name)
tenant_idstringYesTenant identifier
routesarrayYesRequested route access
reasonstringYesJustification for the key
emailstringYesRequester email

Response: 201 Created

json
{
  "id": "kr-abc12345",
  "email": "dev@alpha.com",
  "tenant_id": "tenant-alpha",
  "name": "my-app-key",
  "routes": ["/v1/chat/completions", "/v1/models"],
  "reason": "Need API access for my application",
  "requested_at": "2026-03-25T10:00:00Z",
  "status": "pending"
}

curl Example:

bash
curl -X POST http://localhost:4001/api/keys/request \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "my-app-key",
    "tenant_id": "tenant-alpha",
    "routes": ["/v1/chat/completions"],
    "reason": "API access for my app",
    "email": "dev@alpha.com"
  }'

GET /api/keys/requests

List pending API key requests.

Response: 200 OK

json
[
  {
    "id": "kr-abc12345",
    "email": "dev@alpha.com",
    "tenant_id": "tenant-alpha",
    "name": "my-app-key",
    "routes": ["/v1/chat/completions"],
    "reason": "API access for my app",
    "requested_at": "2026-03-25T10:00:00Z",
    "status": "pending"
  }
]

curl Example:

bash
curl http://localhost:4001/api/keys/requests \
  -H "Authorization: Bearer $TOKEN"

POST /api/keys/requests/:id/approve

Approve a key request. Creates an APISIX consumer with key-auth plugin and returns the full API key (shown only once).

Path Parameters:

ParameterDescription
idKey request identifier

Response: 200 OK

json
{
  "status": "approved",
  "key_id": "k-abc12345",
  "full_key": "gtz_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6",
  "name": "my-app-key"
}

DANGER

The full_key is returned only once upon approval. Store it securely. It cannot be retrieved again.

curl Example:

bash
curl -X POST http://localhost:4001/api/keys/requests/kr-abc12345/approve \
  -H "Authorization: Bearer $TOKEN"

POST /api/keys/requests/:id/deny

Deny a key request.

Path Parameters:

ParameterDescription
idKey request identifier

Response: 200 OK

json
{"status": "denied"}

curl Example:

bash
curl -X POST http://localhost:4001/api/keys/requests/kr-abc12345/deny \
  -H "Authorization: Bearer $TOKEN"

DELETE /api/keys/:id

Revoke an API key. Removes the APISIX consumer and marks the key as revoked.

Path Parameters:

ParameterDescription
idAPI key identifier

Response: 200 OK

json
{"status": "revoked"}

curl Example:

bash
curl -X DELETE http://localhost:4001/api/keys/k-abc12345 \
  -H "Authorization: Bearer $TOKEN"

Rate Limits

GET /api/rate-limits/:tenant_id

Get the rate limit hierarchy for a tenant (global default, tenant override, route overrides).

Path Parameters:

ParameterDescription
tenant_idTenant identifier

Response: 200 OK

json
{
  "tenant_id": "tenant-alpha",
  "global_default": {
    "limit": 5000,
    "window": "60s",
    "current_traffic": 0
  },
  "tenant_override": {
    "limit": 2500,
    "window": "60s",
    "current_traffic": 0
  },
  "route_overrides": []
}

If no tenant override is set, tenant_override is null.

curl Example:

bash
curl http://localhost:4001/api/rate-limits/tenant-alpha \
  -H "Authorization: Bearer $TOKEN"

PUT /api/rate-limits/:tenant_id

Update the tenant-level rate limit override.

Path Parameters:

ParameterDescription
tenant_idTenant identifier

Request Body:

json
{
  "limit": 5000,
  "window": "60s"
}
FieldTypeRequiredDescription
limitintegerYesRequests per window
windowstringNoTime window (default: 60s)

Response: 200 OK

json
{"status": "updated", "limit": 5000}

curl Example:

bash
curl -X PUT http://localhost:4001/api/rate-limits/tenant-alpha \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"limit": 5000}'

PUT /api/rate-limits/:tenant_id/routes/:route_id

Update a route-level rate limit override for a tenant.

Path Parameters:

ParameterDescription
tenant_idTenant identifier
route_idAPISIX route identifier

Request Body:

json
{
  "limit": 1000,
  "window": "60s"
}

Response: 200 OK

json
{"status": "updated", "route_id": "route-123", "limit": 1000}

curl Example:

bash
curl -X PUT http://localhost:4001/api/rate-limits/tenant-alpha/routes/route-123 \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"limit": 1000}'

Analytics

All analytics endpoints query ClickHouse and accept the following query parameters:

ParameterTypeDefaultDescription
tenant_idstring(all tenants)Filter by tenant
rangestring24hTime range: 1h, 24h, 7d, 30d

GET /api/analytics/traffic

L1 API Gateway traffic analytics (requests, errors, latency).

Response: 200 OK

json
{
  "data": [
    {
      "hour": "2026-03-25 10:00:00",
      "requests": 1520,
      "errors": 12,
      "avg_latency_ms": 8.5,
      "p99_latency_ms": 42.3
    }
  ]
}

curl Example:

bash
curl "http://localhost:4001/api/analytics/traffic?tenant_id=tenant-alpha&range=24h" \
  -H "Authorization: Bearer $TOKEN"

GET /api/analytics/llm

L2 AI Gateway LLM usage analytics (tokens, models, cache hits).

Response: 200 OK

json
{
  "data": [
    {
      "hour": "2026-03-25 10:00:00",
      "model": "gpt-4o",
      "provider": "openai",
      "prompt_tokens": 45000,
      "completion_tokens": 12000,
      "total_tokens": 57000,
      "avg_latency_ms": 350.2,
      "cache_hits": 42,
      "total_requests": 120
    }
  ]
}

curl Example:

bash
curl "http://localhost:4001/api/analytics/llm?tenant_id=tenant-alpha&range=7d" \
  -H "Authorization: Bearer $TOKEN"

GET /api/analytics/agents

L3 Agent Gateway analytics (tool calls, actions, errors).

Response: 200 OK

json
{
  "data": [
    {
      "hour": "2026-03-25 10:00:00",
      "action": "tool_call",
      "tool_name": "read_file",
      "total": 85,
      "errors": 2
    }
  ]
}

curl Example:

bash
curl "http://localhost:4001/api/analytics/agents?range=24h" \
  -H "Authorization: Bearer $TOKEN"

Audit

GET /api/audit

Query the audit trail from ClickHouse. Supports filtering and CSV export.

Query Parameters:

ParameterTypeDefaultDescription
tenant_idstring(all)Filter by tenant
actionstring(all)Filter by action (partial match)
fromstring(none)Start timestamp (ISO 8601)
tostring(none)End timestamp (ISO 8601)
limitinteger100Max rows (capped at 1000)
formatstringjsonResponse format: json or csv

Response (JSON): 200 OK

json
{
  "data": [
    {
      "timestamp": "2026-03-25T10:05:00Z",
      "tenant_id": "tenant-alpha",
      "session_id": "sess-xyz789",
      "agent_id": "agent-orchestrator",
      "tool_name": "read_file",
      "action": "tool_call",
      "status": "success",
      "trace_id": "abc123"
    }
  ],
  "rows": 1
}

Response (CSV): 200 OK with Content-Type: text/csv and Content-Disposition: attachment; filename=audit_log.csv

curl Example (JSON):

bash
curl "http://localhost:4001/api/audit?tenant_id=tenant-alpha&action=tool_call&limit=50" \
  -H "Authorization: Bearer $TOKEN"

curl Example (CSV):

bash
curl "http://localhost:4001/api/audit?tenant_id=tenant-alpha&format=csv" \
  -H "Authorization: Bearer $TOKEN" \
  -o audit_log.csv

Export

GET /api/export/:table

Generic CSV export for ClickHouse tables.

Path Parameters:

ParameterDescription
tableTable name (allowed: request_log, ai_request_log, agent_audit_log)

Query Parameters:

ParameterTypeDefaultDescription
tenant_idstring(all)Filter by tenant
fromstring(none)Start timestamp
tostring(none)End timestamp
limitinteger1000Max rows (capped at 10000)

Columns by table:

TableColumns
request_logtimestamp, tenant_id, route_id, method, status_code, latency_ms, trace_id
ai_request_logtimestamp, tenant_id, model, tokens_prompt, tokens_completion, cache_hit, pii_detected, latency_ms, trace_id
agent_audit_logtimestamp, tenant_id, session_id, agent_id, tool_name, action, status, trace_id

Response: 200 OK with Content-Type: text/csv and Content-Disposition: attachment; filename={table}.csv

Error Response (invalid table):

json
{"error": "Invalid table name"}

curl Example:

bash
curl "http://localhost:4001/api/export/ai_request_log?tenant_id=tenant-alpha&limit=500" \
  -H "Authorization: Bearer $TOKEN" \
  -o ai_request_log.csv

Notifications

GET /api/notifications

List notifications for a tenant.

Query Parameters:

ParameterTypeDefaultDescription
tenant_idstringallTenant identifier
unread_onlybooleanfalseFilter to unread only

Response: 200 OK

json
{
  "notifications": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "tenant_id": "tenant-alpha",
      "notification_type": "key_approved",
      "title": "API Key Approved",
      "message": "Your key request 'my-app-key' has been approved.",
      "read": false,
      "created_at": "2026-03-25T10:00:00Z"
    }
  ],
  "total": 1,
  "tenant_id": "tenant-alpha"
}

Notification types: key_approved, key_denied, budget_warning, hitl_pending, session_errored, health_degraded.

curl Example:

bash
curl "http://localhost:4001/api/notifications?tenant_id=tenant-alpha&unread_only=true" \
  -H "Authorization: Bearer $TOKEN"

POST /api/notifications

Create a notification (internal use).

Request Body:

json
{
  "tenant_id": "tenant-alpha",
  "notification_type": "budget_warning",
  "title": "Token Budget Low",
  "message": "Your token budget is below 10%. Current remaining: 5,000 tokens."
}
FieldTypeRequiredDescription
tenant_idstringYesTarget tenant
notification_typestringYesNotification category
titlestringYesShort title
messagestringYesNotification body

Response: 201 Created

json
{"id": "550e8400-e29b-41d4-a716-446655440000", "status": "created"}

curl Example:

bash
curl -X POST http://localhost:4001/api/notifications \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "tenant_id": "tenant-alpha",
    "notification_type": "budget_warning",
    "title": "Token Budget Low",
    "message": "Your token budget is below 10%."
  }'

POST /api/notifications/:id/read

Mark a notification as read.

Path Parameters:

ParameterDescription
idNotification identifier

Response: 200 OK

json
{"id": "550e8400-e29b-41d4-a716-446655440000", "read": true}

curl Example:

bash
curl -X POST http://localhost:4001/api/notifications/550e8400-e29b-41d4-a716-446655440000/read \
  -H "Authorization: Bearer $TOKEN"

GET /api/notifications/preferences

Get notification preferences for a tenant.

Query Parameters:

ParameterTypeDefaultDescription
tenant_idstringdefaultTenant identifier

Response: 200 OK

json
{
  "tenant_id": "tenant-alpha",
  "webhook_url": null,
  "slack_url": null,
  "email": null,
  "enabled_types": ["key_approved", "key_denied", "budget_warning", "hitl_pending"]
}

curl Example:

bash
curl "http://localhost:4001/api/notifications/preferences?tenant_id=tenant-alpha" \
  -H "Authorization: Bearer $TOKEN"

PUT /api/notifications/preferences

Update notification preferences for a tenant.

Request Body:

json
{
  "tenant_id": "tenant-alpha",
  "webhook_url": "https://hooks.example.com/notify",
  "slack_url": "https://hooks.slack.com/services/T00/B00/xxxx",
  "email": "alerts@alpha.com",
  "enabled_types": ["key_approved", "budget_warning", "hitl_pending", "health_degraded"]
}

Response: 200 OK

json
{"status": "updated", "tenant_id": "tenant-alpha"}

curl Example:

bash
curl -X PUT http://localhost:4001/api/notifications/preferences \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "tenant_id": "tenant-alpha",
    "webhook_url": "https://hooks.example.com/notify",
    "enabled_types": ["key_approved", "budget_warning"]
  }'

Branding

GET /api/tenants/:id/branding

Get tenant-specific portal branding.

Path Parameters:

ParameterDescription
idTenant identifier

Response: 200 OK

json
{
  "tenant_id": "tenant-alpha",
  "logo_base64": null,
  "portal_title": "Gatez Developer Portal",
  "primary_color": null,
  "updated_at": null
}

curl Example:

bash
curl http://localhost:4001/api/tenants/tenant-alpha/branding \
  -H "Authorization: Bearer $TOKEN"

POST /api/tenants/:id/branding

Update tenant portal branding. Logo must be under 100KB (base64-encoded).

Path Parameters:

ParameterDescription
idTenant identifier

Request Body:

json
{
  "portal_title": "Alpha Dev Portal",
  "primary_color": "#2563eb",
  "logo_base64": "iVBORw0KGgoAAAANSUhEUg..."
}
FieldTypeRequiredDescription
logo_base64stringNoBase64-encoded logo image (max 100KB)
portal_titlestringNoCustom portal title
primary_colorstringNoPrimary color hex code

Response: 200 OK

json
{
  "tenant_id": "tenant-alpha",
  "logo_base64": "iVBORw0KGgoAAAANSUhEUg...",
  "portal_title": "Alpha Dev Portal",
  "primary_color": "#2563eb",
  "updated_at": "2026-03-25T12:00:00Z"
}

Error Response: 400 Bad Request

json
{"error": "Logo exceeds 100KB limit"}

curl Example:

bash
curl -X POST http://localhost:4001/api/tenants/tenant-alpha/branding \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"portal_title": "Alpha Dev Portal", "primary_color": "#2563eb"}'

Settings

GET /api/settings

Get platform-wide settings.

Response: 200 OK

json
{
  "platform_name": "Gatez Gateway Platform",
  "default_rate_limit": 100,
  "default_token_budget": 100000,
  "data_retention": {
    "request_log_ttl_days": 90,
    "ai_request_log_ttl_days": 365,
    "audit_log_ttl": "forever"
  },
  "notification_config": {
    "slack_webhook_url": null,
    "email_smtp": null,
    "pagerduty_key": null
  }
}

curl Example:

bash
curl http://localhost:4001/api/settings \
  -H "Authorization: Bearer $TOKEN"

PUT /api/settings

Update platform-wide settings.

Request Body:

json
{
  "platform_name": "Gatez Gateway Platform",
  "default_rate_limit": 200,
  "default_token_budget": 200000,
  "data_retention": {
    "request_log_ttl_days": 90,
    "ai_request_log_ttl_days": 365,
    "audit_log_ttl": "forever"
  },
  "notification_config": {
    "slack_webhook_url": "https://hooks.slack.com/services/T00/B00/xxxx",
    "email_smtp": null,
    "pagerduty_key": null
  }
}

Response: 200 OK

json
{
  "status": "updated",
  "settings": { ... }
}

curl Example:

bash
curl -X PUT http://localhost:4001/api/settings \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"platform_name": "Gatez", "default_rate_limit": 200, "default_token_budget": 200000}'

API Lifecycle

PATCH /api/routes/:id/lifecycle

Update the lifecycle state of an APISIX route. Updates the route labels in APISIX and logs the change to the audit trail.

Path Parameters:

ParameterDescription
idAPISIX route identifier

Request Body:

json
{
  "lifecycle": "deprecated"
}
FieldTypeRequiredValues
lifecyclestringYesdraft, published, deprecated, retired

Response: 200 OK

json
{"status": "updated", "route_id": "route-123", "lifecycle": "deprecated"}

Error Response: 400 Bad Request

json
{"error": "Invalid lifecycle state"}

curl Example:

bash
curl -X PATCH http://localhost:4001/api/routes/route-123/lifecycle \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"lifecycle": "deprecated"}'

Endpoint Summary

MethodPathDescription
GET/healthHealth check
GET/metricsPrometheus metrics
GET/api/health/servicesAggregate service health
GET/api/health/alertsActive alerts
GET/api/tenantsList tenants
POST/api/tenantsCreate tenant
GET/api/tenants/:idGet tenant
PATCH/api/tenants/:idUpdate tenant
DELETE/api/tenants/:idDelete tenant
GET/api/keysList API keys
POST/api/keys/requestRequest API key
GET/api/keys/requestsList pending requests
POST/api/keys/requests/:id/approveApprove key request
POST/api/keys/requests/:id/denyDeny key request
DELETE/api/keys/:idRevoke API key
GET/api/rate-limits/:tenant_idGet rate limit hierarchy
PUT/api/rate-limits/:tenant_idUpdate tenant rate limit
PUT/api/rate-limits/:tenant_id/routes/:route_idUpdate route rate limit
GET/api/analytics/trafficTraffic analytics
GET/api/analytics/llmLLM usage analytics
GET/api/analytics/agentsAgent analytics
GET/api/auditQuery audit trail
GET/api/export/:tableCSV export
GET/api/notificationsList notifications
POST/api/notificationsCreate notification
POST/api/notifications/:id/readMark as read
GET/api/notifications/preferencesGet notification preferences
PUT/api/notifications/preferencesUpdate notification preferences
GET/api/tenants/:id/brandingGet branding
POST/api/tenants/:id/brandingUpdate branding
GET/api/settingsGet platform settings
PUT/api/settingsUpdate platform settings
PATCH/api/routes/:id/lifecycleUpdate route lifecycle
PATCH/api/routes/:id/canarySet canary traffic split (weight + upstream)
GET/api/licenseGet current license tier, validity, expiry
GET/api/tenants/:id/ip-allowlistGet tenant IP allowlist CIDRs
PUT/api/tenants/:id/ip-allowlistSet tenant IP allowlist CIDRs
GET/api/webhooksList webhooks (optionally ?tenant_id=)
POST/api/webhooksRegister webhook (URL + event types)
DELETE/api/webhooks/:idDelete webhook

Enterprise API + AI + Agent Gateway