From 539a0e64d731f3d2b743425fb69d0420e3830b67 Mon Sep 17 00:00:00 2001
From: "mintlify[bot]" <109931778+mintlify[bot]@users.noreply.github.com>
Date: Mon, 20 Jul 2026 15:09:37 +0000
Subject: [PATCH] docs: add July 20, 2026 changelog entry
---
docs/updates/home.mdx | 76 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 76 insertions(+)
diff --git a/docs/updates/home.mdx b/docs/updates/home.mdx
index f032e930..5c362a28 100644
--- a/docs/updates/home.mdx
+++ b/docs/updates/home.mdx
@@ -10,6 +10,82 @@ rss: true
This page contains updates to **Terminal49 API** and **DataSync** only (not general product updates).
+
+ ### New terminal integrations
+
+ Five more terminals join Terminal49's live tracker coverage:
+
+ - **BEST Barcelona (ESBCN)** — Hutchison's BEST terminal in the Port of Barcelona via the shared Hutchison `ubi` mobile JSON API, with a BEST-specific status map (Loaded On Vessel, In Yard, Gate Out) verified across the full lifecycle
+ - **Basra Gateway Terminal (IQUQR)** — ICTSI's Umm Qasr terminal via the BGT CLICK Container Lifetime lookup; covers both BGT West and BGT East
+ - **Chittagong Port Authority (BDCGP)** — one integration covers all four Chittagong container terminals (NCT, CCT, PCT, GCB) via the public CTMS portal, with per-record firms-code attribution and an empty-return event so gated-out boxes advance to `empty_returned`
+ - **Gdynia BCT (PLGDY)** — Baltic Container Terminal Gdynia via ICTSI's e-Brama portal, with seal numbers and gross/cargo weights surfaced and hardened against the portal's periodic slow-response episodes
+ - **Contecon Guayaquil (ECGYE)** — ICTSI's Guayaquil container terminal
+
+
+ View the container resource
+
+
+ ---
+
+ ### New BNSF RailPASS mobile rail tracker
+
+ Added a new **BNSF RailPASS** rail tracker that hits the BNSF mobile app path for container status. It runs alongside the existing BNSF integration to give rail shipments more redundancy against upstream outages.
+
+ ---
+
+ ### Drag-to-reorder columns on container dashboards
+
+ Container column order is now **drag-and-drop**. A grip appears on hover over any non-sticky column header in the **Containers** and **Containers at Risk** dashboards — drag it onto another header to move the column, with a blue edge indicator showing where the drop will land. Sticky columns (like container number) stay pinned on the leading edge. Column order is persisted per view, so your layout is preserved across sessions.
+
+ ---
+
+ ### Per-container custom fields
+
+ Custom fields of type **Cargo** can now target a **specific container** on a shipment instead of always broadcasting to every container. You can also attach **initial custom field values** at tracking-request creation time — values are staged on the tracking request and applied to the shipment and containers as soon as they exist.
+
+ ---
+
+ ### Account-level custom field limits
+
+ Custom field access is no longer gated by feature flags. Every account now has a `custom_field_limit` **entitlement** enforced at value-creation time, exposed on the account API, and overridable per account by admins. The custom field UI is always visible; the limit governs how many active field values you can attach.
+
+ ---
+
+ ### Updates
+
+ - **SSL release status enrichment** — steamship line release statuses are now enriched with additional detail, so line-release progress is more actionable on the container view
+ - **Terminal-released holds visible without polluting legacy holds** — holds cleared at the terminal are now surfaced through the new hold model without appearing in the legacy holds UI, so older integrations keep their current view while the new hold surface gains coverage
+ - **Containers at Risk dashboard on the shared table** — the at-risk dashboard now renders through the same `Container::View` component as the main Containers dashboards, picking up shared filters, column resizing, drag-to-reorder, and consistent defaults
+ - **Container row lifecycle actions refined** — inline container actions on the shipment page have been reorganized by lifecycle state, with appointment editors gated by the current lifecycle stage and container weight now editable from the shipment index
+ - **HIT Cplus transhipment mapping** — Hong Kong HIT Cplus records for inbound transhipment (`Transhipment Laden` + `Inbound On-board` → **On Ship**, + `On Dock`/`At pier` → **Grounded**) now map correctly instead of storing a blank status
+ - **HHLA Hamburg retries** — a transient connection drop or 5xx on HHLA's COAST API now retries once per container lookup instead of failing the whole batch's scrape log
+ - **Port Houston enrichments** — the Port Houston EVP tracker now surfaces **seal numbers** and picks up multi-mode holds and reefer LFD / paid-thru dates
+ - **Removed V1 shipment refresh endpoints** — the V1 shipment-level manual refresh actions (`refresh_containers`, `refresh_shipment`, `refresh_rail`) have been retired now that container-level refresh via the V2 API (`POST /v2/containers/refresh`) supersedes them
+ - **Retired V1 UI models** — roughly 20 unused V1 Ember Data models and their adapters have been removed; public API consumers should already be on V2
+
+ ---
+
+ ### Bug fixes
+
+ - **HIT Cplus terminal re-attribution at gate-out** — at pickup the Cplus feed rewrites the terminal to `HIT4` regardless of which Kwai Tsing yard actually held the box, moving non-HIT pickups to `HKHKGHITHK` and emitting a spurious `pod_terminal_changed` event. The parser now defers the firms code on HIT-named gate-out records so the pickup stays on the terminal that held the container
+ - **MAEU Access Denied classification** — Maersk (`MAEU`) Access Denied responses are now classified as a distinct error instead of being reported as unknown failures
+ - **Trailer Bridge tracking** — Trailer Bridge (`TRBR`) reference numbers are now classified as booking numbers, so TRBR bookings track correctly
+ - **Re-tracking a bill of lading after stopping** — you can now re-submit a tracking request for a BL after previously stopping tracking, instead of being blocked by the prior request
+ - **ONEY container-less bookings** — Ocean Network Express bookings with no containers no longer emit spurious COP events
+ - **ContainerHold reconciliation** — the hold reconciler no longer fabricates cleared-hold records when the terminal returns a blank holds field; existing holds are preserved when the field is missing rather than empty
+ - **Termont scraper** — a WordPress scraper contract change was corrected, and blank `status_info.section` payloads now fall back quietly to the terminal's firms code instead of raising Sentry noise
+ - **GCT Canada holds** — bare `INTACT EXAM` and `HOLD` tokens are now mapped correctly, and customs/freight holds are preserved when the Holds field is blank (only a literal `null` clears them)
+ - **APM otherHolds Integer** — APM Terminals occasionally returns `otherHolds` as an Integer; the parser now coerces to string before splitting so scrapes no longer fail, and `0`/`"0"` is treated as no other holds
+ - **eModal unit statuses** — the `UV`, `UR`, `I`, `O`, and bare in-yard `Y` unit status codes are now mapped to the correct availability instead of falling through to unknown-status Sentry noise
+ - **POV HREW hold** — Port of Virginia `HREW NON-EXAM HOLD` and `shipmentAction I` (gate-in) records are now mapped instead of reporting as unknown status
+ - **MRTML LFD parsing** — Manzanillo International Terminal LFD values with trailing punctuation and month-name formats now parse correctly (unparseable values return `nil` instead of raising)
+ - **wheresmycontainer timestamps** — variable-precision fractional-second timestamps with timezone offsets now parse, and `Inbound by Rail` maps to a status
+ - **Trapacweb Capsolver responses** — non-JSON Capsolver bodies are normalized before dig, so scrapes surface a proper `CaptchaError` instead of a `NoMethodError`
+ - **Goport blank rows** — empty portal data payloads are now treated as scrape failures instead of raising, so cargos are not incorrectly marked inactive
+ - **ScrapeTerminalJob sparse results** — sparse scraper results no longer raise on `nil.merge`, and cargos omitted from a scrape run are no longer deactivated
+
+
+
### New international terminal integrations