Home → Blog

You’re trying to understand how congested Port Klang is today, but you keep running into conflicting dashboards and “live AIS wait time” claims. By the end of this post, you’ll know exactly how to pull the latest FreightPulse congestion signal for Port Klang (MYPKG), what it measures, its 6–7 day lag, how to interpret the 7-day average vs 90-day baseline, and how to embed it safely in your workflow with a minimal Python client.

What the Port Klang congestion signal actually measures

FreightPulse’s congestion signal for Port Klang is sourced from IMF PortWatch, built on UN Global Platform AIS data. It is a daily-updated, lagged indicator:

Illustration: Port Klang Congestion Today

This is not a live AIS wait-time feed. Use it to assess whether Port Klang’s throughput is running above, near, or below its usual cadence over the last quarter, with a short lag that makes it suitable for monitoring and reporting rather than moment-to-moment dispatching.

Endpoint, auth, and envelope

Access the congestion signal for Port Klang via a single GET endpoint. Authentication uses an API key in the X-API-Key header. Guests without a key may make up to 100 requests per day per IP. Responses are wrapped in an envelope that always includes a top-level success boolean and a data object.

Official documentation is here: Documentation.

Copy-pasteable cURL request

The following call requests the PortWatch-based congestion signal for Port Klang (MYPKG). Keep the URL and header exactly as shown:

Live FreightPulse congestion for MYPKG.
Source: live

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

Official JSON response and field meanings

Below is the official response format, including a results array with Port Klang. Values are provided from the live source example:

{
    "success": true,
    "data": {
        "results": [
            {
                "port": "Port Klang",
                "locode": "MY PKG",
                "country": "Malaysia",
                "activity": "moderate",
                "congestion": "moderate",
                "as_of": "2026-10-30",
                "metrics": {
                    "recent_avg_portcalls_per_day": 30.3,
                    "baseline_avg_portcalls_per_day": 31.7,
                    "ratio_vs_baseline": 0.95
                }
            },
            {
                "port": "Pelabuhan Sungai Udang",
                "locode": "MY PKG",
                "country": "Malaysia",
                "activity": "moderate",
                "congestion": "moderate",
                "as_of": "2026-10-30",
                "metrics": {
                    "recent_avg_portcalls_per_day": 2,
                    "baseline_avg_portcalls_per_day": 1.9,
                    "ratio_vs_baseline": 1.08
                }
            }
        ],
        "global_summary": {
            "ports_high_activity": 0,
            "ports_moderate_activity": 2,
            "ports_low_activity": 0,
            "ports_high_congestion": 0,
            "ports_moderate": 2,
            "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": "a19d01f2-877d-40b9-b625-ab6c51df6d8c"
    }
}

What you will actually use:

How to interpret Port Klang’s numbers today

Use the ratio_vs_baseline to express where Port Klang stands versus its 90-day norm. A ratio near 1.0 means activity is around baseline. A ratio well below 1.0 means reduced port-call volume; this can correspond to weather disruptions, holidays, or offshore waiting—but it does not quantify berth/anchorage wait times.

Best-practice display:

Avoid wording like “live congestion” or “current wait time”. Keep the lag disclaimer visible anywhere you chart or alert on this signal.

Python example: fetch and render Port Klang’s congestion

This script calls the same endpoint, filters for the Port Klang row, and formats a compact status line for a dashboard. Replace YOUR_API_KEY with your token. If you do not have one, the endpoint can be called as a guest with daily request limits per IP.

import os
import requests
from datetime import datetime

API_KEY = os.getenv("FREIGHTPULSE_API_KEY", "YOUR_API_KEY")
URL = "https://freightpulsehq.com/api/v1/port-congestion?port=MYPKG"

headers = {"X-API-Key": API_KEY}

def fetch_port_klang_status():
resp = requests.get(URL, headers=headers, timeout=20)
resp.raise_for_status()
payload = resp.json()
if not payload.get("success"):
raise RuntimeError("API returned success=false")

results = payload.get("data", {}).get("results", [])
# Prefer exact port name match to avoid collisions in multi-port arrays
port_row = next((r for r in results if r.get("port") == "Port Klang"), None)
if not port_row:
raise ValueError("Port Klang row not found in results")

metrics = port_row.get("metrics", {})
as_of = port_row.get("as_of") # e.g., "2026-10-30" (date string, lagged ~6–7 days)
activity = port_row.get("activity")
congestion = port_row.get("congestion") # deprecated alias of activity

recent = metrics.get("recent_avg_portcalls_per_day")
baseline = metrics.get("baseline_avg_portcalls_per_day")
ratio = metrics.get("ratio_vs_baseline")

# Build a compact line you can drop into logs or a status widget
line = (
f"Port Klang (MYPKG) — activity: {activity} (alias: {congestion}); "
f"7d avg {recent} vs 90d baseline {baseline} calls/day "
f"[{ratio}x]; as_of {as_of}; source: IMF PortWatch (lag ~6–7 days)"
)
return line

if __name__ == "__main__":
try:
print(fetch_port_klang_status())
except Exception as e:
print(f"Error: {e}")

Notes:

Embedding disclaimers and UI guardrails

Because stakeholders often conflate port “congestion” with “wait time,” add guardrails wherever you show this data:

Error handling and operational considerations

Plan for intermittent network errors and schema stability:

What to log for audits

For traceability, log the following alongside your derived badges:

This makes it easy to reconcile dashboards with downstream analytics later.

Putting it together for Port Klang today

If your dashboard refreshes daily, call the endpoint once per day, cache the response, and render:

This communicates both the magnitude and the measurement caveat without over-claiming real-time precision.

Frequently asked questions

Is this the same as live anchorage or berth wait time?

No. This is a lagged activity signal (7-day average port calls vs a 90-day baseline) derived from IMF PortWatch. It does not measure vessel wait or anchorage time.

How fresh is the “as_of” date?

The feed updates daily but is typically ~6–7 days behind the current calendar date. Always display the as_of field to avoid confusion.

What units are the metrics in?

recent_avg_portcalls_per_day and baseline_avg_portcalls_per_day are calls per day. ratio_vs_baseline is unitless (recent / baseline).

Can I poll this more than once per day?

You can, but it’s unnecessary. The underlying data rolls daily with a lag. Cache for 12–24 hours to reduce load and stay within guest limits if you don’t use an API key.

Should I rely on the “congestion” field?

congestion is a deprecated alias of activity. For logic and alerts, key on metrics.ratio_vs_baseline and show activity as a human-readable label.

Ready to integrate Port Klang into your ops dashboard with a few lines of code? Get an API key in minutes: Register. For more details on fields and usage, see the Documentation.