Tables
The tables endpoints expose table discovery data from the Postgres-backed table cache plus three table-detail contracts:
/statusreturns observed Iceberg table state./healthreturns health status and issues derived from that state./maintenance/recommendationreturns Icepack policy-aware action intent.
The root /metrics path is reserved for Prometheus/OpenMetrics operational
metrics. Table state belongs under /tables/{database}/{table}/status.
List tables
GET /tablesReturns the current set of tables from the table cache. The cache is
periodically refreshed by the API TableCacheSyncWorker; see
cache status to check freshness.
Query parameters
| Parameter | Type | Description |
|---|---|---|
database | string | Filter tables to a single database. |
maintenance_enabled | boolean | Filter by maintenance enrollment (true or false). |
Response — 200 OK
[ { "database": "analytics", "table_name": "page_views", "in_maintenance_allowlist": true }, { "database": "analytics", "table_name": "sessions", "in_maintenance_allowlist": true }]Each object contains:
| Field | Type | Description |
|---|---|---|
| Field | Type | Description |
| ---------------------------- | ----------- | ------------- |
database | string | Database name. |
table_name | string | Table name within the database. |
in_maintenance_allowlist | boolean | Whether the table’s database is in the maintenance allowlist. |
Status codes
| Code | Meaning |
|---|---|
200 | Success. |
Example
# All tablescurl https://icepack-api.internal/tables
# Only tables in the "analytics" database with maintenance explicitly enabledcurl "https://icepack-api.internal/tables?database=analytics&maintenance_enabled=true"Cache status
GET /tables/cache-statusReturns metadata about the table cache — when it was last refreshed and how many tables it contains. Useful for monitoring staleness.
Response — 200 OK
{ "last_synced": "2026-04-25T14:32:00.000000+00:00", "table_count": 247, "maintenance_allowlist": ["analytics", "warehouse"]}| Field | Type | Description |
|---|---|---|
| Field | Type | Description |
| --- | --- | --- |
last_synced | string | null | ISO 8601 timestamp of the last successful sync, or null if never synced. |
table_count | int | Number of tables currently in the cache. |
maintenance_allowlist | string[] | Databases currently eligible for automatic maintenance. |
Status codes
| Code | Meaning |
|---|---|
200 | Success. |
Example
curl https://icepack-api.internal/tables/cache-statusLive table status
GET /tables/{database}/{table}/statusPerforms a live metadata inspection through the configured metadata inspector (PyIceberg by default, or iceberg-go when enabled) and returns observed table state. The response contains raw table facts and collection metadata only. It does not contain health status, health issues, maintenance policy, or recommended actions.
Successful responses are persisted to table_status_snapshots for cached
lookups. Collection failures that happen after identifier validation are also
recorded so cached status can expose a newer last_error.
This endpoint is slower than the cached variant (seconds vs. milliseconds) but always returns current data.
Path parameters
| Parameter | Type | Description |
|---|---|---|
database | string | Database name. |
table | string | Table name. |
Response — 200 OK
{ "table": { "database": "analytics", "table_name": "page_views", "location": "s3://lakehouse/analytics/page_views", "format_version": 2 }, "collected_at": "2026-04-25T14:32:00+00:00", "source": "live", "stale": false, "collection": { "scan_mode": "metadata_inspector", "exact": true, "capped": false, "warnings": [] }, "snapshot": { "current_snapshot_id": 7238461923847, "snapshot_count": 34, "hours_since_last_snapshot": 3.2, "oldest_snapshot_age_hours": 168.5 }, "files": { "data_file_count": 1284, "delete_file_count": 12, "position_delete_file_count": null, "equality_delete_file_count": null, "total_data_size_bytes": 53687091200, "total_records": 5200000, "avg_file_size_bytes": 41812000, "min_file_size_bytes": null, "max_file_size_bytes": null, "files_per_gb": 25.68, "delete_file_ratio": 0.0093, "file_size_bins": [] }, "derived": { "small_file_count": 87, "small_file_pct": 6.78, "large_file_count": null, "large_file_pct": null }, "manifests": { "manifest_count": 18, "total_manifest_size_bytes": null }, "partitions": { "partition_count": null, "avg_files_per_partition": null, "max_files_per_partition": null, "partition_skew_ratio": null, "partitions_with_delete_files": null }, "last_error": null}Key response sections:
| Field | Type | Description |
|---|---|---|
collection | object | How status was collected and any scan warnings. |
snapshot | object | Current snapshot and retained snapshot age/count facts. |
files | object | Data/delete file counts, sizes, records, and ratios. |
derived | object | File classifications derived during collection, such as small-file count and percent. |
manifests | object | Manifest count and size facts when available. |
partitions | object | Partition distribution facts when available. |
last_error | string | null | Newer cached collection failure, when serving cached status. |
Status codes
| Code | Meaning |
|---|---|
200 | Success. |
404 | Table not found in the catalog. |
422 | Invalid identifier or unsupported Iceberg schema type. |
503 | Catalog unavailable or status collection failed. |
Example
curl https://icepack-api.internal/tables/analytics/page_views/statusCached table status
GET /tables/{database}/{table}/status/cachedReturns the latest successful status payload from table_status_snapshots.
The API recomputes stale using the configured health-sync interval and includes
last_error when a newer status collection failure exists.
Response — 200 OK
The shape matches the live status response, with source: "cached".
Status codes
| Code | Meaning |
|---|---|
200 | Success. |
404 | No successful status snapshot exists for this table. |
503 | Postgres unavailable. |
Example
curl https://icepack-api.internal/tables/analytics/page_views/status/cachedLive table health
GET /tables/{database}/{table}/healthCollects live status once, derives a policy-independent health assessment, and persists both the status payload and health assessment when Postgres is available. This endpoint returns health status and issues only. Maintenance eligibility, cadence, policy details, and actions are intentionally excluded.
Response — 200 OK
{ "table": { "database": "analytics", "table_name": "page_views", "location": "s3://lakehouse/analytics/page_views", "format_version": 2 }, "assessed_at": "2026-04-25T14:32:01+00:00", "status_collected_at": "2026-04-25T14:32:00+00:00", "health_status": "Warning", "issues": [ { "code": "small_files", "severity": "warning", "message": "Table has 87 files below the small-file threshold.", "evidence": { "small_file_count": 87, "small_file_pct": 6.78 } } ], "collection": { "source": "live", "stale": false, "warnings": [] }, "error": null}Key response fields:
| Field | Type | Description |
|---|---|---|
health_status | string | Summary label: Healthy, Warning, or Critical. |
issues | object[] | Health issues with code, severity, message, and supporting evidence. |
status_collected_at | string | Timestamp of the status payload used for assessment. |
collection | object | Source/freshness metadata inherited from status collection. |
error | string|null | Non-null if assessment could not be completed. |
Status codes
| Code | Meaning |
|---|---|
200 | Success. |
404 | Table not found in the catalog. |
422 | Invalid identifier or unsupported Iceberg schema type. |
503 | Catalog unavailable or health analysis failed. |
Example
curl https://icepack-api.internal/tables/analytics/page_views/healthCached table health
GET /tables/{database}/{table}/health/cachedReturns the most recent table_health_snapshots row from Postgres for the given
table. This is the fast path — responses return in roughly 1 ms because no
catalog or storage access is required.
Health assessments are written by two sources:
- The live health endpoint (above) persists every successful analysis.
- The background health-sync worker periodically refreshes snapshots for all tables in configured databases.
Path parameters
| Parameter | Type | Description |
|---|---|---|
database | string | Database name. |
table | string | Table name. |
Response — 200 OK
The shape matches the live health response, with collection.source: "cached"
and freshness recomputed from status_collected_at.
Status codes
| Code | Meaning |
|---|---|
200 | Success. |
404 | No health snapshot exists for this table. |
503 | Postgres unavailable. |
Example
curl https://icepack-api.internal/tables/analytics/page_views/health/cachedMaintenance recommendation
GET /tables/{database}/{table}/maintenance/recommendationReturns Icepack’s policy-aware action intent for a table. This is the only
read endpoint that emits recommended_actions. It evaluates status, table
metadata, maintenance enrollment, cadence/history, and action thresholds.
The endpoint prefers a fresh cached status snapshot. If no usable cached status
exists, it collects live status and saves it before planning. If status cannot
be collected, the endpoint returns 200 OK with no actions and
skip_reasons: ["status_unavailable"] so callers can distinguish
“cannot evaluate” from “no action needed”.
Response — 200 OK
{ "table": { "database": "analytics", "table_name": "page_views", "location": "s3://lakehouse/analytics/page_views", "format_version": 2 }, "evaluated_at": "2026-04-25T14:32:02+00:00", "status_collected_at": "2026-04-25T14:32:00+00:00", "recommended_actions": [ "expire_snapshots", "remove_orphan_files", "rewrite_data_files" ], "skip_reasons": [], "policy": { "source": "icepack_table_properties", "maintenance_enabled": true, "opt_in_mode": false, "maintenance_cadence_hours": 24, "effective_cadence_hours": 24, "icepack_config": { "maintenance_enabled": "true", "maintenance_cadence_hours": "24" } }, "history": { "last_completed_at": "2026-04-24T14:00:00+00:00", "cadence_elapsed": true }, "evidence": { "rewrite_data_files": { "small_file_count": 87, "min_input_files": 5 }, "expire_snapshots": { "compaction_recommended": true }, "remove_orphan_files": { "expire_snapshots_recommended": true } }, "error": null}Skip reasons
| Reason | Meaning |
|---|---|
no_action_needed | Status was evaluated and no maintenance action is warranted. |
no_policy | No matching policy exists. |
table_not_in_allowlist | The table database is outside the maintenance allowlist. |
operation_disabled | Maintenance is disabled by table properties or skip flags. |
recent_success | The last successful maintenance is still inside the cadence window. |
status_unavailable | Status could not be collected and no usable cache was available. |
Status codes
| Code | Meaning |
|---|---|
200 | Recommendation evaluated or explicitly skipped. |
404 | Table not found in the catalog or table cache. |
422 | Invalid identifier. |
Example
curl https://icepack-api.internal/tables/analytics/page_views/maintenance/recommendation