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.
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:
- Auth: header X-API-Key: YOUR_API_KEY. Guest without key: 100 requests/day per IP.
- Envelope: {"success":true,"data":{...}}
- Port congestion is IMF PortWatch, lagged ~6-7 days, 7-day avg vs 90-day baseline — not live AIS.
- Do not quote a freight-rates USD fare as today’s price.
- Port: Kaohsiung (TWKHH)
- curl: curl -H "X-API-Key: YOUR_API_KEY" "https://freightpulsehq.com/api/v1/port-congestion?port=TWKHH"
- No official congestion JSON is published for TWKHH. Show the curl and field names (congestion, ratio_vs_baseline, as_of). Do not reuse the USLAX 0.85 fixture.
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:
- data.results[0].as_of: ISO-8601 date for the latest tick (lagged ~6–7 days).
- data.results[0].activity (same as congestion): categorical label (“low”, “moderate”, “high”).
- data.results[0].metrics.ratio_vs_baseline: numeric ratio of the 7-day average to the 90-day baseline.
- data.results[0].metrics.recent_avg_portcalls_per_day and baseline_avg_portcalls_per_day: helpful for dashboards that prefer absolute call counts.
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
- Update cadence and lag: The series is updated daily, but values reflect a ~6–7 day lag. Do not treat it as live AIS or queue length.
- Caching: Since the metric changes at most daily and is lagged, cache responses per port for 24 hours. This avoids redundant calls and aligns with the data cadence.
- Timestamps and timezone: The as_of field is a date (YYYY-MM-DD). No timezone conversion is required; treat it as a calendar date for the port’s reporting tick.
- Envelope and errors: Always check the top-level success flag and expect data.results to be an array. Handle empty results defensively.
- Throughput: Without an API key, guests are limited to 100 requests/day per IP. If you expect more traffic or multiple ports, use an API key via the X-API-Key header.
- Field semantics: congestion is present as a deprecated alias of activity. Prefer activity in new code, but read congestion for backward compatibility if needed.
- Port identifier: Use port=TWKHH for Kaohsiung. The payload also includes locode ("TW KHH") for display; the request parameter does not include the space.
- Units: The metrics are counts of port calls per day (floats). The ratio_vs_baseline is dimensionless.
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.