Bulk Carrier Tracking API: Search, Track and Nearby

Bulk Carrier Tracking API: Search, Track and Nearby

Your bulk carrier team needs reliable AIS data to answer three questions fast: which bulker is it, where is it now (and where has it been), and what ships are nearby that might affect an approach or transit. By the end of this guide you’ll be able to search for bulk carriers, track live positions with recent history and voyage context, and query nearby traffic around any coordinate—using a single REST API with one key and consistent JSON responses.

Why this API for bulk carrier operations

vessels-api.com exposes 18 REST endpoints across vessel search, live AIS tracking, fleet operations, analytics, port intelligence, and IMO CII scoring. Every response follows the same JSON envelope—{status, success, message, data}—and every request authenticates with a single X-API-Key. For transportation workflows around bulkers, you can stitch together:

Illustration: Bulk Carrier Tracking API: Search, Track and Nearby
  • GET /vessels/search — find bulk carriers by name/IMO/MMSI with filters (DWT, year built, flag, etc.).
  • GET /vessels/track — current position, up to 168 hours of history, route, and optional predicted ETA.
  • GET /vessels/nearby — traffic around a lat/lon within a selected radius.
  • GET /vessels/analytics — voyage aggregates per vessel, port, or a fleet list.
  • POST /vessels/fleet — batch routes/positions for multiple bulkers in one hit.

Coverage is global, refresh is near real-time, and each field is designed to wire directly into dashboards, dispatch tooling, and operational alerts.

Authentication, base URL, and response model

All endpoints share the same base URL and header:

  • Base URL: https://vessels-api.com/api/V1
  • Header: X-API-Key: YOUR_API_KEY

All responses share a consistent envelope:

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

Error codes you should handle:

  • 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

1) Search for bulk carriers with filters

Use GET /vessels/search to locate a specific bulker or build lists of candidates for a route plan. You can filter by ship_type=Bulk Carrier, flag, DWT, TEU (where applicable), and build year.

cURL example: search bulk carriers named “Atlantic” under Panama

curl -s -H "X-API-Key: YOUR_API_KEY" \
"https://vessels-api.com/api/V1/vessels/search?query=atlantic&flag=Panama&ship_type=Bulk%20Carrier&per_page=5"

Illustrative JSON snippet (values are examples; field names are exact):

{
"status": 200,
"success": true,
"message": "OK",
"data": {
"vessels": [
{
"imo": "9461234",
"mmsi": "354123000",
"name": "ATLANTIC HORIZON",
"flag": "Panama",
"vessel_type": "Bulk Carrier",
"gross_tonnage": 43000,
"deadweight_tonnage": 82000,
"year_built": 2010,
"length_m": 225,
"width_m": 32
},
{
"imo": "9526789",
"mmsi": "354789000",
"name": "ATLANTIC SPIRIT",
"flag": "Panama",
"vessel_type": "Bulk Carrier",
"gross_tonnage": 38000,
"deadweight_tonnage": 76000,
"year_built": 2009,
"length_m": 225,
"width_m": 32
}
],
"pagination": {
"current_page": 1,
"per_page": 5,
"total": 12,
"last_page": 3
}
}
}

What matters for bulkers:

  • deadweight_tonnage is in metric tons (use it to segment Handy vs Panamax vs Capesize workflows).
  • length_m and width_m help check berth fit constraints.
  • pagination lets you stream larger result sets with per_page up to 100.

2) Live tracking with history and route context

GET /vessels/track returns a bulker’s current AIS position, optional 24–168 hours of historical positions, current route with predicted ETA, and last port calls. Units are:

  • Coordinates in decimal degrees; EPSG:4326.
  • Speed in knots; course/heading in degrees (0–359).
  • Timestamps are UTC (ISO-8601 preferred in your UI).

cURL example: track a known MMSI for 48 hours with route

Below uses the documented track fixture MMSI 258785000. Values shown are illustrative.

