← backManage my API keys →

Port Flow public API

Simple REST API, JSON, Bearer authentication. Available from the Starter plan (5k req/day) up to Pro+ (600 req/min).

Authentication

All routes under /api/v1/* require a header Authorization: Bearer pf_xxxxx. Create your key on the /account page ("API keys" section). Shown once — copy it to your secrets manager immediately.

# Quick test
curl -H "Authorization: Bearer pf_xxxxxxxxxxxxxxx" \
  https://portflow.uk/api/v1/ports

# 401 → invalid or revoked token
# 429 → rate limit exceeded (the X-RateLimit-Reset header gives the next window)

Rate limits

PlanReq / minReq / day (est.)
Free—API not available
Starter120~5,000 / day
Professional300~18,000 / hour
Pro+600~36,000 / hour
Enterprise6 000unlimited in practice

Limits apply per token. Headers X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset on every response.

Endpoints

GET/api/v1/ports

List all 51 tracked ports with bbox, region, country, vessel count.

curl -H "Authorization: Bearer pf_xxxxxxxxxxxxxxx" \
  https://portflow.uk/api/v1/ports
Example response
{
  "ports": [
    { "id": "rotterdam", "name": "Rotterdam", "country": "Netherlands",
      "flag": "🇳🇱", "region": "northern-europe", "strategic": true,
      "center": [51.95, 4.10], "bbox": [...], "vesselCount": 935 },
    ...
  ]
}
GET/api/v1/ports/{id}/snapshot

Live KPI snapshot for a port (anchored / underway / moored / inbound).

  • id (string) required — port id, e.g. rotterdam
curl -H "Authorization: Bearer pf_xxxxxxxxxxxxxxx" \
  https://portflow.uk/api/v1/ports/rotterdam/snapshot
Example response
{
  "port": "rotterdam", "ts": 1777465634000,
  "snapshot": { "totalVessels": 935, "anchored": 17, "underway": 150,
                "moored": 736, "inboundLastHour": 588, ... }
}
GET/api/v1/ports/{id}/vessels

Live vessels at a port (last position, SOG, COG, state, cargo class).

curl -H "Authorization: Bearer pf_xxxxxxxxxxxxxxx" \
  https://portflow.uk/api/v1/ports/rotterdam/vessels
Example response
{
  "port": "rotterdam", "count": 935,
  "vessels": [
    { "mmsi": 244690099, "name": "ELJA", "lat": 51.95, "lon": 4.10,
      "sog": 0.0, "cog": 130, "state": "anchored",
      "cargoClass": "container", "destination": "ROTTERDAM" },
    ...
  ]
}
GET/api/v1/ports/{id}/voyages/active

Open voyages with predicted ETA (model v2) and broadcast ETA.

  • tankersOnly (0|1) — filter to tanker cargo classes
curl -H "Authorization: Bearer pf_xxxxxxxxxxxxxxx" \
  "https://portflow.uk/api/v1/ports/rotterdam/voyages/active?tankersOnly=1"
Example response
{
  "port": "rotterdam", "count": 211,
  "voyages": [
    { "voyageId": "rotterdam_244690099_...", "mmsi": 244690099,
      "name": "ELJA", "cargoClass": "container", "currentSog": 0.0,
      "currentDistanceNm": 6.7, "predictedEta": 1777445400000,
      "broadcastEta": null }
  ]
}
GET/api/v1/ports/{id}/voyages/closed

Recent closed voyages with arrival timestamp + RMSE benchmark.

  • days (int) — lookback window, default 30
curl -H "Authorization: Bearer pf_xxxxxxxxxxxxxxx" \
  "https://portflow.uk/api/v1/ports/rotterdam/voyages/closed?days=30"
Example response
{
  "port": "rotterdam", "windowDays": 30,
  "voyages": [...], "rmseHours": 4.01, "baselineRmseHours": null
}
GET/api/v1/ports/{id}/anomalies

Active anomalies detected (AIS gap, sudden zone change, drift, etc.).

curl -H "Authorization: Bearer pf_xxxxxxxxxxxxxxx" \
  https://portflow.uk/api/v1/ports/rotterdam/anomalies
GET/api/sanctions

OFAC SDN + UK Sanctions List screening for a vessel by MMSI or IMO.

  • mmsi (int) — 9-digit MMSI
  • imo (int) — 7-digit IMO number
curl "https://portflow.uk/api/sanctions?mmsi=123456789"
Example response
{
  "mmsi": 123456789, "flagged": false, "matches": [],
  "status": { "fetchedAt": ..., "count": 1987, "errors": [...] }
}
POST/api/v1/webhooks

Register a webhook for vessel events (subscribe to your watchlist).

curl -X POST -H "Authorization: Bearer pf_xxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://your-server/hook", "event": "vessel.arrived",
       "port": "rotterdam"}' \
  https://portflow.uk/api/v1/webhooks

Webhooks

Beyond REST pull calls, configure a webhook (Slack, Discord, Telegram, email or a custom endpoint) directly on /account → Alerts section. Supported events: vessel.arrived, vessel.departed, vessel.anomaly. Watchlist and port filters available.

API stability