Home → Blog

You’re trying to quantify how congested Hong Kong (HKHKG) is right now, but “right now” data for port congestion isn’t the same as live AIS wait times. By the end of this post, you’ll be able to query IMF PortWatch–derived congestion for Hong Kong via a single API call, interpret the 7‑day average vs 90‑day baseline methodology, and integrate the response into your own dashboards or alerting.

What this dataset measures for Hong Kong—and what it doesn’t

FreightPulse port congestion for Hong Kong is derived from IMF PortWatch and UN Global Platform AIS data. It is updated daily but lagged by roughly 6–7 days. That means you should treat it as a stable, near-real-time indicator of port throughput rather than a live feed of anchorage wait times or queue lengths.

Illustration: Hong Kong Congestion Today

Key points specific to this feed:

Because the indicator focuses on port call counts, use it to understand directional throughput pressure at Hong Kong, not to estimate minutes-to-berth for a specific vessel.

How to access Hong Kong port congestion programmatically

The congestion endpoint for Hong Kong uses the port code HKHKG. Authentication supports an API key passed as a header; requests without a key are rate-limited at the IP level.

You can retrieve the latest lagged congestion series for Hong Kong with a single GET:

curl -H "X-API-Key: YOUR_API_KEY" "https://freightpulsehq.com/api/v1/port-congestion?port=HKHKG"

Official example response for HKHKG

Below is the official JSON response example for Hong Kong. Use this as your integration reference for field names and nesting:

{
    "success": true,
    "data": {
        "results": [
            {
                "port": "Hong Kong",
                "locode": "HK HKG",
                "country": "Hong Kong SAR",
                "congestion": "moderate",
                "as_of": "2026-10-30",
                "metrics": {
                    "recent_avg_portcalls_per_day": 33.3,
                    "baseline_avg_portcalls_per_day": 38.1,
                    "ratio_vs_baseline": 0.87
                }
            }
        ],
        "global_summary": {
            "ports_high_congestion": 0,
            "ports_moderate": 1,
            "ports_low": 0
        },
        "meta": {
            "source": "IMF PortWatch (portwatch.imf.org) - UN Global Platform AIS data",
            "data_lag_days": "~6-7 (daily updates, not real-time)",
            "methodology": "congestion level is an approximation: last 7 days' avg port calls vs 90-day baseline for the same port. Does not measure vessel wait/anchorage time."
        }
    },
    "meta": {
        "request_id": "3a1b401a-4212-402a-829d-f1e7d20e8699"
    }
}

Fields you’ll actually use:

Interpreting the 7‑day vs 90‑day baseline for Hong Kong

The methodology compares recent throughput (last 7 days of port calls per day) to the prior 90‑day baseline for the same port. A ratio_vs_baseline below 1.0 indicates throughput below baseline; above 1.0 indicates throughput above baseline. The categorical congestion string (e.g., “moderate”) maps to thresholds derived from this ratio and other business logic internal to the feed.

Practical tips for interpretation:

Copy-paste JavaScript example

This example requests Hong Kong congestion, extracts the categorical label, the as_of date, and key metrics, then prints a concise line you can reuse in logs or alerts. It mirrors the official curl and JSON structure exactly.

async function fetchHongKongCongestion() {
const url = "https://freightpulsehq.com/api/v1/port-congestion?port=HKHKG";
const resp = await fetch(url, {
headers: { "X-API-Key": "YOUR_API_KEY" }
});

if (!resp.ok) {
throw new Error(`HTTP ${resp.status} - ${resp.statusText}`);
}

const body = await resp.json();

// Envelope is {"success": true, "data": {...}}
if (!body.success || !body.data || !Array.isArray(body.data.results)) {
throw new Error("Unexpected response shape");
}

const hk = body.data.results[0];
if (!hk) {
throw new Error("No results for Hong Kong (HKHKG)");
}

const port = hk.port; // "Hong Kong"
const locode = hk.locode; // "HK HKG"
const asOf = hk.as_of; // e.g., "2026-10-30" (lagged ~6-7 days)
const congestion = hk.congestion; // e.g., "moderate"

const metrics = hk.metrics || {};
const recent = metrics.recent_avg_portcalls_per_day; // number, port calls/day
const baseline = metrics.baseline_avg_portcalls_per_day; // number, port calls/day
const ratio = metrics.ratio_vs_baseline; // number, dimensionless

console.log(`[${asOf}] ${port} (${locode}) congestion=${congestion}; ratio=${ratio}; recent=${recent}/day vs baseline=${baseline}/day`);
}

