Platform Support Vessel Tracking API: Real-Time Maritime Data & Analytics

Platform Support Vessel Tracking API: Real-Time Maritime Data & Analytics

Platform Support Vessels (PSVs) keep offshore energy operations moving: crew transfers, cargo runs, ROV launch and recovery, urgent spares, and station-keeping in unpredictable seas. Yet many teams still manage these high-stakes operations with spreadsheets, email ETAs, and stale position reports. The result: missed connections, underutilized assets, and preventable demurrage. Developers building maritime applications for PSVs need clean, live AIS streams, route-aware analytics, port conditions, and fleet-wide observability—without stitching together inconsistent data sources. This is exactly where vessels-api.com delivers. It centralizes real-time AIS tracking, fleet operations, port insights, and IMO CII emissions analytics behind a single, predictable REST interface that your team can integrate in hours, not months.

Why vessels-api.com for Platform Support Vessel tracking and maritime analytics

As a developer advocate working closely with offshore operators and logistics startups, I’ve seen the same pain points: building ingestion pipelines for disparate AIS feeds, writing custom parsers for slightly different envelopes, and maintaining separate clients for search, tracking, fleet, and port data. vessels-api.com eliminates that complexity by offering:

  • 18 REST endpoints covering vessel search, live AIS tracking with history and routes, fleet operations, port intelligence, and IMO CII emissions analytics.
  • One base URL and a single request header for access—no per-endpoint differences to remember.
  • A consistent JSON response envelope on every call: {status, success, message, data}.
  • Global AIS coverage with near real-time refresh rates to keep PSV dispatch and DP operations updated.
  • Developer-first ergonomics: query parameters that match real maritime workflows, rich filters, and helpful error metadata for reliable automation.

Throughout this guide, we’ll focus on PSV-centric workflows: dispatch boards that show live positions and latest routes, digital twins of offshore fields using nearby queries, supply base congestion monitoring, fleet performance analytics for offshore campaigns, and ESG reporting aligned to IMO CII. You’ll see cURL, Python, and JavaScript snippets, complete example JSON, and concrete implementation steps you can apply immediately.

Complete endpoint overview: vessel intelligence, fleet operations, and port insights

vessels-api.com groups functionality into three domains plus legacy compatibility endpoints. Each endpoint returns the same top-level envelope so you can design uniform clients and standardized observability across your stack.

Vessel Intelligence

  • GET /vessels/search — Find vessels by name (fuzzy), IMO, or MMSI; filter by ship_type, flag, size, TEU, year built; pagination.
  • GET /vessels/track — Live position, up to 168-hour history, active route with predicted ETA, and weather; by IMO or MMSI.
  • GET /vessels/nearby — Discover vessels within a radius of a coordinate; filter by ship_type; set radius and result limit.
  • GET /vessels/analytics — Aggregated voyage statistics for a vessel, port, or fleet over a period (24h to 90d).

Fleet Operations

  • POST /vessels/fleet — Batch positions, routes, and stats for multiple vessels in one request; summarize fleet at-a-glance.
  • GET /vessels/green — IMO CII emissions scoring and estimates for ESG/compliance; supports various time windows.

Port Intelligence

  • GET /ports/congestion — Real-time congestion snapshot and wait-time statistics for a port.
  • GET /ports — Full catalog of 248 ports with coordinates, country, timezone.
  • GET /ports/data — Detailed port info including live vessel counts and expected vessels.
  • GET /port/expected-arrivals — Expected arrivals with ETA and origin per port.
  • GET /port/activity — Recent arrivals and departures for logistics event feeds.

Legacy (stable, kept for compatibility)

  • GET /vessel/info?imo=IMO — Static vessel particulars.
  • GET /vessel/route?imo=IMO — Current voyage route with ETA and distance.
  • GET /vessel/position?imo=IMO — Last known AIS position by IMO.
  • GET /vessel/mmsi-position?mmsi=MMSI — Last known AIS position by MMSI.
  • GET /vessel/port?port=PORT_ID — Vessels in a port by code.
  • GET /vessel/port/mmsi?mmsi=MMSI — Current port call for a vessel by MMSI.

All endpoints share the base URL https://vessels-api.com/api/V1 and the same response envelope so you can normalize logging, retries, and analytics across your integration.

Core PSV workflows: track, dispatch, port ops, analytics, and ESG

