Ro-Ro Vessel Near a Port

Ro-Ro Vessel Near a Port

You need to know if a Ro-Ro vessel is near a port, how fast it’s moving, when it will berth, and how that impacts your yard, truck gates, and delivery SLAs. By the end of this guide, you’ll query live AIS for Ro-Ro proximity, inspect active routes and ETAs, surface expected arrivals at a specific port, and roll those insights into a minimal “near a port” decision service using vessels-api.com.

What matters for Ro-Ro near-port intelligence

Ro-Ro operations compress a lot of value into the last nautical mile. To keep gates synchronized with vessel arrivals and dwell time, you generally need:

Illustration: Ro-Ro Vessel Near a Port
  • Fast answers to “is a Ro-Ro inside 10–30 NM of my port?”
  • Live speed/course and navigational status (e.g., at anchor vs. underway)
  • Expected arrivals with ETAs and origins for berth planning
  • Recent port visits to estimate dwell and turnaround patterns
  • ESG/compliance visibility (e.g., IMO CII) for reporting

We’ll leverage four endpoints that cover these needs end to end:

  • GET /vessels/nearby — detect Ro-Ro presence within a port radius
  • GET /vessels/track — read live position, 48–168h history, route, and recent port calls
  • GET /port/expected-arrivals — identify vessels en route to a port with ETA and origin
  • GET /vessels/analytics — aggregated voyage stats useful for dwell and speed baselines

All requests use the same base URL and a single API key in an X-API-Key header. Every response is a consistent JSON envelope: {status, success, message, data}.

Detect a Ro-Ro vessel near your port

Start by scanning a geographic radius around your port’s coordinates. This is the fastest way to answer “who is in range” without knowing an MMSI/IMO up front.

Endpoint

GET /vessels/nearby

  • Required: latitude, longitude
  • Optional: radius (NM, default 50, max 200), ship_type, limit

Sample cURL

curl -H "X-API-Key: YOUR_API_KEY" "https://vessels-api.com/api/V1/vessels/track?mmsi=258785000&hours=48"

What to look for in the response:

  • data.vessels[].ship_type: Filter to confirm it’s actually a Ro-Ro (and not a PCTC mislabeled elsewhere).
  • data.vessels[].position.timestamp_utc: UTC timestamp for freshness; treat as AIS time.
  • data.vessels[].distance_nm: Great-circle distance from the query center in nautical miles.
  • data.vessels[].speed_knots and course_degrees: For approach direction and pace.
  • data.vessels[].navigational_status: Useful to detect anchor vs. underway.

Practical notes:

  • Units: radius and distance_nm are nautical miles. Speeds are in knots. Timestamps are UTC (ISO 8601).
  • Caching: For high-refresh dashboards, cache nearby results briefly (e.g., 30–60 seconds) to avoid 429 rate limits and to smooth AIS noise.
  • Filtering: Use ship_type=Ro-Ro to cut clutter in busy anchorages.

Drill into a single Ro-Ro’s live track and route

Once you have a candidate MMSI or IMO from the nearby scan, switch to the live tracking endpoint to get the latest position, current route, and predicted ETA if available.

Endpoint

GET /vessels/track

  • Required: imo OR mmsi
  • Optional: hours (default 24, max 168), include_route, include_predicted_eta, include_weather

Official sample (MMSI 258785000, copy-paste)

{
    "status": 200,
    "success": true,
    "message": "OK",
    "data": {
        "vessel": {
            "imo": "9122556",
            "mmsi": "258785000",
            "name": null
        },
        "current_position": {
            "latitude": 53.33708,
            "longitude": 7.17993,
            "position_precision": "precise",
            "position_accuracy_nm": null,
            "speed_knots": 0,
            "course_degrees": 212,
            "heading_degrees": null,
            "navigational_status": 5,
            "timestamp_utc": "2017-01-24T04:07:12+00:00",
            "age_minutes": 5158040,
            "destination": null,
            "eta": null
        },
        "predicted_eta": null,
        "position_history": [],
        "route": {
            "departure_port": "HERACLIO",
            "departure_time": "2026-04-27T21:35:36+00:00",
            "destination_port": "HERACLIO",
            "eta": null,
            "distance_nm": null,
            "avg_speed_knots": 17.1
        },
        "last_port_visits": [
            {
                "port_id": "156",
                "port_name": "EMDEN",
                "arrival_time": "2026-07-30T13:00:10+00:00",
                "departure_time": null,
                "duration_hours": null
            },
            {
                "port_id": "10",
                "port_name": "HERACLIO",
                "arrival_time": "2026-04-20T12:00:00+00:00",
                "departure_time": "2026-04-23T08:00:00+00:00",
                "duration_hours": 68
            }
        ],
        "weather": null
    }
}

