Home → Blog

You need a dependable way to quantify how busy Los Angeles-Long Beach is right now without chasing live AIS “ships at anchor” snapshots. By the end of this guide you’ll be able to pull lagged congestion metrics from FreightPulse for USLAX, interpret the 7‑day average vs 90‑day baseline, and ship a small integration that you can cache inside your workflow.

What this congestion metric is (and isn’t)

FreightPulse congestion data for Los Angeles-Long Beach (USLAX) comes from IMF PortWatch and is lagged by roughly 6–7 days. It is not a live AIS estimate of vessels waiting off the port. Instead, it summarizes recent activity with a 7‑day rolling average and compares it to a 90‑day baseline.

Illustration: Los Angeles-Long Beach Congestion Today

This design is intentional: the signal is stable enough for planning and trending, less prone to hour-by-hour volatility, and easier to integrate into scheduling, pricing, and exception-alert workflows.

Endpoint you will call

The port congestion endpoint is a straightforward GET that accepts a port code and returns a standardized envelope. Authentication is via an API key header. A guest without a key can make up to 100 requests per day per IP, but you should still structure your code to cache responses because the dataset is lagged and not changing minute-to-minute.

Official cURL you can paste and run:

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

Field notes:

If you’re new to the API, read the Documentation for general patterns you can reuse (authentication, response shapes, and error handling).

Los Angeles-Long Beach example response and how to read it

The following is the documented fixture for USLAX (as_of 2026‑08‑14 — not live today). Keep these values intact when building mocks or unit tests:

{
    "success": true,
    "data": {
        "results": [
            {
                "port": "Los Angeles-Long Beach",
                "locode": "US LAX",
                "country": "United States",
                "congestion": "moderate",
                "as_of": "2026-08-14",
                "metrics": {
                    "recent_avg_portcalls_per_day": 8.7,
                    "baseline_avg_portcalls_per_day": 10.2,
                    "ratio_vs_baseline": 0.85
                }
            }
        ]
    }
}

How to interpret the key fields you’ll actually use:

For programmatic consumers, you’ll pair the categorical “congestion” field with ratio_vs_baseline and the two averages to decide whether to trigger actions (e.g., allocate additional buffer time when the ratio is meaningfully below 1.0).

Production-ready Python example for USLAX

This snippet fetches congestion for Los Angeles-Long Beach, validates the envelope, and extracts the fields you need. It also demonstrates basic caching guidance via a comment because the metric is lagged and stable intra-day.

import os
import sys
import json
import time
import urllib.request

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

def fetch_uslax_congestion():
req = urllib.request.Request(API_URL, method="GET")
req.add_header("X-API-Key", API_KEY)

try:
with urllib.request.urlopen(req, timeout=20) as resp:
raw = resp.read().decode("utf-8")
payload = json.loads(raw)
except Exception as e:
raise RuntimeError(f"Request failed: {e}")

# Validate the envelope
if not isinstance(payload, dict) or not payload.get("success"):
raise ValueError(f"Unexpected response shape or success=false: {payload}")

data = payload.get("data", {})
results = data.get("results", [])
if not results:
raise ValueError("No results in response")

row = results[0]
# Required fields
port = row.get("port")
locode = row.get("locode")
as_of = row.get("as_of")
congestion = row.get("congestion")
metrics = row.get("metrics", {})

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

if None in (port, locode, as_of, congestion, recent, baseline, ratio):
raise ValueError(f"Missing required fields in response for {locode}")

return {
"port": port,
"locode": locode,
"as_of": as_of,
"congestion": congestion,
"recent_avg_portcalls_per_day": recent,
"baseline_avg_portcalls_per_day": baseline,
"ratio_vs_baseline": ratio,
}

def main():
# Caching tip: since the source is lagged by ~6–7 days and updates daily at most,
# cache this response for hours to reduce calls and stay within guest limits.
result = fetch_uslax_congestion()
print(json.dumps(result, indent=2))

if __name__ == "__main__":
sys.exit(main())

Turning the numbers into an operational signal

For Los Angeles-Long Beach, you can form a practical rule by combining the ratio and the qualitative label:

Because the data is a 7‑day average, it smooths daily spikes. This helps prevent alert fatigue while still capturing shifts in port activity at USLAX.

Integration details that save time

Origin catalog facts

Validation workflow for USLAX

When you wire this into a production pipeline for Los Angeles-Long Beach, validate on three levels:

  1. Schema: Ensure the envelope is present and results is an array with at least one element. Fail fast if not.
  2. Semantics: Check that as_of is within the plausible 6–7 day lag window relative to your system date; if it’s older than expected, surface a “stale data” warning but do not crash your pipeline.
  3. Numerics: Verify recent_avg_portcalls_per_day and baseline_avg_portcalls_per_day are positive numbers and ratio_vs_baseline is between 0 and a reasonable upper bound (e.g., 3). If out of range, quarantine the tick for manual review.

This prevents a single malformed tick from propagating into planning systems.

Common pitfalls to avoid

FAQ

Is this the same as tracking ships at anchor off Los Angeles-Long Beach?

No. This is IMF PortWatch data with a ~6–7 day lag and a 7‑day rolling average compared to a 90‑day baseline. It is not a live AIS wait-time feed.

How often should I refresh USLAX congestion in production?

Once per day is typical. Many teams cache for 6–24 hours given the lagged nature of the source.

What’s the minimum I need to display a reliable status?

Show congestion (string), as_of (date), and ratio_vs_baseline (number). Optionally include the recent and baseline port calls per day to add context.

Do I need an API key to test?

No, you can make up to 100 requests/day per IP as a guest. For sustained use, add X-API-Key: YOUR_API_KEY and manage caching.

Can I use these metrics to set freight rates today?

Do not quote a USD freight rate as “today’s price” based solely on these metrics. They are lagged indicators for congestion, not live pricing.

Get an API key and put this into your pipeline in minutes. Create your account at Register, then pull the USLAX endpoint and cache the 7‑day average vs 90‑day baseline. If you need more details on envelopes, fields, and conventions, see the Documentation.