Home → Blog

You need a reliable way to programmatically detect cyclone-related port disruptions and act on them in routing, ETAs, and risk dashboards—without building your own hazard pipeline. By the end of this post, you will be able to query FreightPulse’s Cyclone Disruptions endpoint with guest access (no key, 100 requests/day per IP), parse the standard response envelope, understand what’s lagged vs. live, and integrate the results into your weather-aware logistics workflows.

What the Cyclone Disruptions API does and what it does not

The Cyclone Disruptions lookup focuses on weather-driven natural hazards only. Its hazard sources are public agencies (GDACS/USGS/NOAA), and its goal is to surface cyclone-related operational impacts at ports. It does not cover labor actions, strikes, canal transits, or other non-weather disruptions.

Illustration: API for Cyclone Disruptions

FreightPulse also publishes port congestion metrics. Those are derived from IMF PortWatch and are lagged by roughly 6–7 days, reported as a 7-day average vs. a 90-day baseline. They are not live AIS wait times. Keep this in mind when combining disruptions with congestion context in a single view; you are mixing near-real-time hazard signals with delayed congestion indicators.

Access model: guest vs. API key

FreightPulse supports a very simple access pattern for getting started:

Responses use a consistent envelope wrapper to simplify parsing and error handling:

Envelope: {"success":true,"data":{...}}

You can begin immediately using guest access for quick lookups and move to a registered key later for higher-volume or production traffic.

The documented Cyclone Disruptions lookup path

The core lookup you will need for weather-driven cyclone impacts at a port is shown below. This is the documented path you should copy:

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

This request queries the Cyclone Disruptions lookup for the Los Angeles port (USLAX). For guest access, you can omit the X-API-Key header and the request will count toward the 100 requests/day per IP allowance. The response will arrive in the standard {"success":true,"data":{...}} envelope.

Official JSON example and how to read the envelope

Below is the OFFICIAL SAMPLE JSON response block you should use to understand the envelope and field-shape patterns when parsing FreightPulse responses. Copy it exactly as shown:

{
    "success": true,
    "data": {
        "timestamp": "2026-10-24T00:00:14+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": "5ebea297-1cdd-40f7-bd28-4ac04788c6b6"
    }
}

How to use it in your integration:

This example demonstrates the envelope and field nesting. When calling the Cyclone Disruptions lookup, do not assume the same internal keys as the example above; instead, always check the presence of top-level success, then parse data and meta. The precise hazard fields can vary by endpoint and should be inspected at runtime.

End-to-end example: curl and a minimal parser

Copy-pasteable curl

The following curl is the documented Cyclone Disruptions lookup. You can run it with or without the header if you are using guest access:

JavaScript example (Node.js with fetch)

This example calls the same endpoint, checks the standard envelope, and demonstrates safe field access without assuming a specific hazard schema.

import fetch from "node-fetch";

async function getCycloneDisruptionsUSLAX({ apiKey } = {}) {
const url = "https://freightpulsehq.com/api/v1/disruptions?port=USLAX&type=cyclone";
const headers = {};
if (apiKey) {
headers["X-API-Key"] = "YOUR_API_KEY";
}
const res = await fetch(url, { headers });
if (!res.ok) {
throw new Error(`HTTP ${res.status} ${res.statusText}`);
}
const json = await res.json();

// Standard envelope guard
if (!json || json.success !== true || typeof json.data !== "object") {
throw new Error("Unexpected response envelope");
}

// Generic fields commonly needed across FreightPulse responses
const timestamp = json.data.timestamp || null; // ISO-8601, with timezone
const source = json.data.source || null; // Data origin (e.g., GDACS/USGS/NOAA for weather hazards)
const requestId = json.meta && json.meta.request_id ? json.meta.request_id : null;

// The disruption-specific structure may vary. Avoid assumptions:
// Safely inspect present keys for your downstream logic.
const keys = Object.keys(json.data);

return {
raw: json,
timestamp,
source,
requestId,
topLevelKeys: keys
};
}

getCycloneDisruptionsUSLAX({ apiKey: process.env.FREIGHTPULSE_API_KEY })
.then((out) => {
console.log("Success:", out.timestamp, out.source, out.requestId);
console.log("Top-level data keys:", out.topLevelKeys);
})
.catch((err) => {
console.error("Error:", err);
process.exit(1);
});

How to integrate Cyclone Disruptions into weather-aware logistics

To build a practical, production-grade integration for cyclone-related weather risks at ports, focus on four steps: normalize the envelope, separate hazard vs. congestion timescales, implement cache and retries, and keep your UI clear about what’s live.

  1. Normalize the envelope and logging:
    • Always check success first, then parse data, then meta.request_id for traceability.
    • Log timestamp and source from data so you know how fresh and where the hazard info originated.
  2. Separate timescales in your logic:
    • Weather hazards (cyclones) are near-real-time signals. Use them to trigger alerts and re-planning.
    • Port congestion metrics are lagged ~6–7 days and represent a 7-day average vs. a 90-day baseline from IMF PortWatch, not live AIS wait times. Treat these as context, not a live indicator.
  3. Caching and rate usage:
    • For guest mode (100 requests/day per IP), cache responses per port+type combination for several minutes to an hour depending on your tolerance for freshness. Use data.timestamp for cache invalidation.
    • Include exponential backoff on non-2xx responses; retry idempotently as needed.
  4. UI/UX clarity:
    • Show that cyclone hazard status is sourced from public weather agencies.
    • When you show congestion alongside hazards, label congestion as “lagged (IMF PortWatch, ~6–7 days)” to avoid misinterpretation as live AIS.

