Skip to content

Load Balancer

POST /v1/load-balancers/{id}/backends · scope lb:write · reversible · idempotent

A shortcut over PUT /listeners for the common case of adding a machine. It revalidates and applies the full configuration, so it inherits the same guarantee: either the backend ends up receiving traffic, or nothing changed.

Terminal window
curl https://api.truo.cloud/v1/load-balancers/svc_10432/backends \
-X POST \
-H "Authorization: Bearer $TRUO_TOKEN" \
-H "Content-Type: application/json" \
-d '{"listener":"<listener>","ip":"<ip>","port":1}'

operationId: lb.backends.create

DELETE /v1/load-balancers/{id}/backends/{listener}/{ip}/{port} · scope lb:write · destructive — cannot be undone · idempotent

The three values identifying the backend go in the path. The upstream expects them in the body of a DELETE, which proxies and CDNs discard and several HTTP clients refuse to send; the body is built on this side.

A listener cannot be left without backends. Removing the last one returns 400 validation_failed: to remove the whole listener, use PUT /listeners without it.

Terminal window
curl https://api.truo.cloud/v1/load-balancers/svc_10432/backends/web/10.0.0.5/8080 \
-X DELETE \
-H "Authorization: Bearer $TRUO_TOKEN"

operationId: lb.backends.delete

GET /v1/load-balancers/{id}/backends · scope lb:read

The backends of every listener, flattened, each with the listener it belongs to. It is a view over the same configuration that GET /listeners returns.

Terminal window
curl https://api.truo.cloud/v1/load-balancers/svc_10432/backends \
-H "Authorization: Bearer $TRUO_TOKEN"

operationId: lb.backends.list

GET /v1/load-balancers/{id} · scope lb:read

Queries the control plane, which in turn probes the balancer. If it does not respond, the state fields come back null instead of failing.

Terminal window
curl https://api.truo.cloud/v1/load-balancers/svc_10432 \
-H "Authorization: Bearer $TRUO_TOKEN"

operationId: lb.instances.get

GET /v1/load-balancers · scope lb:read

Served from the database, without querying the control plane: provisioning_state, healthy, and listener_count come back null. Fetching them would cost one call per page item.

A page can come back with fewer items than limit even when more exist: every control plane product shares the same provisioning module, so the family filter can only be applied after reading the page. has_more remains the correct signal for whether anything is left to fetch.

Terminal window
curl https://api.truo.cloud/v1/load-balancers \
-H "Authorization: Bearer $TRUO_TOKEN"

operationId: lb.instances.list

GET /v1/load-balancers/{id}/listeners · scope lb:read

The balancer’s full configuration, including each listener’s backends. It is what you read, modify, and send back in PUT.

Terminal window
curl https://api.truo.cloud/v1/load-balancers/svc_10432/listeners \
-H "Authorization: Bearer $TRUO_TOKEN"

operationId: lb.listeners.list

PUT /v1/load-balancers/{id}/listeners · scope lb:write · destructive — cannot be undone · idempotent

Replaces the entire set: listeners missing from listeners are deleted, along with their backends. Sending [] leaves the balancer with nothing listening and cuts traffic. Read GET /listeners, modify, and send everything back.

The change is applied within the call: by the time this returns, the new configuration is already serving traffic. If the resulting configuration is invalid, nothing is applied and the response is 400 validation_failed — the service is never left half-configured.

Terminal window
curl https://api.truo.cloud/v1/load-balancers/svc_10432/listeners \
-X PUT \
-H "Authorization: Bearer $TRUO_TOKEN" \
-H "Content-Type: application/json" \
-d '{"listeners":[]}'

operationId: lb.listeners.replace

GET /v1/load-balancers/{id}/stats · scope lb:read

A point-in-time snapshot: current connections and bytes accumulated since the balancer’s last start, plus each backend’s health from the latest probe. For the series over time, use GET /v1/load-balancers/{id}/stats/history.

If the balancer does not answer the probe, the listeners still appear —they come from the stored configuration— with state: unknown and zeroed counters. A listener that exists but does not respond and one that exists with no traffic cannot be told apart by the counters: check state.

Terminal window
curl https://api.truo.cloud/v1/load-balancers/svc_10432/stats \
-H "Authorization: Bearer $TRUO_TOKEN"

operationId: lb.stats.get

GET /v1/load-balancers/{id}/stats/history · scope lb:read

Fixed-size buckets for the requested window: new connections per second, bytes in and out per second, average and peak concurrent connections, and the lowest number of healthy backends. total adds every listener; listeners has the same series per listener.

The balancer is sampled once a minute and samples are kept 14 days. Every bucket of the window is returned; a bucket with no samples (before the service existed, or while it was unreachable) has null fields, which is a gap and not a zero. Rates come from cumulative counters, so a configuration change does not produce a spike or a negative value.

Terminal window
curl https://api.truo.cloud/v1/load-balancers/svc_10432/stats/history \
-H "Authorization: Bearer $TRUO_TOKEN"

operationId: lb.stats.history