Home → Blog

Detention and demurrage costs are the silent margin killers for freight forwarders and 3PLs. A single container sitting at the terminal for an extra day because of a missed free-time window, a weather delay, or a carrier handoff issue can wipe out profitability on an entire lane. Multiply that across dozens of shipments per week and you get a material hit to gross margin and cash flow—plus frustrated customers and strained operations teams.

Most teams try to reduce these costs with a patchwork of siloed data feeds and spreadsheets: AIS tools for port activity, separate dashboards for weather or earthquakes, fuel price emails from the EIA, spreadsheets for fuel surcharge ramps, one-off freight quotes for alternative routings, and browser tabs for FMCSA/FMC carrier vetting. The result is operational latency—your teams are always a step behind what the network is doing. The path to predictable detention and demurrage isn’t more dashboards; it’s a single, programmable data plane that your TMS, shipment tracker, or exception-management workflow can call in real time.

This post shows how to use FreightPulse—one REST API for real-time logistics intelligence—to predict and reduce detention and demurrage. We will connect the dots between lagged-but-actionable port congestion signals, natural-disruption alerts, live US FTL quotes, EIA fuel prices, and carrier verification. You will learn how to assemble a practical risk score for each shipment, trigger preemptive actions (expedite drayage, extend free time, resequence pickups), and verify last-mile motor carriers—all in code, without stitching five different integrations together.

Introduction

Detention and demurrage charges are, at their core, a problem of uncertainty and timing. Containers or trucks arrive later than planned, appointments slip, yard capacity tightens, and trade-lane conditions change mid-transit. Operators face three specific challenges:

With FreightPulse, you can eliminate those integration hurdles. One API delivers EIA fuel prices for surcharge logic, live US FTL quotes for alternative routings, IMF PortWatch-based congestion signals for ~20 major ports, FMCSA/FMC carrier lookups for compliance checks, and natural-disruption alerts you can filter by port radius. The goal is straightforward: give developers and operators an immediate path to production-grade, data-driven detention and demurrage mitigation—without integration debt.

Why FreightPulse

There are many sources for the individual signals you need, but the practical differentiator for developers and operators is consolidation, consistency, and timeliness of action. Here are four reasons teams use FreightPulse to drive down detention and demurrage:

Quick Start

Base URL for all endpoints:

https://freightpulsehq.com/api/v1

Each response follows a consistent shape: {"success": true|false, "data": {...}, "error": "..."} where error only appears if success is false. For example, here’s your first request to check the latest national and regional EIA fuel prices. This matters because your detention/demurrage exposure is often correlated with over-the-road costs for recovery options (e.g., re-routing to an inland CY or expediting a truck).

curl "https://freightpulsehq.com/api/v1/fuel-prices"

Sample JSON response:

{
"success": true,
"data": {
"timestamp": "2026-07-30T12:00:00Z",
"source": "EIA (U.S. Energy Information Administration)",
"currency": "USD",
"unit": "gallon",
"data": {
"diesel": {
"national_average": 3.847,
"change_week": -0.023,
"change_percent": -0.6,
"regions": {
"east_coast": 3.912,
"midwest": 3.756,
"gulf_coast": 3.623,
"rocky_mountain": 3.891,
"west_coast": 4.456,
"california": 4.892
},
"historical": {
"30d_avg": 3.82,
"90d_avg": 3.75,
"yoy_change_percent": -8.2
}
},
"gasoline": {
"national_average": 3.156,
"historical": {
"30d_avg": 3.1,
"90d_avg": 3.05,
"yoy_change_percent": 1.1
}
}
}
}
}

Key fields:

Core Endpoints

1) Port Congestion: GET /port-congestion

Purpose: Estimate how strained a port is relative to its 90-day history. This is an approximation derived from IMF PortWatch (AIS-based) with a ~6–7 day lag, captured as a 7-day average of port calls vs a 90-day baseline. It is not live vessel wait times, but it is actionable for planning buffers, choosing discharge ports, or sequencing pickups to avoid demurrage at terminals that are trending tight.

Key parameters:

curl "https://freightpulsehq.com/api/v1/port-congestion?port=USLAX"

Sample JSON response:

{
"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 use it:

Implementation tips:

2) Natural Disruptions Near Ports: GET /disruptions

Purpose: Flag cyclones, earthquakes, floods, severe weather, and similar hazards from GDACS, USGS, and NOAA/NWS. Filter by a port to capture events within 300km (100km for US weather), which is critical for preemptive exception management: reschedule drayage, move containers to alternate terminals, or secure yard space to buy time before free time runs out.

