Home → Blog

Your operations team needs a reliable way to detect volcano-related weather disruptions that could affect cargo flows at key ports. By the end of this guide, you’ll be able to query FreightPulse for “Volcano Disruptions,” integrate the response into a PHP service, and safely handle authentication, envelopes, and downstream parsing without guessing fields or quoting non-weather data as live prices.

What you can and cannot retrieve with the Volcano Disruptions lookup

The “Volcano Disruptions” lookup returns natural-hazard information only. It focuses on events sourced from GDACS, USGS, and NOAA that are relevant to port operations. Do not use it for labor actions, canal restrictions, or other non-weather categories.

Illustration: How to Get Volcano Disruptions

If you need to build beyond the examples here, refer to the official Documentation.

Authentication and request envelope

FreightPulse uses a simple header for authentication. Provide your key exactly as shown below. Without a key, a guest is limited to 100 requests per day per IP. Successful requests return an envelope with top-level "success" and a "data" object you will parse.

Quick test with curl (Volcano Disruptions for USLAX)

Run this from a shell to validate your connectivity and authentication. Replace YOUR_API_KEY with your actual key.

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

Notes:

PHP integration guide for the FreightPulse Volcano Disruptions lookup

This section shows a production-ready PHP pattern that calls the endpoint, validates the response envelope, and makes no assumptions about optional fields that are not documented here.

1) Build a minimal HTTP client with timeouts and headers

Use PHP cURL with explicit timeouts and the X-API-Key header. Keep retries modest and exponential if you add them in your environment.

<?php
declare(strict_types=1);

function fetchVolcanoDisruptions(string $portCode, string $apiKey): array {
$url = 'https://freightpulsehq.com/api/v1/disruptions?port=' . rawurlencode($portCode) . '&type=volcano';

$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_CONNECTTIMEOUT => 5, // seconds
CURLOPT_TIMEOUT => 15, // total seconds
CURLOPT_HTTPHEADER => [
'Accept: application/json',
'X-API-Key: ' . $apiKey,
],
]);

$body = curl_exec($ch);
$errno = curl_errno($ch);
$error = curl_error($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($errno !== 0) {
throw new RuntimeException('Network error calling FreightPulse: ' . $error, $errno);
}
if ($status < 200 || $status >= 300) {
throw new RuntimeException('Unexpected HTTP status from FreightPulse: ' . $status);
}
if ($body === false || $body === '') {
throw new RuntimeException('Empty response from FreightPulse');
}

$json = json_decode($body, true);
if (!is_array($json)) {
throw new RuntimeException('Invalid JSON returned by FreightPulse');
}

// Enforce the documented envelope
if (!array_key_exists('success', $json) || $json['success'] !== true) {
// If success is false or missing, surface a generic error; optionally log the full body
throw new RuntimeException('FreightPulse indicates an unsuccessful request');
}
if (!array_key_exists('data', $json) || !is_array($json['data'])) {
throw new RuntimeException('FreightPulse payload missing data object');
}

return $json['data'];
}

// Example usage:
try {
$data = fetchVolcanoDisruptions('USLAX', 'YOUR_API_KEY');

// At this point, $data contains the disruptions payload.
// Do not assume specific fields unless you have them from the docs.
// Safely probe for keys before accessing them.
if (isset($data['events']) && is_array($data['events'])) {
foreach ($data['events'] as $event) {
// Only read keys if they exist; avoid assuming field names
$id = $event['id'] ?? '(no-id)';
$severity = $event['severity'] ?? '(n/a)';
$reportedAt = $event['reported_at'] ?? '(n/a)';
echo "Event {$id} | Severity: {$severity} | Reported: {$reportedAt}\n";
}
} else {
echo "No events array present; nothing to display.\n";
}
} catch (Throwable $e) {
// Production systems should log details and surface a user-friendly message
error_log($e->getMessage());
echo "Failed to load volcano disruptions.";
}

Recommendations:

JavaScript example: fetch volcano disruptions for USLAX

This snippet uses the same endpoint. It demonstrates basic error handling and reading the envelope without assuming optional fields beyond the documented success/data structure.