Below are the endpoints that typically anchor a PSV application: live tracking with history and route intelligence, dynamic radius queries around offshore fields, congestion monitoring for supply bases and staging ports, fleet-wide batching, and ESG analytics aligned to IMO CII. Each section includes cURL and a language client so you can copy, paste, and ship.

1) Live PSV tracking and route-aware ETA: GET /vessels/track

Business problem: Dispatch and HSE teams require continuous awareness—current position, drift vs DP, course, speed, navigational status, last port visit, current route, and predicted ETA. Without a unified API, you wind up merging AIS feeds, scraping port call data, and guessing at route context. That’s brittle and time-consuming.

Solution: /vessels/track provides the live position, up to 168 hours of history, active route, predicted ETA, and optional weather—crucial for offshore operations planning and rapid turnarounds at the supply base.

Key parameters:

  • imo or mmsi — one is required.
  • hours — default 24; max 168 for a week of history.
  • include_route — include route context (departure, destination, ETA).
  • include_predicted_eta — include ML-generated ETA for the active voyage leg.
  • include_weather — surface conditions alongside the track when available.

cURL example:

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

JavaScript (Node.js, fetch) example:

import fetch from "node-fetch";

async function getPsvTrack(mmsi) {
const url = `https://vessels-api.com/api/V1/vessels/track?mmsi=${mmsi}&hours=48&include_route=true&include_predicted_eta=true`;
const res = await fetch(url, {
headers: { "X-API-Key": process.env.VESSELS_API_KEY }
});
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const body = await res.json();
if (!body.success) throw new Error(body.message || "API error");
return body.data;
}

getPsvTrack("258785000")
.then(data => console.log(JSON.stringify(data, null, 2)))
.catch(err => console.error(err));

Example response (truncated for brevity):

{
"status": 200,
"success": true,
"message": "OK",
"data": {
"vessel": {
"imo": "9391234",
"mmsi": "258785000",
"name": "NORSEA SUPPORT"
},
"current_position": {
"latitude": 61.1234,
"longitude": 2.3456,
"speed_knots": 11.2,
"course_degrees": 235,
"heading_degrees": 240,
"navigational_status": "Under way using engine",
"timestamp_utc": "2026-09-25T10:14:12Z",
"destination": "STAVANGER BASE",
"eta": "2026-09-25T13:45:00Z"
},
"position_history": [
{
"latitude": 61.2102,
"longitude": 2.5678,
"speed_knots": 12.1,
"course_degrees": 238,
"timestamp_utc": "2026-09-25T08:14:12Z"
},
{
"latitude": 61.3001,
"longitude": 2.7890,
"speed_knots": 0.2,
"course_degrees": 0,
"timestamp_utc": "2026-09-25T07:05:30Z"
}
],
"route": {
"departure_port": "NOSTV",
"departure_time": "2026-09-25T05:40:00Z",
"destination_port": "NOSTV",
"eta": "2026-09-25T13:45:00Z",
"distance_nm": 72.4,
"avg_speed_knots": 10.8
},
"last_port_visits": [
{ "port_id": "NOSTV", "arrived": "2026-09-23T19:12:00Z", "departed": "2026-09-24T03:08:00Z" },
{ "port_id": "NOBGO", "arrived": "2026-09-22T09:31:00Z", "departed": "2026-09-22T18:15:00Z" }
]
}
}

What to do with it:

  • Visualize live PSV positions on a map with a 48-hour trail to confirm holding patterns near platforms and DP stability.
  • Drive onshore warehouse picks and quay crane prep from predicted ETA; align crew change vans and hot-shot deliveries.
  • Identify idle-time anomalies (speed 0, long timestamps) to spot delays or weather holds.
  • Highlight status changes (e.g., “Under way” to “At anchor”) to trigger automated notifications.

Field meanings:

  • current_position.timestamp_utc — always consume as authoritative ordering for the last AIS fix.
  • route.distance_nm and avg_speed_knots — useful for sanity-checking ETA and for cycle time analytics.
  • last_port_visits — quickly infer base rotation patterns without calling a separate port-calls endpoint.

2) Build digital twins of offshore fields: GET /vessels/nearby

Business problem: Operators need to see all traffic around platforms, FPSOs, and wind farm constructions to enforce safety zones, reduce collision risk, and stage supply runs. Polling all vessels and filtering client-side is wasteful and slow.

Solution: /vessels/nearby returns all vessels within a radius of a coordinate, optionally filtered by ship_type (e.g., “Platform Supply Ship”, “Offshore Tug/Supply Ship”, “Utility Vessel”). Use it to power field overlays and safety dashboards.

