Density
Global vessel density by type, bucketed into daily H3 cells over the trailing 30 days — endpoints for density layers, choropleth maps, and lane occupancy.
Global vessel density at H3 resolution 8 (~0.74 km² per cell), bucketed by day and vessel type. The underlying matview is sourced from ais_positions joined to vessels.vessel_type, with per-IMO-per-hour bucketing so that vessels broadcasting every 10 seconds don't drown out vessels broadcasting hourly.
The matview holds a rolling 30-day window and is refreshed nightly at 02:00 UTC, after the previous day's bucket has closed. Use GET /api/v1/density to render heatmaps, identify traffic corridors, or surface where a given vessel class is concentrated on a specific day.
GET /api/v1/density
H3 cells with vessel density for a given vessel type and day, ordered by positions_count descending.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
type | string | Vessel type filter. Default bulk_carrier. There is no all aggregate — the matview is keyed per (h3_index, vessel_type, day), so an unfiltered pull would return duplicate per-type cells rather than a true union; the route always filters on a single vessel type. Common values: bulk_carrier, tanker, container, lng_carrier, chemical_tanker, general_cargo, cargo, passenger, fishing, service, other | |
day | string | ISO date (YYYY-MM-DD). Defaults to yesterday in UTC — the most recent closed-day bucket the matview will have populated | |
limit | number | Cells per response. Default 1,000. Clamped to your tier's per-call ceiling (free/public 20, starter 100, pro 500, admin 10,000), then hard-capped at 1,000 regardless of tier — PostgREST truncates TABLE responses at 1,000 rows on this project, so a higher tier limit is unreachable here. |
Response
{
"day": "2026-04-28",
"vessel_type": "bulk_carrier",
"cells": [],
"count": 0,
"tier": "starter"
}Each cells entry carries h3_index, vessel_type, positions_count, unique_vessels:
h3_index— H3 resolution-8 cell ID (~0.74 km²)positions_count— distinct per-IMO-per-hour position records that fell in this cell on this dayunique_vessels— distinct IMOs that pinged inside this cell on this day
Errors
500— Internal server error (matview query failed)
Example
curl https://www.axiomoverwatch.io/api/v1/density?type=bulk_carrier&day=2026-04-28# A different vessel type, with an explicit (tier-bounded) limit
curl https://www.axiomoverwatch.io/api/v1/density?type=tanker&day=2026-04-28&limit=500Freshness
Every response reflects the matview as of its most recent successful refresh. The dashboard surface at /dashboard/density displays the last refresh timestamp and status (ok or otherwise) sourced from the derived_views_freshness ledger. If you need to programmatically detect a stale matview before consuming density data, request a recent day and check that count is non-zero.
If the latest scheduled refresh failed, the most recent closed day may not yet be queryable — fall back to the prior day until the ledger reports ok.
Congestion
Query port congestion indices, vessel wait time trends, and queue-depth time series across major global ports — for supply chain analytics and route planning.
Berth Utilization
Query berth occupancy rates, turnaround times, and vessel-by-vessel berth utilization across monitored ports — endpoints for terminal performance analytics.