fetchHongKongCongestion().catch(err => {
console.error("Failed to load Hong Kong congestion:", err);
});

Integration notes that save time

Common pitfalls when using Hong Kong congestion

Minimal Python example

If you prefer Python, this snippet mirrors the same endpoint and fields, returning a compact dict ready for templating or storage:

import requests

def get_hk_congestion():
url = "https://freightpulsehq.com/api/v1/port-congestion?port=HKHKG"
headers = {
"X-API-Key": "YOUR_API_KEY"
}
r = requests.get(url, headers=headers, timeout=20)
r.raise_for_status()
body = r.json()

# Envelope validation
if not body.get("success") or "data" not in body:
raise ValueError("Unexpected response: missing 'success' or 'data'")

results = body["data"].get("results", [])
if not results:
raise ValueError("No results for Hong Kong (HKHKG)")

hk = results[0]
metrics = hk.get("metrics", {})

return {
"port": hk.get("port"),
"locode": hk.get("locode"),
"country": hk.get("country"),
"as_of": hk.get("as_of"), # ISO date (UTC), lagged ~6-7 days
"congestion": hk.get("congestion"),
"recent_avg_portcalls_per_day": metrics.get("recent_avg_portcalls_per_day"),
"baseline_avg_portcalls_per_day": metrics.get("baseline_avg_portcalls_per_day"),
"ratio_vs_baseline": metrics.get("ratio_vs_baseline")
}

if __name__ == "__main__":
try:
data = get_hk_congestion()
print(f"[{data['as_of']}] {data['port']} congestion={data['congestion']} (ratio={data['ratio_vs_baseline']})")
except Exception as e:
print("Error:", e)

Operationalizing Hong Kong congestion in your stack

Data refresh and SLAs

Schedule a daily job to refresh Hong Kong congestion. Store the as_of date with the payload and render it in your UI subtitle, e.g., “Hong Kong congestion: moderate (as of 2026‑10‑30; IMF PortWatch; ~6–7 day lag).” This prevents confusion between the period of validity and your fetch time.

Alert thresholds

Select a ratio_vs_baseline threshold that’s meaningful to your workflows. For example, if your downstream milestones are sensitive to dips in throughput, alert when ratio falls below a chosen value for N consecutive days. Because the input is already a 7‑day average, a 2–3 day persistence requirement can filter noise without missing real shifts.

UI semantics

Use the congestion label for badges (low, moderate, high) and attach a tooltip that explains the methodology in one sentence. Include the data source and lag in a help modal so stakeholders understand why the date is not “today.”

Caching and fallbacks

Cache the entire response envelope and expose a last_good_tick. If the next fetch fails, continue serving the cached payload with a soft warning in logs. Because updates are daily, stale writes for a few hours will not materially impact decision-making.

What to include (and exclude) in your product copy

Reference: Official curl for HKHKG

This is the copy‑paste request you can use in CI scripts, cron jobs, or Postman collections:

Where to go next

For complete parameter notes, response envelopes, and integration patterns across endpoints, see the Documentation. Keep Hong Kong as your initial focus while you wire up caching, error handling, and UI messaging that explains the lag and methodology.

FAQ

Is the Hong Kong congestion value real-time?
No. It’s updated daily with a ~6–7 day lag from IMF PortWatch. It is not a live AIS queue metric.

Which fields should I store for alerting?
Store as_of, congestion, and metrics.ratio_vs_baseline. Consider also keeping recent_avg_portcalls_per_day and baseline_avg_portcalls_per_day for debugging and historical context.

Do I need an API key?
You can call without a key, but guests are limited to 100 requests/day per IP. For production, set X-API-Key: YOUR_API_KEY.

What timezone is as_of in?
The as_of field is a date (YYYY-MM-DD). Treat it as UTC date boundaries for consistency across systems.

Can I use this to quote prices or ETAs?
No. This dataset does not include fares or live wait times. Do not present it as today’s price or as a live ETA predictor.

If you need stable, daily congestion visibility for Hong Kong that you can ship into production quickly, create your key and start querying today: Register.