cURL example:

curl -H "X-API-Key: YOUR_API_KEY" \
"https://vessels-api.com/api/V1/vessels/nearby?latitude=61.2500&longitude=2.9000&radius=30&ship_type=Platform%20Supply%20Ship"

Python example:

import os
import requests

def get_nearby_psvs(lat, lon, radius_nm=30):
url = "https://vessels-api.com/api/V1/vessels/nearby"
params = {
"latitude": lat,
"longitude": lon,
"radius": radius_nm,
"ship_type": "Platform Supply Ship",
"limit": 100
}
r = requests.get(url, headers={"X-API-Key": os.getenv("VESSELS_API_KEY")}, params=params, timeout=20)
r.raise_for_status()
body = r.json()
if not body.get("success"):
raise RuntimeError(body.get("message", "API error"))
return body["data"]

data = get_nearby_psvs(61.25, 2.9, radius_nm=25)
print(data)

Example response:

{
"status": 200,
"success": true,
"message": "OK",
"data": {
"center": { "latitude": 61.25, "longitude": 2.9 },
"radius_nm": 25,
"total": 3,
"vessels": [
{
"imo": "9391234",
"mmsi": "258785000",
"name": "NORSEA SUPPORT",
"ship_type": "Platform Supply Ship",
"position": {
"latitude": 61.2621,
"longitude": 2.9265,
"timestamp_utc": "2026-09-25T10:16:45Z"
},
"distance_nm": 1.2,
"speed_knots": 0.3,
"course_degrees": 15,
"navigational_status": "Restricted manoeuverability"
},
{
"imo": "9776543",
"mmsi": "259000111",
"name": "VIKING SUPPLIER",
"ship_type": "Offshore Tug/Supply Ship",
"position": {
"latitude": 61.2712,
"longitude": 2.9150,
"timestamp_utc": "2026-09-25T10:14:59Z"
},
"distance_nm": 0.9,
"speed_knots": 0.0,
"course_degrees": 0,
"navigational_status": "At anchor"
},
{
"imo": "9345678",
"mmsi": "235987654",
"name": "SEA LIFTER",
"ship_type": "Utility Vessel",
"position": {
"latitude": 61.2480,
"longitude": 2.9120,
"timestamp_utc": "2026-09-25T10:12:31Z"
},
"distance_nm": 0.4,
"speed_knots": 2.1,
"course_degrees": 198,
"navigational_status": "Under way using engine"
}
]
}
}

Implementation tips:

  • Call every 30–60 seconds for DP zones; back off to 2–5 minutes during low activity windows.
  • Overlay restricted zones and compute intersection with vessel positions client-side to trigger alerts.
  • Use ship_type filter to reduce noise when you only care about PSVs and offshore support craft.
  • Leverage distance_nm to sort a “closest to platform” list for quick tasking decisions.

3) Fleet-wide snapshot in one call: POST /vessels/fleet

Business problem: PSV operators often manage 10–80 vessels across multiple offshore assets. Hitting /vessels/track per vessel leads to chatty clients and more moving parts to monitor.

Solution: /vessels/fleet batches multiple vessels and returns consolidated positions, routes, and a rolled-up fleet summary. Use it to power a single-pane-of-glass for dispatch and HSE.

cURL example:

curl -X POST -H "X-API-Key: YOUR_API_KEY" -H "Content-Type: application/json" \
-d '{"vessels":[{"imo":"9122556"},{"mmsi":"309374000"},{"mmsi":"258785000"}],"include_positions":true,"include_routes":true}' \
"https://vessels-api.com/api/V1/vessels/fleet"

Example response:

{
"status": 200,
"success": true,
"message": "OK",
"data": {
"fleet": {
"total_vessels": 3,
"vessels_at_sea": 2,
"vessels_in_port": 1
},
"vessels": [
{
"imo": "9122556",
"mmsi": "257000123",
"name": "OCEAN RUNNER",
"position": {
"latitude": 59.9123,
"longitude": 10.7454,
"speed_knots": 0.0,
"course_degrees": 0,
"timestamp_utc": "2026-09-25T10:17:00Z"
},
"route": {
"departure_port": "NOBGO",
"destination_port": "NOSTV",
"eta": "2026-09-25T16:30:00Z",
"distance_nm": 98.7,
"avg_speed_knots": 11.1
}
},
{
"imo": "9391234",
"mmsi": "258785000",
"name": "NORSEA SUPPORT",
"position": {
"latitude": 61.1234,
"longitude": 2.3456,
"speed_knots": 11.2,
"course_degrees": 235,
"timestamp_utc": "2026-09-25T10:14:12Z"
},
"route": {
"departure_port": "NOSTV",
"destination_port": "NOSTV",
"eta": "2026-09-25T13:45:00Z",
"distance_nm": 72.4,
"avg_speed_knots": 10.8
}
},
{
"imo": null,
"mmsi": "309374000",
"name": "SEA RANGER",
"position": null,
"route": null
}
]
}
}