Handling parameters, units, timezones, and currency

Parameters: Use the documented query parameters in the sample call: port=USLAX and type=cyclone. If you need additional filtering, consult the product Documentation. Do not assume support for undocumented parameters.

Units and currency: FreightPulse responses can declare unit and currency fields where applicable. Always read and propagate them. The official example demonstrates including currency and unit within the data object; your cyclone-specific response may or may not include those exact fields, so do not hardcode.

Timestamps and timezone: Timestamps are ISO-8601 with explicit offsets (e.g., +00:00). Store them as strings and parse to UTC in your application layer for comparisons and SLAs.

Non-trading days equivalent: Unlike financial markets, weather hazards do not have market hours—but upstream public-agency feeds can have publish cycles. Combine timestamp checks with caching to avoid redundant fetches between cycle updates.

Production patterns: error handling and observability

Error classes to handle:

Observability tips:

Cross-referencing hazards with lagged congestion

If you display both cyclone disruptions and congestion on the same page, clearly distinguish the freshness. Any automated decisioning should treat hazard signals as triggers, while congestion supplies medium-term baseline context. Never present lagged congestion as live AIS data, and never infer today’s wait time from the 7-day vs. 90-day baseline without explicit labeling.

Security, keys, and migration from guest to production

Guest mode is valuable for prototyping, but production workloads should move to key-based access for stability and higher limits. Pass X-API-Key: YOUR_API_KEY over HTTPS only, never log secrets in plaintext, and store the key in a secrets manager. Your integration code should make the header optional, enabling the same binary to run in guest mode locally and key-based mode in CI/CD and production.

Testing strategy without fixtures

Because the API uses a stable envelope, you can write contract tests that assert success is true and that data is an object with a timestamp and any hazard-specific fields. Record-and-replay can be implemented at the HTTP layer, keyed by URL and the presence/absence of the X-API-Key header. Avoid brittle field assertions for hazard-specific sub-objects; prefer presence checks and type assertions.

What not to do

Python example for operational use

This Python snippet calls the same Cyclone Disruptions endpoint, validates the envelope, and surfaces fields you can safely rely on across endpoints. Adapt the inner parsing once you’ve inspected the keys present in data for cyclone-specific attributes.

import os
import sys
import json
import urllib.request

def get_cyclone_disruptions_uslax(api_key=None):
url = "https://freightpulsehq.com/api/v1/disruptions?port=USLAX&type=cyclone"
req = urllib.request.Request(url)
if api_key:
req.add_header("X-API-Key", "YOUR_API_KEY")
try:
with urllib.request.urlopen(req, timeout=20) as resp:
body = resp.read()
data = json.loads(body.decode("utf-8"))
except Exception as e:
raise RuntimeError(f"Request failed: {e}")

if not isinstance(data, dict) or data.get("success") is not True or not isinstance(data.get("data"), dict):
raise ValueError("Unexpected response envelope")

d = data["data"]
ts = d.get("timestamp") # ISO-8601 with timezone
src = d.get("source") # Agency/source descriptor
req_id = (data.get("meta") or {}).get("request_id")

# Inspect the keys actually present for cyclone-specific handling
top_level_keys = list(d.keys())

return {
"timestamp": ts,
"source": src,
"request_id": req_id,
"top_level_keys": top_level_keys,
"raw": data
}

if __name__ == "__main__":
api_key = os.environ.get("FREIGHTPULSE_API_KEY")
try:
out = get_cyclone_disruptions_uslax(api_key=api_key)
print("Timestamp:", out["timestamp"])
print("Source:", out["source"])
print("Request ID:", out["request_id"])
print("Top-level data keys:", out["top_level_keys"])
except Exception as e:
print("Error:", e, file=sys.stderr)
sys.exit(1)

Practical integration details that save time

Where to go next

Move from guest access to a registered key once you’re satisfied with your prototype. The Cyclone Disruptions lookup, combined with clearly labeled lagged congestion context, gives you a weather-aware operational picture you can automate in routing and risk models.

FAQ

Can I call the Cyclone Disruptions endpoint without an API key?
Yes. Guest access allows 100 requests/day per IP without a key. Add X-API-Key: YOUR_API_KEY when you’re ready for higher limits and production use.

Are congestion metrics live?
No. FreightPulse congestion is lagged by about 6–7 days and presented as a 7-day average versus a 90-day baseline from IMF PortWatch. It is not live AIS wait time.

Which hazards are included?
Natural weather hazards only, sourced from GDACS/USGS/NOAA. This post focuses on cyclone disruptions. Non-weather events like strikes or canal constraints are out of scope.

Can I quote a current freight rate from this API?
No. Do not quote a freight-rates USD fare as today’s price; that is unrelated to the Cyclone Disruptions lookup.

How should I parse the response?
Start by validating the envelope: success must be true and data an object. Use data.timestamp for freshness and data.source for attribution. Inspect keys within data for cyclone-specific fields at runtime.

Ready to move beyond guest access and put weather-aware disruption detection into production? Create your account on FreightPulse and get your key here: Register. For parameter details and endpoint behavior, see the Documentation.