Key parameters:

curl "https://freightpulsehq.com/api/v1/disruptions?port=USLAX&severity=high"

Sample JSON response:

{
"success": true,
"data": {
"results": [
{
"id": "gdacs:TC:1001305",
"type": "cyclone",
"severity": "moderate",
"title": "Tropical Cyclone SAUDEL-26",
"country": "Japan",
"starts_at": "2026-08-18T12:00:00+00:00",
"source": "GDACS"
}
]
}
}

How to use it:

Implementation tips:

3) Live US FTL Freight Quotes: GET /freight-rates

Purpose: When a terminal is trending tight or a disruption is imminent, your fastest path to avoiding demurrage may be a proactive truck move: pre-pull to a yard, divert to another ramp, or reposition to a DC. This endpoint gives you live US FTL truckload quotes (via Warp) in the same schema as everything else, so you can embed “what-if” routing in your exception workflows.

Key parameters (trucking mode):

curl "https://freightpulsehq.com/api/v1/freight-rates?mode=trucking&origin_zip=90058&destination_zip=85281&pickup_date=2026-08-24&total_weight_lb=32000"

Sample JSON response:

{
"success": true,
"data": {
"mode": "trucking",
"service": "FTL (53' dry van)",
"source": "Warp",
"price_usd": 7207.92,
"transit_days": 4,
"pickup_date": "2026-08-24",
"delivery_date": "2026-08-28"
}
}

How to use it:

Implementation tips:

4) Fuel Prices for Surcharges and Scenario Planning: GET /fuel-prices and GET /historical

Purpose: Your drayage or FTL recovery cost often hinges on fuel surcharges. Use current and historical diesel benchmarks to normalize quotes, simulate different pickup windows, and communicate cost tradeoffs to customers deciding whether to pre-pull.

No parameters are required for GET /fuel-prices. For historical series, use GET /historical with metric=fuel_price_diesel_national and a period.

curl "https://freightpulsehq.com/api/v1/historical?metric=fuel_price_diesel_national&period=90d"

Sample JSON response:

{
"success": true,
"data": {
"metric": "fuel_price_diesel_national",
"period": "90d",
"series": [
{
"date": "2026-07-27",
"value": 5.257
},
{
"date": "2026-08-03",
"value": 5.343
}
]
}
}

How to use it:

5) Carrier Verification: GET /carriers

Purpose: Avoid secondary detention by ensuring your handoff carrier is compliant and adequately staffed. Look up US trucking carriers via FMCSA SAFER or ocean NVOCC/OTI via FMC. This prevents last-minute surprises (inactive status, insufficient drivers at location) that can cause missed gates and extra days at port.

Key parameters:

curl "https://freightpulsehq.com/api/v1/carriers?q=54283"

Sample JSON response:

{
"success": true,
"data": {
"type": "trucking",
"query": "54283",
"results": [
{
"dot_number": 54283,
"legal_name": "SWIFT TRANSPORTATION COMPANY OF ARIZONA LLC",
"status": "active",
"safety_rating": "S",
"drivers": 12883,
"address": {
"city": "Phoenix",
"state": "AZ",
"country": "US"
}
}
]
}
}

How to use it:

6) Port and Fuel Time Series: GET /historical (port_congestion:<portid>)

Purpose: Shipments that arrive during trend inflection points are most at risk. Plot daily port congestion series for curated major ports (e.g., Shanghai, Singapore, Rotterdam, Los Angeles-Long Beach) to detect tightening conditions ahead of schedule finalization. Pair with fuel series to run multi-factor risk forecasts.

Example:

curl "https://freightpulsehq.com/api/v1/historical?metric=port_congestion:USLAX&period=1y"

Interpretation:

End-to-End Implementation Patterns

The fastest way to production is to compute a “Demurrage Risk Score” per shipment, update it on a schedule, and wire it to action rules. Below are language-agnostic ideas and code snippets to accelerate your build.

Risk Scoring Logic

Example: JavaScript (Node.js) polling and scoring

import fetch from "node-fetch";

const BASE = "https://freightpulsehq.com/api/v1";

async function getPortCongestion(locode) {
const res = await fetch(`${BASE}/port-congestion?port=${encodeURIComponent(locode)}`);
const json = await res.json();
if (!json.success) throw new Error(json.error || "port-congestion error");
const entry = (json.data.results || [])[0];
return entry || null;
}

