Oil Tanker Near a Port

Oil Tanker Near a Port

You need to know when an oil tanker is near a port, how fast it’s moving, whether it’s likely to berth, and when cargo operations could start. By the end of this guide, you’ll be able to detect oil tankers around a port radius, track a specific tanker’s live AIS position and voyage route, surface expected arrivals for port ops, and attach ESG/IMO CII context — all with a few endpoints from vessels-api.com.

Why developers use vessels-api.com for port-adjacent oil tanker workflows

Oil tanker operations near a port are time-critical: pilot dispatch, berth planning, tug allocation, terminal readiness, and downstream logistics all depend on reliable AIS data. vessels-api.com provides 18 REST endpoints that unify vessel search, live tracking, fleet ops, port intelligence, IMO CII emissions, and a premium real-time stream — all with one API key and a consistent JSON envelope.

Illustration: Oil Tanker Near a Port
  • One header for auth on every call: X-API-Key
  • Base URL: https://vessels-api.com/api/V1
  • Consistent JSON envelope on every response: {status, success, message, data}
  • Global AIS coverage with near real-time refresh rates
  • Targets: developers, logistics startups, fleet managers, port operators, ESG/compliance teams

We’ll focus on five endpoints that unlock “oil tanker near a port” use cases:

  • GET /vessels/nearby — detect all vessels inside a port radius
  • GET /vessels/track — follow a specific tanker, current position + voyage route
  • GET /port/expected-arrivals — upcoming port calls with ETA and origin
  • GET /vessels/green — attach IMO CII emissions context
  • GET /vessels/search — find a tanker by name/IMO/MMSI with filters

Authentication, headers, and response model

Every request uses the X-API-Key header:

X-API-Key: YOUR_API_KEY

Every response shares the same envelope so your client code can standardize error handling and data extraction:

{
"status": 200,
"success": true,
"message": "OK",
"data": { ... }
}

Timestamps are UTC ISO 8601. Distances are nautical miles. Speeds are knots. Angles are degrees.

Locate oil tankers within a port radius

Use GET /vessels/nearby to list all vessels within a configurable radius (nautical miles) of a given latitude/longitude. You can filter by ship_type to focus on tankers close to anchorage or harbor limits.

cURL: oil tankers within 20 NM of Singapore

curl -H "X-API-Key: YOUR_API_KEY" "https://vessels-api.com/api/V1/vessels/nearby?latitude=1.264&longitude=103.820&radius=20&ship_type=Tanker&limit=50"

JSON response (example)

{
"status": 200,
"success": true,
"message": "OK",
"data": {
"center": { "latitude": 1.264, "longitude": 103.82 },
"radius_nm": 20,
"total": 2,
"vessels": [
{
"imo": "9387421",
"mmsi": "563012345",
"name": "PACIFIC ATHENA",
"ship_type": "Tanker",
"position": {
"latitude": 1.3012,
"longitude": 103.7541,
"timestamp_utc": "2026-07-30T12:58:00+00:00"
},
"distance_nm": 4.2,
"speed_knots": 0.5,
"course_degrees": 95,
"navigational_status": 5
},
{
"imo": "9456789",
"mmsi": "565009876",
"name": "EASTERN VOYAGER",
"ship_type": "Tanker",
"position": {
"latitude": 1.2115,
"longitude": 103.9022,
"timestamp_utc": "2026-07-30T12:57:20+00:00"
},
"distance_nm": 7.8,
"speed_knots": 6.2,
"course_degrees": 220,
"navigational_status": 0
}
]
}
}

Key fields:

  • distance_nm: quick sort metric to find the closest tanker to a pilot boarding ground or channel entrance.
  • speed_knots and course_degrees: detect approach vs holding patterns; 0–1 kn near anchorage typically means waiting.
  • navigational_status: integer AIS NavStatus (e.g., 5 often used for anchored). Treat as advisory.

Python: filter nearest anchored tanker

import requests

API_KEY = "YOUR_API_KEY"
url = "https://vessels-api.com/api/V1/vessels/nearby"
params = {
"latitude": 1.264,
"longitude": 103.820,
"radius": 20,
"ship_type": "Tanker",
"limit": 50
}
headers = {"X-API-Key": API_KEY}

resp = requests.get(url, headers=headers, params=params, timeout=20)
resp.raise_for_status()
payload = resp.json()

if not payload.get("success"):
raise RuntimeError(payload.get("message"))

