REST API Reference
Nexus GSLB exposes a REST API for managing pools, members, services, health checks, and geo rules. Enable it via api.enabled: true in your config.
Base URL: http://<listenAddr>:<port>/api/v1
All request and response bodies are JSON. Successful list endpoints return [] (not null) when empty.
HealthGET /api/v1/health
Returns server liveness.
Response 200:
{"status": "ok"}
Pools
A pool is a named group of backend members.
POST /api/v1/pools
Create a pool.
Request:
{"name": "web"}
Response 201:
{"id": "a1b2c3...", "name": "web"}
Errors:
400 —
namemissing or empty.
GET /api/v1/pools
List all pools.
Response 200:
[{"id": "a1b2c3...", "name": "web"}]
GET /api/v1/pools/{id}
Get a pool by ID.
Response 200: Pool object. Response 404: pool not found.
PUT /api/v1/pools/{id}
Rename a pool.
Request:
{"name": "web-v2"}
Response 200: updated Pool object. Response 400 — name missing. Response 404 — pool not found.
DELETE /api/v1/pools/{id}
Delete a pool. Cascades to members, health checks, and geo rules.
Response 204: no content. Response 404: pool not found.
Members
A member is a backend server (IP + port + weight) belonging to a pool.
POST /api/v1/pools/{id}/members
Add a member to a pool. Also adds the endpoint to the running balancer.
Request:
{"ipAddress": "10.0.0.1", "port": 80, "weight": 3, "priority": 1}
Fields:
ipAddress(string, required): valid IPv4 or IPv6 address.port(int, required): 1–65535.weight(int, optional): default 1 if ≤ 0. Used byweighted-round-robin.priority(int, optional): default 0 (unset). Used by thefailoveralgorithm — lower number = higher preference (1 = primary, 2 = secondary, …). 0 sorts last.
Response 201:
{"id": "...", "poolId": "...", "ipAddress": "10.0.0.1", "port": 80, "weight": 3, "priority": 1, "enabled": true}
Errors:
400 — invalid IP or port out of range.
404 — pool not found (on internal lookup failure).
GET /api/v1/pools/{id}/members
List members in a pool.
Response 200: array of Member objects.
GET /api/v1/members/{id}
Get a member by ID.
Response 200: Member object. Response 404: member not found.
PUT /api/v1/members/{id}
Update a member's weight, priority, and enabled state. Reflects the change in the running balancer immediately (weight set to 0 if disabled).
Request:
{"weight": 1, "priority": 2, "enabled": true}
Fields:
weight(int): negative values coerced to 0.priority(int): failover preference order (1 = primary, 2 = secondary, …; 0 = unset/last-resort).enabled(bool).
Response 200: updated Member object. Response 404: member not found.
DELETE /api/v1/members/{id}
Delete a member. Removes the endpoint from the running balancer.
Response 204: no content. Response 404: member not found.
Services
A service binds a DNS name + domain to a pool and a load balancing algorithm.
POST /api/v1/services
Create a service.
Request:
{"name": "www", "domain": "example.com.", "algorithm": "round-robin", "ttl": 60, "poolId": null}
Fields:
name(string, required).domain(string, required): fully-qualified DNS name (include trailing dot).algorithm(string, optional): one ofround-robin(default),weighted-round-robin,geo-ip,map-file,failover.ttl(int, optional): DNS TTL in seconds. Default 60.poolId(string | null, optional): ID of the pool to attach.
Response 201:
{"id": "...", "name": "www", "domain": "example.com.", "algorithm": "round-robin", "poolId": null}
Errors:
400 —
nameordomainmissing.
GET /api/v1/services
List all services.
Response 200: array of Service objects.
GET /api/v1/services/{id}
Get a service by ID.
Response 200: Service object. Response 404: not found.
PUT /api/v1/services/{id}
Update a service.
Request: same fields as POST.
Response 200: updated Service object. Response 400 — name or domain missing. Response 404 — service not found.
DELETE /api/v1/services/{id}
Delete a service.
Response 204: no content. Response 404: not found.
Health Checks
Each pool can have at most one health check configuration (upsert semantics).
PUT /api/v1/pools/{id}/healthcheck
Create or replace the health check for a pool.
Request:
{ "type": "http", "port": 443, "intervalMs": 5000, "timeoutMs": 1000, "httpPath": "/ping", "httpHost": "", "httpExpectedStatus": 200, "httpContains": "", "tls": true, "insecureSkipVerify": false, "scoreWindow": 0}
Fields (all optional — defaults applied for zero values):
type(string):tcporhttp. Defaulttcp.port(int): default 80.intervalMs(int): milliseconds between checks. Default 10000.timeoutMs(int): check timeout milliseconds. Default 2000.httpPath(string): HTTP request path. Default/.httpHost(string): HTTPHostheader override.httpExpectedStatus(int): expected HTTP status. Default 200.httpContains(string): required response body substring.tls(bool): use HTTPS.insecureSkipVerify(bool): skip TLS certificate verification.scoreWindow(int): rolling probe window for partial health scoring. 0 (default) = disabled; N = score over last N probes (0.0–1.0). See Health Checks for details.
Response 200: HealthCheck object.
GET /api/v1/pools/{id}/healthcheck
Get the health check for a pool.
Response 200: HealthCheck object. Response 404: no health check configured for this pool.
DELETE /api/v1/pools/{id}/healthcheck
Delete the health check for a pool.
Response 204: no content. Response 404: no health check found.
Geo Rules
Geo rules map source CIDR blocks to preferred endpoint IPs for a pool.
POST /api/v1/pools/{id}/georules
Create a geo rule.
Request:
{"cidr": "10.0.0.0/8", "endpoint": "203.0.113.1", "priority": 5}
Fields:
cidr(string, required): valid CIDR block.endpoint(string, required): valid IP address.priority(int, optional): lower values = higher priority (convention; not enforced by storage).
Response 201:
{"id": "...", "poolId": "...", "cidr": "10.0.0.0/8", "endpoint": "203.0.113.1", "priority": 5}
Errors:
400 — invalid CIDR or invalid endpoint IP.
GET /api/v1/pools/{id}/georules
List geo rules for a pool.
Response 200: array of GeoRule objects.
DELETE /api/v1/georules/{id}
Delete a geo rule by ID.
Response 204: no content. Response 404: rule not found.
Error responses
All error responses have the form:
{"error": "description"}
Common status codes:
400 Bad Request — validation failure (invalid IP, port, CIDR, missing required field).
404 Not Found — resource does not exist.
500 Internal Server Error — unexpected database or server error.
Running the API server
api: enabled: true listenAddr: "127.0.0.1" port: 8080 webuiPath: "/opt/gslb/webui" # Optional: path to Next.js static export output (webui/out/)
The server starts as a goroutine alongside the DNS server. Shut down is graceful (context cancellation). Set listenAddr: "0.0.0.0" to expose on all interfaces (ensure firewall rules are in place).
Dashboard EndpointsGET /api/v1/dashboard/stats
Returns aggregated statistics for the dashboard.
Response 200:
{ "totalPools": 3, "totalMembers": 12, "healthyMembers": 10, "unhealthyMembers": 2, "totalServices": 5, "totalGeoRules": 8, "uptimeSeconds": 86400, "webSocketClients": 2}
GET /api/v1/snapshot
Returns the full current state of the GSLB system. Used for initial load of the WebUI.
Response 200:
{ "pools": [...], "members": {"pool-id-1": [...]}, "services": [...], "healthStatus": {"pool-id-1": {"192.168.1.1": {"healthy": true, "score": 1.0, "lastChecked": 1234567890}}}, "geoRules": {"pool-id-1": [...]}, "stats": {...}, "timestamp": 1234567890000}
WebSocketGET /api/v1/ws/token
Generates a JWT token for WebSocket authentication. Include this token when connecting to the WebSocket endpoint.
Response 200:
{ "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "expiresAt": 1234567890000}
WebSocket Connection
Connect to ws://<host>:<port>/api/v1/ws?token=<token>
The WebSocket connection provides real-time updates for:
Health status changes (members going online/offline)
Pool, member, and service CRUD operations
Dashboard statistics updates
Message Types
Health Update:
{ "type": "health_update", "payload": { "poolId": "pool-123", "ipAddress": "192.168.1.1", "healthy": true, "score": 1.0, "timestamp": 1234567890000, "rttMs": 5, "node": "node-1" }}
Pool Update:
{ "type": "pool_update", "payload": { "action": "created|updated|deleted", "pool": {...} }}
Member Update:
{ "type": "member_update", "payload": { "action": "created|updated|deleted|snapshot", "poolId": "pool-123", "member": {...} }}
Service Update:
{ "type": "service_update", "payload": { "action": "created|updated|deleted", "service": {...} }}
WebUI
The WebUI is a Next.js-based dashboard for managing the GSLB system. It connects to the REST API and WebSocket for real-time updates.
Enabling the WebUI
Build the Next.js application:
cd webuinpm installnpm run build
Configure the WebUI path in config.yaml:
api: enabled: true listenAddr: "0.0.0.0" port: 8080 webuiPath: "/opt/gslb/webui"
Access the WebUI at
http://<host>:<port>/ui/
WebUI Features
Dashboard: Real-time overview of all pools and their health status
Pool Management: Create, view, and manage pools
Member Management: Add, update, and remove pool members
Health Monitoring: Real-time health status updates via WebSocket
Activity Feed: Live feed of health changes and configuration updates