Home → Blog

Teams responsible for routing and ETA promises struggle when weather, quakes or floods threaten key gateways. By the end of this guide you’ll query the FreightPulse Supply Chain Disruptions API for a port like USLAX, understand the envelope and field semantics, run a working cURL and Python example, and deploy an integration that respects guest access limits, caching and data provenance.

What you can query and how it is scoped

The Supply Chain Disruptions lookup targets natural-hazard risk that can affect port throughput and schedules. Sources include GDACS, USGS and NOAA. This means you should not expect labor actions, strikes, or canal traffic advisories in this endpoint. The intent is to surface hazard context alongside congestion signals so planners know when to build slack into schedules around a port.

Illustration: API for Supply Chain Disruptions

For congestion context, FreightPulse references IMF PortWatch aggregates that are lagged by roughly 6–7 days. Values are typically expressed as a 7‑day average versus a 90‑day baseline and are not live AIS vessel wait times. Pair these lagged congestion indicators with the disruptions lookup to decide when to re-route or buffer SLAs.

Access model, authentication and request envelope

If you are validating feasibility or building a prototype, you can start without a key and remain within the 100 requests/day per IP limit. For production traffic or higher volume, obtain a key and pass it via the X-API-Key header. The endpoint described here is a GET with a port parameter, and sample usage is provided below.

For full parameter coverage and production guidance, keep the Documentation open while you implement.

Data sources and semantics you should rely on

Quickstart: cURL request for Supply Chain Disruptions

The following request targets the disruptions lookup for the Los Angeles port (USLAX). You can run this as a guest (no key header) within the stated limits, or add your key with the documented header.

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

Official JSON response sample

Below is the official sample payload. Use it to validate your parser and confirm envelope handling and field naming. Preserve the types and nesting exactly as shown.

{
    "success": true,
    "data": {
        "timestamp": "2026-10-23T00:00:21+00:00",
        "source": "EIA (U.S. Energy Information Administration)",
        "currency": "USD",
        "unit": "gallon",
        "data": {
            "diesel": {
                "national_average": 6.276,
                "change_week": 0.097,
                "change_percent": 1.57,
                "updated_at": "2026-10-19",
                "regions": {
                    "east_coast": 5.984,
                    "midwest": 6.352,
                    "gulf_coast": 5.903,
                    "rocky_mountain": 6.422,
                    "west_coast": 7.394,
                    "california": 8.242
                }
            },
            "gasoline": {
                "national_average": 4.284,
                "change_week": -0.047,
                "change_percent": -1.09,
                "updated_at": "2026-10-19",
                "grades": {
                    "regular": 4.284,
                    "midgrade": 4.915,
                    "premium": 5.314
                }
            },
            "bunker_fuel": {
                "available": false,
                "note": "No known free source (Rotterdam/Singapore/Houston) — requires a paid provider (e.g. Ship & Bunker, Argus)."
            }
        },
        "historical": {
            "diesel_30d_avg": 6.259,
            "diesel_90d_avg": 5.88,
            "diesel_yoy_change": 73.4,
            "gasoline_30d_avg": 4.359,
            "gasoline_90d_avg": 4.213,
            "gasoline_yoy_change": 41.9
        }
    },
    "meta": {
        "request_id": "af02532e-85e0-4469-bd54-4836a02f57b8"
    }
}

Field notes you will actually use:

End-to-end example in Python

This example calls the same endpoint, validates the envelope, reads core fields, and prints a compact summary. Replace YOUR_API_KEY with your key when you move beyond guest access.

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

API_URL = "https://freightpulsehq.com/api/v1/disruptions"
PORT_CODE = "USLAX"
API_KEY = os.getenv("FREIGHTPULSE_API_KEY", "YOUR_API_KEY")

def fetch_disruptions(port_code):
url = f"{API_URL}?port={urllib.parse.quote(port_code)}"
req = urllib.request.Request(url)
# Guest calls can omit the header; include it when you have a key.
if API_KEY and API_KEY != "YOUR_API_KEY":
req.add_header("X-API-Key", API_KEY)
with urllib.request.urlopen(req, timeout=20) as resp:
if resp.status != 200:
raise RuntimeError(f"HTTP {resp.status}")
data = json.loads(resp.read().decode("utf-8"))
return data

def main():
payload = fetch_disruptions(PORT_CODE)

# Envelope check
if not isinstance(payload, dict) or not payload.get("success"):
print("Request failed or malformed envelope", file=sys.stderr)
sys.exit(1)

d = payload.get("data", {})
meta = payload.get("meta", {})

# Minimal fields that are safe to assume from the sample
ts = d.get("timestamp")
source = d.get("source")
currency = d.get("currency")
unit = d.get("unit")
nested = d.get("data", {})
historical = d.get("historical", {})

# Read a few nested values if present; guard against missing keys
diesel = (nested.get("diesel") or {})
gasoline = (nested.get("gasoline") or {})

summary = {
"timestamp": ts,
"source": source,
"currency": currency,
"unit": unit,
"diesel_national_avg": diesel.get("national_average"),
"gasoline_national_avg": gasoline.get("national_average"),
"historical_keys": sorted(historical.keys()),
"request_id": meta.get("request_id")
}

print(json.dumps(summary, indent=2))

if __name__ == "__main__":
main()

Notes:

Handling units, timestamps, caching and rate limits

Interpreting lagged congestion alongside disruptions

If you combine the disruptions lookup with IMF PortWatch congestion context, remember it is lagged by roughly 6–7 days and expressed as a 7‑day moving average against a 90‑day baseline. Use it as a trend indicator rather than a live ETA predictor. For live berth queues or AIS-based metrics, consult a real-time feed separately; do not assume FreightPulse congestion is live AIS.

Practical approach:

Choosing and validating port codes

The example above uses the Los Angeles port code USLAX. Keep a consistent registry of port codes in your application and validate inputs to avoid typos that would return valid 200 responses with empty or irrelevant data. When storing results, index by the normalized port code to prevent duplicate cache entries.

Do not conflate this disruptions scope with labor or canal issues. The lookup is natural hazards only, derived from GDACS/USGS/NOAA, and should be interpreted accordingly.

Troubleshooting and operational tips

FAQ

Can I use this without an API key?
Yes. Guest access allows up to 100 requests/day per IP without a key. For higher volume or production SLAs, register for a key and pass it via X-API-Key.

Are congestion metrics live vessel wait times?
No. FreightPulse congestion references IMF PortWatch and is lagged by about 6–7 days, using a 7‑day average versus a 90‑day baseline. It is not live AIS.

Does the disruptions lookup include strikes or canal incidents?
No. It covers natural hazards only (GDACS/USGS/NOAA). Do not expect labor actions or canal advisories in this feed.

What currency and units should I expect?
The payload specifies currency and unit fields where applicable (e.g., USD and gallon). Always read these fields instead of assuming defaults.

How should I cache results safely?
Cache by full query string (e.g., port=USLAX) with a modest TTL (15–30 minutes) and revalidate using the timestamp field to avoid unnecessary requests.

Ready to move beyond guest limits and wire this into production? Create your key in minutes at Register, then keep the Documentation open as you ship your integration.