SettleMint
Observability

Blockchain monitoring endpoints

Read per-chain indexer and chain-RPC health, sync lag, finality lag, block age, reindex progress, and raw health snapshots from the DALP blockchain monitoring API.

Overview

A bank that runs digital assets has to prove its ledger is current. If the indexer falls behind the chain, balances, holder lists, and compliance checks read stale data, and an auditor cannot trust any report drawn from them. The blockchain monitoring endpoints answer the question directly: for every chain the platform tracks, how fresh is the indexed data, how far behind the chain head is each service, and is a reindex in progress.

The surface reports two kinds of service. A chain-rpc service is the node connection DALP reads the chain through, measured by head block age, finality lag, and head stall. An indexer service is the component that turns chain events into queryable data, measured by sync lag against the chain head and, during a rebuild, reindex progress and deployment versions.

The endpoints are read-only. They report captured health, not live state, and do not change token, participant, wallet, or compliance data. Use them when you need to show an operator or an auditor that the data behind your reports is current.

Access and scope

Blockchain monitoring calls require an authenticated DALP account with the global administrator role, or the owner role for the active organization. Callers without one of those roles receive an authorization error.

The data describes platform infrastructure health: network names, chain identifiers, block heights, lag figures, and timing. It carries no personal data and no token holder balances.

Requirements

Before calling these endpoints:

  • Authenticate with a DALP account that has administrator or organization-owner access.
  • Send from and to timestamps as ISO 8601 values.
  • Keep each request range inside the endpoint-specific range limit.
  • Read the head status from latestStatus or status before acting on any block or lag figure.

Endpoint summary

PurposeMethod and pathRange limitPaginationUse it for
SummaryGET /api/v2/blockchain-monitoring/health-metrics/summary7 daysNoneCurrent health, block height, lag, and reindex state per service for stat cards.
TimelineGET /api/v2/blockchain-monitoring/health-metrics/timeline31 daysNoneHealth percentages bucketed by hour or day for charting a trend.
Service metricsGET /api/v2/blockchain-monitoring/service-health-metrics7 daysNonePer-service averages and the healthy, degraded, and critical mix across a range.
SnapshotsGET /api/v2/blockchain-monitoring/health-snapshotsNonelimit 1-100, cursorThe raw, filterable, keyset-paginated health-check log, for drill-down and evidence.
Snapshot streamGET /api/v2/blockchain-monitoring/health-snapshots/streamN/AN/AA server-sent event stream of new health snapshots as they are captured.

Health status uses five values across the surface: healthy, degraded, critical, unknown, and reindexing.

Summary

GET /api/v2/blockchain-monitoring/health-metrics/summary returns the current health line for every tracked service, with the latest block height, lag figures, a recent-latency series for sparkline rendering, and indexer deployment state. Pass from and to to set the window the snapshot count and latency series are computed over. The range cannot exceed 7 days.

curl --globoff "$DALP_API_URL/api/v2/blockchain-monitoring/health-metrics/summary?from=2024-01-01T00:00:00Z&to=2024-01-02T00:00:00Z" \
  --header "X-Api-Key: ${DALP_API_TOKEN}"

The response is a services array, one entry per service:

{
  "services": [
    {
      "serviceId": "8a1b2c3d-4e5f-6789-abcd-ef0123456789",
      "serviceType": "indexer",
      "chainId": 1,
      "networkName": "Ethereum Mainnet",
      "latestStatus": "healthy",
      "latestSampledAt": "2024-01-02T00:00:00Z",
      "snapshotCount": 288,
      "syncLag": 2,
      "blockHeight": 19000000,
      "blockAgeSeconds": null,
      "finalityLagBlocks": null,
      "stallSeconds": null,
      "recentLatencies": [120, 118, 125],
      "deploymentState": {
        "servingVersion": 42,
        "buildingVersion": null,
        "codeVersion": 42,
        "reindexProgressPct": null,
        "reindexCurrentBlock": null,
        "reindexTargetBlock": null,
        "reindexStartedAt": null,
        "pendingBackfillCount": null,
        "backfillingCount": null,
        "syncedCount": null,
        "failedCount": null
      }
    }
  ]
}

The lag fields apply to different service types. syncLag is the block gap between the chain head and an indexer. blockAgeSeconds, finalityLagBlocks, and stallSeconds describe a chain-RPC service and are null for an indexer. The fields not relevant to a given service type return null.

deploymentState is null for chain-RPC services. For indexer services it is also nullable: it is populated when deployment metadata is available, and null when the latest health poll failed or produced no raw payload. When no rebuild is running, servingVersion and codeVersion report the live indexer version and the reindex fields are null. During a rebuild, buildingVersion, reindexProgressPct, reindexCurrentBlock, and reindexTargetBlock report rebuild progress, and pendingBackfillCount, backfillingCount, syncedCount, and failedCount report how many contracts are queued, backfilling, synced, or failed in the building deployment.

Timeline

GET /api/v2/blockchain-monitoring/health-metrics/timeline returns health percentages grouped into time buckets so you can chart a trend. Set granularity to hour or day; the default is hour. Pass serviceId to chart a single service. The range cannot exceed 31 days.

curl --globoff "$DALP_API_URL/api/v2/blockchain-monitoring/health-metrics/timeline?from=2024-01-01T00:00:00Z&to=2024-01-08T00:00:00Z&granularity=day" \
  --header "X-Api-Key: ${DALP_API_TOKEN}"

