Skip to main content
Vessel registry and real-time AIS positions.

GET /api/v1/vessels

Search vessels by port and type. Returns IMO, name, DWT, flag, dimensions. Parameters
NameTypeRequiredDescription
portstringPort slug
typestringVessel type filter
limitnumberDefault 50, max 200
Response
{ "vessels": [...] }
Example
curl -X GET \
  https://axiomoverwatch.io/api/v1/vessels?port=VALUE&type=VALUE

GET /api/v1/positions

Latest AIS positions for all vessels at a port. Includes course, speed, draft, nav status. Parameters
NameTypeRequiredDescription
portstringPort slug
Response
[{ imo_number, latitude, longitude, speed, course, draft, nav_status, name, vessel_type }]
Example
curl -X GET \
  https://axiomoverwatch.io/api/v1/positions?port=VALUE

GET /api/v1/positions/latest

Global GeoJSON FeatureCollection of the latest known position for every tracked vessel (~18K). Powers the public live vessel map. Public, no auth required, CDN-cached for 5 minutes (Cache-Control: public, s-maxage=300, stale-while-revalidate=60). Use this when you want a single global snapshot — for a map, a heatmap, or a periodic dashboard refresh — instead of paging by port. To zoom into a region, supply a bounding box; omit it to get every vessel worldwide. Parameters
NameTypeRequiredDescription
typestringFilter by vessel type (e.g. bulk_carrier, tanker, container)
westnumberWestern longitude of bounding box
southnumberSouthern latitude of bounding box
eastnumberEastern longitude of bounding box
northnumberNorthern latitude of bounding box
All four bounds must be supplied together; partial bounds are ignored and a global response is returned. Bounding boxes that cross the antimeridian (where west > east) are supported. Response
{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "geometry": { "type": "Point", "coordinates": [-46.30, -23.97] },
      "properties": {
        "imo": "9876543",
        "name": "EXAMPLE CARRIER",
        "vessel_type": "bulk_carrier",
        "flag": "PA",
        "speed": 12.4,
        "course": 87,
        "draft": 11.2,
        "destination": "BR SSZ",
        "nav_status": "under way using engine",
        "timestamp": "2026-04-27T18:42:11Z",
        "dwt": 81600,
        "length": 229,
        "beam": 32,
        "build_year": 2014,
        "photo_url": "https://..."
      }
    }
  ],
  "meta": {
    "total_vessel_count": 18243,
    "viewport_vessel_count": 18243,
    "updated_at": "2026-04-27T18:42:30Z",
    "cache_ttl": 300,
    "viewport_applied": false
  }
}
The full global payload is roughly 800 KB gzipped. Refresh no more than once every 5 minutes — additional requests inside that window are served from the CDN cache and return identical data. Example
# Global snapshot
curl https://axiomoverwatch.io/api/v1/positions/latest

# Tankers only, in a Gulf of Mexico bounding box
curl "https://axiomoverwatch.io/api/v1/positions/latest?type=tanker&west=-98&south=18&east=-80&north=31"

GET /api/v1/ais/{provider}/{imo}/location/latest

Public, no-auth, citable lookup of the latest known position for a single vessel. Reads from a deduped materialized view (one row per IMO per source) and returns a JSON-LD payload that AI ingestion pipelines and academic citations can pick up directly. Use this when you need a single vessel’s most recent fix and want a stable, machine-readable contract you can reference from a paper, news article, or LLM training pipeline. For port-wide snapshots use /api/v1/positions; for the global feed use /api/v1/positions/latest.
  • No API key required.
  • Open CORS (Access-Control-Allow-Origin: *).
  • IP-keyed rate limiting: 60 requests/minute and 1,000 requests/UTC day.
  • Cached at the edge for 60 seconds (Cache-Control: public, max-age=60).
  • Released under CC-BY 4.0 with attribution.
A machine-readable OpenAPI 3.1 spec for this endpoint is published at https://axiomoverwatch.io/openapi/positions.yaml. Path parameters
NameTypeRequiredDescription
providerstringAIS source. One of aishub, aisstream, satellite, spire, or any. Use any to get the freshest position across all sources.
imostring7-digit IMO number, zero-padded if needed (matches ^[0-9]{7}$).
Response headers Every successful response includes rate-limit headers:
  • X-RateLimit-Limit-Minute, X-RateLimit-Remaining-Minute
  • X-RateLimit-Limit-Day, X-RateLimit-Remaining-Day
429 responses include Retry-After (seconds until the offending bucket resets). Response (200)
{
  "@context": "https://schema.org",
  "@type": "GeoCoordinates",
  "imo_number": "9876543",
  "vessel_name": "EXAMPLE TRADER",
  "vessel_type": "Bulk Carrier",
  "flag": "PA",
  "latitude": -23.9876,
  "longitude": -46.3214,
  "speed_kt": 0.1,
  "course_deg": 187.4,
  "draft_m": 12.4,
  "destination": "SANTOS",
  "nav_status": "At anchor",
  "timestamp": "2026-04-28T18:42:11.000Z",
  "source": "aishub",
  "freshness_seconds": 312,
  "attribution": {
    "name": "Axiom Overwatch",
    "url": "https://axiomoverwatch.io",
    "cite_as": "Axiom Overwatch — vessel position lookup for IMO 9876543, 2026-04-28T18:42:11.000Z",
    "license": "CC-BY 4.0 with attribution"
  }
}
freshness_seconds is the age of the position relative to request time. Stale positions (vessel hasn’t broadcast in a while) are still returned — inspect freshness_seconds and timestamp to decide whether to trust the fix. The self-declared destination field is frequently inaccurate or deliberately deceptive; for due-diligence work prefer the paid-tier destination-reliability scoring. Error responses
StatusWhen
400provider not in the allowed set, or imo is not 7 digits
404No recent position for this IMO + provider combination
429Rate limit exceeded (per-minute or per-day)
500Backing materialized view lookup failed
Example
# Freshest position across any source
curl https://axiomoverwatch.io/api/v1/ais/any/9876543/location/latest

# Filter to a single source
curl https://axiomoverwatch.io/api/v1/ais/satellite/9876543/location/latest