DEVELOPER DOCS

REST API

Fleet Monitor

On this page

Live topology and health for a fleet — a group of agents running together. Unlike trace endpoints, which are historical, the fleet API is near-real-time and backed by a streaming WebSocket.


List fleets

HTTP
GET /v1/observ/orgs/{org}/workspaces/{ws}/fleet/fleets

Auth: API key or JWT · Role: viewer

Response 200 — not schema-modelled

JSON
{
  "fleets": [
    {
      "fleet_id": "checkout-fleet",
      "agent_count": 12,
      "status": "active",
      "last_seen": "2026-09-01T14:23:05Z",
      "open_flag_count": 2
    }
  ]
}

Examples

fl = evigauge.get("/v1/observ/orgs/{org}/workspaces/{ws}/fleet/fleets")
for f in fl["fleets"]:
    print(f"{f['fleet_id']:20} {f['agent_count']} agents  {f['open_flag_count']} flags")

Fleet graph

HTTP
GET /v1/observ/orgs/{org}/workspaces/{ws}/fleet/{fleet_id}/graph

The fleet's agent topology — nodes and the call edges between them, with token and latency rollups per node.

Auth: API key or JWT · Role: viewer

Path parameters

NameTypeRequiredDescription
orgstring✅Organization slug
wsstring✅Workspace slug
fleet_idstring✅Fleet identifier

Response 200 — not schema-modelled

JSON
{
  "fleet_id": "checkout-fleet",
  "nodes": [
    { "id": "router",  "kind": "agent", "call_count": 8120, "p95_latency_ms": 210,  "total_tokens": 410233, "status": "ok" },
    { "id": "pricing", "kind": "agent", "call_count": 6402, "p95_latency_ms": 4900, "total_tokens": 992010, "status": "flagged" }
  ],
  "edges": [{ "from": "router", "to": "pricing", "call_count": 6402 }]
}

Examples

g = evigauge.get(f"/v1/observ/orgs/{{org}}/workspaces/{{ws}}/fleet/{fleet_id}/graph")
for n in g["nodes"]:
    mark = "⚠" if n["status"] != "ok" else " "
    print(f"{mark} {n['id']:15} p95={n['p95_latency_ms']}ms tokens={n['total_tokens']:,}")

Fleet flags

HTTP
GET /v1/observ/orgs/{org}/workspaces/{ws}/fleet/{fleet_id}/flags

Health flags raised on the fleet. Flags auto-resolve: after 3 consecutive clean spans, a resolve event is emitted and the flag leaves the active set.

Auth: API key or JWT · Role: viewer

Query parameters

NameTypeRequiredDefaultDescription
statusstring➖activeactive — one row per still-open flag episode; all — the raw append-only event log (fires and resolves), newest first

Examples

flags = evigauge.get(
    f"/v1/observ/orgs/{{org}}/workspaces/{{ws}}/fleet/{fleet_id}/flags",
    params={"status": "active"},
)
print(flags)

Pause / resume / clear a fleet

HTTP
POST /v1/observ/orgs/{org}/workspaces/{ws}/fleet/{fleet_id}/pause
POST /v1/observ/orgs/{org}/workspaces/{ws}/fleet/{fleet_id}/resume
POST /v1/observ/orgs/{org}/workspaces/{ws}/fleet/{fleet_id}/clear

Auth: API key or JWT · Role: admin · Request body: none

ActionEffect
pauseStops fleet monitoring and flag evaluation. Spans still ingest.
resumeResumes monitoring from live state.
clearDiscards accumulated fleet state and starts a fresh topology.

pause does not stop your agents. Evigauge never controls your runtime — it pauses monitoring only. And clear is destructive to accumulated topology state; the underlying spans are untouched.

Examples

base = f"/v1/observ/orgs/{{org}}/workspaces/{{ws}}/fleet/{fleet_id}"
evigauge.post(f"{base}/pause")
evigauge.post(f"{base}/resume")
evigauge.post(f"{base}/clear")    # destructive: resets topology state

Mint a WebSocket ticket

HTTP
POST /v1/observ/orgs/{org}/workspaces/{ws}/fleet/ws-ticket

Mints a short-lived, single-use ticket for the fleet WebSocket. Browsers cannot set an Authorization header on a native WebSocket, so the ticket rides the query string instead.

Auth: API key or JWT · Role: viewer · Request body: none

Response 200 — not schema-modelled

JSON
{ "ticket": "wst_01J8XYZ...", "expires_in": 60 }

The ticket is consumed on first use. Mint a fresh one for every connection — including every reconnect after a drop.


Fleet WebSocket stream

code
WSS wss://api.opexia.dev/ws/fleet/{workspace_id}?ticket={ticket}

Streams live fleet delta frames. Note the parameter is {workspace_id} — a UUID, not the slug used elsewhere in the fleet API. The ticket is validated before the connection is accepted.

Close codeMeaning
1008Ticket missing, expired, already used, or bound to a different workspace

Examples

import json, httpx, websockets   # pip install websockets

def mint_ticket():
    return evigauge.post("/v1/observ/orgs/{org}/workspaces/{ws}/fleet/ws-ticket")["ticket"]

async def stream(workspace_uuid: str):
    # A ticket is single-use: mint a new one for every connect and reconnect.
    url = f"wss://api.opexia.dev/ws/fleet/{workspace_uuid}?ticket={mint_ticket()}"
    async with websockets.connect(url) as ws:
        async for raw in ws:
            frame = json.loads(raw)
            print(frame["type"], frame.get("nodes", []))