How to use these fields:

  • data.current_position.latitude/longitude: Plot on your map and compute port proximity if needed.
  • data.current_position.speed_knots and course_degrees: If speed → 0 and status indicates anchorage, prepare anchorage ops. If steady course and speed, project gate opening.
  • data.route: Provides active voyage context for departure/destination and a baseline avg_speed_knots.
  • data.last_port_visits: Great for lead time modeling based on recent calls and dwell duration_hours when present.
  • predicted_eta: When non-null, you can surface ETAs directly in your dashboard. If null, compute a simple ETA using distance/speed.

Python example: flag Ro-Ro within 25 NM and stream track details

import requests
from math import radians, sin, cos, asin, sqrt

API_KEY = "YOUR_API_KEY"
BASE_URL = "https://vessels-api.com/api/V1"

def nm_distance(lat1, lon1, lat2, lon2):
# Haversine with nautical mile conversion
R_km = 6371.0
dlat, dlon = radians(lat2 - lat1), radians(lon2 - lon1)
a = sin(dlat/2)**2 + cos(radians(lat1)) * cos(radians(lat2)) * sin(dlon/2)**2
c = 2 * asin(sqrt(a))
km = R_km * c
return km * 0.539957 # km to NM

def find_roro_near_port(port_lat, port_lon, radius_nm=25):
url = f"{BASE_URL}/vessels/nearby"
params = {"latitude": port_lat, "longitude": port_lon, "radius": radius_nm, "ship_type": "Ro-Ro", "limit": 50}
r = requests.get(url, headers={"X-API-Key": API_KEY}, params=params, timeout=15)
r.raise_for_status()
payload = r.json()
return payload["data"]["vessels"]

def track_mmsi(mmsi):
url = f"{BASE_URL}/vessels/track"
params = {"mmsi": str(mmsi), "hours": 48}
r = requests.get(url, headers={"X-API-Key": API_KEY}, params=params, timeout=15)
r.raise_for_status()
return r.json()["data"]

if __name__ == "__main__":
# Example: a port in Singapore Roads
lat, lon = 1.264, 103.820
nearby = find_roro_near_port(lat, lon, 25)
for v in nearby:
mmsi = v.get("mmsi")
name = v.get("name")
dist = v.get("distance_nm")
print(f"Candidate Ro-Ro {name or mmsi} at {dist} NM")
td = track_mmsi(mmsi)
cp = td.get("current_position", {})
print(f" Speed: {cp.get('speed_knots')} kn, Course: {cp.get('course_degrees')}°, Status: {cp.get('navigational_status')}")
route = td.get("route", {})
print(f" Route: {route.get('departure_port')} -> {route.get('destination_port')}, avg {route.get('avg_speed_knots')} kn")
visits = td.get("last_port_visits", [])
if visits:
last = visits[0]
print(f" Last call: {last.get('port_name')} at {last.get('arrival_time')}")

The example filters to Ro-Ro vessels within 25 NM and fetches 48-hour track context for each match. Use navigational_status along with speed_knots to trigger near-real-time alerts (e.g., “underway at 14 kn, closing range 12 NM”).

Surface expected arrivals to a specific port

To plan berth windows and landside capacity, you’ll often need an “expected arrivals” feed from the port perspective. This endpoint returns vessels en route with ETAs and origin ports.

Endpoint

GET /port/expected-arrivals

  • Required: port (identifier)

Sample cURL

Key fields to read:

  • data.expected_arrivals[].mmsi / imo / name: Use MMSI for follow-up /vessels/track calls.
  • data.expected_arrivals[].vessel_type: Filter to Ro-Ro vs. other traffic.
  • data.expected_arrivals[].eta: Your primary scheduling anchor in UTC.
  • data.expected_arrivals[].departure_port: Helps estimate laden/unladen scenarios.

Combine this with /vessels/track to validate the approach vector and speed profile. If an ETA drifts, your dashboard can re-forecast yard utilization.

Quantify movement and dwell with voyage analytics

Aggregates help detect anomalies early. For example, if a Ro-Ro’s 7-day average speed dips well below baseline, you can flag potential schedule slippage before the ETA catches up.

Endpoint

GET /vessels/analytics

  • Required: type=vessel|port|fleet
  • Conditional: mmsi or imo for type=vessel
  • Optional: period=24h|7d|30d|90d

Sample cURL

Key fields:

  • statistics.total_distance_nm: Cross-check whether the vessel is operating near expected cycle distances.
  • statistics.avg_speed_knots and max_speed_knots: Detect slow-steaming or weather/traffic impacts.
  • statistics.port_calls_count and total_time_in_port_hours: Useful for dwell time benchmarks.
  • statistics.ports_visited: Spot repeat patterns for Ro-Ro loops and seasonal changes.

Scale to a Ro-Ro fleet with a single request

