API
Alle Flotten- und Ereignisdaten stehen auch als offene, unauthentifizierte JSON-API zur Verfügung — kein Account, kein API-Key nötig. Gedacht für eigene Automatisierungen (Home Assistant, n8n, Node-RED, eigene Skripte). Um Missbrauch vorzubeugen gilt ein Rate-Limit von 60 Requests/Minute pro IP-Adresse; die Antwort enthält dazu die Header X-RateLimit-Limit und X-RateLimit-Remaining, bei Überschreitung 429 mit Retry-After.
GET /api/v1/ships
Aktueller Status aller 8 Schiffe der Flotte.
curl https://schiffstracker.example.de/api/v1/ships
[
{
"mmsi": "477116800",
"slug": "hefei",
"name": "BYD Hefei",
"latitude": 53.55,
"longitude": 8.58,
"sog": 15.2,
"cog": 41,
"destination_name": "Hamburg",
"destination_confidence": "gesichert",
"heading_to_germany": 1,
"eta": "2026-08-27T06:00:00.000Z",
"position_updated_at": "2026-08-25T20:04:00.000Z",
"...": "weitere Felder, siehe /api/v1/ships/{slug}"
}
]GET /api/v1/ships/{slug}
Status eines einzelnen Schiffs. Die Slugs entsprechen den URLs der Schiffsseiten (z. B. hefei für /schiff/hefei). Unbekannter Slug → 404.
curl https://schiffstracker.example.de/api/v1/ships/hefei
{
"mmsi": "477116800",
"slug": "hefei",
"name": "BYD Hefei",
"latitude": 53.55,
"longitude": 8.58,
"sog": 15.2,
"cog": 41,
"destination_name": "Hamburg",
"destination_confidence": "gesichert",
"heading_to_germany": 1,
"eta": "2026-08-27T06:00:00.000Z",
"position_updated_at": "2026-08-25T20:04:00.000Z",
"approach": {
"state": "approaching",
"closingKm": 180.4,
"windowHours": 22.5,
"nearestPort": { "locode": "DEHAM", "name": "Hamburg", "distanceKm": 210.1 }
}
}Das Feld eta ist die voraussichtliche Ankunftszeit, wie die Besatzung sie im AIS meldet (ISO-Zeitstempel in UTC, oder null). Sie wird nicht geprüft und nach der Ankunft oft nicht zurückgesetzt.
Das Feld approach ist eine bewegungsbasierte Richtungsschätzung aus der Fahrtspur (unabhängig vom gemeldeten Ziel): state ist approaching, receding, steady oder unknown; closingKm ist die Netto-Annäherung an den nächsten deutschen Hafen im Zeitfenster. Es steht auch bei GET /api/v1/ships pro Schiff dabei.
Das Feld projection ist die voraussichtliche Route zum deutschen Zielhafen (oder null): kind ist to-port, points sind [lat, lng]-Paare von der aktuellen Position zum Hafen. Die aktuelle Fahrtrichtung eines Schiffs steckt separat im Feld cog (Kurs über Grund).
GET /api/v1/ships/{slug}/track
Die aufgezeichnete Fahrtspur eines Schiffs (ausgedünnte Positionspunkte, älteste zuerst). Optionaler Query-Parameter sinceHours (Standard 72, maximal 720 = 30 Tage Aufbewahrung).
curl "https://schiffstracker.example.de/api/v1/ships/hefei/track?sinceHours=48"
[
{
"id": 1024,
"mmsi": "477116800",
"latitude": 51.9,
"longitude": 4.1,
"sog": 12.4,
"cog": 88,
"recorded_at": "2026-08-25T18:02:00.000Z"
}
]GET /api/v1/events
Ereignisse zu Kurs auf Deutschland und Ankünften in deutschen Häfen (dieselben, die auch im RSS-Feed stehen; bei gesichertem Ziel und bei Ankunft zusätzlich als Discord-Benachrichtigung), als JSON statt XML.
Optionale Query-Parameter: limit (Standard 30, maximal 100), mmsi (auf ein Schiff filtern) und type (auf einen Ereignistyp filtern).
Ereignistypen im Feld event_type: heading_to_germany_possible (mögliches Ziel in Deutschland, unbestätigt), heading_to_germany (gesichertes Ziel in Deutschland) und arrived (am deutschen Zielhafen angekommen, also festgemacht, vor Anker oder nahezu gestoppt).
curl "https://schiffstracker.example.de/api/v1/events?limit=10&mmsi=477116800"
curl "https://schiffstracker.example.de/api/v1/events?type=arrived"
[
{
"id": 42,
"mmsi": "477116800",
"ship_name": "BYD Hefei",
"ship_slug": "hefei",
"event_type": "heading_to_germany",
"destination_name": "Hamburg",
"occurred_at": "2026-08-25T20:04:00.000Z"
}
]Beispiel: Home Assistant
„Benachrichtige mich bei Ankunft“: Ein REST-Sensor fragt den letzten arrived-Eintrag ab, sein Wert ist die Ereignis-id. Ändert sie sich, ist ein Schiff angekommen, und die Automation meldet es. Die Bedingung verhindert eine Meldung beim Neustart von Home Assistant. Mit type=heading_to_germany statt arrived geht dasselbe für „nimmt Kurs auf Deutschland“.
# configuration.yaml
rest:
- resource: https://schiffstracker.example.de/api/v1/events?type=arrived&limit=1
scan_interval: 300
sensor:
- name: "BYD letzte Ankunft"
value_template: "{{ value_json[0].id if value_json | length > 0 else 0 }}"
json_attributes_path: "$[0]"
json_attributes:
- ship_name
- destination_name
- occurred_at# automations.yaml
- alias: "BYD-Schiff angekommen"
trigger:
- platform: state
entity_id: sensor.byd_letzte_ankunft
condition:
- condition: template
value_template: "{{ trigger.from_state.state not in ['unknown', 'unavailable'] }}"
action:
- service: notify.notify
data:
message: >-
{{ state_attr('sensor.byd_letzte_ankunft', 'ship_name') }} ist in
{{ state_attr('sensor.byd_letzte_ankunft', 'destination_name') }} angekommen