Get bridge health
curl --request GET \
--url https://demo-api.mobula.io/api/2/bridge/healthimport requests
url = "https://demo-api.mobula.io/api/2/bridge/health"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://demo-api.mobula.io/api/2/bridge/health', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://demo-api.mobula.io/api/2/bridge/health",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://demo-api.mobula.io/api/2/bridge/health"
req, _ := http.NewRequest("GET", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://demo-api.mobula.io/api/2/bridge/health")
.asString();require 'uri'
require 'net/http'
url = URI("https://demo-api.mobula.io/api/2/bridge/health")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_body{
"data": {
"state": "operational",
"shedding": true,
"killswitchActive": true,
"fills": {
"pending": 123,
"oldestPendingSec": 123,
"lastMinute": 123,
"latencyMs": {
"p50": 123,
"p90": 123
}
},
"refunds": {
"pending": 123,
"lastMinute": 123
},
"pods": [
{
"pod": "<string>",
"leader": true,
"cpuCores": 123,
"eventLoopUtilization": 123,
"rssMB": 123,
"heapUsedMB": 123,
"uptimeSec": 123,
"ageSec": 123
}
],
"updatedAt": 123
}
}Bridge Health
[Alpha Preview] Live health of the bridge solver: overall state, fill and refund activity, and solver load.
GET
/
2
/
bridge
/
health
Get bridge health
curl --request GET \
--url https://demo-api.mobula.io/api/2/bridge/healthimport requests
url = "https://demo-api.mobula.io/api/2/bridge/health"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://demo-api.mobula.io/api/2/bridge/health', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://demo-api.mobula.io/api/2/bridge/health",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://demo-api.mobula.io/api/2/bridge/health"
req, _ := http.NewRequest("GET", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://demo-api.mobula.io/api/2/bridge/health")
.asString();require 'uri'
require 'net/http'
url = URI("https://demo-api.mobula.io/api/2/bridge/health")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_body{
"data": {
"state": "operational",
"shedding": true,
"killswitchActive": true,
"fills": {
"pending": 123,
"oldestPendingSec": 123,
"lastMinute": 123,
"latencyMs": {
"p50": 123,
"p90": 123
}
},
"refunds": {
"pending": 123,
"lastMinute": 123
},
"pods": [
{
"pod": "<string>",
"leader": true,
"cpuCores": 123,
"eventLoopUtilization": 123,
"rssMB": 123,
"heapUsedMB": 123,
"uptimeSec": 123,
"ageSec": 123
}
],
"updatedAt": 123
}
}Alpha Preview — Endpoints and response shape may change without notice.
GET /api/2/bridge/health returns the bridge’s current health: whether fills are going out, how long they take, and how loaded the solver is. Use it for a status page, or to pause quoting when the bridge is paused or down. No query parameters.
The solver publishes this data every 5 seconds, so two calls within that window return the same snapshot.
Response
{
"data": {
"state": "operational",
"shedding": false,
"killswitchActive": false,
"fills": {
"pending": 3,
"oldestPendingSec": 21,
"lastMinute": 14,
"latencyMs": { "p50": 380, "p90": 1270 }
},
"refunds": { "pending": 0, "lastMinute": 0 },
"pods": [
{ "pod": "bridge-solver-659cd59dff-zb5ph", "leader": true, "cpuCores": 0.42, "eventLoopUtilization": 0.38, "rssMB": 1310, "heapUsedMB": 610, "uptimeSec": 5400, "ageSec": 3 },
{ "pod": "bridge-solver-659cd59dff-j8pbg", "leader": false, "cpuCores": 0.05, "eventLoopUtilization": 0.04, "rssMB": 980, "heapUsedMB": 420, "uptimeSec": 5390, "ageSec": 1 }
],
"updatedAt": 1792794302465
}
}
State
state | Meaning |
|---|---|
operational | One solver replica holds the leader lease, it is publishing activity, and its main thread has headroom. |
degraded | Fills may be slow. Either the solver is shedding load (shedding), no replica holds the lease, two replicas both claim it, the leader isn’t publishing activity, or the leader’s main thread is saturated (eventLoopUtilization ≥ 0.9). |
paused | The treasury killswitch is tripped. No fills, refunds or rebalances go out until it is reset. |
down | No solver replica has reported in the last 30 seconds. |
Fields
shedding— the solver leader is saturated by incoming deposits, so cross-chain quotes return503(“Bridge temporarily at capacity”) until it recovers, usually within a few minutes. Deposits already made are still filled. Same-chain swaps are not affected.killswitchActive— the treasury killswitch.nullwhen the leader isn’t publishing activity.fills—nullwhen the leader isn’t publishing activity.pending— intents infillingorretrying, created in the last 24 hours.oldestPendingSec— age of the oldest of those, ornullwhen nothing is pending.lastMinute— fills confirmed in the last minute.latencyMs.p50/latencyMs.p90— time from deposit detection to fill, over fills confirmed in the last 10 minutes.nullwhen there were none. A retried fill counts its full wait, so a recovery after an incident shows up here.
refunds—nullwhen the leader isn’t publishing activity.pending— intents inrefunding, created in the last 24 hours.lastMinute— refunds completed in the last minute.
pods— every solver replica that reported in the last 30 seconds, leader first.leader— held the leader lease when its snapshot was taken. Only the leader moves funds.cpuCores— CPU used over the last 5 seconds, in cores (1 = one full core).eventLoopUtilization— share of the last 5 seconds the main thread was busy (1 = saturated).rssMB/heapUsedMB— process memory.uptimeSec— process uptime.ageSec— age of the snapshot.
updatedAt— epoch ms the leader computedfillsandrefunds, ornull.
Reading it
- A climbing
fills.pendingwith a growingoldestPendingSecwhilefills.lastMinutedrops means fills are stalling, even ifstateis stilloperational. degradedbecause of a saturated leader often clears within seconds. Treat it as a signal to watch, not an outage.- Status for a single intent is at
/2/bridge/status/{id}.
Response
200 - application/json
Bridge health.
Show child attributes
Show child attributes