Each bucket carries a start timestamp and a per-service breakdown of the healthy, degraded, and critical share of checks in that bucket. The percentages are normalized over only checks with one of those three statuses. Checks classified as unknown or reindexing are omitted from the denominator, so the three percentages sum to 100 within each service entry:

{
  "buckets": [
    {
      "timestamp": "2024-01-01T00:00:00Z",
      "services": [
        {
          "serviceKey": "indexer-1",
          "serviceType": "indexer",
          "chainId": 1,
          "networkName": "Ethereum Mainnet",
          "healthyPct": 100,
          "degradedPct": 0,
          "criticalPct": 0
        }
      ]
    }
  ]
}

Service metrics

GET /api/v2/blockchain-monitoring/service-health-metrics returns one aggregated row per service over the requested range, with average lag figures and the share of healthy, degraded, and critical checks. The percentages are normalized over only checks with one of those three statuses. Checks classified as unknown or reindexing are omitted from the denominator, so the three percentages sum to 100. Use this endpoint for a breakdown table that ranks services by reliability. The range cannot exceed 7 days.

curl --globoff "$DALP_API_URL/api/v2/blockchain-monitoring/service-health-metrics?from=2024-01-01T00:00:00Z&to=2024-01-02T00:00:00Z" \
  --header "X-Api-Key: ${DALP_API_TOKEN}"
{
  "items": [
    {
      "serviceId": "8a1b2c3d-4e5f-6789-abcd-ef0123456789",
      "serviceType": "indexer",
      "chainId": 1,
      "networkName": "Ethereum Mainnet",
      "latestStatus": "healthy",
      "latestSampledAt": "2024-01-02T00:00:00Z",
      "snapshotCount": 288,
      "avgSyncLag": 1.4,
      "avgBlockAgeSeconds": null,
      "avgFinalityLagBlocks": null,
      "avgStallSeconds": null,
      "healthyPct": 99.3,
      "degradedPct": 0.7,
      "criticalPct": 0
    }
  ],
  "totalCount": 1,
  "facets": {}
}

facets reports server-computed counts for filterable columns so you can build a filter panel without a second query.

Snapshots

GET /api/v2/blockchain-monitoring/health-snapshots returns the raw health-check log, newest first, with keyset pagination. Use it as your drill-down and evidence endpoint. Each row is one health check at one moment, with the values that produced its classification. Filter by from, to, serviceId, serviceType, status, or a search substring on the network name. Set limit between 1 and 100; the default is 20.

curl --globoff "$DALP_API_URL/api/v2/blockchain-monitoring/health-snapshots?serviceType=indexer&status=degraded&limit=50" \
  --header "X-Api-Key: ${DALP_API_TOKEN}"
{
  "items": [
    {
      "id": "018e0c2a-7b3d-7c00-9a1f-2b4c6d8e0f12",
      "serviceType": "indexer",
      "chainId": 1,
      "networkName": "Ethereum Mainnet",
      "status": "degraded",
      "rawStatus": "critical",
      "sampledAt": "2024-01-02T00:00:00Z",
      "blockHeight": 18999990,
      "chainHeadBlock": 19000000,
      "syncLag": 10,
      "blockAgeSeconds": null,
      "finalityLagBlocks": null,
      "stallSeconds": null,
      "collectorLatencyMs": 122
    }
  ],
  "nextCursor": "018e0c2a-7b3d-7c00-9a1f-2b4c6d8e0f11",
  "totalCount": 1432,
  "facets": {}
}

status is the classified health value after smoothing, and rawStatus is the per-snapshot classification before smoothing. The two values can differ when a single check spikes but the service is otherwise stable. To page, pass the returned nextCursor as the cursor on the next request. A null nextCursor means there are no more results.

Snapshot stream

GET /api/v2/blockchain-monitoring/health-snapshots/stream delivers blockchain health events as a server-sent event stream, so a live dashboard updates without polling. The stream emits two event types. Read eventType on every message and dispatch to the handler for that type. Do not assume every event is a snapshot.

Snapshot events (eventType: "snapshot") carry the same health fields as a snapshots-list item, plus serviceId and an optional deploymentState:

{
  "eventType": "snapshot",
  "id": "01964f32-4cc1-7000-a05e-88a188d62921",
  "serviceId": "01964f21-9f02-7000-9e8d-1e6d1fdc7f01",
  "serviceType": "indexer",
  "chainId": 11155111,
  "networkName": "Sepolia",
  "status": "healthy",
  "rawStatus": "healthy",
  "sampledAt": "2026-05-01T11:59:30.000Z",
  "blockHeight": 8154321,
  "chainHeadBlock": 8154323,
  "syncLag": 2,
  "entityCount": null,
  "blockAgeSeconds": null,
  "finalityLagBlocks": null,
  "stallSeconds": null,
  "collectorLatencyMs": 124,
  "deploymentState": null
}

Block-progress events (eventType: "block-progress") are lightweight updates the stream emits while an indexer processes block batches, including during reindexing. They carry only chainId and blockNumber:

{
  "eventType": "block-progress",
  "chainId": 11155111,
  "blockNumber": 8154321
}

Use the list endpoint for historical pages and the stream for live updates. Keep the connection open and route each event by its eventType so your view stays correct as both snapshot and block-progress events arrive.

On this page