curl -s -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"

Python example: parse current position, route, and last fixes

import requests

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

params = {
"mmsi": "258785000",
"hours": "48",
"include_route": "true",
"include_predicted_eta": "true"
}

resp = requests.get(
f"{BASE_URL}/vessels/track",
headers={"X-API-Key": API_KEY},
params=params,
timeout=20
)
resp.raise_for_status()
payload = resp.json()

data = payload.get("data", {})
vessel = data.get("vessel", {})
current = data.get("current_position", {})
route = data.get("route", {})
history = data.get("position_history", []) # most recent last

print("Vessel:", vessel.get("name"), vessel.get("imo"), vessel.get("mmsi"))
print("Now @", current.get("timestamp_utc"), "lat/lon:",
current.get("latitude"), current.get("longitude"),
"spd(kn):", current.get("speed_knots"))
if route:
print("Route:", route.get("departure_port"), "→", route.get("destination_port"),
"ETA:", route.get("eta"))
if history:
print("Last fix:", history[-1]["timestamp_utc"], history[-1]["latitude"], history[-1]["longitude"])

Illustrative JSON snippet (minimal fields, names exact):

{
"status": 200,
"success": true,
"message": "OK",
"data": {
"vessel": { "imo": "9461234", "mmsi": "258785000", "name": "BULK EXAMPLE" },
"current_position": {
"latitude": -34.9123,
"longitude": -56.2034,
"speed_knots": 12.4,
"course_degrees": 78,
"heading_degrees": 80,
"navigational_status": "Under way using engine",
"timestamp_utc": "2026-09-01T12:20:00Z",
"destination": "BRSSZ",
"eta": "2026-09-03T08:00:00Z"
},
"position_history": [
{ "latitude": -35.0100, "longitude": -56.6000, "speed_knots": 12.1, "course_degrees": 80, "timestamp_utc": "2026-08-31T20:20:00Z" },
{ "latitude": -34.9500, "longitude": -56.4000, "speed_knots": 12.2, "course_degrees": 79, "timestamp_utc": "2026-09-01T06:20:00Z" }
],
"route": {
"departure_port": "ARBBT",
"departure_time": "2026-08-31T10:10:00Z",
"destination_port": "BRSSZ",
"eta": "2026-09-03T08:00:00Z",
"distance_nm": 520,
"avg_speed_knots": 12.3
},
"last_port_visits": [
{ "port_id": "ARBUE", "arrival_time": "2026-08-28T02:00:00Z", "departure_time": "2026-08-31T10:10:00Z" }
]
}
}

Key fields for operations:

  • current_position.timestamp_utc: normalize all alerts and ETAs in UTC.
  • navigational_status: gate conditions for “at sea” vs “in port” logic.
  • route.eta and destination_port: drive berth scheduling and trucking windows.
  • position_history: generate tracklines or compute turn-around alerts when speed_knots drops to near-zero.

3) Nearby traffic around approaches, anchorages, or bunkering

GET /vessels/nearby helps you monitor risk and opportunity: tugs available near a pilot station, congestion at a typical anchorage for Capesize vessels, or meeting situations on a narrow fairway.

cURL example: 30 NM around Buenos Aires approach

curl -s -H "X-API-Key: YOUR_API_KEY" \
"https://vessels-api.com/api/V1/vessels/nearby?latitude=-34.60&longitude=-58.38&radius=30&ship_type=Bulk%20Carrier&limit=25"

Illustrative JSON snippet (field names exact):

{
"status": 200,
"success": true,
"message": "OK",
"data": {
"center": { "latitude": -34.60, "longitude": -58.38 },
"radius_nm": 30,
"total": 9,
"vessels": [
{
"imo": "9526789",
"mmsi": "701234000",
"name": "RIO BULKER",
"ship_type": "Bulk Carrier",
"position": { "latitude": -34.72, "longitude": -58.55, "timestamp_utc": "2026-09-01T12:16:00Z" },
"distance_nm": 8.3,
"speed_knots": 9.8,
"course_degrees": 102,
"navigational_status": "Under way using engine"
}
]
}
}

