TriportRPC

Chain events stream (SSE)

GEThttps://api.triport.io/v1/chains/events

A live, one-way **Server-Sent Events** stream of chain health changes and metric ticks for the Triport network catalogue.

— (multi-chain — events carry a chain_id)— (the stream is scoped to the chains visible to your session)

GET /v1/chains/events is a Server-Sent Events (SSE) endpoint, consumed in the browser with the native EventSource API. It is a long-lived, server-to-client, text/event-stream connection — it is not a WebSocket, so there is no client-to-server channel and no upgrade handshake. Open it once and the server pushes named events as chain health and metrics change.

Two named event types are emitted:

  • chain_status — a chain's health transitioned (e.g. livedegraded).
  • chain_metric_tick — a periodic metrics sample for a chain (p50 latency, block height).

There is no snapshot frame on connect. The stream only delivers changes that occur after you subscribe. To render correct initial state, seed each chain from GET /v1/chains/{id}/metrics on mount, then apply the events as they arrive.

EventSource reconnects automatically on network drops. On reconnect the backend resumes the connection with periodic keepalive comments and any future events; it does not replay a backlog, so treat a reconnect like a fresh subscription and re-seed from the metrics endpoint if you need a guaranteed-consistent baseline.

The broadcaster fans out events non-blocking: a subscriber that cannot keep up has events dropped rather than back-pressuring the server. Do not assume you receive every tick — design your UI to converge from whatever events arrive plus the periodic metrics read.

Parameters

This endpoint takes no path, query, or body parameters. Authentication is the browser session cookie, which EventSource sends when opened with withCredentials: true.

optional
No request parameters. Stream contents are scoped to the chains your session can see.

Response

Content-Type: text/event-stream. Each event is a event:/data: pair; lines beginning with : are keepalive comments. The data: payload is a JSON object.

chain_idstring
Chain identifier (e.g. ethereum-mainnet).
prevstring
Previous status: live | degraded | down | scope_missing.
nextstring
New status: live | degraded | down | scope_missing.
atstring
RFC 3339 timestamp of the transition.

Errors

SSE has no per-event error envelope; failures surface as the connection failing to open or the EventSource error event firing (after which it auto-reconnects).

CodeMeaningWhen it happens
401UnauthenticatedNo valid session cookie — sign in first.
404Not foundChains vector not mounted on this deployment.

For the standard JSON error envelope used by the REST endpoints, see errors.

Examples

JavaScript (fetch)

EventSource, not fetch, is the right primitive for SSE in the browser:

const es = new EventSource("https://api.triport.io/v1/chains/events", {
  withCredentials: true,
});


es.addEventListener("chain_status", (e) => {
  const ev = JSON.parse(e.data); // { chain_id, prev, next, at }
  console.log(`${ev.chain_id}: ${ev.prev}${ev.next}`);
});


es.addEventListener("chain_metric_tick", (e) => {
  const ev = JSON.parse(e.data); // { chain_id, latency_p50_ms, block_height, at }
  if (ev.latency_p50_ms != null) {
    console.log(`${ev.chain_id} p50=${ev.latency_p50_ms}ms`);
  }
});


es.onerror = () => {
  // EventSource reconnects on its own; no snapshot is replayed on resume.
};


// later: es.close();

TypeScript SDK (@triport/sdk)

import { TriportClient, ChainEvent } from "@triport/sdk";


const client = new TriportClient({ apiKey: process.env.TRIPORT_API_KEY });


// Seed initial state, then subscribe for live updates.
const seed = await client.chains.metrics("solana-mainnet");
let p50 = seed.latency_p50_ms;


const stop = client.chains.subscribeEvents((ev: ChainEvent) => {
  if (ev.type === "chain_metric_tick" && ev.chain_id === "solana-mainnet") {
    if (ev.latency_p50_ms != null) p50 = ev.latency_p50_ms;
  }
});


// stop(); // closes the stream and removes listeners

Python (triport-sdk)

from triport import TriportClient


client = TriportClient(api_key="...")  # use os.environ["TRIPORT_API_KEY"]


# Seed first, then stream live changes (the stream sends no snapshot frame).
seed = client.chains.metrics("solana-mainnet")


for event in client.chains.events():
    if event.type == "chain_status":
        print(f"{event.chain_id}: {event.prev} -> {event.next} @ {event.at}")
    elif event.type == "chain_metric_tick":
        if event.latency_p50_ms is not None:
            print(f"{event.chain_id} p50={event.latency_p50_ms}ms")

Notes

  • Server-Sent Events, one direction only. There is no message channel from client to server; to issue requests use the REST endpoints.
  • No snapshot on connect, no backlog on reconnect. Always seed from GET /v1/chains/{id}/metrics and treat the stream as a delta feed. For historical trends use GET /v1/chains/{id}/metrics/series.
  • Lossy by design. Slow subscribers have events dropped (non-blocking fan-out), so reconcile periodically against the metrics endpoint rather than assuming a complete event log.
  • Nulls are meaningful. latency_p50_ms and block_height arrive as JSON null when unmeasured — check != null rather than truthiness, since a real 0 is a valid value.
  • Discover the chain catalogue with GET /v1/chains and per-chain detail with GET /v1/chains/{id}.