For operators running multiple Ro-Ro vessels, a batch call reduces round trips and improves dashboard performance.

Endpoint

POST /vessels/fleet

  • Body: { vessels: [{imo, mmsi}, ...], include_positions: true, include_routes: true }

Sample cURL

Use cases:

  • Fleet heatmap: Highlight vessels at sea vs. in port at a glance.
  • Exception board: Sort by distance to a designated port or by stale AIS timestamp_utc.
  • Route sanity: Compare current route destination_port against the schedule file.

Putting it together: a minimal “Ro-Ro near a port” decision flow

  1. Query /vessels/nearby with ship_type=Ro-Ro and a 20–30 NM radius of your port center.
  2. For each candidate MMSI, call /vessels/track with hours=48 to get speed, course, and route.
  3. If predicted_eta is null, compute a temporary ETA: distance_to_pilot_station_nm / max(current_speed, fallback_avg_speed).
  4. Cross-check with /port/expected-arrivals to confirm scheduling and surface the planned berth window.
  5. Use /vessels/analytics for the last 7–30 days to baseline typical speeds and dwell. Flag anomalies (e.g., avg_speed_knots below threshold).

This flow supports simple alerting: “Ro-Ro within 12 NM, ETA 01:20 UTC; navigational_status indicates anchorage; shift gates accordingly.”

Operational details that save time

  • Auth: X-API-Key header on all endpoints. No OAuth, no per-endpoint differences.
  • Envelope: Each response returns {status, success, message, data}. Check status and success before parsing data.
  • Coordinates: latitude/longitude are decimal degrees in WGS84; AIS timestamps are UTC ISO 8601.
  • Pagination: /vessels/search supports page and per_page (max 100) if you widen your scan beyond nearby.
  • Units: speed_knots, distance_nm, radius in NM. DWT/TEU filters exist on /vessels/search if you want size-restricted Ro-Ro classes.
  • Refresh: AIS is near real-time. For map UIs, a 30–90 second polling cadence usually balances freshness and rate controls.

Optional: find Ro-Ro candidates by name or particulars

When you don’t have the MMSI, use fuzzy search by name and narrow down by vessel_type or flag.

Endpoint

GET /vessels/search

Sample cURL

From the results, pull imo or mmsi and switch to /vessels/track as shown earlier.

Port-side snapshots and congestion awareness

For berth teams, it’s helpful to combine “Ro-Ro near the port” with a congestion snapshot to anticipate anchorage wait. You can fetch a port’s real-time congestion and wait-time statistics, then layer your Ro-Ro approach logic on top.

Endpoint

GET /ports/congestion

Sample cURL

Read snapshot.vessels_in_anchorage and vessels_at_berth to understand crowding. statistics fields help compare the current week to historical wait and berth durations. Merge this with /vessels/nearby to produce an operational “ETA × congestion” score for Ro-Ro priority handling.

Why developers choose vessels-api.com for Ro-Ro tracking

  • 18 REST endpoints ranging from search to real-time tracking, fleet ops, port intelligence, and CII.
  • Global AIS coverage and near real-time refresh rates, one consistent JSON envelope.
  • Single base URL and API key across all endpoints — no per-endpoint auth drift.
  • Works for lightweight indie dashboards up to enterprise fleet control rooms.

Links you’ll use while building:

FAQ

How do I filter only Ro-Ro traffic when scanning nearby?
Use ship_type=Ro-Ro on GET /vessels/nearby. You can also re-check the vessel_type value in the returned list for defensive filtering.

What timezone are ETAs and timestamps in?
All timestamps in the API are UTC ISO 8601. When showing ETAs to end users, convert to the port’s local time zone on the client side.

How often should I poll for a live board?
For map UIs, 30–90 seconds is a common window. For webhook-like behavior, you can poll faster for a single vessel that’s inside 5–10 NM of the pilot station, then relax after berthing.

What if predicted_eta is null in /vessels/track?
Compute a simple fallback: distance_to_port_nm / speed_knots. If speed is low or erratic, consider the route.avg_speed_knots as a secondary baseline and display uncertainty.

Can I process multiple Ro-Ro vessels in one request?
Yes. Use POST /vessels/fleet with include_positions=true (and include_routes=true when you need voyage context). This reduces latency and API round trips for dashboards.

Next steps

Stand up your “Ro-Ro near a port” decision service by combining /vessels/nearby, /vessels/track, and /port/expected-arrivals. Add /vessels/analytics for baselines and /vessels/fleet for scale. When you’re ready to code, start with the Documentation, spin up a key via Register, and test endpoints interactively in the MCP. Ship the first version, iterate on alerts, and keep Ro-Ro gates in sync with live AIS.

Ready to get started?

Get your API key and start tracking vessels in minutes.

Get API Key

Related posts