Field insights:

  • fleet.vessels_at_sea vs vessels_in_port — power KPIs in ops dashboards.
  • Null position/route fields — treat gracefully; indicates no recent AIS fix or insufficient route context.
  • Use one batch request per tick in your UI to minimize network overhead and simplify retries.

4) Port and supply base congestion: GET /ports/congestion and /ports/data

Business problem: Supply bases and staging ports can bottleneck PSVs with quay constraints, pilotage slots, and weather windows. Stale spreadsheets won’t keep crews and cargo moving.

Solution: The port intelligence endpoints deliver up-to-date congestion snapshots, historical wait-time statistics, and live vessel counts—ideal for dispatch and berth scheduling.

cURL examples:

curl -H "X-API-Key: YOUR_API_KEY" \
"https://vessels-api.com/api/V1/ports/congestion?port_id=ARBUE&period=7d"

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

Example response (congestion):

{
"status": 200,
"success": true,
"message": "OK",
"data": {
"port_id": "ARBUE",
"port_name": "Buenos Aires",
"period": "7d",
"snapshot": {
"vessels_in_anchorage": 12,
"vessels_at_berth": 18
},
"statistics": {
"avg_wait_time_hours_last_7d": 9.4,
"max_wait_time_hours_last_7d": 31.7,
"avg_berth_time_hours_last_7d": 12.5,
"port_calls_count": 203
}
}
}

Example response (data):

{
"status": 200,
"success": true,
"message": "OK",
"data": {
"port_id": "ARBUE",
"name": "Buenos Aires",
"country": "Argentina",
"latitude": -34.6037,
"longitude": -58.3816,
"timezone": "America/Argentina/Buenos_Aires",
"vessels_in_port": 27,
"vessels_expected": 14
}
}

Operational uses:

  • Feed wait-time KPIs into automated ETA buffers for inbound PSVs to avoid misaligned quay windows.
  • Combine vessels_expected with your fleet routes to preemptively resolve conflicts.
  • Use timezone and coordinates to normalize all time math on your backend and frontends.

5) ESG and IMO CII scoring for PSVs: GET /vessels/green

Business problem: Offshore operators increasingly report emissions performance, and many charterers require transparent carbon intensity ratings. Calculating this from scratch—data gathering, normalization, and score computation—is expensive.

Solution: /vessels/green returns the estimated emissions for your time window and the IMO CII rating (A–E) following the MEPC.339(76) framework. Integrate it into dashboards and compliance packs.

cURL:

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

Example response:

{
"status": 200,
"success": true,
"message": "OK",
"data": {
"imo": "9391234",
"mmsi": "258785000",
"name": "NORSEA SUPPORT",
"period": "30d",
"distance_nm": 1865.3,
"estimated_emissions": {
"co2_tons": 142.8,
"co2_per_nm": 0.0765
},
"cii": {
"score": 6.7,
"rating": "C",
"year": 2026,
"regulation_reference": "IMO MEPC.339(76)"
}
}
}

Practical tips:

  • Use co2_per_nm to normalize performance across vessels and voyage types.
  • Track rating deltas over successive periods (e.g., 30d to 90d) to evaluate operational changes such as speed reduction or hull cleanings.
  • Store period windows and raw returns for reproducible ESG reporting.

Supporting endpoints that supercharge PSV applications

Search and discovery: GET /vessels/search

Initialize your application with robust vessel discovery. This endpoint supports fuzzy name matching and exact lookups by IMO or MMSI, with optional filters to narrow to PSV-like vessels.

cURL:

curl -H "X-API-Key: YOUR_API_KEY" \
"https://vessels-api.com/api/V1/vessels/search?query=sea&ship_type=Platform%20Supply%20Ship&page=1&per_page=50"

