You need a reliable way to check congestion conditions at the Los Angeles-Long Beach complex so you can plan bookings, drayage, chassis, and yard resources. By the end of this guide, you will be able to query a transport-specific API endpoint in Python, interpret the response for USLAX, and integrate the result into your planning workflows.
What this endpoint provides (and what it does not)
The port congestion endpoint returns IMF PortWatch-based congestion signals for a given port code. For Los Angeles-Long Beach (USLAX), the data reflects a 7-day average compared against a 90-day baseline and is lagged by roughly 6–7 days. It is not live AIS vessel wait times. Treat it as a stabilized signal for planning rather than a minute-by-minute operational feed.
The response uses a consistent JSON envelope with a top-level success flag and a data object. You should expect to receive a single result for the requested port.
Authentication, quotas, and headers
Authentication uses an HTTP header. Provide X-API-Key with your key value. If you do not have a key, you can still test as a guest; the guest tier allows 100 requests per day per IP. For production services, register for an API key.
Auth header:
- X-API-Key: YOUR_API_KEY
Envelope format:
- {"success": true, "data": {...}}
Endpoint and parameters
Method: GET
URL: https://freightpulsehq.com/api/v1/port-congestion
Query parameters:
- port: Required. Use the port code for the terminal or complex you want to query. For this guide we use Los Angeles-Long Beach with port=USLAX.
Keep the discussion and implementation focused on transportation and USLAX to avoid mixing unrelated datasets.
Official cURL example
Use this exact call to retrieve the documented fixture for Los Angeles-Long Beach congestion signals.
curl -H "X-API-Key: YOUR_API_KEY" "https://freightpulsehq.com/api/v1/port-congestion?port=USLAX"
Official JSON example and what to read from it
Below is the official sample response for USLAX. It is a documented fixture as of 2026-08-14 and not live today.
{
"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
}
}
]
}
}
Fields you will typically consume:
- port and locode: Human-readable port name and the LOCode for the complex.
- congestion: A categorical congestion label you can display in dashboards and alerts.
- as_of: A date string marking the reference date of the signal (lagged by ~6–7 days from real time).
- metrics.recent_avg_portcalls_per_day: 7-day average vessel port calls per day.
- metrics.baseline_avg_portcalls_per_day: 90-day baseline for comparison.
- metrics.ratio_vs_baseline: recent divided by baseline. Values below 1.0 indicate fewer calls than baseline (often consistent with congestion effects).
Python: end-to-end example for USLAX
This Python sample demonstrates how to call the same endpoint, handle the envelope, and extract congestion and metrics for Los Angeles-Long Beach. It includes a basic timeout, a simple retry loop for transient network issues, and minimal validation.
Install dependencies
Use Python 3.9+ and requests. If you do not already have it:
python -m pip install requests
Implement the client
import time
import requests
from typing import Any, Dict, Optional, Tuple
API_URL = "https://freightpulsehq.com/api/v1/port-congestion"
PORT_CODE = "USLAX"
API_KEY = "YOUR_API_KEY"
def fetch_uslax_congestion(
max_retries: int = 3,
timeout_seconds: int = 10
) -> Dict[str, Any]:
"""
Calls the port congestion endpoint for Los Angeles-Long Beach (USLAX).
Returns the parsed JSON dictionary.
"""
headers = {"X-API-Key": API_KEY}
params = {"port": PORT_CODE}
last_exc: Optional[Exception] = None
for attempt in range(1, max_retries + 1):
try:
resp = requests.get(API_URL, headers=headers, params=params, timeout=timeout_seconds)
# If the server responds (even with an error), break retry loop on non-5xx
if 500 <= resp.status_code < 600:
# transient server error: retry
raise requests.HTTPError(f"Server error {resp.status_code}")
resp.raise_for_status()
return resp.json()
except (requests.Timeout, requests.ConnectionError, requests.HTTPError) as exc:
last_exc = exc
if attempt == max_retries:
break
# Exponential backoff with cap
sleep_for = min(2 ** (attempt - 1), 8)
time.sleep(sleep_for)
raise RuntimeError(f"Failed to fetch congestion after {max_retries} attempts") from last_exc
def extract_uslax_fields(payload: Dict[str, Any]) -> Tuple[str, str, str, float, float, float]:
"""
Validates the envelope and extracts the fields you will need for dashboards and alerts.
Returns:
congestion_label, as_of_date, locode, recent_avg, baseline_avg, ratio
"""
if not isinstance(payload, dict) or not payload.get("success"):
raise ValueError("Unexpected API envelope: missing or false 'success'")
data = payload.get("data")
if not isinstance(data, dict):
raise ValueError("Unexpected API envelope: 'data' not found")
results = data.get("results")
if not isinstance(results, list) or len(results) == 0:
raise ValueError("No results returned for USLAX")
row = results[0]
congestion_label = row.get("congestion")
as_of_date = row.get("as_of") # date string (no time component)
locode = row.get("locode")
metrics = row.get("metrics") or {}
recent_avg = float(metrics.get("recent_avg_portcalls_per_day"))
baseline_avg = float(metrics.get("baseline_avg_portcalls_per_day"))
ratio = float(metrics.get("ratio_vs_baseline"))
# Lightweight checks
if congestion_label is None or as_of_date is None or locode is None:
raise ValueError("Missing expected top-level fields in result row")
return congestion_label, as_of_date, locode, recent_avg, baseline_avg, ratio
def main() -> None:
payload = fetch_uslax_congestion()
congestion_label, as_of_date, locode, recent, baseline, ratio = extract_uslax_fields(payload)
# Render a concise summary for an ops dashboard or alert
summary = (
f"USLAX congestion: {congestion_label} (as_of={as_of_date}); "
f"7d avg port calls={recent:.1f}, 90d baseline={baseline:.1f}, "
f"ratio={ratio:.2f}"
)
print(summary)
if __name__ == "__main__":
main()
Notes for transport operations:
- Timeouts: This example uses a 10s timeout. Adjust according to your job runner or orchestrator.
- Retries: The backoff loop retries on timeouts, network errors, and 5xx responses.
- Validation: Always check the top-level success flag and that data.results is present.
- Display: Show congestion along with the as_of date so stakeholders do not confuse it with live AIS waits.
How to interpret the metrics for planning
For USLAX, the metrics are designed to signal relative congestion against a 90-day baseline:
- recent_avg_portcalls_per_day: Lower recent port calls can be associated with slowed throughput or bunching effects.
- baseline_avg_portcalls_per_day: Provides the comparative norm.
- ratio_vs_baseline: A direct multiplier. Values below 1.0 indicate fewer recent calls than baseline; above 1.0 indicates more.
Use the categorical congestion field to drive human-readable alerts, and the ratio to support quantitative thresholds in automated routing or booking logic.
Practical engineering details that save time
- Staleness window: The signal is lagged by ~6–7 days by design (IMF PortWatch methodology). Do not expect it to match live anchorage or berth counts.
- Timestamps: as_of is provided as a date string without a time component. Treat it as a date boundary when storing or comparing.
- Units: Port calls are counts per day; ratio is unitless.
- Caching: Because the series is lagged and updates on a low frequency cadence, you can cache the response for a day without losing fidelity for planning dashboards.
- Pagination: The response returns a single results array for the requested port; pagination is not applicable for this use case.
- Error surfaces: If success is false or the results array is empty, treat it as a hard failure and notify your ops channel.
- Financial data: Do not quote freight-rates USD fares as today’s price based on this endpoint; it is not a rate feed.
Embedding the signal into transportation workflows
In a transportation context, you can connect this congestion reading to several operational levers:
- Booking lead times: When congestion is moderate or above, increase required lead times for drayage and yard appointments near USLAX.
- Yard and chassis planning: Trigger a capacity review if ratio_vs_baseline drops below a threshold you define; align returns and pickups accordingly.
- Routing: For cargo with flexible ports of discharge, flag USLAX congestion to planners so they can consider alternative routings upstream in the schedule.
- Carrier communications: Include the congestion label and as_of date in vendor updates to keep expectations aligned.
Testing without keys and moving to production
If you are testing from a CI server or local machine without a registered key, you can operate as a guest. The guest tier provides 100 requests per day per IP. For persistent services, background jobs, or multi-system integrations, use a registered key and centralize it in a secure secret store rather than in source code.
When ready to scale, review the Documentation and obtain credentials via Register.
Quality checks for transport dashboards
Before surfacing the value to dispatchers or planners, apply these guardrails:
- Always print or display the as_of date next to the congestion label to prevent misinterpretation as live AIS.
- Set safe defaults: If the API cannot be reached, hold the previous day’s cached result and note the retrieval time in your logs.
- Alert thresholds: Base alerts on ratio_vs_baseline and not just the categorical label; it gives a more precise trigger boundary.
- Audit trail: Log the raw envelope {"success": true, "data": {...}} and a reduced projection of the fields you render, so you can trace decisions made by planners or automation.
Common pitfalls to avoid
- Confusing this endpoint with live AIS: Do not use it to estimate hour-by-hour berth waits.
- Inventing a port code: For this workflow, stick to USLAX. Do not switch to another port purely to fill a dashboard widget.
- Assuming USD fares: The endpoint does not provide freight-rate prices; do not quote a fare as a current market rate.
- Ignoring the envelope: Code that jumps straight into data.results without checking success may fail silently.
End-to-end validation checklist
- Request uses GET /api/v1/port-congestion with port=USLAX.
- Auth header is X-API-Key with YOUR_API_KEY in non-production examples.
- Envelope validated: success is true, data is present, results array non-empty.
- Parsed fields: congestion, as_of, locode, and metrics (recent_avg_portcalls_per_day, baseline_avg_portcalls_per_day, ratio_vs_baseline).
- Displayed value includes the as_of date and a clear label that it is a lagged IMF PortWatch signal.
- Guest request volume controlled to 100/day per IP during testing.
FAQ
Is the congestion value live?
No. The congestion signal is derived from IMF PortWatch and is lagged by roughly 6–7 days. It is not a live AIS wait-time feed.
What authentication is required?
Use the header X-API-Key with your key. Guests without a key can make up to 100 requests per day per IP.
What fields should I store?
Store port, locode, congestion, as_of, and the metrics block. These are sufficient for dashboards, alerts, and historical comparisons.
Does the API include multiple pages for USLAX?
No. For the USLAX query, the response returns a single results array; pagination is not part of this endpoint’s usage here.
Can I quote freight-rate prices from this data?
No. Do not quote a freight-rates USD fare as today’s price using this endpoint; it does not provide current rate data.
Next step
Spin up the Python snippet above, confirm you can retrieve and display USLAX congestion and ratio_vs_baseline, then connect it to your transport planning UI or alerting pipeline. When you are ready to run this in production, create your key via Register and review the Documentation for deployment details.