Operational tips:

  • radius defaults to 50 NM and maxes at 200 NM.
  • Use ship_type if you want bulker-only traffic vs a full radar sweep.
  • distance_nm gives a straight-line great-circle distance from the center.

4) Analytics and fleet batching for bulk carrier dashboards

Two endpoints save time when you scale from one vessel to many: /vessels/analytics for aggregated KPIs and /vessels/fleet for batching multiple ships in one request.

Voyage analytics (per vessel)

Compute distance sailed, average/max speed, and port calls over a selectable period for performance and schedule adherence checks.

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

Illustrative JSON snippet:

{
"status": 200,
"success": true,
"message": "OK",
"data": {
"type": "vessel",
"mmsi": "258785000",
"imo": "9461234",
"name": "BULK EXAMPLE",
"period": "7d",
"statistics": {
"total_distance_nm": 1423.5,
"avg_speed_knots": 11.8,
"max_speed_knots": 14.2,
"port_calls_count": 2,
"total_time_in_port_hours": 38.2,
"ports_visited": ["ARBUE", "BRSSZ"]
}
}
}

Use cases:

  • Benchmark time-in-port by terminal for schedule risk modeling.
  • Detect underperformance when avg_speed_knots trails plan even in fair weather.
  • Compute emissions intensity later by combining distance with CII data when needed.

Batch fleet positions and routes

POST /vessels/fleet retrieves multiple bulkers in one request, reducing network overhead for wallboard dashboards.

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

Illustrative JSON snippet:

{
"status": 200,
"success": true,
"message": "OK",
"data": {
"fleet": { "total_vessels": 2, "vessels_at_sea": 1, "vessels_in_port": 1 },
"vessels": [
{
"imo": "9122556",
"mmsi": "538001234",
"name": "IRON MERIDIAN",
"position": {
"latitude": 1.2101,
"longitude": 103.8090,
"speed_knots": 0.2,
"course_degrees": 0,
"timestamp_utc": "2026-09-01T12:10:00Z"
},
"route": {
"departure_port": "MYTPP",
"departure_time": "2026-08-30T18:00:00Z",
"destination_port": "SGSIN",
"eta": "2026-09-02T04:00:00Z",
"distance_nm": 40,
"avg_speed_knots": 10.8
}
},
{
"imo": "9300001",
"mmsi": "309374000",
"name": "PACIFIC ORE",
"position": {
"latitude": -20.3140,
"longitude": 57.4980,
"speed_knots": 12.0,
"course_degrees": 260,
"timestamp_utc": "2026-09-01T12:12:00Z"
},
"route": null
}
]
}
}

Practical notes:

  • Send mixed identifiers (IMO or MMSI) per vessel object; at least one is required.
  • include_positions and include_routes flags let you slim payloads for refreshes.
  • Use fleet.vessels_at_sea to summarize operations in your header bar without recomputing.

Putting the endpoints together for bulk carrier workflows

Here’s a simple path to production for a bulker ETA and approach-monitoring tool:

  1. Resolve vessels with GET /vessels/search filtered by ship_type=Bulk Carrier and your fleet’s flags or DWT floor.
  2. Persist IMO/MMSI pairs in your DB. Use IMO as the primary key where available; MMSI can change more often.
  3. Poll GET /vessels/track every 5–10 minutes for active voyages; pass include_route=true and hours=24 for near-term tracks.
  4. When a route ETA is within 12 hours of a pilot station, call GET /vessels/nearby centered on the approach waypoint to detect crossing traffic or tug availability.
  5. Compute schedule risk by comparing route.eta against terminal slot times; route.distance_nm / current speed gives a quick sanity check.
  6. Render KPIs with GET /vessels/analytics for weekly summaries across your bulker program.
  7. For fleet overviews, switch to POST /vessels/fleet to cut your refresh latency and request volume.

