You need a reliable way to programmatically check current congestion conditions for Tianjin Xin Gang (Tianjin) and turn that signal into transportation decisions. By the end of this guide, you will be able to call the FreightPulse port congestion API for Tianjin from Python, parse the response, and safely integrate the metrics into planning pipelines without mixing it up with live AIS wait-time data.
Origin catalog facts you must implement exactly
Keep these integration constraints in your code and runbooks:
- 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.
- Do not quote a freight-rates USD fare as today’s price.
- Port: Tianjin Xin Gang (Tianjin)
- curl: curl -H "X-API-Key: YOUR_API_KEY" "https://freightpulsehq.com/api/v1/port-congestion?port=Tianjin"
- No official congestion JSON is published for Tianjin. Show the curl and field names (congestion, ratio_vs_baseline, as_of). Do not reuse the USLAX 0.85 fixture.
For complete parameter notes and changelog, see the Documentation.
What this endpoint returns (and what it does not)
The GET /api/v1/port-congestion?port= endpoint returns an object wrapped in {"success": true, "data": {...}}. Inside data, you will consume fields that describe congestion at the specified port based on IMF PortWatch methodology. The data are lagged approximately 6–7 days and refreshed daily; they are not live AIS vessel wait/anchorage times.
Key fields you will read for Tianjin:
- congestion: a categorical level (for example, low, moderate, high) derived from recent activity vs baseline.
- metrics.ratio_vs_baseline: numeric ratio of recent average port calls to a 90‑day baseline (7‑day average vs 90‑day baseline).
- as_of: date string (YYYY-MM-DD) indicating the reference day for the computed metrics.
Units and interpretations:
- recent_avg_portcalls_per_day and baseline_avg_portcalls_per_day: port calls/day.
- ratio_vs_baseline: unitless. Values below 1.0 suggest activity below baseline; above 1.0 suggests above-baseline throughput.
- as_of: date-only; treat as a daily snapshot, not a timestamp.
Authentication, headers, and request budget
Authenticate requests with an X-API-Key header. Use YOUR_API_KEY in development; never hardcode a real key in client-side code. Without a key, you are treated as a guest and limited to 100 requests per day per IP, so implement basic caching and avoid tight polling loops.
- Header: X-API-Key: YOUR_API_KEY
- Method: GET
- Endpoint: https://freightpulsehq.com/api/v1/port-congestion
- Required parameter: port=Tianjin
If you need a key or a sandbox, create an account here: Register.
Make your first request for Tianjin
Use curl to verify your environment and headers. This is copy-paste ready and targets Tianjin:
curl -H "X-API-Key: YOUR_API_KEY" "https://freightpulsehq.com/api/v1/port-congestion?port=Tianjin"
Below is the official example JSON for Tianjin. Do not alter field names or values when testing your parser:
{
"success": true,
"data": {
"results": [
{
"port": "Tianjin Xin Gang",
"locode": null,
"country": "China",
"congestion": "moderate",
"as_of": "2026-10-09",
"metrics": {
"recent_avg_portcalls_per_day": 26.9,
"baseline_avg_portcalls_per_day": 29.6,
"ratio_vs_baseline": 0.91
}
}
],
"global_summary": {
"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": "~6-7 (daily updates, not real-time)",
"methodology": "congestion level is an approximation: last 7 days' avg port calls vs 90-day baseline for the same port. Does not measure vessel wait/anchorage time."
}
},
"meta": {
"request_id": "dfb29463-f730-4dee-94ba-e9a2ecd0f0b2"
}
}
Fields you will actually use in most transportation workflows:
- data.results[0].congestion: a categorical level for Tianjin Xin Gang.
- data.results[0].metrics.ratio_vs_baseline: numerical ratio for quick thresholding in code.
- data.results[0].as_of: the day the ratio and congestion label refer to.
Python: fetch, validate, and interpret Tianjin congestion
This Python example calls the same endpoint, validates the standard envelope, and reads congestion, ratio_vs_baseline, and as_of. It also demonstrates simple caching hints and safe defaults when fields are missing.
import os
import time
import requests
API_URL = "https://freightpulsehq.com/api/v1/port-congestion"
PORT = "Tianjin"
API_KEY = os.getenv("FREIGHTPULSE_API_KEY", "YOUR_API_KEY")
HEADERS = {
"X-API-Key": API_KEY,
"Accept": "application/json",
"User-Agent": "tianjin-congestion-checker/1.0"
}
def get_tianjin_congestion(session: requests.Session) -> dict:
resp = session.get(API_URL, params={"port": PORT}, headers=HEADERS, timeout=20)
resp.raise_for_status()
payload = resp.json()
if not isinstance(payload, dict) or not payload.get("success"):
raise ValueError("API did not return success=true; payload=%r" % payload)
data = payload.get("data") or {}
results = data.get("results") or []
if not results:
raise LookupError("No results returned for port=%s" % PORT)
rec = results[0]
congestion = rec.get("congestion")
as_of = rec.get("as_of")
metrics = rec.get("metrics") or {}
ratio_vs_baseline = metrics.get("ratio_vs_baseline")
# Minimal validation
if congestion is None or ratio_vs_baseline is None or as_of is None:
raise KeyError("Missing one of required fields: congestion, ratio_vs_baseline, as_of")
return {
"port": rec.get("port"),
"country": rec.get("country"),
"congestion": congestion,
"ratio_vs_baseline": ratio_vs_baseline,
"as_of": as_of,
"recent_avg_portcalls_per_day": metrics.get("recent_avg_portcalls_per_day"),
"baseline_avg_portcalls_per_day": metrics.get("baseline_avg_portcalls_per_day"),
}
def main():
# Basic in-memory cache with a TTL suitable for daily-updated data.
cache = {}
cache_ttl_seconds = 6 * 60 * 60 # 6 hours
key = f"{PORT}"
now = time.time()
if key in cache and now - cache[key]["t"] < cache_ttl_seconds:
result = cache[key]["v"]
else:
with requests.Session() as s:
result = get_tianjin_congestion(s)
cache[key] = {"t": now, "v": result}
print("Tianjin Xin Gang congestion:")
print(f" Level: {result['congestion']}")
print(f" Ratio vs 90-day baseline: {result['ratio_vs_baseline']}")
print(f" As of date: {result['as_of']}")
print(f" Recent avg port calls/day: {result['recent_avg_portcalls_per_day']}")
print(f" Baseline avg port calls/day: {result['baseline_avg_portcalls_per_day']}")
if __name__ == "__main__":
main()
Interpreting Tianjin’s congestion safely in transport planning
Because FreightPulse’s congestion uses IMF PortWatch methodology, the signal is a throughput proxy—not a direct wait-time metric. Use ratio_vs_baseline and the congestion label for directional decisions like routing flexibility, container allocation, or ETD allowances.
- Thresholding: if ratio_vs_baseline is substantially below 1.0, treat Tianjin as operating below its 90‑day throughput baseline, which may reflect congestion or other anomalies; use the categorical congestion field to avoid over-interpreting small ratio moves.
- Units: port calls/day is a count-based flow measure; it abstracts away vessel size and doesn’t measure queue durations.
- Lag and refresh: values are lagged approximately 6–7 days and updated daily. Plan at daily cadence; avoid hour-level automation assumptions.
- Caching: daily or multi-hour caching is appropriate; the underlying stats won’t change intraday at sub-hour resolution.
- Do not treat this as live AIS: it does not represent real-time anchorage or berth wait times.
Robustness: validation, fallbacks, and guardrails
Handle the envelope and fields defensively. Always check success is true before reading data. Expect optional fields like locode to be null. If results is empty for a valid request, treat that as a soft failure and retry later rather than substituting data from a different port.
- Network timeouts: set a client timeout (for example, 20 seconds) and implement a small retry with exponential backoff. Avoid aggressive loops to respect guest limits.
- Date handling: as_of is date-only (YYYY-MM-DD). Store as a date string or normalize to your warehouse date type without adding a timezone offset.
- Version drift: pin any parsing logic to the documented fields and avoid relying on undocumented attributes. Re-check the Documentation for schema notes if your parser starts failing.
Operational guidance for transportation teams
Integrate Tianjin’s congestion feed into your job scheduler or TMS as a daily step. Because the metric is relative to a 90-day baseline, you can maintain a simple rule engine per port: alert when ratio_vs_baseline crosses preset thresholds, and persist the last as_of to avoid duplicate alerts on the same daily print.
- Alerting: suppress duplicate notifications for the same as_of value; refresh after the daily data cutover.
- Downstream controls: tag bookings or routings touching Tianjin for review if congestion is moderate or higher while ratio_vs_baseline < 1.0.
- Comparability: use the ratio for cross-port comparisons; raw port calls/day are port-specific.
Testing notes specific to Tianjin
When writing tests, do not reuse fixture values from other ports. For Tianjin Xin Gang, test your code against the field names shown above (congestion, ratio_vs_baseline, as_of) and the documented envelope. Avoid asserting on transient numbers beyond basic type checks unless you’re snapshotting responses in a recorded test suite.
- Schema tests: assert that success is boolean and data.results[0] contains congestion (string), as_of (YYYY‑MM‑DD string), and metrics.ratio_vs_baseline (number).
- Nullability: accept null for optional fields like locode.
- Idempotency: repeated GETs with the same port within a day should yield the same as_of until the next daily refresh.
FAQ
Is this a real-time AIS wait-time feed for Tianjin Xin Gang?
No. FreightPulse congestion is derived from IMF PortWatch and is lagged roughly 6–7 days. It compares the last 7 days’ average port calls to a 90‑day baseline and does not measure berth or anchorage waiting times.
What authentication is required, and what are the guest limits?
Send X-API-Key: YOUR_API_KEY. If you do not provide a key, you are treated as a guest with 100 requests per day per IP. Use caching and avoid tight polling.
Which fields should I persist for dashboards?
Store congestion, metrics.ratio_vs_baseline, as_of, and optionally recent_avg_portcalls_per_day and baseline_avg_portcalls_per_day. These are sufficient for alerting and time-series tracking.
How should I treat the as_of date?
It’s a date-only string (YYYY‑MM‑DD) representing the reference day for the calculated averages. Use a daily pipeline; do not assume intraday updates.
Can I quote spot freight rates based on this response?
No. Do not quote a freight-rates USD fare as today’s price based on this congestion data. The endpoint provides throughput signals, not pricing.
Ready to integrate Tianjin congestion into your transportation stack? Create your API key and start building today: Register. For endpoint details, field references, and changelog, see the Documentation.