Skip to content

IceLens Read API

IceLens exposes read-only endpoints over the table-health snapshots its scheduled collection persists every 15 minutes. Hosts are per environment, e.g. https://icelens-api.data-platform.us-east-1.dev-dataops.fetchrewards.com.

Per-table reads

Live status — GET /tables/{database}/{table}/status

Inspects the table’s Iceberg metadata on request (Glue catalog, shared inspector) and returns raw status facts: collection, snapshot, files, derived, manifests, partitions, with source: "live" and stale: false. Live reads never write to the collection store.

Cached status — GET /tables/{database}/{table}/status/cached

Returns the latest stored status snapshot with source: "cached", stale recomputed against ICELENS_STALE_AFTER_SECONDS (default 1800 s), and last_error populated when a collection failure for this table is newer than the served snapshot.

Live health — GET /tables/{database}/{table}/health

Inspects once and assesses health with the same library-default thresholds collection uses. Returns health_status (Healthy / Warning / Critical), issues (code, severity, message, evidence), and collection metadata. Never persists.

Cached health — GET /tables/{database}/{table}/health/cached

Returns the latest stored assessment with collection.source: "cached" and stale recomputed from status_collected_at.

Health history — GET /tables/{database}/{table}/health/history?limit=

Compact trend rows, newest first: assessed_at, health_status, issue_codes. Default limit 100, maximum 1500; the store retains 14 days (~1344 cycles). A table with no stored assessments returns 200 with an empty list.

Catalog browsing

Databases — GET /databases

One rollup row per database from latest-per-table snapshots: table_count, healthy_count / warning_count / critical_count, stale_count, total_data_size_bytes, total_data_file_count, last_collected_at.

Tables — GET /tables?database=&health_status=&stale=

Flat per-table summary rows: database, table_name, health_status, issue_count, stale, collected_at, total_data_size_bytes, data_file_count, avg_file_size_bytes, small_file_pct, snapshot_count. Filters combine with AND; empty results are 200 with an empty list.

Collection operations

Cycles — GET /cycles?limit=

Recent collection cycles, newest first: id, started_at, finished_at, complete (false when finished_at is null — an incomplete cycle), discovery_source (polaris | glue), and discovered/collected/failed counts. Default limit 20.

Cycle failures — GET /cycles/{cycle_id}/failures

Per-table failure detail for one cycle: database, table_name, error, failed_at. Unknown cycle ids return 404; a clean cycle returns an empty list.

Response envelopes

List endpoints wrap results in a keyed object ({"tables": [...]}, {"databases": [...]}, {"cycles": [...]}, {"history": [...]}, {"failures": [...]}) so sibling fields can be added without breaking consumers.

Status codes

CodeCached / browsing / opsLive
200Success, including empty listsSuccess
400Invalid query parameter (unknown health_status, out-of-range limit)
404No snapshot for this table; unknown cycle_idTable not found in the catalog
422Invalid database/table identifierSame
503Postgres unreachable (collection store unavailable) or not configured (collection store not configured)Catalog unavailable, inspection failed or timed out, or live reads not configured