Example response:

{
"status": 200,
"success": true,
"message": "OK",
"data": {
"vessels": [
{
"imo": "9391234",
"mmsi": "258785000",
"name": "NORSEA SUPPORT",
"flag": "Norway",
"vessel_type": "Platform Supply Ship",
"gross_tonnage": 3530,
"deadweight_tonnage": 4200,
"year_built": 2010,
"length_m": 81.5,
"width_m": 18.0
},
{
"imo": "9345678",
"mmsi": "235987654",
"name": "SEA LIFTER",
"flag": "United Kingdom",
"vessel_type": "Utility Vessel",
"gross_tonnage": 1250,
"deadweight_tonnage": 1400,
"year_built": 2012,
"length_m": 62.0,
"width_m": 14.2
}
],
"pagination": {
"current_page": 1,
"per_page": 50,
"total": 2,
"last_page": 1
}
}
}

Use filters like year_built_from and max_dwt to curate standardized PSV fleets programmatically. Pagination returns total and last_page so you can pre-fetch or lazy-load in UIs.

Voyage statistics and utilization: GET /vessels/analytics

Compute utilization and turnaround KPIs without building your own aggregation pipelines. /vessels/analytics returns voyage statistics for a vessel, port, or fleet over 24h, 7d, 30d, or 90d.

cURL (per-vessel):

curl -H "X-API-Key: YOUR_API_KEY" \
"https://vessels-api.com/api/V1/vessels/analytics?type=vessel&mmsi=258785000&period=7d"

Example response:

{
"status": 200,
"success": true,
"message": "OK",
"data": {
"type": "vessel",
"mmsi": "258785000",
"imo": "9391234",
"name": "NORSEA SUPPORT",
"period": "7d",
"statistics": {
"total_distance_nm": 412.6,
"avg_speed_knots": 9.8,
"max_speed_knots": 15.3,
"port_calls_count": 6,
"total_time_in_port_hours": 41.7,
"ports_visited": ["NOSTV", "NOBGO"]
}
}
}

With these fields, you can:

  • Benchmark vessels by cycle time and distance covered across comparable campaigns.
  • Identify vessels with excessive time in port to surface possible planning issues or repairs.
  • Combine with /vessels/green to see if speed policies affect both CII ratings and schedule adherence.

Port arrival planning and logistics event feeds

Expected arrivals: GET /port/expected-arrivals

Feed your port planning UI with inbound vessels, ETAs, and origins. For PSVs, this keeps lines of balance in sync and helps quayside teams plan crane and forklift assignments.

cURL:

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

Example response:

{
"status": 200,
"success": true,
"message": "OK",
"data": {
"port_id": "ARBUE",
"port_name": "Buenos Aires",
"expected_arrivals": [
{
"mmsi": "258785000",
"imo": "9391234",
"name": "NORSEA SUPPORT",
"vessel_type": "Platform Supply Ship",
"eta": "2026-09-25T13:45:00Z",
"departure_port": "NOSTV"
},
{
"mmsi": "259000111",
"imo": "9776543",
"name": "VIKING SUPPLIER",
"vessel_type": "Offshore Tug/Supply Ship",
"eta": "2026-09-25T15:20:00Z",
"departure_port": "NOBGO"
}
],
"total": 2
}
}

Recent port activity: GET /port/activity

Create logistics event feeds to coordinate berth allocations, tug/pilot scheduling, and shore crew dispatch.

cURL:

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

Example response:

{
"status": 200,
"success": true,
"message": "OK",
"data": {
"port_id": "ARBUE",
"port_name": "Buenos Aires",
"arrivals": [
{ "mmsi": "258785000", "name": "NORSEA SUPPORT", "arrival_time": "2026-09-25T11:05:00Z", "from_port": "NOSTV" }
],
"departures": [
{ "mmsi": "259000111", "name": "VIKING SUPPLIER", "departure_time": "2026-09-25T09:30:00Z", "to_port": "NOBGO" }
]
}
}

Downstream uses:

  • Notify stevedores and forklift teams 60 minutes pre-arrival for hot loads.
  • Automatically allocate berth windows and update internal Gantt views in real time.
  • Correlate arrival/departure events with /vessels/analytics to refine turn time benchmarks.

Legacy endpoints: quick wins and compatibility bridges