async function getDisruptionsForPort(locode, severity = "moderate") {
const res = await fetch(`${BASE}/disruptions?port=${encodeURIComponent(locode)}&severity=${severity}`);
const json = await res.json();
if (!json.success) throw new Error(json.error || "disruptions error");
return json.data.results || [];
}

async function getFuelPrices() {
const res = await fetch(`${BASE}/fuel-prices`);
const json = await res.json();
if (!json.success) throw new Error(json.error || "fuel-prices error");
return json.data.data.diesel;
}

function scoreRisk({ congestion, ratio }, disruptions, diesel) {
let score = 0;
if (congestion === "moderate") score += 1;
if (congestion === "high") score += 2;
if (ratio >= 1.0) score += 1;
const hasHigh = disruptions.some(d => d.severity === "high");
const hasModerate = disruptions.some(d => d.severity === "moderate");
if (hasHigh) score += 2;
else if (hasModerate) score += 1;

const risingFuel = (diesel.national_average - diesel.historical["30d_avg"]) / diesel.historical["30d_avg"];
if (risingFuel >= 0.05) score += 1;
return score;
}

async function main() {
const port = "USLAX";
const pc = await getPortCongestion(port);
const dis = await getDisruptionsForPort(port, "moderate");
const diesel = await getFuelPrices();

const metrics = {
congestion: pc?.congestion || "low",
ratio: pc?.metrics?.ratio_vs_baseline || 0.9
};

const risk = scoreRisk(metrics, dis, diesel);
console.log({ port, risk, metrics, disruptions: dis.length, dieselAvg: diesel.national_average });

if (risk >= 3) {
// trigger internal workflow: request quotes, notify ops, pre-book drayage, or extend free time
}
}

main().catch(console.error);

Example: Python fallback probing for alternate routings

import requests
from datetime import date, timedelta

BASE = "https://freightpulsehq.com/api/v1"

def get_quote(origin_zip, dest_zip, pickup_date=None, weight_lb=None):
params = {
"mode": "trucking",
"origin_zip": origin_zip,
"destination_zip": dest_zip
}
if pickup_date:
params["pickup_date"] = pickup_date
if weight_lb:
params["total_weight_lb"] = weight_lb

r = requests.get(f"{BASE}/freight-rates", params=params, timeout=20)
j = r.json()
if not j.get("success"):
raise RuntimeError(j.get("error", "freight-rates error"))
return j["data"]

def best_alternate(origin_zip, candidates, weight_lb=30000):
best = None
for dz in candidates:
try:
data = get_quote(origin_zip, dz, pickup_date=str(date.today() + timedelta(days=1)), weight_lb=weight_lb)
if best is None or data["price_usd"] < best["price_usd"]:
best = data
except Exception:
continue
return best

if __name__ == "__main__":
alternates = ["85281", "75201", "80216"] # candidate inland ramps or DC zips
quote = best_alternate("90058", alternates)
print("Best alternate:", quote)

Real-World Use Cases

1) Automated Demurrage Risk Watchlist

For every import with an ETA in the next 14 days, poll GET /port-congestion for the discharge port and GET /disruptions filtered by that port. Compute a daily risk score that combines congestion category, ratio_vs_baseline, and any moderate/high hazards within the window. If the score crosses your threshold, trigger GET /freight-rates to price a pre-pull to a nearby yard or a re-route to a less constrained ramp. Endpoints: /port-congestion, /disruptions, /freight-rates, /historical (optional for trends).

2) Fuel-Aware Pre-Pull Decisioning

When fuel is rising rapidly, waiting an extra day to pull a container can add both demurrage and higher drayage costs. Use GET /fuel-prices and GET /historical to determine whether diesel is significantly above its 30- or 90-day average. If yes, favor earlier pre-pull. If congestion at the port is moderate/high, immediately fetch a live US FTL quote to relocate the container to a nearby DC before the free-time clock runs out. Endpoints: /fuel-prices, /historical, /port-congestion, /freight-rates.

3) Carrier Handoff Assurance for Drayage and Final-Mile

Missed drayage appointments and noncompliance issues are recurring causes of avoidable detention. Before assigning a carrier, run GET /carriers with type=trucking or type=ocean to verify status, safety rating, and general capacity. If a carrier appears inactive or below your safety threshold, automatically request one or two backup quotes with GET /freight-rates and re-assign. Endpoints: /carriers, /freight-rates.

FAQ

