> ## Documentation Index
> Fetch the complete documentation index at: https://docs.axiomancer.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Vessels & Positions

> Vessel registry and real-time AIS positions — endpoints for vessel lookup by IMO or MMSI, latest position, position history, and global position snapshots.

Vessel registry and real-time AIS positions.

## `GET` `/api/v1/vessels`

Search vessels by port and type. Returns IMO, name, DWT, flag, dimensions.

**Parameters**

| Name    | Type   | Required | Description         |
| ------- | ------ | -------- | ------------------- |
| `port`  | string |          | Port slug           |
| `type`  | string |          | Vessel type filter  |
| `limit` | number |          | Default 50, max 200 |

**Response**

```json theme={null}
{ "vessels": [...] }
```

**Example**

```bash theme={null}
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**

| Name   | Type   | Required | Description |
| ------ | ------ | -------- | ----------- |
| `port` | string | ✓        | Port slug   |

**Response**

```json theme={null}
[{ imo_number, latitude, longitude, speed, course, draft, nav_status, name, vessel_type }]
```

**Example**

```bash theme={null}
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**

| Name    | Type   | Required | Description                                                        |
| ------- | ------ | -------- | ------------------------------------------------------------------ |
| `type`  | string |          | Filter by vessel type (e.g. `bulk_carrier`, `tanker`, `container`) |
| `west`  | number |          | Western longitude of bounding box                                  |
| `south` | number |          | Southern latitude of bounding box                                  |
| `east`  | number |          | Eastern longitude of bounding box                                  |
| `north` | number |          | Northern 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**

```json theme={null}
{
  "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**

```bash theme={null}
# 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`](https://axiomoverwatch.io/openapi/positions.yaml).

**Path parameters**

| Name       | Type   | Required | Description                                                                                                                          |
| ---------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `provider` | string | ✓        | AIS source. One of `aishub`, `aisstream`, `satellite`, `spire`, or `any`. Use `any` to get the freshest position across all sources. |
| `imo`      | string | ✓        | 7-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`)**

```json theme={null}
{
  "@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**

| Status | When                                                        |
| ------ | ----------------------------------------------------------- |
| `400`  | `provider` not in the allowed set, or `imo` is not 7 digits |
| `404`  | No recent position for this IMO + provider combination      |
| `429`  | Rate limit exceeded (per-minute or per-day)                 |
| `500`  | Backing materialized view lookup failed                     |

**Example**

```bash theme={null}
# 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
```