async function getVolcanoDisruptions(port, apiKey) {
const url = `https://freightpulsehq.com/api/v1/disruptions?port=${encodeURIComponent(port)}&type=volcano`;
const res = await fetch(url, {
headers: {
'Accept': 'application/json',
'X-API-Key': apiKey
}
});

if (!res.ok) {
throw new Error(`HTTP ${res.status} from FreightPulse`);
}

const payload = await res.json();

if (!payload || payload.success !== true || typeof payload.data !== 'object') {
throw new Error('Invalid FreightPulse envelope');
}

// Handle the data object carefully; do not assume undocumented fields
const data = payload.data;

// If an events array exists, iterate safely
if (Array.isArray(data.events)) {
return data.events.map(evt => ({
id: evt.id ?? null,
severity: evt.severity ?? null,
reported_at: evt.reported_at ?? null
}));
}

// If no events array, return the entire data object for caller-side handling
return data;
}

// Example usage:
getVolcanoDisruptions('USLAX', 'YOUR_API_KEY')
.then(eventsOrData => {
console.log('Volcano disruptions:', eventsOrData);
})
.catch(err => {
console.error('Failed to load volcano disruptions:', err);
});

Official sample response and what to use from it

FreightPulse samples share a consistent success/data envelope. The official blocks below must be copied exactly as-is. While this sample’s inner fields are about fuel prices, you’ll use it to pattern-match the top-level structure and safe parsing for all weather lookups (including volcano disruptions).

{
"success": true,
"data": {
"timestamp": "2026-10-10T00:00:20+00:00",
"source": "EIA (U.S. Energy Information Administration)",
"currency": "USD",
"unit": "gallon",
"data": {
"diesel": {
"national_average": 6.199,
"change_week": -0.183,
"change_percent": -2.87,
"updated_at": "2026-10-05",
"regions": {
"east_coast": 5.951,
"midwest": 6.286,
"gulf_coast": 5.819,
"rocky_mountain": 6.267,
"west_coast": 7.229,
"california": 8.082
}
},
"gasoline": {
"national_average": 4.354,
"change_week": -0.111,
"change_percent": -2.49,
"updated_at": "2026-10-05",
"grades": {
"regular": 4.354,
"midgrade": 4.99,
"premium": 5.4
}
},
"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.349,
"diesel_90d_avg": 5.686,
"diesel_yoy_change": 67,
"gasoline_30d_avg": 4.404,
"gasoline_90d_avg": 4.155,
"gasoline_yoy_change": 39.4
}
},
"meta": {
"request_id": "b089ad89-1827-4363-990a-b66fc2a31258"
}
}

How to apply this to volcano disruptions parsing:

Practical implementation details that save time

End-to-end flow: from request to dashboard

Here is a robust flow that aligns with the envelope and hazard scope:

  1. Build the URL with your target port (e.g., USLAX) and type=volcano
  2. Send the request with X-API-Key and a 10–15 second total timeout
  3. On 2xx, parse JSON; verify success === true and that data is an object
  4. Extract only documented or present fields. If events is provided, loop defensively, checking keys before use
  5. Cache the sanitized result for a short TTL; display UTC timestamps in your UI; include request_id in your logs
  6. On errors or empty results, show a clear “No volcano disruptions detected” message without guessing causes

Testing strategies and edge cases

Security and operational hygiene

FAQ

Q: Can I call the disruptions endpoint without a key?
A: Yes, as a guest you get 100 requests per day per IP. For production, use X-API-Key: YOUR_API_KEY to avoid rate limits and improve reliability.

Q: Are volcano disruptions based on live AIS wait times?
A: No. FreightPulse’s related congestion context is based on IMF PortWatch and is lagged about 6–7 days (7-day average vs 90-day baseline). The volcano disruptions lookup is focused on natural hazards (GDACS/USGS/NOAA), not live AIS.

Q: Can I rely on a fixed field list inside data?
A: Do not assume undocumented fields. Always validate that fields exist before reading them. The only guaranteed structure here is the top-level envelope.

Q: Can I quote a USD freight rate from this API as a current price?
A: No. Do not quote a freight-rates USD fare as today’s price from this weather disruptions endpoint.

Q: What’s the best way to cache results?
A: Use a short TTL (e.g., 1–5 minutes) and key by the exact query (port+type). Normalize timestamps to UTC for consistent cache invalidation.

Ready to integrate the Volcano Disruptions lookup for your ports? Create an account and get your API key here: Register. For endpoint and field references, see the Documentation.