While the /vessels/* endpoints are richer and more flexible, the legacy endpoints remain valuable when you need simple, single-purpose calls for compatibility with existing toolchains:

  • /vessel/info?imo=IMO — static particulars like name, flag, dimensions, call sign.
  • /vessel/route?imo=IMO — voyage meta without position history.
  • /vessel/position?imo=IMO and /vessel/mmsi-position?mmsi=MMSI — last known fix quickly.
  • /vessel/port?port=PORT_ID — list vessels currently in a port.
  • /vessel/port/mmsi?mmsi=MMSI — current port call for a given vessel.

These endpoints share the same envelope and error semantics, so rolling them into existing systems is straightforward.

Implementation guidance: building reliable, observable PSV apps

Design for consistent envelopes and field evolution

  • Always parse the top-level {status, success, message, data}. Use success and status together for robust flow control.
  • Handle nullable fields like route or position gracefully; they communicate real-world AIS gaps or unavailable context.
  • Avoid assuming enumerations are exhaustive; navigational_status can occasionally carry unexpected values from AIS encoders. Fall back to “Unknown” states in your UI.

Pagination, windows, and result sizing

  • /vessels/search supports page and per_page (max 100). Implement “Load more” or prefetch the next page to keep UIs snappy.
  • /vessels/track supports hours up to 168. Favor 24–48 hours for UI; fetch longer windows for analysis jobs to reduce payload size.
  • /vessels/nearby supports radius up to 200 NM. Use tighter radii (5–25 NM) near offshore installations to focus on safety-critical traffic.

Fleet polling strategies

  • Prefer POST /vessels/fleet to reduce N calls to 1 per polling interval; it also returns summary KPIs for dashboards.
  • Use exponential backoff and jitter for retries when non-200 responses occur; log message for troubleshooting.
  • Separate UI refresh cadence (e.g., 30–60 seconds) from archival polling (e.g., 5–15 minutes) to control costs in downstream storage and analytics.

Error handling and troubleshooting

Error codes are standardized:

  • 200: OK
  • 400: Missing/invalid parameter
  • 401: Invalid or missing X-API-Key
  • 404: Vessel/port not found
  • 422: Parameter out of range
  • 429: Rate limit exceeded
  • 500: Server error

Example error response:

{
"status": 422,
"success": false,
"message": "radius must be between 1 and 200 NM",
"data": null
}

Best practices:

  • Validate inputs client-side (e.g., radius range, hours range) before calling.
  • Log both status and message to accelerate root cause analysis.
  • Implement circuit breakers on dependent services to protect your UI if an upstream is transiently unavailable.

Performance considerations

  • Leverage incremental polling by preserving timestamps; only redraw tracks when timestamp_utc has advanced.
  • Cache static data like /ports for 24 hours; invalidate only on-demand in admin workflows.
  • Use conditional polling on /vessels/track; slow your cadence when speed_knots is near 0 and navigational_status indicates anchorage/berth.

Observability patterns

  • Instrument every request with a correlation ID in logs; persist {status, success, message} for later audit.
  • Emit metrics per endpoint: success_rate, p95_latency, and payload_bytes to tune polling schedules.
  • Create synthetic monitors for critical routes (e.g., a known PSV MMSI) to detect external feed changes proactively.

Putting it together: end-to-end PSV dispatch board

Here is a practical orchestration flow used by many PSV operations teams building on vessels-api.com:

  • Initialization: Query /vessels/search with ship_type=Platform Supply Ship to seed your fleet list. Store IMO/MMSI and key particulars.
  • Live board: Every 45 seconds, call POST /vessels/fleet with include_positions and include_routes. Render map markers, routes, and ETAs.
  • Field overlays: For each critical installation, call /vessels/nearby every 60–120 seconds with a 5–10 NM radius. Trigger proximity alerts and safety warnings.
  • Port ops: Poll /ports/congestion and /port/expected-arrivals every 10–15 minutes to align quay resources and schedule turnarounds.
  • Analytics: Nightly jobs call /vessels/analytics (7d/30d) to compute utilization trends and compare vessels by distance_nm and time_in_port.
  • ESG: Weekly or monthly, call /vessels/green for all PSVs and publish CII dashboards by route, vessel, and period.

Example JavaScript composition (simplified):

import fetch from "node-fetch";

const BASE = "https://vessels-api.com/api/V1";
const HEADERS = { "X-API-Key": process.env.VESSELS_API_KEY, "Content-Type": "application/json" };

async function fleetTick(vessels) {
const payload = { vessels, include_positions: true, include_routes: true };
const res = await fetch(`${BASE}/vessels/fleet`, { method: "POST", headers: HEADERS, body: JSON.stringify(payload) });
const body = await res.json();
if (!res.ok || !body.success) throw new Error(body.message || `HTTP ${res.status}`);
return body.data;
}

async function fieldOverlay(lat, lon) {
const url = `${BASE}/vessels/nearby?latitude=${lat}&longitude=${lon}&radius=10&ship_type=Platform%20Supply%20Ship&limit=100`;
const res = await fetch(url, { headers: { "X-API-Key": process.env.VESSELS_API_KEY } });
const body = await res.json();
if (!res.ok || !body.success) throw new Error(body.message || `HTTP ${res.status}`);
return body.data;
}

async function portOps(portId) {
const [congRes, arrRes] = await Promise.all([
fetch(`${BASE}/ports/congestion?port_id=${portId}&period=7d`, { headers: { "X-API-Key": process.env.VESSELS_API_KEY } }),
fetch(`${BASE}/port/expected-arrivals?port=${portId}`, { headers: { "X-API-Key": process.env.VESSELS_API_KEY } })
]);
const congestion = await congRes.json();
const arrivals = await arrRes.json();
if (!congestion.success) throw new Error(congestion.message);
if (!arrivals.success) throw new Error(arrivals.message);
return { congestion: congestion.data, arrivals: arrivals.data };
}

// Example usage in your scheduler:
(async () => {
const vessels = [{ mmsi: "258785000" }, { imo: "9122556" }, { mmsi: "309374000" }];
const fleet = await fleetTick(vessels);
const field = await fieldOverlay(61.25, 2.9);
const port = await portOps("ARBUE");
console.log({ fleet, field, port });
})();

Port catalog and discovery

To power dropdowns, autocomplete, or region pickers, fetch the port catalog once and cache it:

cURL:

curl -H "X-API-Key: YOUR_API_KEY" "https://vessels-api.com/api/V1/ports"

Example response:

{
"status": 200,
"success": true,
"message": "OK",
"data": {
"ports": [
{ "port_id": "ARBUE", "name": "Buenos Aires", "country": "Argentina", "latitude": -34.6037, "longitude": -58.3816, "timezone": "America/Argentina/Buenos_Aires" },
{ "port_id": "NOSTV", "name": "Stavanger", "country": "Norway", "latitude": 58.9701, "longitude": 5.7331, "timezone": "Europe/Oslo" }
],
"total": 248
}
}

Use timezone for local ETAs and shift planning, and coordinates to compute bearings and distances to nearby platforms or depots.

Developer concerns addressed: reliability, control, and ergonomics

vessels-api.com is built to simplify your maritime integrations and reduce operational risk:

  • Uniform envelope and query semantics reduce branching in your clients.
  • Batching with /vessels/fleet supports efficient polling and rollups for large PSV fleets.
  • Explicit error codes and clear messages streamline retries, backoff, and alerting logic.
  • Consistent models across intelligence, fleet, and port endpoints accelerate feature delivery and testing.
  • Simple routing—one base URL—eases environment promotion from staging to production.

From a governance perspective, standardizing on vessels-api.com lets platform teams implement per-app keys, scoped roles in your own gateway, and internal audit logs around your usage of the maritime data. Teams often pair these APIs with centralized observability (structured logs, traces, and metrics) and SRE guardrails like health checks and circuit breakers to keep dashboards healthy even when upstream networks wobble.

For performance-sensitive UIs, keep latency low by:

  • Coalescing calls (e.g., /vessels/fleet for dashboards) and avoiding multi-hop service chains per refresh.
  • Strategically caching static resources (/ports) and long-lived lists (fleet manifests).
  • Right-sizing payloads by limiting radius and hours and avoiding unnecessary include parameters.

Advanced analytics ideas for PSV operators

Once your tracking and port ops views are live, expand into higher-value analytics:

  • Cycle time decomposition: Combine /vessels/track history with /vessels/analytics to apportion time at sea, holding, DP near platform, in port, and alongside.
  • Safety analytics: Use /vessels/nearby to detect safety zone intrusions and near-misses; correlate with course and speed to evaluate SOP adherence.
  • ESG optimization: Compare /vessels/green ratings before and after voyage policies such as eco-speed or optimized routing to staging ports; report improvements to stakeholders.
  • Demand forecasting: Use expected_arrivals and congestion to simulate quay utilization for the next 24–72 hours and pre-allocate crews.

End-to-end example: nightly job for KPIs and ESG

Python script outline for nightly KPIs:

import os
import time
import requests
from datetime import datetime

BASE = "https://vessels-api.com/api/V1"
HEADERS = {"X-API-Key": os.getenv("VESSELS_API_KEY")}

FLEET = [{"mmsi": "258785000"}, {"imo": "9122556"}, {"mmsi": "309374000"}]

def get_analytics(mmsi):
url = f"{BASE}/vessels/analytics"
params = {"type": "vessel", "mmsi": mmsi, "period": "7d"}
r = requests.get(url, headers=HEADERS, params=params, timeout=20)
r.raise_for_status()
body = r.json()
if not body["success"]:
raise RuntimeError(body["message"])
return body["data"]["statistics"]

def get_green(mmsi):
url = f"{BASE}/vessels/green"
params = {"mmsi": mmsi, "period": "30d"}
r = requests.get(url, headers=HEADERS, params=params, timeout=20)
r.raise_for_status()
body = r.json()
if not body["success"]:
raise RuntimeError(body["message"])
return body["data"]

def main():
report = []
for v in FLEET:
mmsi = v.get("mmsi")
if not mmsi:
continue # simplify example
try:
stats = get_analytics(mmsi)
green = get_green(mmsi)
report.append({
"mmsi": mmsi,
"total_distance_nm_7d": stats["total_distance_nm"],
"port_calls_7d": stats["port_calls_count"],
"cii_rating_30d": green["cii"]["rating"],
"co2_tons_30d": green["estimated_emissions"]["co2_tons"]
})
except Exception as e:
print(f"Error for {mmsi}: {e}")
time.sleep(1)
print(datetime.utcnow().isoformat(), report)

if __name__ == "__main__":
main()

This pattern produces a compact daily KPI and ESG report ready for BI tools or Slack notifications.

Performance tips and best practices per endpoint

  • /vessels/track: Limit hours to what the UI needs; pagination isn’t applicable here, so keep payloads light. Use include_route and include_predicted_eta selectively to reduce JSON size if you don’t render ETAs every tick.
  • /vessels/nearby: Tune radius and limit. For crowded anchorages, smaller radii produce faster responses and fewer markers to render.
  • /vessels/fleet: Prefer it over many single-vessel track calls. Validate that each item has either imo or mmsi set; deduplicate before sending.
  • /ports/*: Cache for a short interval (e.g., 10–15 minutes) unless you have operational needs for minute-by-minute updates.
  • /vessels/analytics and /vessels/green: Run these in background jobs on a cadence (daily/weekly) and store results to compare trends over time.

Field-by-field cheat sheet for PSV UIs

  • current_position.speed_knots: Show color-coded indicators (0–0.5 idle, 0.5–3 maneuvering, 3–12 transit).
  • navigational_status: Map to icons (under way, at anchor, restricted). Key for safety dashboards.
  • route.eta: Drive quay readiness timers and crew callouts.
  • analytics.total_time_in_port_hours: Benchmark turnaround performance across bases and seasons.
  • green.cii.rating: Track compliance posture and power quarterly ESG summaries.

Common edge cases and how to handle them

  • Stale AIS: If timestamp_utc is older than your threshold (e.g., 30 minutes), flag the position as stale and avoid drawing directional vectors.
  • Null routes: For short offshore hops, a formal route may be absent. Fall back to last_port_visits and current destination fields.
  • Dense port areas: When /vessels/nearby returns many vessels, filter to PSV ship types client-side for readability and performance.
  • Geographic extremes: Consider map projections and bearing calculations near high latitudes for North Sea operations.

From prototype to production: ship faster with vessels-api.com

Whether you are building a lightweight PSV tracker for a new offshore campaign or an enterprise-grade operations platform, vessels-api.com streamlines every step: consistent payloads, predictable parameters, rich analytics, and deep port intelligence—all tuned for real maritime workflows.

Explore the endpoints, wire up a dispatch board, and turn live AIS into decisions that save hours per turnaround and improve safety around your offshore assets.

Vessels API

Ready to build? Try Vessels API for free and connect your first PSV in minutes. Developers shipping production features today can Get started with Vessels API and deliver reliable maritime intelligence to crews, dispatchers, and stakeholders worldwide.

Ready to get started?

Get your API key and start tracking vessels in minutes.

Get API Key

Related posts