AIS Vessel Position API: Last Fix From IMO

AIS Vessel Position API: Last Fix From IMO

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 code
  • success: boolean success flag
  • message: string message, often useful on errors
  • data: 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.

  1. Register and start your trial.
  2. Copy your X-API-Key from the dashboard.
  3. Call GET /vessel/position with imoCode=9702510 to retrieve the last AIS fix for that hull.
  4. 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 parse data. Throw or surface message along with status.
  • data=null or 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/track for up to 168 hours of history. Use this for sparklines, breadcrumb trails, anomaly detection, and arrival-departure analysis.
  • GET /vessel/live-position to 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-Key in environment variables or a secrets manager.
  • Parameterize the base URL https://vessels-api.com/api/V1 so 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 the message for 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.

MCP

Going live in minutes

  1. Register for the 7-day trial on Starter ($19.99/mo, 2,500 calls).
  2. Copy your X-API-Key from the dashboard.
  3. Call GET https://vessels-api.com/api/V1/vessel/position?imoCode=9702510 with your key in the header.
  4. Switch to GET /vessels/track for 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.

Ready to get started?

Get your API key and start tracking vessels in minutes.

Get API Key