Home → Blog

You need a reliable way to quantify congestion at Kaohsiung (TWKHH) without scraping AIS wait times or guessing from news. By the end of this post, you will be able to query a stable, lagged congestion proxy for Kaohsiung, understand what it measures (and what it does not), and integrate it into your application with a copy-paste cURL and Python snippet.

What this congestion metric really measures

The FreightPulse Kaohsiung congestion series comes from IMF PortWatch, which is updated daily but reflects a lag of roughly 6–7 days. It is not real-time vessel wait or anchorage time. Instead, it compares the last 7 days of port-call volume at Kaohsiung against that port’s own 90-day baseline.

Illustration: Kaohsiung Congestion Today

Activity labels (low, moderate, high) describe relative port-call activity versus baseline. “Congestion” in this dataset is a deprecated alias of activity, kept for backward compatibility. A higher ratio_vs_baseline indicates more port calls relative to recent history; a lower ratio indicates fewer calls. Fewer calls can be due to closures or offshore waiting, but the series does not measure dwell or queue duration.

Quick start: endpoint, auth, and envelope

All you need to query Kaohsiung:

For additional request/response conventions, see the Documentation.

Copy-paste cURL for Kaohsiung (TWKHH)

Call the congestion endpoint with the Kaohsiung UN/LOCODE (TWKHH). Use an API key for higher limits; without a key you’re limited per IP.

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

Official sample JSON and fields you will use

Below is an official example of the response structure. The fields you will read for Kaohsiung are activity (alias congestion), metrics.ratio_vs_baseline, and as_of.

{
    "success": true,
    "data": {
        "results": [
            {
                "port": "Kaohsiung",
                "locode": "TW KHH",
                "country": "Taiwan Province of China",
                "activity": "moderate",
                "congestion": "moderate",
                "as_of": "2026-10-30",
                "metrics": {
                    "recent_avg_portcalls_per_day": 30.9,
                    "baseline_avg_portcalls_per_day": 26.9,
                    "ratio_vs_baseline": 1.15
                }
            }
        ],
        "global_summary": {
            "ports_high_activity": 0,
            "ports_moderate_activity": 1,
            "ports_low_activity": 0,
            "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": "activity is port-call volume, not congestion: last 7 days' avg calls vs a 90-day baseline for the same port. low means fewer calls than usual, which can be a closure or ships waiting offshore. It does not measure vessel wait or anchorage time. congestion is a deprecated alias of activity."
        }
    },
    "meta": {
        "request_id": "fd8ca658-8d8b-430b-ba65-7cbc9b632ed7"
    }
}

Key fields you will typically use:

Python example: fetch Kaohsiung and read ratio_vs_baseline

This example calls the same endpoint, checks the envelope, extracts the label and ratio, and prints a concise summary. Replace YOUR_API_KEY with your key if you have one.

import os
import requests

API_KEY = os.getenv("FREIGHTPULSE_API_KEY", "YOUR_API_KEY")
URL = "https://freightpulsehq.com/api/v1/port-congestion"
PARAMS = {"port": "TWKHH"} # Kaohsiung (UN/LOCODE)
HEADERS = {"X-API-Key": API_KEY}

def fetch_kaohsiung_congestion():
resp = requests.get(URL, params=PARAMS, headers=HEADERS, timeout=20)
resp.raise_for_status()
payload = resp.json()

if not payload.get("success", False):
raise RuntimeError(f"API returned success=false: {payload}")

data = payload.get("data", {})
results = data.get("results", [])
if not results:
raise RuntimeError("No results returned for TWKHH")

r0 = results[0]
as_of = r0.get("as_of")
label = r0.get("activity") or r0.get("congestion")
metrics = r0.get("metrics", {})
ratio = metrics.get("ratio_vs_baseline")
recent = metrics.get("recent_avg_portcalls_per_day")
baseline = metrics.get("baseline_avg_portcalls_per_day")

print(f"Kaohsiung (TWKHH) as_of={as_of} activity={label} ratio_vs_baseline={ratio}")
if recent is not None and baseline is not None:
print(f"7d avg calls/day={recent} vs 90d baseline={baseline}")

if __name__ == "__main__":
fetch_kaohsiung_congestion()

Implementation details that save time

Interpreting Kaohsiung’s signal in your app

Use ratio_vs_baseline for quantitative thresholds and activity for labels. For example, you might color-code a dashboard tile for Kaohsiung based on activity while plotting ratio_vs_baseline over time. When ratio_vs_baseline is above 1.0, recent activity exceeds the 90-day baseline; below 1.0, it is below baseline.

Avoid mapping this directly to vessel wait time or anchorage duration. The data represents port-call volume, not service time. Pair it with your own ETAs, berthing windows, or carrier advisories if your use case demands queue-time estimates.

FAQ

Is this real-time congestion?
No. It is based on IMF PortWatch and lags by ~6–7 days. It updates daily but should not be used to infer live anchorage or queue times.

Which fields should I store?
Store as_of, activity, and metrics.ratio_vs_baseline for trend analysis. Keep recent_avg_portcalls_per_day and baseline_avg_portcalls_per_day if you need absolute counts.

How many calls can I make without a key?
Guests are limited to 100 requests per day per IP. Use the X-API-Key header to raise limits.

Is the congestion field different from activity?
No. congestion is a deprecated alias of activity. Use activity moving forward.

Can I quote freight rates alongside this metric?
Do not present a USD rate quote as “today’s price” based on this endpoint. It only provides port-call activity relative to baseline.

Build your Kaohsiung dashboard or alerting workflow in minutes: register for an API key and put the endpoint into production. Get started at Register.