# Baltic & Nordic Vessel Tracker — Live AIS for AI Agents (`haketa/vessel-tracker`) Actor

Track live ships in the Baltic & Nordic seas via AIS. Get real-time vessel positions, speed, course, type, size, IMO/MMSI, flag and destination — filter by area, MMSI or ship type. Real-time maritime grounding for AI agents, logistics & compliance.

- **URL**: https://apify.com/haketa/vessel-tracker.md
- **Developed by:** [Haketa](https://apify.com/haketa) (community)
- **Categories:** AI, Agents, Travel
- **Stats:** 1 total users, 1 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.70 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Baltic & Nordic Vessel Tracker — Live AIS for AI Agents

Track **live ships** across the **Baltic and Nordic seas** in real time. Give this Actor a sea area, a ship type, or a list of MMSI numbers and it returns every matching vessel's **live position, speed, course, type, size, flag and destination** — clean, structured, and ready for an AI agent, a logistics pipeline, or a maritime dashboard.

No API key, no setup. Just current AIS vessel data, filterable the way you need it.

***

### Why this Actor?

A large language model can't know where a ship is right now — AIS positions change by the minute. This Actor is the **real-time maritime grounding** an agent or app needs: ask "what tankers are in the Gulf of Finland heading to St. Petersburg?" and get back a precise, structured answer with names, flags and destinations.

- **AI agents & assistants** — a live tool an agent can call to answer maritime questions with real data.
- **Logistics & supply chain** — see what's moving, where, and toward which port.
- **Compliance & risk** — watch tanker traffic and flag states in sensitive corridors (the Baltic is a focus area for "shadow fleet" and sanctions monitoring).
- **Maritime dashboards & research** — feed a live vessel layer into your own map or analysis.

The Baltic and Gulf of Finland are among the busiest and most geopolitically watched waters in the world — this Actor gives you a clean, programmable window into them.

***

### What you get

For every vessel the Actor returns:

| Field | Description |
| --- | --- |
| `mmsi` | Maritime Mobile Service Identity |
| `imo` | IMO number (permanent hull ID) |
| `name` | Vessel name |
| `callSign` | Radio call sign |
| `shipTypeText` | Cargo / Tanker / Passenger / Fishing / Tug / … |
| `flag` | Flag state, derived from the MMSI |
| `latitude`, `longitude` | Live position |
| `speedKnots` | Speed over ground |
| `courseOverGround` | Course over ground (degrees) |
| `heading` | True heading (degrees) |
| `navStatusText` | Under way / At anchor / Moored / Fishing / … |
| `destination` | Reported destination |
| `draughtMeters` | Current draught |
| `lengthMeters`, `widthMeters` | Vessel dimensions |
| `positionTime` | When the AIS feed was last updated |
| `scrapedAt` | Extraction timestamp |

Live position and movement are joined with each ship's identity and dimensions into one flat record — no separate lookups.

***

### Example output

```json
{
  "mmsi": "219598000",
  "imo": "9692129",
  "name": "NORD SUPERIOR",
  "callSign": "OWPA2",
  "shipTypeText": "Tanker",
  "flag": "Denmark",
  "latitude": "55.770832",
  "longitude": "20.85169",
  "speedKnots": "12.4",
  "courseOverGround": "246.5",
  "heading": "247",
  "navStatusText": "Under way using engine",
  "destination": "NL AMS",
  "draughtMeters": "11.8",
  "lengthMeters": "183",
  "widthMeters": "32",
  "positionTime": "2026-07-06T14:11:51Z",
  "scrapedAt": "2026-07-06T14:12:43.965Z"
}
```

***

### Input

| Field | Type | Default | Description |
| --- | --- | --- | --- |
| `region` | string | `all` | Sea area: `all`, `gulf-of-finland`, `gulf-of-bothnia`, `baltic-proper`, `danish-straits`, `kattegat-skagerrak`, or `custom`. |
| `bbox` | string | — | Custom bounding box `minLon,minLat,maxLon,maxLat` (when `region` = `custom`). |
| `mmsi` | array | — | Track only these vessels by MMSI. |
| `shipType` | string | `all` | `cargo`, `tanker`, `passenger`, `fishing`, `tug`, `sailing`, `pleasure`, `high-speed`, `other`. |
| `nameQuery` | string | — | Only vessels whose name contains this text. |
| `destination` | string | — | Only vessels whose destination contains this text. |
| `movingOnly` | boolean | `false` | Exclude stopped/anchored/moored vessels. |
| `maxItems` | integer | `1000` | Maximum vessels to return. |

#### Track all tankers heading to a port

```json
{
  "region": "gulf-of-finland",
  "shipType": "tanker",
  "destination": "PETERSBURG"
}
```

#### Watch specific vessels

```json
{
  "mmsi": ["230123456", "265847000"],
  "movingOnly": false
}
```

#### A custom area

```json
{
  "region": "custom",
  "bbox": "18,59,21,60",
  "shipType": "cargo"
}
```

***

### Sea areas

| Area | Roughly covers |
| --- | --- |
| **Gulf of Finland** | Helsinki, Tallinn, St. Petersburg approaches |
| **Gulf of Bothnia** | Between Finland and Sweden |
| **Baltic Proper** | Central Baltic, Gotland, southern approaches |
| **Danish Straits** | Øresund, Great Belt — the gateway in/out of the Baltic |
| **Kattegat & Skagerrak** | Between Denmark, Sweden and Norway |
| **All** | The full Baltic & Nordic coverage area |

For anything more precise, use a `custom` bounding box.

***

### Use cases in detail

#### 1. AI agents & real-time tools

Expose this as a tool an assistant can call: "Which cargo ships are near Helsinki?" or "Where is the vessel with MMSI 265847000?" — the agent gets structured data it can reason over, in seconds.

#### 2. Logistics & port operations

See inbound traffic to a port by filtering on `destination`, or watch a fleet by MMSI. Combine with draught and dimensions to plan berthing and pilotage.

#### 3. Compliance, sanctions & "shadow fleet" monitoring

Filter tankers by area, flag and destination to keep an eye on sensitive corridors. Flag state and destination make it easy to flag traffic worth a closer look — a strong companion to name-based sanctions screening.

#### 4. Maritime dashboards & mapping

Feed a live vessel layer into your own map (each record has latitude/longitude and heading), refreshed on demand.

#### 5. Research & journalism

Study traffic patterns, port calls and flag distributions in one of the world's most closely-watched maritime regions.

***

### How to use it

1. Click **Try for free**.
2. Pick a `region` (and optionally a `shipType`, `destination`, or `mmsi` list).
3. Click **Start**.
4. Read the results as **JSON, CSV, Excel**, or via the Apify API.

Runs finish in seconds — the whole area is fetched and filtered in one pass.

***

### Calling from the API

```bash
curl -X POST "https://api.apify.com/v2/acts/YOUR_ACTOR_ID/runs?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "region": "gulf-of-finland", "shipType": "tanker" }'
```

Then fetch the dataset:

```bash
curl "https://api.apify.com/v2/acts/YOUR_ACTOR_ID/runs/last/dataset/items?token=YOUR_APIFY_TOKEN"
```

Works with webhooks, Zapier, Make and n8n so you can pipe a live vessel feed straight into your systems.

***

### Frequently asked questions

**What area does it cover?**
The Baltic Sea and Nordic waters — Gulf of Finland, Gulf of Bothnia, the Baltic Proper, the Danish Straits, and the Kattegat/Skagerrak. This is coastal (terrestrial) AIS, which covers these busy, enclosed seas very well.

**How fresh is the data?**
Positions are pulled live on each run; `positionTime` tells you when the feed was last updated.

**Can I track a specific ship?**
Yes — pass its MMSI (or several) in the `mmsi` field.

**Can I filter by ship type or destination?**
Yes — `shipType` (tanker, cargo, passenger, …) and `destination` (substring match on the reported destination).

**How do I get only moving ships?**
Set `movingOnly: true` to drop anchored, moored and stopped vessels.

**What's the `flag` field?**
The flag state, derived from the vessel's MMSI country code — useful for spotting flags of convenience and monitoring specific registries.

**Can an AI agent call this automatically?**
Yes — it's keyless and returns structured JSON, so it works cleanly as an agent/MCP tool.

***

### Notes & responsible use

This Actor surfaces **publicly broadcast AIS data** for the Baltic and Nordic region for informational, logistics and research purposes. AIS positions are self-reported by vessels and can be delayed, inaccurate, or absent; treat the data as indicative, not authoritative, and don't rely on it for safety-of-navigation or as sole evidence for any decision. Use it in line with applicable laws in your jurisdiction.

*Source: official Baltic maritime AIS data (Fintraffic / digitraffic.fi), licensed CC BY 4.0.*

***

### Support

Want another sea area, more ship-type detail, or an extra field? Open an issue from the Actor's page. Fair winds.

# Actor input Schema

## `region` (type: `string`):

Pick the Baltic or Nordic sea area you want to watch. Choose "All" to see the whole live fleet across the region.

## `shipType` (type: `string`):

Show only one category of vessel, or keep "All types" to include everything.

## `movingOnly` (type: `boolean`):

Turn on to hide ships that are stopped, anchored or moored, and keep only vessels currently under way.

## `nameQuery` (type: `string`):

Optional. Type part of a ship name to keep only matching vessels (case-insensitive). Leave blank to include every vessel.

## `destination` (type: `string`):

Optional. Type part of a reported destination port to keep only ships heading there, e.g. HELSINKI or ROTTERDAM. Leave blank for all destinations.

## `maxItems` (type: `integer`):

Cap how many vessels to return. Set 0 for no limit (return everything that matches your filters).

## `mmsi` (type: `array`):

Optional. Follow only certain ships by their MMSI number, e.g. 230123456. Leave empty to include the whole fleet.

## `bbox` (type: `string`):

Optional. Only used when Sea area is set to "Custom map area". Enter a bounding box as minLon,minLat,maxLon,maxLat (for example 22,59,28,61 for the Gulf of Finland).

## `proxyConfiguration` (type: `object`):

Apify Proxy settings. This data source is public, so a proxy is off by default and not needed for normal use.

## Actor input object example

```json
{
  "region": "all",
  "shipType": "all",
  "movingOnly": false,
  "maxItems": 100,
  "mmsi": [],
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `vessels` (type: `string`):

Download the full list of tracked vessels.

## `mmsi` (type: `string`):

Maritime Mobile Service Identity

## `imo` (type: `string`):

IMO number

## `name` (type: `string`):

Vessel name

## `callSign` (type: `string`):

Radio call sign

## `shipTypeText` (type: `string`):

Ship type

## `flag` (type: `string`):

Flag state (from MMSI)

## `latitude` (type: `string`):

Latitude

## `longitude` (type: `string`):

Longitude

## `speedKnots` (type: `string`):

Speed over ground in knots

## `courseOverGround` (type: `string`):

Course over ground (degrees)

## `heading` (type: `string`):

True heading (degrees)

## `navStatusText` (type: `string`):

Navigational status

## `destination` (type: `string`):

Reported destination

## `draughtMeters` (type: `string`):

Draught in meters

## `lengthMeters` (type: `string`):

Length in meters

## `widthMeters` (type: `string`):

Width in meters

## `positionTime` (type: `string`):

Timestamp of the position

## `scrapedAt` (type: `string`):

Extraction timestamp

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "nameQuery": "",
    "destination": "",
    "maxItems": 100,
    "mmsi": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("haketa/vessel-tracker").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "nameQuery": "",
    "destination": "",
    "maxItems": 100,
    "mmsi": [],
}

# Run the Actor and wait for it to finish
run = client.actor("haketa/vessel-tracker").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "nameQuery": "",
  "destination": "",
  "maxItems": 100,
  "mmsi": []
}' |
apify call haketa/vessel-tracker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,haketa/vessel-tracker"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/pW580bScEOE525WpX/builds/oXARNK6EUQRaAUIUL/openapi.json
