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
| Code | Cached / browsing / ops | Live |
|---|---|---|
200 | Success, including empty lists | Success |
400 | Invalid query parameter (unknown health_status, out-of-range limit) | — |
404 | No snapshot for this table; unknown cycle_id | Table not found in the catalog |
422 | Invalid database/table identifier | Same |
503 | Postgres unreachable (collection store unavailable) or not configured (collection store not configured) | Catalog unavailable, inspection failed or timed out, or live reads not configured |