Field behavior, units, and implementation details

  • Timestamps: All timestamps are UTC. Persist as UTC and convert at the edge for user timezones.
  • Speed and course: speed_knots (kn) and degrees true (0–359). Heading can differ from course during maneuvers.
  • Distance: distance_nm is nautical miles when provided.
  • Pagination: /vessels/search supports page and per_page (max 100). Use pagination.total to preload page counts.
  • Polling cadence: For live maps, 2–5 minute intervals are common. For analytics, once per period is sufficient.
  • Error handling: Retry 429 (Rate limit exceeded) with exponential backoff. Do not retry 400/422 without fixing inputs. For 404, confirm IMO/MMSI and consider fallback to /vessel/mmsi-position if you maintain legacy integrations.
  • Idempotence: GETs are read-only. Only /vessels/fleet is POST; it is a read-style batch call and safe to retry on network timeouts.
  • Caching: Cache static particulars from /vessels/search for days; cache /vessels/track for a short TTL (e.g., 60–120 seconds) if your UI tolerates slight staleness.

End-to-end example: search → track → nearby

Step 1 — Search a bulker candidate list

curl -s -H "X-API-Key: YOUR_API_KEY" \
"https://vessels-api.com/api/V1/vessels/search?query=cape&ship_type=Bulk%20Carrier&min_dwt=120000&per_page=3"

Step 2 — Track one selection for 24h with route and ETA

curl -s -H "X-API-Key: YOUR_API_KEY" \
"https://vessels-api.com/api/V1/vessels/track?imo=9461234&hours=24&include_route=true&include_predicted_eta=true"

Step 3 — Monitor nearby vessels at the arrival waypoint

curl -s -H "X-API-Key: YOUR_API_KEY" \
"https://vessels-api.com/api/V1/vessels/nearby?latitude=-23.96&longitude=32.74&radius=20&limit=50&ship_type=Bulk%20Carrier"

This simple pipeline powers a control-room map that filters to bulkers, shows where they are and where they’re headed, and reveals local traffic that could impact pilot boarding or anchorage selection.

Security and operational considerations

  • Transport: Always use HTTPS. Do not log your API key in client-side apps; route calls through your backend.
  • Input validation: For /vessels/nearby, clamp radius to 200 NM and validate lat/lon ranges server-side to avoid 422 errors.
  • Graceful degradation: If include_route=true yields no route, handle a null route object without crashing the map layer.
  • Monitoring: Alert on abnormal navigational_status transitions (e.g., “Aground”) for incident workflows.

FAQ

Which identifier should I use for bulk carriers: IMO or MMSI?
Use IMO as the durable identifier when available; MMSI can change with flag or equipment updates. Endpoints accept either, but IMO is preferred for long-lived records.

How far back can I fetch track history?
Use the hours parameter with GET /vessels/track up to 168 hours (7 days). The default is 24 hours.

How do I limit nearby results to bulkers only?
Pass ship_type=Bulk Carrier to GET /vessels/nearby to filter the traffic list to bulk carriers.

What timezone are timestamps in?
All timestamps are UTC. Convert at render time for end users; keep storage in UTC.

How do I handle rate limits?
On HTTP 429, back off and retry with jitter. Consider batching with POST /vessels/fleet to reduce call volume for dashboards.

Next steps

Stand up your bulker search and tracking backend in an afternoon: resolve vessels with /vessels/search, poll /vessels/track for live status and ETAs, and layer /vessels/nearby to detect approach risks. When you’re ready to scale across a program, add /vessels/analytics and /vessels/fleet for fast KPIs and low-latency wallboards.

Register • Documentation • MCP

Ready to get started?

Get your API key and start tracking vessels in minutes.

Get API Key

Related posts