How often do FreightPulse fuel prices update?

Fuel prices in FreightPulse reflect EIA-reported values and include national and regional breakdowns with weekly changes and historical averages. Use the historical series to smooth volatility, and the current national/regional fields to align surcharge policies with live quotes from /freight-rates.

Can I look up ocean carriers as well as trucking carriers?

Yes. GET /carriers supports both trucking (FMCSA SAFER) and ocean NVOCC/OTI lookups (FMC directory). Provide q with the organization number or name and set type=ocean to query ocean entries; for US trucking, you can query by DOT number or legal name with type=trucking.

Does the port congestion data reflect real-time vessel wait times?

No. Port congestion is an approximation derived from IMF PortWatch AIS data with a ~6–7 day lag. It’s a 7-day average of port calls versus a 90-day baseline—ideal for trend-aware planning, buffer policies, and early warning, but not a real-time queue length indicator.

How should I combine disruptions with congestion to predict demurrage?

A practical approach is to compute a composite risk score: assign points for congestion category and ratio_vs_baseline, then add points for any moderate/high disruptions within 300km of your discharge port during the ETA window. If the score exceeds a threshold, fetch recovery truck quotes and start a pre-pull or reroute workflow.

What’s the fastest way to build a dashboard that surfaces at-risk containers?

Start with a daily batch that joins your container ETAs to GET /port-congestion and GET /disruptions by discharge port. Add GET /historical for a 30–90 day context. Rank shipments by risk and embed inline actions: “Get truck quote” using GET /freight-rates and “Verify carrier” using GET /carriers. Because all endpoints share the same JSON envelope, you can build quick front-end cards without special-case parsing.

Error Handling and Reliability Best Practices

Even simple REST calls benefit from defensive patterns to ensure your detention/demurrage workflows are resilient under load and transient failures.

Putting It All Together: A Reference Flow

Here’s a concrete, step-by-step blueprint for a forwarder or 3PL building a production-grade demurrage-reduction engine on top of FreightPulse:

  1. Ingest and normalize your shipments: container ID, discharge port (LOCODE), ETA window, consignee appointment windows, and current free-time allowances.
  2. Daily at 06:00 local time, run:
    • GET /port-congestion for each discharge port in your backlog; store congestion, ratio_vs_baseline, and as_of.
    • GET /disruptions for each discharge port; store active events and severity.
    • GET /fuel-prices; store national_average and 30d_avg.
  3. Compute a Demurrage Risk Score per shipment:
    • Base on congestion category and ratio_vs_baseline.
    • Add disruption penalties as applicable.
    • Adjust for diesel trend if above 30d_avg by a threshold.
  4. For shipments with score ≥ threshold:
    • GET /freight-rates to quote pre-pull or alternate inland ramps; annotate quotes with transit_days and delivery_date to match receiving windows.
    • GET /carriers for your selected drayage provider; auto-block inactive or high-risk carriers.
  5. Surface recommended actions in your TMS: “Pre-pull to DC A by Tuesday,” “Extend free time by 24 hours,” “Divert to ramp Z and truck to consignee by Friday,” with side-by-side cost comparisons.
  6. Close the loop by logging outcomes: when demurrage was avoided, which signals triggered action, and how accurate the risk thresholds were. Iterate monthly on threshold values using /historical to spot new trend dynamics.

Additional End-to-End Examples with Complete Responses

Example A: LA/LB Spike, Fast Pre-Pull to Phoenix DC

1) Check port congestion:

curl "https://freightpulsehq.com/api/v1/port-congestion?port=USLAX"
{
"success": true,
"data": {
"results": [
{
"port": "Los Angeles-Long Beach",
"locode": "US LAX",
"country": "United States",
"congestion": "high",
"as_of": "2026-08-14",
"metrics": {
"recent_avg_portcalls_per_day": 12.3,
"baseline_avg_portcalls_per_day": 10.2,
"ratio_vs_baseline": 1.21
}
}
]
}
}

2) Check disruptions within 300km of USLAX:

curl "https://freightpulsehq.com/api/v1/disruptions?port=USLAX&severity=moderate"
{
"success": true,
"data": {
"results": [
{
"id": "nws:SWX:LA:20260815",
"type": "severe_weather",
"severity": "moderate",
"title": "High Wind Advisory",
"country": "United States",
"starts_at": "2026-08-15T09:00:00+00:00",
"source": "NOAA/NWS"
}
]
}
}

3) Get FTL recovery quotes from LA to Phoenix:

curl "https://freightpulsehq.com/api/v1/freight-rates?mode=trucking&origin_zip=90058&destination_zip=85043&pickup_date=2026-08-15&total_weight_lb=38000"
{
"success": true,
"data": {
"mode": "trucking",
"service": "FTL (53' dry van)",
"source": "Warp",
"price_usd": 2145.40,
"transit_days": 1,
"pickup_date": "2026-08-15",
"delivery_date": "2026-08-16"
}
}

4) Validate drayage carrier:

curl "https://freightpulsehq.com/api/v1/carriers?q=PHOENIX%20DRAY%20LLC&type=trucking"
{
"success": true,
"data": {
"type": "trucking",
"query": "PHOENIX DRAY LLC",
"results": [
{
"dot_number": 1234567,
"legal_name": "PHOENIX DRAY LLC",
"status": "active",
"safety_rating": "S",
"drivers": 112,
"address": {
"city": "Phoenix",
"state": "AZ",
"country": "US"
}
}
]
}
}

Decision: ratio_vs_baseline is 1.21 (elevated), there’s moderate severe weather forecast, and a one-day truck move costs $2,145. If terminal free time is two days but appointment windows are tight, pre-pull to the Phoenix DC avoids demurrage and downstream detention risk.

Example B: Fuel-Aware Tradeoff on a Midwest Lane

1) Current diesel prices:

curl "https://freightpulsehq.com/api/v1/fuel-prices"
{
"success": true,
"data": {
"timestamp": "2026-07-30T12:00:00Z",
"source": "EIA (U.S. Energy Information Administration)",
"currency": "USD",
"unit": "gallon",
"data": {
"diesel": {
"national_average": 3.847,
"change_week": -0.023,
"change_percent": -0.6,
"regions": {
"midwest": 3.756
},
"historical": {
"30d_avg": 3.82,
"90d_avg": 3.75,
"yoy_change_percent": -8.2
}
}
}
}
}

2) Historical diesel series to spot trend:

curl "https://freightpulsehq.com/api/v1/historical?metric=fuel_price_diesel_national&period=30d"
{
"success": true,
"data": {
"metric": "fuel_price_diesel_national",
"period": "30d",
"series": [
{ "date": "2026-07-27", "value": 3.82 },
{ "date": "2026-08-03", "value": 3.84 }
]
}
}

3) If diesel is rising week-over-week and port congestion is moderate, bias toward earlier pre-pull or dispatch to avoid a compound cost of delayed moves and possible demurrage at a tightening terminal.

Example C: Trend-Aware Import Planning from Asia

1) Track port-congestion for destination ports across the West Coast for the next quarter:

curl "https://freightpulsehq.com/api/v1/historical?metric=port_congestion:USLAX&period=1y"

2) If ratio_vs_baseline trends above 1.0 for two weeks and disruptions are forecast near the origin port, model an alternate discharge port and long-haul FTL to the final DC using GET /freight-rates. The combination of lagged-but-predictive congestion and real-time hazard alerts helps your planners build routings that minimize demurrage exposure without overspending on the truck move.

Field-by-Field Guidance and Practical Use

Below is a condensed cheat sheet of key fields across endpoints and how to employ them in detention/demurrage mitigation:

Troubleshooting and Observability

When integrating logistics signals into production order flows, transparency and fault isolation are as important as the data itself.

Security and Governance Considerations

While the operational focus is on reducing demurrage and detention, governance ensures that your automation remains controlled and auditable:

Conclusion + CTA

Detention and demurrage are a timing problem solvable with the right signals, wired to the right actions. With FreightPulse, you replace a tangle of separate logistics integrations with one consistent REST API—fuel prices for surcharge logic, live US truck quotes for recovery routing, disruption alerts near your ports, port-congestion trends for buffer planning, and carrier verification for risk-free handoffs. The outcome is faster exception playbooks and fewer surprises when a ship slips or the terminal gets tight.

For forwarders, 3PLs, supply chain SaaS platforms, and enterprise teams, the winning strategy is to operationalize these signals: score every import daily, pre-approve playbooks when risk crosses thresholds, and log outcomes to tune your policies. You will cut demurrage and detention while giving customers a transparent narrative backed by consistent data.

If you are ready to turn signals into fewer fees and smoother handoffs, integrate now and start building your risk dashboard, alerting rules, and pre-pull workflows. Try FreightPulse for free and ship your first production-ready demurrage mitigation in days, not months.