vessels = payload["data"]["vessels"]
# Choose anchored or near-stationary tankers first (NavStatus==5 or speed <= 1 kn)
candidates = sorted(
vessels,
key=lambda v: (0 if v.get("navigational_status") == 5 or (v.get("speed_knots") or 0) <= 1 else 1, v["distance_nm"])
)

for v in candidates[:5]:
print(f'{v["name"]} | {v["mmsi"]} | {v["distance_nm"]} nm | {v["speed_knots"]} kn | status={v["navigational_status"]}')

Track a specific oil tanker near the port

When a particular tanker is operationally relevant (e.g., spot charter arriving), use GET /vessels/track to retrieve its current position, optional up to 168 hours of history, route, predicted ETA, and last port calls.

Official cURL (MMSI 258785000, 48h)

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

Official JSON response

{
"status": 200,
"success": true,
"message": "OK",
"data": {
"vessel": {
"imo": "9122556",
"mmsi": "258785000",
"name": null
},
"current_position": {
"latitude": 53.33708,
"longitude": 7.17993,
"speed_knots": 0,
"course_degrees": 212,
"heading_degrees": null,
"navigational_status": 5,
"timestamp_utc": "2017-01-24T04:07:40+00:00",
"age_minutes": 5143580,
"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
}
}

What to read:

  • current_position.latitude/longitude: plot on your port chart UI; age_minutes to decide staleness and caching intervals.
  • navigational_status and speed_knots: whether the ship is maneuvering, at anchor, or berthed.
  • route.*: attach voyage context and average passage speed for micro-ETAs between pilot station, anchorage, and berth.
  • last_port_visits: link recent calls with terminal schedules.

JavaScript: build a concise “now + ETA” card

async function getTrack(mmsi) {
const url = `https://vessels-api.com/api/V1/vessels/track?mmsi=${encodeURIComponent(mmsi)}&hours=48`;
const res = await fetch(url, { headers: { "X-API-Key": "YOUR_API_KEY" } });
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const payload = await res.json();
if (!payload.success) throw new Error(payload.message);
const d = payload.data;
const pos = d.current_position;
return {
mmsi: d.vessel.mmsi,
lat: pos.latitude,
lon: pos.longitude,
speed: pos.speed_knots,
navStatus: pos.navigational_status,
timestampUtc: pos.timestamp_utc,
route: d.route
};
}

getTrack("258785000").then(card => {
console.log(`MMSI ${card.mmsi} @ ${card.lat},${card.lon} | ${card.speed} kn | status ${card.navStatus}`);
if (card.route) {
console.log(`Route: ${card.route.departure_port} → ${card.route.destination_port} | avg ${card.route.avg_speed_knots} kn`);
}
}).catch(console.error);

See who’s coming next: expected arrivals to your port

If your workflow starts before a tanker crosses the harbor line, GET /port/expected-arrivals returns vessels that are bound to a port with ETA and origin. This endpoint complements nearby detection with planned calls for windowed planning (e.g., next 24–72 hours in your UI).

cURL: expected arrivals for ARBUE

curl -H "X-API-Key: YOUR_API_KEY" "https://vessels-api.com/api/V1/port/expected-arrivals?port=ARBUE"

JSON response (example)

{
"status": 200,
"success": true,
"message": "OK",
"data": {
"port_id": "ARBUE",
"port_name": "BUENOS AIRES",
"expected_arrivals": [
{
"mmsi": "701123456",
"imo": "9321456",
"name": "SOUTHERN SPIRIT",
"vessel_type": "Tanker",
"eta": "2026-07-31T02:30:00+00:00",
"departure_port": "RIO GRANDE"
},
{
"mmsi": "701654321",
"imo": "9456123",
"name": "PAMPA ENERGY",
"vessel_type": "Tanker",
"eta": "2026-07-31T13:00:00+00:00",
"departure_port": "MONTEVIDEO"
}
],
"total": 2
}
}

Use eta for sequencing berth windows and tug/survey/STS resources, and vessel_type to filter to Tanker-only lists. Combine with /vessels/nearby to confirm on-water approach behavior inside the last 10–20 NM.

Attach ESG/IMO CII context to port calls

Compliance and sustainability teams often need to surface an IMO CII rating alongside port events. GET /vessels/green returns a periodized CII score and rating (A–E) plus estimated emissions and distance sailed for the period.

cURL: CII for a tanker by MMSI

curl -H "X-API-Key: YOUR_API_KEY" "https://vessels-api.com/api/V1/vessels/green?mmsi=258785000&period=30d"

JSON response (example)

{
"status": 200,
"success": true,
"message": "OK",
"data": {
"imo": "9122556",
"mmsi": "258785000",
"name": "N/A",
"period": "30d",
"distance_nm": 1680.4,
"estimated_emissions": {
"co2_tons": 1425.8,
"co2_per_nm": 0.848
},
"cii": {
"score": 6.3,
"rating": "C",
"year": 2026,
"regulation_reference": "IMO MEPC.339(76)"
}
}
}

Key handling tips:

  • rating scales A (best) → E (worst). Many dashboards color-code this field.
  • distance_nm and co2_per_nm help normalize performance for voyages of different lengths.

Find the right tanker first: search by name, IMO, or MMSI

Before tracking or ESG scoring, start with GET /vessels/search. You can fuzzy match by name, filter by ship_type=Tanker, and bound by year_built or tonnage ranges when you need a particular segment (e.g., MR vs VLCC).

cURL: fuzzy search for “athena” tankers

curl -H "X-API-Key: YOUR_API_KEY" "https://vessels-api.com/api/V1/vessels/search?query=athena&ship_type=Tanker&year_built_from=2005&per_page=5"

JSON response (example)

{
"status": 200,
"success": true,
"message": "OK",
"data": {
"vessels": [
{
"imo": "9387421",
"mmsi": "563012345",
"name": "PACIFIC ATHENA",
"flag": "Singapore",
"vessel_type": "Tanker",
"gross_tonnage": 62000,
"deadweight_tonnage": 110000,
"year_built": 2008,
"length_m": 244,
"width_m": 42
}
],
"pagination": {
"current_page": 1,
"per_page": 5,
"total": 1,
"last_page": 1
}
}
}

Pagination is consistent across endpoints that list entities; per_page max is 100. Cache static particulars (year_built, dimensions) aggressively; re-query live endpoints for movement.

Putting it together: a minimal port-facing tanker monitor

The following flow covers the common “oil tanker near a port” pipeline used by port ops dashboards, agents, and terminal teams:

  1. Use /port/expected-arrivals to seed the watchlist for the next 24–72 hours (show ETA and origin).
  2. As vessels get within 20–30 NM, poll /vessels/nearby with ship_type=Tanker to confirm approach and detect anchorage holding.
  3. For key ships, subscribe/poll /vessels/track to show high-fidelity position, course, route, and last port context.
  4. For compliance overlays, call /vessels/green once per day per vessel and cache the periodized rating.

Python: hybrid workflow for arrivals + nearby + track

import requests
from datetime import datetime, timezone

API_KEY = "YOUR_API_KEY"
BASE = "https://vessels-api.com/api/V1"
H = {"X-API-Key": API_KEY}

def get_expected(port_id):
r = requests.get(f"{BASE}/port/expected-arrivals", headers=H, params={"port": port_id}, timeout=20)
r.raise_for_status(); p = r.json()
if not p.get("success"): raise RuntimeError(p.get("message"))
return [v for v in p["data"]["expected_arrivals"] if v.get("vessel_type") == "Tanker"]

def get_nearby(lat, lon, rnm=20):
r = requests.get(f"{BASE}/vessels/nearby", headers=H, params={
"latitude": lat, "longitude": lon, "radius": rnm, "ship_type": "Tanker", "limit": 100
}, timeout=20)
r.raise_for_status(); p = r.json()
if not p.get("success"): raise RuntimeError(p.get("message"))
return p["data"]["vessels"]

def get_track(mmsi):
r = requests.get(f"{BASE}/vessels/track", headers=H, params={"mmsi": mmsi, "hours": 48}, timeout=20)
r.raise_for_status(); p = r.json()
if not p.get("success"): raise RuntimeError(p.get("message"))
return p["data"]

def fmt_time(s):
return s if not s else datetime.fromisoformat(s.replace("Z","+00:00")).astimezone(timezone.utc).isoformat()

# Example: Buenos Aires coordinates
port_id = "ARBUE"
port_lat, port_lon = -34.60, -58.38

arrivals = get_expected(port_id)
print(f"Expected tanker arrivals to {port_id}: {len(arrivals)}")
for a in arrivals[:3]:
print(f'- {a["name"]} (MMSI {a["mmsi"]}) ETA {a["eta"]} from {a["departure_port"]}')

near = get_nearby(port_lat, port_lon, rnm=30)
print(f"\nTankers within 30 NM: {len(near)}")
for v in sorted(near, key=lambda x: x["distance_nm"])[:5]:
print(f'- {v["name"]} {v["distance_nm"]} nm | {v["speed_knots"]} kn | status {v["navigational_status"]}')

# For the closest vessel, pull a full track card
if near:
top = sorted(near, key=lambda x: x["distance_nm"])[0]
t = get_track(top["mmsi"])
pos = t["current_position"]
route = t.get("route")
print(f'\nTrack: MMSI {t["vessel"]["mmsi"]} @ {pos["latitude"]},{pos["longitude"]} {pos["speed_knots"]} kn')
if route:
print(f'Route: {route["departure_port"]} → {route["destination_port"]} | avg {route["avg_speed_knots"]} kn')

Operational considerations that save time

  • Polling cadence: For port approaches, 1–5 minute intervals are typical; respect age_minutes to avoid re-drawing stale plots.
  • Caching: Cache static particulars (from /vessels/search) for hours or days. Cache /vessels/green for a day per vessel.
  • Pagination: When using /vessels/search, persist pagination state; per_page up to 100 is supported.
  • Type filters: ship_type=Tanker narrows both nearby and search results to relevant hulls.
  • Error handling: 401 indicates an API key issue, 404 for not found, 422 for parameter bounds (e.g., radius max 200 NM).

Additional endpoint you may layer later

Port congestion snapshots (/ports/congestion) help contextualize whether an arriving tanker will wait at anchorage or head straight to berth. Combine with /port/activity if you need recent arrival/departure event streams for your ops feed. Refer to the Documentation for request/response specifics and allowed periods.

End-to-end example: from search to ESG card

The following sequence illustrates how you might build a unified tanker detail view when a vessel is near port:

  1. Search by name substring (“ATHENA”) and filter to ship_type=Tanker to resolve MMSI/IMO.
  2. Call /vessels/track with that MMSI to render the current marker, course vector, and last port visits.
  3. If the tanker is within 20 NM of port coordinates, annotate with “Approach” or “Anchorage” using speed + navigational_status.
  4. Fetch /vessels/green for the 30-day window and show CII rating + CO2 per NM.

JSON: unified card payload (example)

{
"status": 200,
"success": true,
"message": "OK",
"data": {
"identity": {
"imo": "9387421",
"mmsi": "563012345",
"name": "PACIFIC ATHENA",
"vessel_type": "Tanker"
},
"track": {
"latitude": 1.3012,
"longitude": 103.7541,
"speed_knots": 0.5,
"course_degrees": 95,
"navigational_status": 5,
"timestamp_utc": "2026-07-30T12:58:00+00:00"
},
"route": {
"departure_port": "QINGDAO",
"destination_port": "SINGAPORE",
"eta": "2026-07-30T22:00:00+00:00"
},
"esg": {
"period": "30d",
"cii_rating": "C",
"co2_per_nm": 0.848
}
}
}

This shape mirrors the underlying endpoints so you can refresh each sub-block on its own schedule.

Common pitfalls and how to avoid them

  • Radius too large: /vessels/nearby caps radius at 200 NM. For bluewater sweeps, combine port-centric calls with search + analytics.
  • Missing ID: /vessels/track requires either imo or mmsi. Prefer MMSI for live AIS tracking tasks.
  • Overfetching: Do not request 168 hours of history when you only plot “last known.” Start with hours=24 and expand as needed.
  • Null fields: predicted_eta and weather may be null; guard against missing sub-objects in your UI.

FAQ

Q: Can I filter nearby results to only tankers?
A: Yes. Pass ship_type=Tanker to GET /vessels/nearby. You can also set limit to cap results.

Q: Do I need different auth for different endpoints?
A: No. All endpoints use the same X-API-Key header and the same base URL.

Q: What timezone are timestamps in?
A: All timestamps in responses are UTC ISO 8601. Use age_minutes on /vessels/track to assess freshness.

Q: How far back can I get position history?
A: Up to 168 hours via the hours parameter on /vessels/track.

Q: What are the possible IMO CII ratings?
A: A (best), B, C, D, E (worst), provided with a numeric score and regulation reference.

Build your “oil tanker near a port” feature today

Start with the three calls in this article (/vessels/nearby, /vessels/track, /port/expected-arrivals), then layer /vessels/green for ESG. The API surface is consistent, response envelopes are predictable, and the data model maps directly onto port ops needs. Explore the interactive tools on the MCP, ship your first integration using the Documentation, and get an API key to start testing with a 7-day trial: Register.

Ready to get started?

Get your API key and start tracking vessels in minutes.

Get API Key