You need to hit the FreightPulse Freight Rates API for the first time, verify you can retrieve a structured quote, and understand exactly what fields you can rely on—without accidentally treating example values as live prices. By the end of this guide, you will run a working curl request (guest or with a key), parse the JSON envelope in code, and know how to handle port congestion context and caching safely.
What you can do without a key (and when to register)
FreightPulse allows guest access for the freight-rates lookup: up to 100 requests per day per IP with no API key. This is enough to validate connectivity, shape your payloads, and build a low-volume prototype. When you need higher throughput or stable credentials across environments, create an account and use your API key.
When you register, you’ll receive an API key for authenticated requests via the X-API-Key header. Guest and authenticated requests return the same response envelope shape; authentication primarily affects throughput and service level. To obtain a key, use the Register page.
Endpoint, method, and required parameters
This guide covers a single, documented endpoint for freight rate lookup. Stay within these names and fields—do not add or assume parameters that aren’t in the documentation.
- Method: GET
- URL: https://freightpulsehq.com/api/v1/freight-rates
- Auth header (if authenticated): X-API-Key: YOUR_API_KEY
- Guest access: allowed (100 requests/day per IP) without the header
- Query parameters (example lane):
- mode=trucking
- origin_zip=10001
- destination_zip=90210
All responses follow the documented envelope:
{
"success": true,
"data": {
"timestamp": "2026-09-30T16:21:59+00:00",
"source": "EIA (U.S. Energy Information Administration)",
"currency": "USD",
"unit": "gallon",
"data": {
"diesel": {
"national_average": 6.382,
"change_week": -0.147,
"change_percent": -2.25,
"updated_at": "2026-09-28",
"regions": {
"east_coast": 6.137,
"midwest": 6.526,
"gulf_coast": 5.955,
"rocky_mountain": 6.407,
"west_coast": 7.357,
"california": 8.181
}
},
"gasoline": {
"national_average": 4.465,
"change_week": -0.013,
"change_percent": -0.29,
"updated_at": "2026-09-28",
"grades": {
"regular": 4.465,
"midgrade": 5.073,
"premium": 5.482
}
},
"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.291,
"diesel_90d_avg": 5.561,
"diesel_yoy_change": 72,
"gasoline_30d_avg": 4.355,
"gasoline_90d_avg": 4.111,
"gasoline_yoy_change": 42.9
}
},
"meta": {
"request_id": "4a34de71-62bf-4a42-9c3e-f5a7b3a0f792"
}
}
When success is true, expect data to contain the quote details the client needs to display or process a rate. You should always check the success boolean before reading fields.
Run your first request with curl
Option A: Guest (no key, 100 requests/day per IP)
curl -H "X-API-Key: YOUR_API_KEY" "https://freightpulsehq.com/api/v1/fuel-prices"
Guest calls are ideal for smoke tests and local iteration. If you’re on a shared IP (e.g., corporate network), keep in mind the daily cap is counted per IP.
Option B: Authenticated (recommended for production)
Replace YOUR_API_KEY with the key from your account. This header is the only required authentication mechanism as documented.
Understand the JSON response (fields you will actually use)
The official documentation provides a sample response for the lane shown above. This is an example payload, not a live price. Do not display it as today’s fare.
Field notes you will use in code:
- success: Boolean envelope flag. Check before reading data.
- data.mode: Mode returned by the quote (string). Matches your requested mode when available.
- data.service: Service descriptor; useful for UI labels and filtering.
- data.source: The named source of the quote.
- data.price_usd: Price in USD. Do not treat the example value as current.
- data.transit_days: Integer transit estimate in days.
- data.pickup_date / data.delivery_date: Date strings for planning. Review the docs for timezone and business-day handling details before doing SLA math.
Important constraints for production UIs:
- Base currency: USD. If you need multi-currency display, convert externally.
- These are quotes from FreightPulse sources. Do not cache the example payload as if it were your own static price list.
- Never present a docs example as “today’s price.” Always pull fresh.
Practical integration details that save time
- Envelope contract: Always branch on success. If success is false (or missing), treat data as absent and handle errors gracefully.
- Caching: Cache by the full parameter tuple (mode, origin_zip, destination_zip). Add a short TTL at the application layer for UI responsiveness, but refresh on user-triggered re-checks. Since pricing is time-sensitive, don’t store quotes as immutable for long periods.
- Throughput: Guest access is capped at 100 requests/day per IP. Use authenticated calls in CI/CD, servers, and client apps once you move beyond smoke testing.
- Dates and time: pickup_date and delivery_date are date strings. If you compute SLAs or ETAs, confirm timezone/business-day rules in the Documentation.
- Pagination: Not applicable to this single-lane lookup. To evaluate multiple lanes, iterate with separate requests.
- Idempotence and retries: If your network stack retries GETs, ensure you understand the provider’s caching and your own timeout policy to avoid burning through the daily cap.
Port congestion context you should not misinterpret
If you build UIs or logic that mention congestion, keep this distinction explicit: FreightPulse congestion data references IMF PortWatch signals and is lagged roughly 6–7 days. The metric is a 7-day average versus a 90-day baseline. It is not a live AIS wait time feed.
Implications for your product:
- Do not label congestion as “live” or minute-by-minute vessel wait times.
- Use congestion as a planning heuristic, not a hard constraint for same-day dispatch.
- When you display dates, avoid implying congestion-adjusted ETAs are real-time unless you explicitly clarify the lag and aggregation window.
Minimal Python client example (read the fields safely)
This example calls the same endpoint shown above, checks the success envelope, and prints selected fields. Replace YOUR_API_KEY when you move from guest to authenticated usage.
import os
import requests
BASE_URL = "https://freightpulsehq.com/api/v1/freight-rates"
params = {
"mode": "trucking",
"origin_zip": "10001",
"destination_zip": "90210",
}
# Use a header for authenticated requests; omit for guest.
headers = {"X-API-Key": "YOUR_API_KEY"}
# For guest testing, swap to: response = requests.get(BASE_URL, params=params, timeout=15)
response = requests.get(BASE_URL, params=params, headers=headers, timeout=15)
response.raise_for_status()
payload = response.json()
if not isinstance(payload, dict) or not payload.get("success"):
raise SystemExit("Unsuccessful response or invalid envelope")
data = payload.get("data", {})
mode = data.get("mode")
service = data.get("service")
source = data.get("source")
price_usd = data.get("price_usd")
transit_days = data.get("transit_days")
pickup_date = data.get("pickup_date")
delivery_date = data.get("delivery_date")
print("Mode:", mode)
print("Service:", service)
print("Source:", source)
print("Price (USD):", price_usd)
print("Transit (days):", transit_days)
print("Pickup date:", pickup_date)
print("Delivery date:", delivery_date)
Notes:
- timeout: Set a client-side timeout so a transient network issue doesn’t stall your UI.
- Envelope-first parsing: Avoid KeyError by checking success before reading data fields.
- Guest vs key: For guest usage, omit the headers argument entirely.
Validating your pipeline with the docs sample (do not treat as live)
When writing tests, you can hardcode the official documentation’s sample payload to ensure your parser is correct. Remember, these values are not live, and you should never assert on specific prices or dates in production logic.
Recommended test approach:
- Schema-level tests: Validate presence and types of mode, service, source, price_usd, transit_days, pickup_date, delivery_date.
- Presentation: Ensure your currency and date formatters handle USD and date strings consistently.
- Error path: Simulate a payload with success=false and confirm your UI shows a recoverable message instead of crashing.
Operational guidance and pitfalls
- Do not invent a freight rate: Always display or store only what the API returns, and make clear to users that prices can change.
- Cost controls: If you parallelize lane checks, build a small queue with backoff to avoid hitting the guest cap or your own server limits.
- Environment split: Use authenticated calls in server-side contexts (staging, production). For local development, guest mode is sufficient until you need throughput.
- Observability: Log the success boolean, HTTP status, and a hash of query params. Avoid logging full quotes with PII or full payloads if compliance requires minimization.
- User refresh: Provide a “Refresh quote” action and fetch fresh data rather than relying on long-lived caches.
FAQ
Can I call the Freight Rates API without a key?
Yes. Guest access is allowed at up to 100 requests per day per IP. For higher throughput or non-shared limits, register for an API key and send it as X-API-Key.
Is port congestion live?
No. FreightPulse congestion references IMF PortWatch and is lagged approximately 6–7 days. It represents a 7-day average versus a 90-day baseline, not live AIS wait times.
Are the prices in the documentation current?
No. The sample response is for illustration only. Do not quote it as today’s price. Always fetch fresh data from the API.
What fields are guaranteed in a successful response?
Responses follow the envelope {"success":true,"data":{...}}. When success is true, read the documented fields inside data such as mode, service, source, price_usd, transit_days, pickup_date, and delivery_date.
How do I handle errors?
Check the success flag and HTTP status. If success is false or parsing fails, handle gracefully (retry with backoff, show a non-blocking message, or log for review) rather than assuming fields exist.
Ready to move beyond guest mode and ship your integration? Create your key on the Register page, and keep the docs open in a second tab: Documentation.