You’re trying to quantify how congested the Port of New York-New Jersey is right now, but the data you can reliably automate is not live AIS wait times. By the end of this guide, you’ll call a single endpoint, read a small set of fields, and interpret a 7‑day average vs a 90‑day baseline for New York-New Jersey using IMF PortWatch–derived data with a known lag.
What the New York-New Jersey congestion metric measures (and what it doesn’t)
The FreightPulse congestion feed for New York-New Jersey (New York) is built on IMF PortWatch. It is not a live vessel wait-time or anchorage-time feed. Instead, it reflects activity based on port calls: the 7-day average port-call volume compared against a 90-day baseline for the same port.
Because IMF PortWatch republishes the daily series in weekly batches, this dataset is lagged. In practice, expect roughly 6–7 days of lag from “today” to the latest available “as_of” date in the feed. This is perfect for trend-aware reporting, planning buffers, and exception alerts, but it is not a live AIS substitute for minute-by-minute queue tracking.
Endpoint, authorization and envelope
The congestion data for New York-New Jersey is retrieved from the FreightPulse API using a single GET request. Authentication is via an API key header. Guests without a key can make up to 100 requests per day per IP.
- Auth: header X-API-Key: YOUR_API_KEY. Guest without key: 100 requests/day per IP.
- Envelope: {"success":true,"data":{...}}
- Port congestion is IMF PortWatch, lagged ~6-7 days, 7-day avg vs 90-day baseline — not live AIS.
There is no separate, “official” congestion JSON feed published by the New York-New Jersey port authority. Use the FreightPulse API for a standardized response with consistent field names: congestion, ratio_vs_baseline, and as_of.
For full reference on status fields and request structure, see the Documentation.
Quick start: cURL and the canonical JSON for New York-New Jersey
Here is a copy-pasteable cURL that targets New York-New Jersey (New York):
curl -H "X-API-Key: YOUR_API_KEY" "https://freightpulsehq.com/api/v1/port-congestion?port=New%20York"
The official response sample below shows exactly how the fields are structured and what you should parse in your integration:
{
"success": true,
"data": {
"results": [
{
"port": "New York-New Jersey",
"locode": null,
"country": "United States",
"activity": "moderate",
"congestion": "moderate",
"as_of": "2026-11-06",
"metrics": {
"recent_avg_portcalls_per_day": 8.9,
"baseline_avg_portcalls_per_day": 9.5,
"ratio_vs_baseline": 0.93
}
}
],
"global_summary": {
"ports_high_activity": 0,
"ports_moderate_activity": 1,
"ports_low_activity": 0,
"ports_high_congestion": 0,
"ports_moderate": 1,
"ports_low": 0
},
"meta": {
"source": "IMF PortWatch (portwatch.imf.org) - UN Global Platform AIS data",
"data_lag_days": "4-11 (PortWatch republishes the daily series once a week; check as_of)",
"methodology": "activity is port-call volume, not congestion: last 7 days' avg calls vs a 90-day baseline for the same port. low means fewer calls than usual, which can be a closure or ships waiting offshore. It does not measure vessel wait or anchorage time. congestion is a deprecated alias of activity."
}
},
"meta": {
"request_id": "f9a988c8-3838-4206-8f12-ebe503d2509b"
}
}
Fields to use in downstream logic:
- congestion: A categorical status (e.g., moderate). This is a deprecated alias for activity, but still populated; either field works for simple labeling.
- metrics.ratio_vs_baseline: The 7-day average divided by the 90-day baseline for this port (unitless). Values below 1.0 mean fewer calls than the 90-day norm; above 1.0 means more calls than usual.
- as_of: The date (YYYY-MM-DD) representing the last complete observation set. Remember: this is not “today” and typically lags by about a week.
- metrics.recent_avg_portcalls_per_day and metrics.baseline_avg_portcalls_per_day: Helpful for dashboards that want the raw activity figures rather than a single ratio.
Interpreting New York-New Jersey congestion safely
Think of ratio_vs_baseline as a context-normalized activity signal for the port. A ratio close to 1.0 means the last week looks typical relative to the most recent 90 days. A materially lower ratio can represent disruptions or deferred arrivals; a higher ratio can reflect demand spikes or operational catch-up. Because this is port-call activity, not queue-time, it can move differently than anchorage wait-time charts.
Use congestion or activity to assign a simple label in dashboards. The textual categories are designed to be readable in operations centers without additional translation. If you need a numeric KPI, use ratio_vs_baseline directly and pick thresholds appropriate for your alerting (for example, trigger at 0.85 or 1.15). Choose thresholds empirically for your workflow; the API does not prescribe them.
Finally, always display the as_of date so stakeholders see the effective timestamp of the data. When communicating “today’s congestion,” be precise: this feed is lagged and summarizes the last 7 days relative to a 90-day baseline.
Production integration in Python
The snippet below fetches New York-New Jersey, extracts as_of, congestion, and ratio_vs_baseline, then prints a compact summary that you can drop into logs or a status widget. It reads the same endpoint shown in the cURL section.
import os
import requests
API_KEY = os.getenv("FREIGHTPULSE_API_KEY", "YOUR_API_KEY")
URL = "https://freightpulsehq.com/api/v1/port-congestion"
PARAMS = {"port": "New York"}
HEADERS = {"X-API-Key": API_KEY}
def fetch_congestion():
r = requests.get(URL, params=PARAMS, headers=HEADERS, timeout=15)
r.raise_for_status()
payload = r.json()
if not payload.get("success"):
raise RuntimeError("API returned success=false")
results = payload.get("data", {}).get("results", [])
if not results:
raise RuntimeError("No results for New York-New Jersey")
record = results[0]
# Read canonical fields
as_of = record.get("as_of")
congestion = record.get("congestion") or record.get("activity")
metrics = record.get("metrics", {})
ratio = metrics.get("ratio_vs_baseline")
recent = metrics.get("recent_avg_portcalls_per_day")
baseline = metrics.get("baseline_avg_portcalls_per_day")
print(f"Port: {record.get('port')} (as_of {as_of})")
print(f"Congestion/activity: {congestion}")
print(f"7-day vs 90-day ratio: {ratio}")
print(f"Recent avg calls/day: {recent}, Baseline avg calls/day: {baseline}")
if __name__ == "__main__":
fetch_congestion()
Notes for reliability:
- Timeouts: The example uses a 15s client timeout. Adjust based on your environment.
- Resilience: Wrap in retries with backoff for transient network errors.
- Keys: Store YOUR_API_KEY in a secure secret manager; the code uses an environment variable as a simple stand-in.
Scheduling, caching and the PortWatch lag
Because IMF PortWatch republishes on a weekly cadence and the field as_of moves in daily increments, you’ll often see a multi-day lag between the current date and the latest as_of value. For New York-New Jersey, this typically presents as ~6–7 days behind the calendar.
Practical tips that will save time:
- Update cadence: Poll once per day. Polling hourly offers little benefit given the weekly republish window.
- Caching: Cache by as_of date and port key. If the as_of date hasn’t advanced, keep serving cached results.
- Backfills: When as_of jumps forward, store historical snapshots keyed by as_of to support trend charts.
- Display clarity: Always render the as_of date next to the label (e.g., “moderate as_of 2026‑11‑06”).
Field behavior and units
All values are dimensionless ratios or daily call counts; there is no currency and no distance unit to convert. The core fields are:
- congestion/activity: Text label for the port-call activity state.
- metrics.ratio_vs_baseline: Unitless multiplier; 1.00 means on par with the 90-day baseline.
- metrics.recent_avg_portcalls_per_day: Calls/day averaged over the latest 7 days.
- metrics.baseline_avg_portcalls_per_day: Calls/day averaged over the latest 90 days.
- as_of: ISO date (YYYY-MM-DD) marking the data’s effective date. Treat it as local-port agnostic; use it as a dataset “version” tag for your cache.
Do not treat any figure in this feed as a live queue length or a vessel wait time. It is an activity lens that correlates with operational changes but is not a direct measure of anchorage duration.
Operational guardrails for New York-New Jersey dashboards
When you build production widgets for New York-New Jersey, prefer stability and traceability over hyper-frequent refreshes:
- Persist each response with its as_of date. You’ll need this for audits and for charting moving averages correctly.
- Label the port unambiguously as “New York-New Jersey (New York)” so analysts don’t confuse it with neighboring hubs.
- Avoid over-interpreting single-week dips. Use at least a few weeks of the ratio_vs_baseline series before triggering heavy operational changes.
Putting it all together for New York-New Jersey
In many logistics stacks, the simplest approach is best: fetch once daily, store the first result for the day, and power three UI components—(1) a categorical badge from congestion or activity, (2) a numeric badge from ratio_vs_baseline, and (3) a footnote with as_of. This gives planners a clean read without suggesting minute-by-minute precision that the dataset doesn’t provide.
If you need to enrich the story with vessel-level context, you can layer in separate AIS sources for live queue visibility, but keep that distinct from the PortWatch-derived congestion metric to avoid mixed semantics in alerts and reports.
FAQ
Is this “live” congestion for New York-New Jersey?
No. It is derived from IMF PortWatch port-call activity with a typical lag of roughly 6–7 days. It is not a live anchorage or berth wait-time metric.
Which fields should I store for alerts?
Store as_of, congestion (or activity), and metrics.ratio_vs_baseline. Include the two average call-rate fields if you graph raw levels.
How often should I call the endpoint?
Daily is sufficient. The source series is republished weekly; more frequent polling rarely changes outcomes.
What happens if I omit the API key?
Guests without a key are limited to 100 requests per day per IP. For production workloads, use an API key via the X-API-Key header.
Can I quote freight rates (USD) from this feed?
No. This endpoint provides activity metrics, not rate quotes. Do not present any freight rate as “today’s price” from this congestion feed.
Ready to ship this integration for New York-New Jersey? Create an account to get an API key and move your code from trial to production: Register. For parameters, response fields, and additional examples, see the Documentation.