v1 · Live AIS · JSON over HTTPS

Build on live AIS data.

A small, well-documented REST surface for vessel positions, port traffic, and watchlist webhooks. Pair it with a stable authentication model and predictable rate limits, and you've got everything you need to ship maritime-aware features into your own product.

5
Endpoints
600 / min
Rate limit
< 100 ms
p95 latency
JSON
Format

Quick start

From zero to your first call in under a minute.

  1. 01

    Generate an API key

    Pro accounts can create keys at /account/api-keys. The full secret is shown once — store it safely; we only display the first 8 characters afterwards.

  2. 02

    Send the Authorization header

    Every /api/v1/* request must include Authorization: Bearer sr_live_…. Anonymous traffic is reserved for the public site-rendering endpoints.

  3. 03

    Read rate-limit headers

    Every response includes x-ratelimit-* headers. When you hit a 429, the x-ratelimit-reset tells you when to retry.

Example: fetch a vessel
curl https://shipradar.io/api/v1/vessels/565819000 \
  -H "Authorization: Bearer sr_live_…"

Drop in your key, hit Enter, get back a JSON snapshot. That's the whole pattern.

Authentication

Bearer tokens, scoped per key

Keys begin with sr_live_ (production) or sr_test_ (testing). Revoke any key from the same page you created it on — revocation propagates to live traffic in seconds.

Rate limits

Generous and predictable

  • Authed · 600 requests / minute per key
  • Anonymous · 60 / minute per IP (public surface only)
  • 429 · { "error": "rate limited" }

Need higher limits for a legitimate use case? Email support@shipradar.io — we tune individual keys.

Endpoints

REST reference

5 endpoints across vessels and ports. All responses are JSON. All paths are versioned at /api/v1.

GET/api/v1/vessels/:mmsiVessel snapshot

Latest position for one vessel. Falls back to Postgres if the vessel has aged out of the Redis hot cache.

Response
{
  "vessel": {
    "mmsi": 565819000,
    "name": "MAERSK ALGOL",
    "imo": 9333394,
    "category": "cargo",
    "flag": "SG",
    "lat": 33.732,
    "lon": -118.248,
    "sog": 0,
    "cog": 213.2,
    "heading": 70,
    "navStatus": 5,
    "destination": "LONG BEACH",
    "lastSeen": 1700000000000
  }
}
GET/api/v1/vessels/:mmsi/trackPosition history

Historical track points for one vessel — useful for ETA models, anomaly detection, or simply playing back a route.

Query parameters
NameTypeNotes
hoursintegerDefault 6, max 168 (7 days)
Response
{
  "mmsi": 565819000,
  "hours": 24,
  "points": [
    { "ts": 1700000000000, "lat": 33.74, "lon": -118.27, "sog": 12.4, "cog": 90 },
    { "ts": 1700000060000, "lat": 33.75, "lon": -118.28, "sog": 12.5, "cog": 91 }
  ]
}
GET/api/v1/vessels/searchVessel search

Match vessels by name (substring, case-insensitive) or MMSI / IMO / call sign (prefix).

Query parameters
NameTypeNotes
qstring≥ 2 chars
limitinteger1–50 (default 20)
Response
{
  "results": [
    { "mmsi": 565819000, "name": "MAERSK ALGOL", "category": "cargo", "flag": "SG" },
    { "mmsi": 477123400, "name": "MAERSK ALPHA",  "category": "cargo", "flag": "HK" }
  ]
}
GET/api/v1/portsPorts list

Every UN/LOCODE port we track. Currently 32 high-traffic container terminals; growing toward the full UN/LOCODE list.

Response
{
  "ports": [
    { "unlocode": "CNSHA", "name": "Shanghai",  "country": "CN", "lat": 31.23,  "lon": 121.47 },
    { "unlocode": "SGSIN", "name": "Singapore", "country": "SG", "lat": 1.265,  "lon": 103.832 }
  ]
}
GET/api/v1/ports/:unlocodePort detail

Port metadata + every vessel currently inside the configured radius. Sorted by distance from the port centre.

Query parameters
NameTypeNotes
radiusKmintegerDefault 10, max 50
Response
{
  "port": {
    "unlocode": "USLAX",
    "name": "Los Angeles",
    "country": "US",
    "lat": 33.732,
    "lon": -118.262,
    "radiusKm": 10,
    "vessels": [ /* … VesselSnapshot[] … */ ]
  }
}

Webhooks

Push, not poll.

Watchlists fire vessel.enter / vessel.leave events to a URL you configure. We sign every payload with HMAC-SHA256 against the secret shown when you created the watch.

  • Verify the signature

    Compute sha256(secret + raw_body) and compare to the x-shipradar-signature header. Reject mismatches.

  • Be idempotent

    Each event has a unique id. We retry on non-2xx responses with exponential backoff.

  • Respond fast

    Acknowledge with 2xx in under 5 s. Do heavy work async on your side.

Example payload
POST <your-url>
content-type: application/json
x-shipradar-signature: sha256=<hex>
x-shipradar-event: vessel.enter

{
  "id": "<event id>",
  "type": "vessel.enter",
  "watch_id": "<watch id>",
  "mmsi": 565819000,
  "vessel_name": "MAERSK ALGOL",
  "lat": 33.74,
  "lon": -118.27,
  "occurred_at": "2026-01-01T12:00:00Z"
}

Ready to build?

API access ships with the Pro plan. Generate a key, paste it into your env, and you're shipping in under a minute.

Questions? support@shipradar.io