You need the single freshest AIS position for a known hull, keyed by its official IMO number—not a timeline or a heatmap—so you can update a map, trigger alerts, or reconcile an ETA. By the end of this guide you’ll request the last AIS fix for a vessel by IMO, interpret the response, handle missing fields, and know when to use history or a live feed instead.
What the “last fix” is and when to use it
An AIS vessel position API returns exactly one data point: the most recent AIS fix the platform has for a specific hull at the time of your request. This is ideal when your UI or workflow needs a single coordinate pair (and metadata) to render a marker, verify a departure, or power a quick lookup by IMO in a back office.
On Vessels API the stable, singular path for this is a GET request to /vessel/position with the vessel’s official IMO number. It does not return a 48-hour trail or a mini-series of points. For multi-hour context, use /vessels/track (up to 168 hours). If you need an official live feed, use /vessel/live-position (available on Professional+ plans).
Endpoint and parameters
Base URL:
- https://vessels-api.com/api/V1
Authentication:
- HTTP header
X-API-Key: YOUR_API_KEY
Last known fix by IMO:
- GET
/vessel/position - Query parameter:
imoCode(for example,imoCode=9702510)
Response envelope:
status: numeric status codesuccess: boolean success flagmessage: string message, often useful on errorsdata: object with the last AIS fix and related fields
Quick start: request the last AIS fix by IMO
Make sure you have an API key. If you don’t, start a 7-day trial on the Starter plan ($19.99/mo for 2,500 calls) and retrieve your key.
- Register and start your trial.
- Copy your
X-API-Keyfrom the dashboard. - Call
GET /vessel/positionwithimoCode=9702510to retrieve the last AIS fix for that hull. - When you need multi-hour context, switch to
GET /vessels/track(up to 168 hours).
curl -H "X-API-Key: YOUR_API_KEY" \
"https://vessels-api.com/api/V1/vessel/position?imoCode=9702510"
One more way to call it: Python example
This Python snippet calls the same endpoint to fetch a last fix by IMO and safely reads the response envelope. Replace YOUR_API_KEY before running.
import os
import requests
BASE_URL = "https://vessels-api.com/api/V1"
API_KEY = os.getenv("VESSELS_API_KEY", "YOUR_API_KEY")
def last_fix_by_imo(imo: str):
url = f"{BASE_URL}/vessel/position"
headers = {"X-API-Key": API_KEY}
params = {"imoCode": imo}
r = requests.get(url, headers=headers, params=params, timeout=15)
r.raise_for_status()
payload = r.json()
# Envelope checks
if not isinstance(payload, dict):
raise ValueError("Unexpected payload format")
status = payload.get("status")
success = payload.get("success")
message = payload.get("message")
data = payload.get("data")
if not success:
# Bubble up a clear error with any server message
raise RuntimeError(f"Vessels API error (status={status}): {message}")
if data is None:
# Data may be null or missing if there is no recent fix
return None
# Extract common fields defensively; names can vary by endpoint revision.
# Only access keys after verifying their presence.
fix = {
"latitude": data.get("latitude"),
"longitude": data.get("longitude"),
"speed": data.get("speed"), # typically knots if present
"course": data.get("course"), # degrees (true) if present
"timestamp": data.get("timestamp"),
"imo": data.get("imo"),
"mmsi": data.get("mmsi"),
"name": data.get("name"),
}
return fix
if __name__ == "__main__":
fix = last_fix_by_imo("9702510")
if fix is None:
print("No recent AIS fix is available for this hull.")
else:
print(f"IMO {fix.get('imo')} last position: "
f"{fix.get('latitude')}, {fix.get('longitude')} "
f"at {fix.get('timestamp')}")
Reading the JSON: what to look for
The API returns an envelope with status, success, message, and data. The data object contains identifiers (such as IMO, MMSI, and name when available), positional attributes (latitude and longitude in decimal degrees), movement attributes (speed and course when available), and a timestamp for the AIS fix. Values can be absent or null if they were not present in the underlying AIS message.
The official sample below demonstrates the numeric positioning values on a track response for a specific hull (MMSI 258785000, name ZJ ATLANTIC). It is a historical sample, not the last-fix-by-IMO call used in the title. Use it to understand the numeric fields you’ll parse; when you implement the single last fix from IMO, call /vessel/position?imoCode=9702510 as shown above.
{
"status": 200,
"success": true,
"message": "OK",
"data": {
"vessel": {"imo": "9702510", "mmsi": "258785000", "name": "ZJ ATLANTIC"},
"current_position": {
"latitude": -34.603722,
"longitude": -58.381592,
"speed_knots": 15.5,
"course_degrees": 145,
"navigational_status": "Underway using engine",
"timestamp_utc": "2026-02-09T10:30:00Z",
"destination": "BRSSZ",
"eta": "2026-02-11T08:00:00Z"
}
}
}
What you’ll extract in practice:
- Identifiers: IMO, MMSI, and vessel name help confirm you’re plotting the correct hull.
- Latitude and longitude: decimal degrees suitable for map SDKs; verify your map expects lat, then lon.
- Speed and course: if present, speed is typically in knots and course in degrees (true), useful for heading arrows or ETA updates.
- Timestamp: the fix time for freshness checks, shown in the sample as a standard timestamp. Treat it as UTC for storage and comparisons unless the field explicitly includes timezone data.
Error handling, missing values, and retries
Always branch on the envelope:
success=false: do not parsedata. Throw or surfacemessagealong withstatus.data=nullor missing: there is no current fix for that IMO; handle gracefully by showing “no recent AIS” in your UI or queue a retry.
Missing movement fields (speed, course) are common when the relevant AIS sentence was not present. Keep your rendering robust by checking for nulls and defaulting map arrows or speed readouts to “unknown” states rather than zero.
Network timeouts and server errors should be retried with exponential backoff. Cache successful responses to reduce duplicate calls when multiple widgets or services request the same hull within a short interval.
When to choose track history or a live feed
If you need more than the single latest fix, call:
GET /vessels/trackfor up to 168 hours of history. Use this for sparklines, breadcrumb trails, anomaly detection, and arrival-departure analysis.GET /vessel/live-positionto tap into the official live feed (Professional+). Use this when you must minimize latency and fan out updates to many consumers.
Note there is no geofence endpoint. To build geofence logic, poll positions or tracks and apply your own polygon test in your service.
Units, timestamps, and caching tips
- Coordinates: decimal degrees (latitude, longitude). Ensure your client doesn’t expect radians or a reversed order.
- Movement: speed values, when present, are used as knots in common maritime contexts; verify units in your downstream calculations.
- Timestamps: store and compare as UTC. If your UI must show local times, convert at the edge and keep UTC internally for consistency.
- Caching: cache by IMO for short TTLs aligned with your refresh cadence. In list views, render cached positions and refresh in background to avoid UI stalls.
Environment setup and observability
Configuration
- Store
X-API-Keyin environment variables or a secrets manager. - Parameterize the base URL
https://vessels-api.com/api/V1so environments are easy to swap if needed.
Logging
- Log
status,success, and request duration for each call. Redact the API key. - On
success=false, capture themessagefor triage.
Testing with MCP
For endpoint exploration, collections, and quick iteration, open the MCP tool and import the endpoints. It’s helpful for validating headers and seeing the envelope schema before you wire it into code.
Going live in minutes
- Register for the 7-day trial on Starter ($19.99/mo, 2,500 calls).
- Copy your
X-API-Keyfrom the dashboard. - Call
GET https://vessels-api.com/api/V1/vessel/position?imoCode=9702510with your key in the header. - Switch to
GET /vessels/trackfor up to 168 hours of history when you need traces.
If you want a deeper reference while you build, open the Documentation.
FAQ
Does the last-fix endpoint return more than one point?
No. /vessel/position returns a single latest AIS fix for the requested IMO. Use /vessels/track for up to 168 hours of history.
Can I filter by a region or geofence?
There is no geofence endpoint. Implement geofencing by polling positions or tracks and testing against your polygons server-side.
What if success is false or data is null?
Treat success=false as a hard error; surface the message and retry if appropriate. If data is null or missing, no recent fix is available—render a fallback state and try again later.
Which identifier should I pass to get the last fix?
For the last point by official registry identity, pass the IMO with imoCode to /vessel/position. If you need a demonstration of numeric position fields, see the sample above (which shows a track for a specific MMSI and vessel name).
How do I get a continuous stream of updates?
Use /vessel/live-position (Professional+). For occasional UI refreshes, stick with /vessel/position and cache between polls.
Ready to fetch the last AIS fix by IMO and ship your integration? Start your 7-day trial, pull a live position with one GET call, and expand to history when you need it: Register.