OpenGSLB API Reference
OpenGSLB provides a comprehensive REST API for health status monitoring, external health overrides, DNSSEC key management, Overwatch agent management, domain/server/region configuration, metrics, audit logging, and routing.
Base URL: http://localhost:8080/api/v1
Table of Contents
Security & Authentication
The API exposes internal infrastructure details including server addresses, health states, and failure information. Secure access appropriately.
Access Control
Endpoint |
ACL Protected |
|---|---|
|
No |
|
Yes |
|
Yes |
|
Yes |
|
Yes |
|
Yes |
|
Yes |
|
Yes |
|
Yes |
|
Yes |
|
Yes |
|
Yes |
|
Yes |
|
Yes |
|
Yes |
|
Yes |
|
No |
|
No |
|
No |
By default, the API:
Binds to
127.0.0.1:8080(localhost only)Allows connections only from localhost (
127.0.0.1/32,::1/128)Does not trust proxy headers
For production deployments, see API Hardening Guide.
Configuration
api:
enabled: true
address: "127.0.0.1:8080"
allowed_networks:
- "127.0.0.1/32"
- "::1/128"
trust_proxy_headers: false
enable_cors: false
cors:
allowed_origins:
- "*"
allowed_methods:
- "GET"
- "POST"
- "PUT"
- "PATCH"
- "DELETE"
- "OPTIONS"
allowed_headers:
- "Accept"
- "Authorization"
- "Content-Type"
- "X-Requested-With"
allow_credentials: false
max_age: 86400
Field |
Type |
Default |
Description |
|---|---|---|---|
|
bool |
|
Enable the API server |
|
string |
|
Listen address (IP:port) |
|
[]string |
|
CIDR networks allowed to connect |
|
bool |
|
Trust X-Forwarded-For headers |
|
bool |
|
Enable CORS middleware for cross-origin requests |
|
[]string |
|
Origins allowed to access the API |
|
[]string |
See example |
HTTP methods allowed |
|
[]string |
See example |
Request headers allowed |
|
bool |
|
Allow credentials in requests |
|
int |
|
Preflight cache duration in seconds |
Note: The
allowed_networkslist is matched exactly by IP family. If you want to allow all IPs, you must include both0.0.0.0/0(IPv4) and::/0(IPv6). Including only0.0.0.0/0will block IPv6 clients, including localhost connections via::1.
Simple Health Check
GET /api/health
Simple health endpoint with version and uptime information. This endpoint is not ACL protected.
ACL Protected: No
Response: 200 OK
{
"status": "healthy",
"version": "1.0.0",
"uptime_seconds": 86400,
"timestamp": "2025-01-15T10:30:00Z"
}
Response Fields:
Field |
Type |
Description |
|---|---|---|
|
string |
Health status: |
|
string |
Application version |
|
int |
Seconds since application start |
|
string |
ISO 8601 timestamp |
Core Health Endpoints
GET /api/v1/health/servers
Returns health status for all configured servers.
ACL Protected: Yes
Response: 200 OK
{
"servers": [
{
"address": "10.0.1.10",
"port": 80,
"region": "us-east-1",
"healthy": true,
"status": "healthy",
"last_check": "2025-01-15T10:30:00Z",
"last_healthy": "2025-01-15T10:30:00Z",
"consecutive_failures": 0,
"consecutive_successes": 5,
"last_error": null
},
{
"address": "10.0.1.11",
"port": 80,
"region": "us-east-1",
"healthy": false,
"status": "unhealthy",
"last_check": "2025-01-15T10:30:00Z",
"last_healthy": "2025-01-15T10:25:00Z",
"consecutive_failures": 3,
"consecutive_successes": 0,
"last_error": "connection refused"
}
],
"generated_at": "2025-01-15T10:30:05Z"
}
Response Fields:
Field |
Type |
Description |
|---|---|---|
|
string |
Server IP address |
|
int |
Server port |
|
string |
Region name (if configured) |
|
bool |
Current health status |
|
string |
Status string: |
|
string |
ISO 8601 timestamp of last health check |
|
string |
ISO 8601 timestamp when last healthy |
|
int |
Number of consecutive failed checks |
|
int |
Number of consecutive successful checks |
|
string |
Error message from last failed check (null if healthy) |
GET /api/v1/health/regions
Returns health summary aggregated by region.
ACL Protected: Yes
Response: 200 OK
{
"regions": [
{
"name": "us-east-1",
"total_servers": 3,
"healthy_count": 2,
"unhealthy_count": 1,
"health_percent": 66.67
},
{
"name": "us-west-2",
"total_servers": 2,
"healthy_count": 2,
"unhealthy_count": 0,
"health_percent": 100.0
}
],
"generated_at": "2025-01-15T10:30:05Z"
}
Response Fields:
Field |
Type |
Description |
|---|---|---|
|
string |
Region name |
|
int |
Total servers in region |
|
int |
Number of healthy servers |
|
int |
Number of unhealthy servers |
|
float |
Percentage of healthy servers |
Liveness & Readiness Probes
These endpoints are not ACL protected and accessible from anywhere.
GET /api/v1/ready
Readiness probe for load balancers and orchestrators.
ACL Protected: No
Response (ready): 200 OK
{
"ready": true,
"dns_ready": true,
"health_ready": true
}
Response (not ready): 503 Service Unavailable
{
"ready": false,
"message": "health checks not ready",
"dns_ready": true,
"health_ready": false
}
Readiness Criteria:
DNS server is initialized and listening
At least one health check cycle has completed
GET /api/v1/live
Liveness probe. Returns 200 if the process is running.
ACL Protected: No
Response: 200 OK
{
"alive": true
}
Version Endpoint
GET /api/v1/version
Returns build version and information. This endpoint is not ACL protected.
ACL Protected: No
Response: 200 OK
{
"version": "1.1.2",
"go_version": "go1.21.0",
"git_commit": "abc123def",
"build_date": "2025-12-18T10:30:00Z"
}
Response Fields:
Field |
Type |
Description |
|---|---|---|
|
string |
OpenGSLB version |
|
string |
Go compiler version used to build |
|
string |
Git commit hash of the build |
|
string |
ISO 8601 timestamp of when the binary was built |
Domain API
Manage DNS domain configurations.
NEW in v1.1.1: Full CRUD support for domains and backends. API-created domains are automatically registered with the DNS server for immediate DNS resolution (v1.1.2).
GET /api/v1/domains
List all configured domains.
ACL Protected: Yes
Response: 200 OK
{
"domains": [
{
"id": "d1",
"name": "api.example.com",
"ttl": 300,
"routing_policy": "weighted",
"health_check_id": "hc1",
"dnssec_enabled": true,
"enabled": true,
"description": "Main API endpoint",
"tags": ["production"],
"backend_count": 3,
"healthy_backends": 2,
"created_at": "2025-01-01T10:00:00Z",
"updated_at": "2025-01-15T10:00:00Z"
}
],
"total": 1,
"generated_at": "2025-01-15T10:30:00Z"
}
GET /api/v1/domains/{name}
Get a specific domain by name.
ACL Protected: Yes
Response: 200 OK
{
"domain": {
"id": "d1",
"name": "api.example.com",
"ttl": 300,
"routing_policy": "weighted",
"dnssec_enabled": true,
"enabled": true,
"settings": {
"geo_routing_enabled": true,
"failover_enabled": true,
"failover_threshold": 2,
"load_balancing_method": "round-robin"
}
}
}
POST /api/v1/domains
Create a new domain.
ACL Protected: Yes
Request Body:
{
"name": "api.example.com",
"ttl": 300,
"routing_policy": "weighted",
"dnssec_enabled": true,
"enabled": true,
"description": "Main API endpoint"
}
Response: 201 Created
PUT /api/v1/domains/{name}
Update an existing domain.
ACL Protected: Yes
Request Body:
{
"ttl": 600,
"enabled": false
}
Response: 200 OK
DELETE /api/v1/domains/{name}
Delete a domain.
ACL Protected: Yes
Response: 204 No Content
GET /api/v1/domains/{name}/backends
Get backends for a domain.
ACL Protected: Yes
Response: 200 OK
{
"backends": [
{
"id": "b1",
"address": "10.0.1.10",
"port": 80,
"weight": 100,
"priority": 1,
"region": "us-east-1",
"healthy": true,
"enabled": true,
"last_check": "2025-01-15T10:30:00Z"
}
],
"total": 1,
"generated_at": "2025-01-15T10:30:00Z"
}
POST /api/v1/domains/{name}/backends
Add a backend server to a domain (v1.1.1). The backend is automatically registered with the DNS server for immediate DNS resolution (v1.1.2).
ACL Protected: Yes
Path Parameters:
Parameter |
Type |
Description |
|---|---|---|
|
string |
Domain name |
Request Body:
{
"address": "10.0.2.10",
"port": 443,
"weight": 100,
"region": "us-west-2"
}
Request Fields:
Field |
Type |
Required |
Description |
|---|---|---|---|
|
string |
Yes |
Server IP address |
|
int |
Yes |
Server port |
|
int |
No |
Load balancing weight (default: 1) |
|
string |
No |
Geographic region |
Response: 201 Created
{
"message": "backend added",
"id": "api.example.com:10.0.2.10:443"
}
Error Responses:
400 Bad Request- Domain not found or backend already exists501 Not Implemented- Store not configured
DELETE /api/v1/domains/{name}/backends/{id}
Remove a backend from a domain (v1.1.1). The backend is automatically deregistered from the DNS server (v1.1.2).
Note: Only API-created backends can be deleted. Config-based backends cannot be deleted via API.
ACL Protected: Yes
Path Parameters:
Parameter |
Type |
Description |
|---|---|---|
|
string |
Domain name |
|
string |
Backend ID format: |
Example: DELETE /api/v1/domains/api.example.com/backends/api.example.com:10.0.2.10:443
Response: 204 No Content
Error Responses:
400 Bad Request- Cannot delete config-based backend404 Not Found- Backend not found501 Not Implemented- Store not configured
Server API
NEW in v1.1.0: Manage backend server configurations dynamically. The unified server architecture allows creating, updating, and deleting servers via API without configuration file changes.
GET /api/v1/servers
List all configured servers (static, agent-registered, and API-created).
ACL Protected: Yes
Response: 200 OK
{
"servers": [
{
"id": "app.example.com:10.0.1.10:80",
"service": "app.example.com",
"address": "10.0.1.10",
"port": 80,
"weight": 100,
"region": "us-east-1",
"source": "static",
"effective_status": "healthy",
"agent_healthy": null,
"draining": false,
"created_at": "2025-01-15T10:00:00Z",
"updated_at": "2025-01-15T10:00:00Z"
},
{
"id": "app.example.com:10.0.2.10:80",
"service": "app.example.com",
"address": "10.0.2.10",
"port": 80,
"weight": 150,
"region": "us-west-2",
"source": "api",
"effective_status": "healthy",
"agent_healthy": null,
"draining": false,
"created_at": "2025-01-15T11:00:00Z",
"updated_at": "2025-01-15T11:00:00Z"
}
]
}
Response Fields:
Field |
Type |
Description |
|---|---|---|
|
string |
Server ID format: |
|
string |
Domain/service this server belongs to |
|
string |
Server IP address |
|
int |
Server port |
|
int |
Load balancing weight (1-1000) |
|
string |
Geographic region |
|
string |
Registration source: |
|
string |
Current health status: |
|
bool |
Agent-reported health (null for static/API servers) |
|
bool |
Whether server is being drained |
POST /api/v1/servers
Create a new server dynamically (v1.1.0).
ACL Protected: Yes
Request Body:
{
"service": "app.example.com",
"address": "10.0.3.10",
"port": 80,
"weight": 100,
"region": "eu-west-1"
}
Request Fields:
Field |
Type |
Required |
Description |
|---|---|---|---|
|
string |
Yes |
Domain/service name (must match configured domain) |
|
string |
Yes |
Server IP address |
|
int |
Yes |
Server port |
|
int |
No |
Load balancing weight (default: 100) |
|
string |
Yes |
Geographic region |
Response: 201 Created
{
"message": "server created",
"id": "app.example.com:10.0.3.10:80"
}
Error Response: 400 Bad Request
{
"error": "server already exists: app.example.com:10.0.3.10:80"
}
GET /api/v1/servers/{id}
Get a specific server by ID.
ACL Protected: Yes
Path Parameters:
Parameter |
Type |
Description |
|---|---|---|
|
string |
Server ID format: |
Example: GET /api/v1/servers/app.example.com:10.0.1.10:80
Response: 200 OK
{
"id": "app.example.com:10.0.1.10:80",
"service": "app.example.com",
"address": "10.0.1.10",
"port": 80,
"weight": 100,
"region": "us-east-1",
"source": "static",
"effective_status": "healthy"
}
PATCH /api/v1/servers/{id}
Update a server’s weight and region (v1.1.0).
ACL Protected: Yes
Path Parameters:
Parameter |
Type |
Description |
|---|---|---|
|
string |
Server ID format: |
Request Body:
{
"weight": 150,
"region": "us-east-1"
}
Request Fields:
Field |
Type |
Required |
Description |
|---|---|---|---|
|
int |
No |
New load balancing weight |
|
string |
No |
New geographic region |
Response: 200 OK
{
"message": "server updated",
"id": "app.example.com:10.0.1.10:80"
}
DELETE /api/v1/servers/{id}
Delete a dynamically-created server (v1.1.0).
Note: Only servers created via API (source: "api") can be deleted. Static servers from configuration cannot be deleted via API.
ACL Protected: Yes
Path Parameters:
Parameter |
Type |
Description |
|---|---|---|
|
string |
Server ID format: |
Response: 204 No Content
Error Response: 400 Bad Request
{
"error": "cannot delete static server"
}
GET /api/v1/servers/{id}/health-check
Get health check configuration for a server.
ACL Protected: Yes
Response: 200 OK
{
"server_id": "s1",
"health_check": {
"enabled": true,
"type": "http",
"path": "/health",
"interval": "30s",
"timeout": "5s",
"healthy_threshold": 2,
"unhealthy_threshold": 3,
"expected_status": 200
}
}
PUT /api/v1/servers/{id}/health-check
Update health check configuration.
ACL Protected: Yes
Response: 200 OK
Region API
Manage geographic region configurations.
GET /api/v1/regions
List all configured regions.
ACL Protected: Yes
Query Parameters:
Parameter |
Type |
Description |
|---|---|---|
|
bool |
Filter by enabled status |
|
string |
Filter by continent |
Response: 200 OK
{
"regions": [
{
"id": "r1",
"name": "US East",
"code": "us-east-1",
"description": "Virginia region",
"latitude": 37.7749,
"longitude": -122.4194,
"continent": "NA",
"countries": ["US"],
"enabled": true,
"priority": 1,
"server_count": 5,
"healthy_servers": 4
}
],
"total": 1,
"generated_at": "2025-01-15T10:30:00Z"
}
POST /api/v1/regions
Create a new region.
ACL Protected: Yes
Request Body:
{
"name": "US East",
"code": "us-east-1",
"description": "Virginia region",
"latitude": 37.7749,
"longitude": -122.4194,
"continent": "NA",
"enabled": true,
"priority": 1
}
Response: 201 Created
GET /api/v1/regions/{id}
Get a specific region.
ACL Protected: Yes
Response: 200 OK
PUT /api/v1/regions/{id}
Update a region.
ACL Protected: Yes
Response: 200 OK
DELETE /api/v1/regions/{id}
Delete a region.
ACL Protected: Yes
Response: 204 No Content
Node API
Manage Overwatch and Agent nodes.
GET /api/v1/nodes/overwatch
List all Overwatch nodes.
ACL Protected: Yes
Query Parameters:
Parameter |
Type |
Description |
|---|---|---|
|
string |
Filter by status: |
|
string |
Filter by region |
Response: 200 OK
{
"nodes": [
{
"id": "ow1",
"name": "overwatch-east-1",
"address": "10.0.1.100",
"port": 53,
"api_port": 8080,
"region": "us-east-1",
"status": "online",
"version": "1.0.0",
"uptime_seconds": 86400,
"last_seen": "2025-01-15T10:30:00Z",
"queries_total": 1000000,
"queries_per_sec": 500.5,
"dnssec_enabled": true
}
],
"total": 1,
"generated_at": "2025-01-15T10:30:00Z"
}
GET /api/v1/nodes/overwatch/{id}
Get a specific Overwatch node.
ACL Protected: Yes
Response: 200 OK
GET /api/v1/nodes/agent
List all Agent nodes.
ACL Protected: Yes
Query Parameters:
Parameter |
Type |
Description |
|---|---|---|
|
string |
Filter by status: |
|
string |
Filter by region |
Response: 200 OK
{
"nodes": [
{
"id": "ag1",
"name": "agent-east-1",
"address": "10.0.2.100",
"port": 8443,
"region": "us-east-1",
"status": "online",
"version": "1.0.0",
"uptime_seconds": 86400,
"last_seen": "2025-01-15T10:30:00Z",
"checks_total": 500000,
"checks_per_sec": 100.5,
"active_checks": 50,
"target_count": 25,
"certificate_expiry": "2026-01-15T10:30:00Z",
"registered_at": "2025-01-01T10:00:00Z"
}
],
"total": 1,
"generated_at": "2025-01-15T10:30:00Z"
}
POST /api/v1/nodes/agent
Register a new Agent node.
ACL Protected: Yes
Request Body:
{
"name": "agent-east-1",
"address": "10.0.2.100",
"port": 8443,
"region": "us-east-1",
"version": "1.0.0"
}
Response: 201 Created
GET /api/v1/nodes/agent/{id}
Get a specific Agent node.
ACL Protected: Yes
Response: 200 OK
DELETE /api/v1/nodes/agent/{id}
Deregister an Agent node.
ACL Protected: Yes
Response: 204 No Content
GET /api/v1/nodes/agent/{id}/certificate
Get certificate information for an Agent.
ACL Protected: Yes
Response: 200 OK
{
"certificate": {
"agent_id": "ag1",
"serial": "ABC123",
"not_before": "2025-01-01T10:00:00Z",
"not_after": "2026-01-01T10:00:00Z",
"fingerprint": "SHA256:...",
"status": "valid",
"issued_at": "2025-01-01T10:00:00Z"
}
}
POST /api/v1/nodes/agent/{id}/certificate
Reissue certificate for an Agent.
ACL Protected: Yes
Response: 201 Created
DELETE /api/v1/nodes/agent/{id}/certificate
Revoke certificate for an Agent.
ACL Protected: Yes
Response: 204 No Content
Gossip API
Manage gossip protocol cluster communication.
GET /api/v1/gossip/nodes
List all nodes in the gossip cluster.
ACL Protected: Yes
Query Parameters:
Parameter |
Type |
Description |
|---|---|---|
|
string |
Filter by status: |
|
string |
Filter by region |
Response: 200 OK
{
"nodes": [
{
"id": "node1",
"name": "overwatch-1",
"address": "10.0.1.100",
"port": 7946,
"status": "alive",
"state": "leader",
"region": "us-east-1",
"version": "1.0.0",
"rtt_ms": 5,
"last_seen": "2025-01-15T10:30:00Z",
"joined_at": "2025-01-01T10:00:00Z"
}
],
"total": 3,
"healthy": 3,
"generated_at": "2025-01-15T10:30:00Z"
}
GET /api/v1/gossip/nodes/{id}
Get a specific gossip node.
ACL Protected: Yes
Response: 200 OK
GET /api/v1/gossip/config
Get gossip protocol configuration.
ACL Protected: Yes
Response: 200 OK
{
"config": {
"enabled": true,
"bind_address": "0.0.0.0",
"bind_port": 7946,
"cluster_name": "opengslb",
"encryption_enabled": true,
"gossip_interval_ms": 200,
"probe_interval_ms": 1000,
"probe_timeout_ms": 500,
"seeds": ["10.0.1.101:7946", "10.0.1.102:7946"]
}
}
PUT /api/v1/gossip/config
Update gossip protocol configuration.
ACL Protected: Yes
Response: 200 OK
POST /api/v1/gossip/generate-key
Generate a new encryption key for gossip protocol.
ACL Protected: Yes
Response: 200 OK
{
"key": "base64-encoded-key",
"algorithm": "AES-256-GCM",
"bits": 256
}
Audit Log API
Access audit logs for compliance and troubleshooting.
GET /api/v1/audit-logs
List audit log entries with pagination and filtering.
ACL Protected: Yes
Query Parameters:
Parameter |
Type |
Description |
|---|---|---|
|
string |
ISO 8601 start time |
|
string |
ISO 8601 end time |
|
string |
Comma-separated list of actions |
|
string |
Comma-separated list of resources |
|
string |
Comma-separated list of actors |
|
string |
Filter by status: |
|
int |
Results per page (default: 100) |
|
int |
Pagination offset |
Response: 200 OK
{
"entries": [
{
"id": "e1",
"timestamp": "2025-01-15T10:30:00Z",
"action": "create",
"resource": "domain",
"resource_id": "d1",
"actor": "admin",
"actor_type": "user",
"actor_ip": "192.168.1.50",
"status": "success",
"duration_ms": 50
}
],
"total": 100,
"limit": 100,
"offset": 0,
"generated_at": "2025-01-15T10:30:00Z"
}
GET /api/v1/audit-logs/{id}
Get a specific audit log entry.
ACL Protected: Yes
Response: 200 OK
GET /api/v1/audit-logs/stats
Get audit log statistics.
ACL Protected: Yes
Response: 200 OK
{
"stats": {
"total_entries": 10000,
"entries_last_24h": 500,
"entries_last_7d": 3000,
"by_action": {
"create": 1000,
"update": 5000,
"delete": 500
},
"by_resource": {
"domain": 2000,
"server": 3000
},
"by_status": {
"success": 9500,
"failure": 500
},
"retention_days": 90
},
"generated_at": "2025-01-15T10:30:00Z"
}
GET /api/v1/audit-logs/export
Export audit logs in CSV or JSON format.
ACL Protected: Yes
Query Parameters:
Parameter |
Type |
Description |
|---|---|---|
|
string |
Export format: |
(plus all filter params from GET /api/v1/audit-logs) |
Response: 200 OK with Content-Disposition: attachment
Metrics API
System and performance metrics.
GET /api/v1/metrics/overview
Get system metrics overview.
ACL Protected: Yes
Response: 200 OK
{
"overview": {
"timestamp": "2025-01-15T10:30:00Z",
"uptime_seconds": 86400,
"queries_total": 1000000,
"queries_per_sec": 500.5,
"health_checks_total": 500000,
"health_checks_per_sec": 100.5,
"active_domains": 50,
"active_servers": 200,
"healthy_servers": 180,
"unhealthy_servers": 20,
"active_regions": 5,
"overwatch_nodes": 3,
"agent_nodes": 10,
"dnssec_enabled": true,
"gossip_enabled": true,
"response_times": {
"avg_ms": 5.5,
"p50_ms": 3.0,
"p95_ms": 10.0,
"p99_ms": 25.0,
"max_ms": 100.0
},
"error_rate": 0.01,
"cache_hit_rate": 0.85,
"memory": {
"used_bytes": 500000000,
"available_bytes": 1500000000,
"total_bytes": 2000000000,
"percent": 25.0
},
"cpu": {
"used_percent": 15.5,
"cores": 8
}
}
}
GET /api/v1/metrics/history
Get historical metrics data.
ACL Protected: Yes
Query Parameters:
Parameter |
Type |
Description |
|---|---|---|
|
string |
ISO 8601 start time |
|
string |
ISO 8601 end time |
|
string |
Duration shorthand: |
|
string |
Comma-separated list of metrics |
|
string |
Data resolution: |
|
string |
Filter by node |
|
string |
Filter by region |
Response: 200 OK
{
"data_points": [
{
"timestamp": "2025-01-15T10:00:00Z",
"values": {
"queries_per_sec": 500.5,
"error_rate": 0.01
}
}
],
"total": 60,
"generated_at": "2025-01-15T10:30:00Z"
}
GET /api/v1/metrics/nodes/{id}
Get metrics for a specific node.
ACL Protected: Yes
Response: 200 OK
GET /api/v1/metrics/regions/{id}
Get metrics for a specific region.
ACL Protected: Yes
Response: 200 OK
GET /api/v1/metrics/routing
Get routing decision statistics.
ACL Protected: Yes
Response: 200 OK
{
"stats": {
"timestamp": "2025-01-15T10:30:00Z",
"total_decisions": 1000000,
"by_algorithm": {
"weighted": 500000,
"geo": 300000,
"failover": 200000
},
"by_region": {
"us-east-1": 400000,
"us-west-2": 300000,
"eu-west-1": 300000
},
"geo_routing_hits": 300000,
"failover_events": 500,
"avg_decision_time_us": 50.5
}
}
Config API
System configuration and user preferences.
GET /api/v1/preferences
Get user preferences for the dashboard.
ACL Protected: Yes
Response: 200 OK
{
"preferences": {
"theme": "dark",
"language": "en",
"timezone": "UTC",
"date_format": "YYYY-MM-DD",
"time_format": "HH:mm:ss",
"refresh_interval_seconds": 30,
"notifications_enabled": true,
"default_view": "overview",
"updated_at": "2025-01-15T10:30:00Z"
}
}
PUT /api/v1/preferences
Update user preferences.
ACL Protected: Yes
Request Body:
{
"theme": "light",
"refresh_interval_seconds": 60
}
Response: 200 OK
GET /api/v1/config/system
Get system configuration (read-only).
ACL Protected: Yes
Response: 200 OK
{
"config": {
"version": "1.0.0",
"build_info": {
"version": "1.0.0",
"git_commit": "abc123",
"build_date": "2025-01-01",
"go_version": "1.21"
},
"mode": "overwatch",
"node_id": "ow1",
"node_name": "overwatch-1",
"region": "us-east-1",
"features": ["dnssec", "gossip", "geo"],
"start_time": "2025-01-15T00:00:00Z"
}
}
GET /api/v1/config/dns
Get DNS configuration.
ACL Protected: Yes
Response: 200 OK
{
"config": {
"listen_address": "0.0.0.0",
"listen_port": 53,
"enable_tcp": true,
"enable_udp": true,
"enable_dot": false,
"enable_doh": false,
"max_udp_size": 4096,
"default_ttl": 300,
"cache_enabled": true,
"cache_size": 10000,
"rate_limit_enabled": true,
"rate_limit_qps": 1000
}
}
PUT /api/v1/config/dns
Update DNS configuration.
ACL Protected: Yes
Response: 200 OK
GET /api/v1/config/health-check
Get health check configuration.
ACL Protected: Yes
Response: 200 OK
{
"config": {
"default_interval_seconds": 30,
"default_timeout_seconds": 5,
"healthy_threshold": 2,
"unhealthy_threshold": 3,
"max_concurrent_checks": 100,
"default_protocol": "http"
}
}
PUT /api/v1/config/health-check
Update health check configuration.
ACL Protected: Yes
Response: 200 OK
GET /api/v1/config/logging
Get logging configuration.
ACL Protected: Yes
Response: 200 OK
{
"config": {
"level": "info",
"format": "json",
"output": "stdout",
"enable_audit": true,
"audit_retention_days": 90
}
}
PUT /api/v1/config/logging
Update logging configuration.
ACL Protected: Yes
Response: 200 OK
Routing API
Traffic routing algorithms and testing.
GET /api/v1/routing/algorithms
List available routing algorithms.
ACL Protected: Yes
Response: 200 OK
{
"algorithms": [
{
"id": "weighted",
"name": "Weighted Round Robin",
"description": "Distribute traffic based on server weights",
"type": "weighted",
"enabled": true,
"default": true
},
{
"id": "geo",
"name": "Geographic Routing",
"description": "Route to nearest region based on client location",
"type": "geo",
"enabled": true,
"default": false
},
{
"id": "failover",
"name": "Active-Passive Failover",
"description": "Route to primary, failover to secondary on failure",
"type": "failover",
"enabled": true,
"default": false
}
],
"total": 3,
"generated_at": "2025-01-15T10:30:00Z"
}
GET /api/v1/routing/algorithms/{id}
Get a specific routing algorithm.
ACL Protected: Yes
Response: 200 OK
POST /api/v1/routing/test
Test routing for a given request.
ACL Protected: Yes
Request Body:
{
"domain": "api.example.com",
"client_ip": "8.8.8.8",
"query_type": "A"
}
Response: 200 OK
{
"result": {
"domain": "api.example.com",
"client_ip": "8.8.8.8",
"client_region": "us-east-1",
"client_country": "US",
"algorithm": "geo",
"selected_backend": {
"address": "10.0.1.10",
"port": 80,
"region": "us-east-1",
"weight": 100,
"priority": 1,
"healthy": true
},
"alternatives": [],
"factors": [
{
"name": "geo_distance",
"type": "geo",
"value": "500km",
"weight": 1.0,
"impact": "positive"
}
],
"decision": "success",
"decision_time_us": 50,
"ttl": 300,
"timestamp": "2025-01-15T10:30:00Z"
}
}
GET /api/v1/routing/decisions
Get recent routing decisions.
ACL Protected: Yes
Query Parameters:
Parameter |
Type |
Description |
|---|---|---|
|
string |
ISO 8601 start time |
|
string |
ISO 8601 end time |
|
string |
Filter by domain |
|
string |
Filter by algorithm |
|
string |
Filter by selected region |
|
string |
Filter by outcome: |
|
int |
Results per page |
|
int |
Pagination offset |
Response: 200 OK
{
"decisions": [
{
"id": "rd1",
"timestamp": "2025-01-15T10:30:00Z",
"domain": "api.example.com",
"client_ip": "8.8.8.8",
"client_region": "us-east-1",
"algorithm": "geo",
"selected_server": "10.0.1.10:80",
"selected_region": "us-east-1",
"decision_time_us": 50,
"outcome": "success"
}
],
"total": 1000,
"limit": 100,
"offset": 0,
"generated_at": "2025-01-15T10:30:00Z"
}
GET /api/v1/routing/flows
Get traffic flow information between regions.
ACL Protected: Yes
Query Parameters:
Parameter |
Type |
Description |
|---|---|---|
|
string |
ISO 8601 start time |
|
string |
ISO 8601 end time |
|
string |
Filter by source region |
|
string |
Filter by destination region |
Response: 200 OK
{
"flows": [
{
"source_region": "us-east-1",
"destination_region": "us-west-2",
"request_count": 100000,
"bytes_transferred": 1000000000,
"avg_latency_ms": 50.5,
"error_rate": 0.01,
"timestamp": "2025-01-15T10:30:00Z"
}
],
"total": 10,
"generated_at": "2025-01-15T10:30:00Z"
}
Override API
External health overrides for individual servers. Allows external systems to mark servers healthy/unhealthy independent of health checks.
GET /api/v1/overrides
List all active health overrides.
ACL Protected: Yes
Response: 200 OK
{
"overrides": [
{
"service": "api-service",
"address": "10.0.1.10",
"healthy": false,
"reason": "Maintenance scheduled",
"source": "monitoring_tool",
"created_at": "2025-01-15T10:30:00Z",
"authority": "192.168.1.50"
}
]
}
GET /api/v1/overrides/{service}/{address}
Get a specific override for a service/address combination.
ACL Protected: Yes
Path Parameters:
Parameter |
Type |
Description |
|---|---|---|
|
string |
Service name |
|
string |
Server IP address |
Response: 200 OK
{
"service": "api-service",
"address": "10.0.1.10",
"healthy": false,
"reason": "Maintenance scheduled",
"source": "monitoring_tool",
"created_at": "2025-01-15T10:30:00Z",
"authority": "192.168.1.50"
}
Error Response: 404 Not Found
{
"error": "override not found",
"code": 404
}
PUT /api/v1/overrides/{service}/{address}
Set or update a health override for a server.
ACL Protected: Yes
Path Parameters:
Parameter |
Type |
Description |
|---|---|---|
|
string |
Service name |
|
string |
Server IP address |
Request Body:
{
"healthy": false,
"reason": "Maintenance window",
"source": "external_monitoring_tool"
}
Field |
Type |
Required |
Description |
|---|---|---|---|
|
bool |
No |
Override health status (default: false) |
|
string |
No |
Human-readable reason for override |
|
string |
Yes |
Identifier for the system setting the override |
Response: 200 OK
{
"service": "api-service",
"address": "10.0.1.10",
"healthy": false,
"reason": "Maintenance window",
"source": "external_monitoring_tool",
"created_at": "2025-01-15T10:30:00Z",
"authority": "192.168.1.50"
}
Error Response: 400 Bad Request
{
"error": "source is required",
"code": 400
}
DELETE /api/v1/overrides/{service}/{address}
Clear a health override for a server.
ACL Protected: Yes
Path Parameters:
Parameter |
Type |
Description |
|---|---|---|
|
string |
Service name |
|
string |
Server IP address |
Response: 204 No Content
Error Response: 404 Not Found
{
"error": "override not found",
"code": 404
}
DNSSEC API
DNSSEC key management and synchronization endpoints. These endpoints are available when DNSSEC is enabled.
GET /api/v1/dnssec/status
Returns the current DNSSEC status including key info and sync status.
ACL Protected: Yes
Response (DNSSEC enabled): 200 OK
{
"enabled": true,
"keys": [
{
"zone": "example.com.",
"key_tag": 12345,
"algorithm": 8,
"flags": 256,
"protocol": 3
}
],
"sync": {
"enabled": true,
"last_sync": "2025-01-15T10:30:00Z",
"last_sync_error": null,
"next_sync": "2025-01-15T11:00:00Z",
"peer_count": 3
}
}
Response (DNSSEC disabled): 200 OK
{
"enabled": false
}
GET /api/v1/dnssec/ds
Returns DS (Delegation Signer) records for all managed zones.
ACL Protected: Yes
Query Parameters:
Parameter |
Type |
Description |
|---|---|---|
|
string |
Optional zone filter |
Response (DNSSEC enabled): 200 OK
{
"enabled": true,
"ds_records": [
{
"zone": "example.com.",
"key_tag": 12345,
"algorithm": 8,
"digest_type": 2,
"digest": "ABC123...",
"ds_record": "example.com. 3600 IN DS 12345 8 2 ABC123...",
"created_at": "2025-01-15T10:30:00Z"
}
]
}
Response (DNSSEC disabled): 200 OK
{
"enabled": false,
"message": "DNSSEC is disabled"
}
GET /api/v1/dnssec/keys
Returns DNSSEC key pairs for synchronization between Overwatches.
ACL Protected: Yes
Response (DNSSEC enabled): 200 OK
{
"enabled": true,
"keys": [
{
"zone": "example.com.",
"key_tag": 12345,
"algorithm": 8,
"flags": 256,
"protocol": 3,
"public_key": "...",
"created_at": "2025-01-15T10:30:00Z"
}
]
}
Response (DNSSEC disabled): 200 OK
{
"enabled": false,
"keys": null
}
POST /api/v1/dnssec/sync
Trigger an immediate DNSSEC key sync from all peers.
ACL Protected: Yes
Request Body: Empty
Response: 200 OK
{
"status": "ok",
"message": "key sync triggered"
}
Error Response: 400 Bad Request
{
"error": "DNSSEC is disabled",
"code": 400
}
Overwatch API
Agent-based health monitoring with validation and overrides. These endpoints are available in Overwatch mode.
GET /api/v1/overwatch/backends
List all backends with agent and validation health info.
ACL Protected: Yes
Query Parameters:
Parameter |
Type |
Description |
|---|---|---|
|
string |
Filter by service name |
|
string |
Filter by region |
|
string |
Filter by status: |
Response: 200 OK
{
"backends": [
{
"service": "api-service",
"address": "10.0.1.10",
"port": 8080,
"weight": 100,
"agent_id": "agent-123",
"region": "us-east-1",
"effective_status": "healthy",
"agent_healthy": true,
"agent_last_seen": "2025-01-15T10:30:00Z",
"validation_healthy": true,
"validation_last_check": "2025-01-15T10:29:00Z",
"validation_error": null,
"override_status": null,
"override_reason": "",
"override_by": "",
"override_at": null
}
],
"generated_at": "2025-01-15T10:30:05Z"
}
Response Fields:
Field |
Type |
Description |
|---|---|---|
|
string |
Service name |
|
string |
Backend IP address |
|
int |
Backend port |
|
int |
Load balancing weight |
|
string |
Reporting agent ID |
|
string |
Region identifier |
|
string |
Final computed status: |
|
bool |
Health status reported by agent |
|
string |
Last heartbeat from agent |
|
bool |
Validation check result (if enabled) |
|
string |
Last validation timestamp |
|
string |
Validation error message |
|
bool |
Manual override status (null if none) |
|
string |
Reason for override |
|
string |
User/system that set override |
|
string |
When override was set |
GET /api/v1/overwatch/stats
Get aggregated statistics across all backends.
ACL Protected: Yes
Response: 200 OK
{
"total_backends": 10,
"healthy_backends": 8,
"unhealthy_backends": 1,
"stale_backends": 1,
"active_overrides": 2,
"validation_enabled": true,
"validated_backends": 7,
"disagreement_count": 0,
"active_agents": 3,
"unique_services": 2,
"backends_by_service": {
"api-service": 5,
"web-service": 5
},
"backends_by_region": {
"us-east-1": 6,
"us-west-2": 4
},
"generated_at": "2025-01-15T10:30:05Z"
}
Response Fields:
Field |
Type |
Description |
|---|---|---|
|
int |
Total registered backends |
|
int |
Backends with healthy status |
|
int |
Backends with unhealthy status |
|
int |
Backends with stale status (no recent heartbeat) |
|
int |
Number of active manual overrides |
|
bool |
Whether validation is running |
|
int |
Backends with validation results |
|
int |
Backends where agent and validation disagree |
|
int |
Number of unique reporting agents |
|
int |
Number of unique services |
|
object |
Backend count per service |
|
object |
Backend count per region |
POST /api/v1/overwatch/backends/{service}/{address}/{port}/override
Set a manual override for a backend’s health status.
ACL Protected: Yes
Path Parameters:
Parameter |
Type |
Description |
|---|---|---|
|
string |
Service name |
|
string |
Backend IP address |
|
int |
Backend port |
Request Body:
{
"healthy": false,
"reason": "Manual maintenance"
}
Field |
Type |
Required |
Description |
|---|---|---|---|
|
bool |
No |
Override health status |
|
string |
No |
Human-readable reason |
Request Headers:
Header |
Description |
|---|---|
|
Optional user identifier for audit trail |
Response: 200 OK
{
"success": true,
"message": "Override set: backend marked as unhealthy"
}
Error Response: 404 Not Found
{
"error": "backend not found",
"code": 404
}
DELETE /api/v1/overwatch/backends/{service}/{address}/{port}/override
Clear a manual override for a backend.
ACL Protected: Yes
Path Parameters:
Parameter |
Type |
Description |
|---|---|---|
|
string |
Service name |
|
string |
Backend IP address |
|
int |
Backend port |
Response: 200 OK
{
"success": true,
"message": "Override cleared"
}
Error Response: 404 Not Found
{
"error": "backend not found",
"code": 404
}
POST /api/v1/overwatch/validate
Trigger immediate validation of all or specific backends.
ACL Protected: Yes
Query Parameters (optional):
Parameter |
Type |
Description |
|---|---|---|
|
string |
Service name (requires all three params) |
|
string |
Backend IP address |
|
int |
Backend port |
Request Body: Empty
Response (all backends): 200 OK
{
"success": true,
"message": "Validation triggered for all backends"
}
Response (specific backend): 200 OK
{
"success": true,
"message": "Validation triggered for specific backend"
}
Error Response: 503 Service Unavailable
{
"error": "validator not available",
"code": 503
}
GET /api/v1/overwatch/agents
List all pinned agent certificates with expiration info.
ACL Protected: Yes
Response: 200 OK
{
"agents": [
{
"agent_id": "agent-123",
"fingerprint": "SHA256:abc123...",
"region": "us-east-1",
"first_seen": "2025-01-01T10:00:00Z",
"last_seen": "2025-01-15T10:30:00Z",
"not_after": "2026-01-01T10:00:00Z",
"revoked": false,
"expires_in_hours": 8760
}
],
"total": 3,
"revoked": 0,
"expiring": 1,
"generated_at": "2025-01-15T10:30:05Z"
}
Response Fields:
Field |
Type |
Description |
|---|---|---|
|
array |
List of agent certificates |
|
int |
Total agent count |
|
int |
Number of revoked certificates |
|
int |
Certificates expiring within 30 days |
GET /api/v1/overwatch/agents/{agent_id}
Get a specific agent’s certificate details.
ACL Protected: Yes
Path Parameters:
Parameter |
Type |
Description |
|---|---|---|
|
string |
Agent identifier |
Response: 200 OK
{
"agent_id": "agent-123",
"fingerprint": "SHA256:abc123...",
"region": "us-east-1",
"first_seen": "2025-01-01T10:00:00Z",
"last_seen": "2025-01-15T10:30:00Z",
"not_after": "2026-01-01T10:00:00Z",
"revoked": false,
"expires_in_hours": 8760
}
Error Response: 404 Not Found
{
"error": "agent not found",
"code": 404
}
DELETE /api/v1/overwatch/agents/{agent_id}
Delete (unpin) an agent’s certificate.
ACL Protected: Yes
Path Parameters:
Parameter |
Type |
Description |
|---|---|---|
|
string |
Agent identifier |
Response: 200 OK
{
"success": true,
"message": "Agent certificate deleted"
}
POST /api/v1/overwatch/agents/{agent_id}/revoke
Revoke an agent’s certificate.
ACL Protected: Yes
Path Parameters:
Parameter |
Type |
Description |
|---|---|---|
|
string |
Agent identifier |
Request Body:
{
"reason": "Security incident"
}
Field |
Type |
Required |
Description |
|---|---|---|---|
|
string |
No |
Reason for revocation (default: “revoked via API”) |
Response: 200 OK
{
"success": true,
"message": "Agent certificate revoked"
}
Error Response: 404 Not Found
{
"error": "agent not found",
"code": 404
}
GET /api/v1/overwatch/agents/expiring
List agent certificates expiring within a threshold.
ACL Protected: Yes
Query Parameters:
Parameter |
Type |
Default |
Description |
|---|---|---|---|
|
int |
30 |
Days until expiration threshold |
Response: 200 OK
{
"expiring": [
{
"agent_id": "agent-456",
"fingerprint": "SHA256:def456...",
"region": "us-west-2",
"first_seen": "2025-01-01T10:00:00Z",
"last_seen": "2025-01-15T10:30:00Z",
"not_after": "2025-02-10T10:00:00Z",
"revoked": false,
"expires_in_hours": 480
}
],
"count": 1,
"threshold_days": 30,
"generated_at": "2025-01-15T10:30:05Z"
}
Error Responses
All endpoints return errors in a consistent format:
{
"error": "error message",
"code": 405
}
HTTP Status Codes
Status Code |
Description |
|---|---|
|
Success |
|
Success (no content) |
|
Bad Request - invalid parameters or malformed JSON |
|
Forbidden - IP not in |
|
Not Found - resource doesn’t exist |
|
Method Not Allowed - wrong HTTP method |
|
Internal Server Error |
|
Service Unavailable - feature disabled or dependency unavailable |
Usage Examples
curl
# Check server health
curl http://localhost:8080/api/v1/health/servers
# Check regional health
curl http://localhost:8080/api/v1/health/regions
# Check readiness
curl -w "%{http_code}" http://localhost:8080/api/v1/ready
# Pretty print with jq
curl -s http://localhost:8080/api/v1/health/servers | jq .
# Set a health override
curl -X PUT http://localhost:8080/api/v1/overrides/api-service/10.0.1.10 \
-H "Content-Type: application/json" \
-d '{"healthy": false, "reason": "maintenance", "source": "admin"}'
# List all overrides
curl http://localhost:8080/api/v1/overrides
# Clear an override
curl -X DELETE http://localhost:8080/api/v1/overrides/api-service/10.0.1.10
# Get DNSSEC status
curl http://localhost:8080/api/v1/dnssec/status
# Get version information
curl http://localhost:8080/api/v1/version
# Create a new domain
curl -X POST http://localhost:8080/api/v1/domains \
-H "Content-Type: application/json" \
-d '{"name": "api.example.com", "ttl": 300, "routing_policy": "latency"}'
# Add a backend to a domain
curl -X POST http://localhost:8080/api/v1/domains/api.example.com/backends \
-H "Content-Type: application/json" \
-d '{"address": "10.0.2.10", "port": 443, "weight": 100, "region": "us-west-2"}'
# List backends for a domain
curl http://localhost:8080/api/v1/domains/api.example.com/backends
# Remove a backend from a domain
curl -X DELETE http://localhost:8080/api/v1/domains/api.example.com/backends/api.example.com:10.0.2.10:443
# Delete a domain
curl -X DELETE http://localhost:8080/api/v1/domains/api.example.com
# Get DS records for a specific zone
curl "http://localhost:8080/api/v1/dnssec/ds?zone=example.com"
# Trigger DNSSEC key sync
curl -X POST http://localhost:8080/api/v1/dnssec/sync
# List Overwatch backends
curl http://localhost:8080/api/v1/overwatch/backends
# Filter backends by service
curl "http://localhost:8080/api/v1/overwatch/backends?service=api-service"
# Get Overwatch stats
curl http://localhost:8080/api/v1/overwatch/stats
# Set backend override
curl -X POST http://localhost:8080/api/v1/overwatch/backends/api-service/10.0.1.10/8080/override \
-H "Content-Type: application/json" \
-H "X-User: admin" \
-d '{"healthy": false, "reason": "deploying new version"}'
# Trigger validation
curl -X POST http://localhost:8080/api/v1/overwatch/validate
# List agent certificates
curl http://localhost:8080/api/v1/overwatch/agents
# Get expiring certificates (custom threshold)
curl "http://localhost:8080/api/v1/overwatch/agents/expiring?threshold_days=60"
# Revoke an agent certificate
curl -X POST http://localhost:8080/api/v1/overwatch/agents/agent-123/revoke \
-H "Content-Type: application/json" \
-d '{"reason": "compromised credentials"}'
Kubernetes Probes
livenessProbe:
httpGet:
path: /api/v1/live
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
readinessProbe:
httpGet:
path: /api/v1/ready
port: 8080
initialDelaySeconds: 10
periodSeconds: 5
Monitoring Integration
Prometheus (via blackbox_exporter or custom scraper):
The API complements the /metrics endpoint. Use /api/v1/ready as a health check target.
Alertmanager webhook:
Poll /api/v1/health/servers and alert on consecutive_failures > 0.
Overwatch monitoring:
Poll /api/v1/overwatch/stats and alert on:
stale_backends > 0- agents not reportingdisagreement_count > 0- agent/validation mismatchunhealthy_backends / total_backends > 0.5- high failure rate