TriportRPC

Polygon node Prometheus metrics mirror

GEThttps://api.triport.io/v1/polygon/metrics/bor-eu-1/bor

Proxies the raw Prometheus exposition from a specific Polygon node (Bor, Heimdall, or an aggregator Prometheus) so you can scrape per-node chain metrics through the Triport edge.

Polygonpolygon.chain_metricspro+ (per-tier RPS with burst)

The metrics mirror fetches the Prometheus text exposition from a single Polygon node and streams it back to you unchanged (after a light sanitization pass). It covers three node layers:

  • bor — the Bor execution client (Geth-style metrics).
  • heimdall — the Heimdall consensus client (CometBFT default metrics).
  • aggregator — an operator-side Prometheus that already aggregates a pool of nodes.

This is not an OpenAPI-defined product endpoint; it is an operational surface for teams that want to pull node-level chain metrics (block height, peer counts, txpool depth, consensus round timings, etc.) into their own Prometheus or Grafana without direct network access to the nodes.

Responses are served from a short-lived cache. The X-Cache response header tells you whether the body was a fresh upstream fetch (MISS), a cache hit (HIT), or a stale copy served because the node was briefly unavailable (STALE). The body is standard Prometheus exposition (text/plain; version=0.0.4), not JSON — point a scrape job at it directly.

Gotcha: the path is two segments{host_id} then {layer}. A request to /v1/polygon/metrics/heimdall (layer only, no host id) returns 404 path_invalid.

Parameters

Path parameters

host_idstringrequired
Identifier of the target node within the layer's pool.
layerstringrequired
One of bor, heimdall, aggregator.

Response

On success the body is raw Prometheus exposition:

Response headers

HeaderExampleDescription
Content-Typetext/plain; version=0.0.4Prometheus exposition format.
X-CacheMISSCache state of this body: HIT, MISS, or STALE.
X-Mesh-Sourcepolygon-prom-mirrorIdentifies the serving subsystem.
Content-Length2048Body length in bytes.

Errors

The error body is the shared JSON envelope: {"error":{"code":"...","message":"..."}}. See errors.md for the full envelope.

CodeHTTPMeaningWhen it happens
unauthorized401Missing or invalid credentialsNo valid session/API key on the request.
tier_locked403Plan lacks polygon.chain_metricsPlan does not include the feature. Currently returned for all callers while the gate is a stub.
429Rate limit exceededPer-tier RPS (with burst) exhausted. Retry after backoff.

Additional non-success codes you may encounter once authorized:

CodeHTTPWhen it happens
path_invalid404Path is not exactly /{host_id}/{layer}.
unknown_layer404layer is not bor / heimdall / aggregator.
host_not_found404No node with host_id exists in that layer.
host_no_capability404The node does not expose Prometheus for that layer.
method_not_allowed405Only GET is supported.
host_quarantined503Node unavailable and no cached body to fall back to.
upstream_error502Upstream scrape failed and no stale cache available.

Examples

JavaScript (fetch)

const res = await fetch(
  "https://api.triport.io/v1/polygon/metrics/bor-eu-1/bor",
  { headers: { Authorization: `Bearer ${process.env.TRIPORT_API_KEY}` } }
);
if (!res.ok) throw new Error(`metrics mirror: ${res.status}`);
console.log(res.headers.get("X-Cache")); // HIT | MISS | STALE
const exposition = await res.text();
console.log(exposition);

TypeScript SDK (@triport/sdk)

import { Triport } from "@triport/sdk";


const triport = new Triport({ apiKey: process.env.TRIPORT_API_KEY! });


const { body, cache } = await triport.polygon.metrics.mirror({
  hostId: "bor-eu-1",
  layer: "bor",
});
console.log(cache); // "MISS"
console.log(body);  // Prometheus exposition text

Python (triport-sdk)

import os
from triport import Triport


triport = Triport(api_key=os.environ["TRIPORT_API_KEY"])


result = triport.polygon.metrics.mirror(host_id="bor-eu-1", layer="bor")
print(result.cache)  # "MISS"
print(result.body)   # Prometheus exposition text

Notes

  • Cache & staleness: bodies are cached briefly. When a node is quarantined or degraded, the mirror serves the last good body with X-Cache: STALE rather than failing — useful for keeping dashboards populated through short blips. Only when no cached body exists does the call return 503 host_quarantined.
  • Scrape interval: because responses are cached, scraping faster than the cache TTL yields repeated HIT bodies; align your Prometheus scrape interval with how fresh you actually need the data.
  • Layers are independent: each {host_id, layer} pair is mirrored from a different upstream path and port. A node may expose bor metrics but not aggregator metrics — expect host_no_capability in that case.
  • No daily cap: rate limiting is RPS-per-tier with burst; there is no daily quota header or daily-quota error.
  • Related: the loopback-only mesh health endpoint and the Polygon WebSocket firehose handlers live alongside this mirror in the same Polygon node-mesh surface.