Skip to main content

Each rolter gateway keeps its own circuit breakers in memory, one set per replica (circuit breaker). GET /api/v1/breaker-state is the control plane’s picture of all of them at once: for every (model, target) that some gateway holds a breaker entry for, the state it is in and how many gateways agree.

The dashboard reads it for the Provider Health screen and for the target rows of Models and Routing Rules. It is a different signal from the 7-day SLA verdict on Provider Health, which comes from request history: this one is what the gateways are doing right now.

How the control plane learns it#

Each gateway samples its breaker registry every 10 seconds and pushes the result to the control plane over the internal channel it already uses for the config snapshot, identifying itself with the same node id as the cluster inventory (see Cluster). A report replaces everything that node sent before, so a breaker that closes again leaves the view on the node’s next report. A node that stops reporting drops out after 40 seconds.

Two consequences follow from that:

  • A target that is not listed is closed. Only targets with an open, half-open or still-counting breaker are reported. gateways_live says how many gateways were polling; 0 means the view knows nothing about the fleet, and a dashboard must not read an empty targets as “all healthy”.
  • A gateway with no node id is invisible. Without ROLTER_NODE_ID or a HOSTNAME, a gateway stays out of the cluster inventory and out of this view too.

The breaker must be enabled ([breaker] enabled = true); a disabled breaker records nothing and there is nothing to report.

Request#

Any authenticated caller may read it. What a caller sees is narrowed to the models they see in GET /api/v1/models, by the same tenancy and access-profile rules: a member of one organization never sees another organization’s models or providers here. Per-node detail (nodes) is returned only to a superadmin, the admin token and open mode, since a node id is a host name. A deployment without a database answers with an empty view, because nothing can push to it.

Response#

FieldMeaning
gateways_livegateways that polled in the last minute, whether or not they hold a breaker entry
targets[].target_indexthe target’s position in the route’s target list
targets[].statethe worst state any gateway reports: open, else half_open, else closed
targets[].nodes_opengateways whose breaker for this target is open
targets[].nodes_half_opengateways currently admitting a single probe
targets[].nodes[]per-gateway detail, superadmin only; retry_after_secs is how long an open breaker has left

A closed row is a target that has been failing without reaching the threshold yet; its consecutive_failures shows how close it is.