NAV
shell

Introduction

Aquaplot lets you compute distances and routes for ships. The API allows you to retrieve distances between any two coordinates in water. You can enter coordinates manually or choose from our port database, which contains over 12.000 locations including ports, offshore installations etc. Read more about the services we offer at aquaplot.com

Version

The API is currently on version 1 (v1), production ready and used by businesses around the world. However, as we introduce new and improve existing functionalities, some endpoints may undergo breaking changes. We will add deprecation notices three months prior to introducing any breaking changes and will send reminders to all API users 8, 4 and 1 week(s) before carrying them out. Thank you for your understanding.

Timeouts

Most calculations do not take longer than a few hundred milliseconds. In exceptional cases, calculations may take a few seconds. All our requests have a hard timeout of 10 seconds. If you don’t get a response afterwards, there must be an issue with the network connection.

Authentication and Request Tokens

To authorize, use this code:

# With shell, you can just pass your credentials
# to cUrl. Replace 'user' and 'secret' with the
# credentials from your license
curl "<some_url>"
  -u "user:secret"

Aquaplot API uses simple HTTP authentication. You find your license credentials by browsing to your account page and clicking on more for one of your licenses. Make sure to call the API via HTTPS.

Every license has a quota of request tokens. The amount of available tokens per day, month or year depends on your purchased plan. The amount of available tokens per time period can be -1, which means there is no limit in place. Different API requests require different amounts of tokens. Only successful requests will reduce your quota. A request has been successful, if our server replies with a HTTP-200 response code. Internal server problems and timeouts will not have a negative impact on your quota. You find information on the number of required tokens of each request in this document.

Request Rate Limits

Depending on your API license, request throttling is enforced. These mechanisms work independent from the request token concept. There can be rate limits for:

Check the details page of your license on your account page. Whenever one of these limits is reached, we will return with a HTTP status 429. Limits are less strict for computational cheap requests like /geocode, /validate and /quota.

Response Codes

A general guide on how we use HTTP status codes:

Status Code Meaning
200 Success
301 Permanently Moved Used an out-dated API version or http instead of https.
400 Invalid Request Input parameters are missing or are not in the correct format.
401 Unauthorized You did not provide credentials / you provided wrong credentials / your license has been deactivated.
402 Payment Required You provided correct credentials, but the license has no request tokens left or is inactive.
429 Too Many Requests You reached the limit of request rate. See above for more details.
500 Internal Server Error Something horrible went wrong. Our engineers get a notification and start working on the issue.
502 Bad Gateway / 503 Service temporarily not available / 504 Gateway Timeout The server is under maintenance. If you see this, retry after a few seconds.

Data Formats

We love geojson. Unfortunately we cannot provide you with a holistic use of geojson, yet. Stay tuned for updates on the API documentation.

Coordinates are always represented as decimal degrees and encoded as JSON numbers. When passed as a list, longitude is always first, followed by latitude. The order in dictionaries (hashes) is undefined.

Strings are encoded as UTF-8. All times are in UTC.

Country codes are in ISO 3166-1 alpha-2

Quota

curl "https://api.aquaplot.com/v1/quota"
     -u "user:secret"

The above command returns JSON structured like this:

{
    "active_licenses": 1,
    "used": 38,
    "allowed": 1000,
    "allowed_concurrent": 1,
    "features": {
        "channel_selection": true
    }
}

This endpoint retrieves information on your quota. used indicates how many request tokens have been used today, allowed how many request tokens are available for today. allowed is fixed throughout the day and is reset at 01:30am UTC. allowed_concurrent indicates how many requests you may perform in parallel and features indicates if certain features are available (currently all API licenses have access to all features).

HTTP Request

GET https://api.aquaplot.com/v1/quota

Requires 0 tokens.

HTTP Response

In the current state, this endpoint might return HTTP responses including 402 status codes. This is subject to changes without change of the API version.

Locations

You can access our database with over 12000 locations including ports, offshore installations, blocks and more. Typical use cases are providing drop-down or search fields or to resolve names to coordinates for further use.

Retrieve Locations Database

curl "https://api.aquaplot.com/v1/locations" -u "user:secret"

The above command returns JSON structured like this:

[
  {
    "name": "Greater Plutonio",
    "latlng": {
      "lat": -7.833333,
      "lng":12.116667
    },
    "country": "AO",
    "locode":"AOGPO",
    "type":"port"
  },
  {
    "name": "Kuito Terminal",
    "latlng": {
      "lat": -5.433333,
      "lng": 11.483333
    },
    "country": "AO",
    "locode": "AOKOT",
    "type": "port"
  },
]

This endpoint lists all public locations in our database. Your points of interest are not included.

Response JSON

Property Name Description
name String description (usually matches name from UN/LOCODE, World Port Index or other publications).
latlng Coordinates that can be used for further calls to the API. The coordinates are already validated and do not need to be rechecked before calling for example /distance.
country Country code in ISO 3166-1 alpha-2 format. Can be an empty string or null if unknown.
locode UN/LOCODE. Can be empty string if not applicable or unknown.
type String description indicating type of location. Currently either one of the following
  • port
  • offshore-installation
  • block

It is not advisable to use this endpoint frequently as the response is rather big in size and does not change often. If you want to provide a search functionality, you can cache the response either on your server or the client, or use our location search endpoint which is much more lightweight.

Search for Locations

curl "https://api.aquaplot.com/v1/locations/hamb"
     -u "user:secret"

The above command returns JSON structured like this:

[
  {
    "name": "Hamburg-Mitte",
    "latlng":{"lat":53.552889,"lng":9.831694},
    "country":"DE",
    "locode":"DEHTJ",
    "type":"port"
  },
  {
    "name":"Hambantota",
    "latlng":{"lat":6.116667,"lng":81.116667},
    "country":"LK",
    "locode":"LKHBA",
    "type":"port"
  },
  {
    "name":"Hamburg",
    "latlng":{"lat":53.552889,"lng":9.831694},
    "country":"DE",
    "locode":"DEHAM",
    "type":"port"
  },
  {
    "name":"Hamburg (Pg) Harbor",
    "latlng":{"lat":-1.623778,"lng":149.958278},
    "country":"PG",
    "locode":"",
    "type":"port"
  },
  {
    "name":"Hamble le Rice",
    "latlng":{"lat":50.852051,"lng":-1.308838},
    "country":null,
    "locode":"",
    "type":"port"
  }
]

This endpoint searches for locations by name or UN/LOCODE. Any match that has the search query as substring will be returned. The search is case-insensitive. Search results are limited to max. 20 results.

HTTP Request

GET https://api.aquaplot.com/v1/locations/<search>

Requires 0 tokens.

URL Parameters

Parameter Description
search Substring of location name or UN/LOCODE

Response JSON

Property Name Description
name String description (usually matches name from UN/LOCODE, World Port Index or other publications).
latlng Coordinates that can be used for further calls to the API. The coordinates are already validated and do not need to be rechecked before calling for example /distance.
country Country code in ISO 3166-1 alpha-2 format. Can be an empty string or null if unknown.
locode UN/LOCODE. Can be empty string if not applicable or unknown.
type String description indicating type of location. Currently either one of the following
  • port
  • offshore-installation
  • block

Geocode

You can resolve port names to coordinates and store custom points of interest (POI) in our database.

Retrieve Port Database

curl "https://api.aquaplot.com/v1/ports" -u "user:secret"

The above command returns JSON structured like this:

{
  "ports": {
    "HAMBURG": {
      "lat": 53.552889,
      "lng": 9.831694,
      "country": "de",
      "wpi": 30780
    },
    "KARLSKRONA": {
      "lat": 56.166667,
      "lng":15.6,
      "country": "se",
      "wpi": 24460
    },
    "SHAKHTERSK": {
      "lat":-49.166667,
      "lng":142.05,
      "country": "ru"
    }
  }
}

This endpoint lists all ports in our database. Your points of interest are not included. Each port must contain the fields lat and lng. country and wpi (world port index number) are optional.

HTTP Request

GET https://api.aquaplot.com/v1/ports

Requires 0 tokens.

Retrieve Port Coordinates

curl "https://api.aquaplot.com/v1/geocode/ham"
     -u "user:secret"

The above command returns JSON structured like this:

[
  {
    "key": "HAMBURG",
    "value": {
      "lat": 53.552889,
      "lng": 9.831694
    }
  },
  {
    "key": "HAMBURG (PG) HABOUR",
    "value": {
      "lat": -1.623778,
      "lng": 149.958278
    }
  },
  {
    "key": "bacon_and_ham",
    "value": {
      "lat": 3.223,
      "lng": -22.53681
    },
    "custom": true
  }
]

This endpoint searches for ports and points of interest (POI) by name. Any match that has the search query as substring will be returned. The search is case-insensitive. Search results are limited to max. 100 results.

HTTP Request

GET https://api.aquaplot.com/v1/geocode/<search>

Requires 0 tokens.

URL Parameters

Parameter Description
search Substring of port name

Store Points of Interest

curl "https://api.aquaplot.com/v1/geocode/Secret%20Bay/12.34/56.78"
     -u "user:secret" --data ""

The above command returns JSON structured like this:

{
  "status": "ok",
  "name": "Secret Bay",
  "lat": 56.78,
  "lng": 12.34
}

This endpoint will store a point of interest (POI) in the database. This POI will only be accessible by you. All your stored POIs can be shown and managed from your account page.

HTTP Request

POST https://api.aquaplot.com/v1/geocode/<name>/<longitude>/<latitude>

Requires 0 tokens.

URL Parameters

Parameter Description
name Name of the POI
longitude JSON number of the longitude in degrees
latitude JSON number of the latitude in degrees

Validation of Coordinates

curl "https://api.aquaplot.com/v1/validate/12.34/56.78"
     -u "user:secret"

The above command returns JSON structured like this:

{
  "is_valid": true,
  "suggestion": [
    12.34,
    56.78
  ],
  "normalized": [
    12.34,
    56.78
  ],
  "moved_by": 0
}

If you validated coordinates that are not routeable water, the result looks like this:

{
  "is_valid": false,
  "suggestion": [
    12.2125,
    57.225
  ],
  "normalized": [
    12.555,
    57.28
  ],
  "moved_by": 21490
}

If you validated coordinates that are outside the normal range for longitude, the normalized coordinates will be validated. It is good practice to always use normalized and suggestion for further calls to the API, not your inital input coordinates.

curl "https://api.aquaplot.com/v1/validate/372.34/56.78" 
      -u "user:secret" 

For example, above command returns JSON structured like this (notice it’s the same as the first):

{ 
  "is_valid": true, 
  "suggestion": [
    12.34, 
    56.78
  ], 
  "normalized": [
    12.340000, 
    56.780000
  ], 
  "moved_by": 0
}

Using this endpoint, you can check if the coordinates point to routeable water. If the input represents a coordinate on land (or to a lake that is not part of the routeable water in our systems), we return a suggestion that you should use for subsequent requests to /route and /distance along with moved_by which gives you the distance between your input coordinates and our suggestion in meters. If your input points to routable water, the suggestion will contain exactly your input and moved_by will be zero.

HTTP Request

GET https://api.aquaplot.com/v1/validate/<longitude>/<latitude>

Requires 0 tokens.

URL Parameters

Parameter Description
longitude JSON number of the longitude in degrees
latitude JSON number of the latitude in degrees

Response JSON

Property Name Description
is_valid Boolean value indicating whether the normalized input can be used for /distance and /route calls
suggestion Suggested location to be used for further calls to the API. Same as the normalized input if in routeable water
normalized Input location normalized such that longitude is within [-180, 180]
moved_by Distance between normalized and suggestion in meters

Calculating Routes

curl "https://api.aquaplot.com/v1/route/from/32.67333984375/33.17434155100208/to/35.92529296875/24.806681353851964" -u "user:secret"

The above command returns geoJSON structured like this:

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": {
        "total_length": 558.49614719928,
        "seca_length": 0,
        "crossed": [
          "suez-canal"
        ]
      },
      "geometry": {
        "type": "LineString",
        "coordinates": [
          [32.67333984375, 33.174341551002],
          [32.3423, 31.2228],
          [32.310393, 31.094417],
          [32.319995, 30.811504],
          [32.342453, 30.703486],
          [32.305385, 30.568682],
          [32.396751, 30.357018],
          [32.449684, 30.285923],
          [32.500598, 30.260175],
          [32.52428, 30.244705],
          [32.560229, 30.198274],
          [32.585092, 29.973555],
          [32.567552, 29.923606],
          [32.714583, 29.448333],
          [33.237083, 28.553278],
          [34.018333, 27.504556],
          [35.92529296875, 24.806681353852]
        ]
      }
    }
  ]
}

If you post a request with correctly formatted, but invalid coordinates (see validate):

curl "https://api.aquaplot.com/v1/route/from/11.940709/57.703551067/to/13.341178894042969/58.06625598088454"
     -u "user:secret"
{
  "level": 0,
  "message": "invalid request"
}

If you post a request with incorrectly formatted coordinates:

curl "https://api.aquaplot.com/v1/route/from/11.940709/57.703551067/to/13.341178894042969/some_where"
     -u "user:secret"
{
  "error": "invalid value for to_lat"
}

To prevent a route to cross a canal, you can add a query parameter to the end of your request. The response will contain a route, that avoids declared canals.

curl "https://api.aquaplot.com/v1/route/from/32.67333984375/33.17434155100208/to/35.92529296875/24.806681353851964?suez=false" -u "user:secret"

/route will generate a list of waypoints between two given points. All waypoints are connected by routeable water and represent the shortest path from the two given points, according to our map data. The list starts with the departure coordinate and will end with the destination coordinate. Your inputs will be included in this ist, if they have been valid coordinates. The system will perform minor corrections of the departure and destination coordinates (changes up to ~100m), if they do not point to routeable waters. The returned JSON object contains a property named total_length which is the sum of the lengths of all segments of the way in nautical miles.

Invalid requests will not return a geoJSON object, but a much shortened JSON. Requests are invalid if

HTTP Request

GET https://api.aquaplot.com/v1/route/from/<from longitude>/<from latitude>/to/<to longitude>/<to latitude>?suez=true&panama=true

Requires 2 tokens.

URL Parameters

Parameter Description
from longitude JSON number of the longitude of the departure in degrees
from latitude JSON number of the latitude of the departure in degrees
to longitude JSON number of the longitude of the destination in degrees
to latitude JSON number of the latitude of the destination in degrees

Query Parameters

Parameter Required Default Description
suez no true Allow passage of the Suez channel. Possible values: true and false
panama no true Allow passage of the Panama channel. Possible values: true and false
kiel no true Allow passage of the Kiel channel. Possible values: true and false
northeast no false Allow passage of the Northeast Passage. Possible values: true and false
northwest no false Allow passage of the Northwest Passage. Possible values: true and false

Response JSON

The returned json is a geojson object according to RFC7946. The response body holds a feature collection with a single feature. This feature is a line string object with properties, such as total_length, seca_length and crossed.

Property Name Description
total_length Total length of the route in nautical miles
seca_length Length of route which falls into (S)ECA zones in nautical miles
crossed Array of string descriptions of Canals that are crossed, when traveling on the given route

Calculating Distances

curl "https://api.aquaplot.com/v1/distance/from/11.940709/57.703551067/to/10.8919017/53.963559"
     -u "user:secret"

The above command returns geoJSON structured like this:

{
  "type":"FeatureCollection",
  "features":[
    {
      "type":"Feature",
      "properties":
      {
        "total_length": 234.90849469415517,
        "seca_length": 234.90849469415517,
        "crossed": []
      },
      "geometry":
      {
        "type":"LineString",
        "coordinates":
        [
          [11.940709054470062,57.70355106791344],
          [10.891801714897156,53.963559337508556]
        ]
      }
    }
  ]
}

/route and /distance are similar:

HTTP Request

GET https://api.aquaplot.com/v1/distance/from/<longitude>/<latitude>/to/<longitude>/<latitude>?panama=true&suez=true

Requires 1 tokens.

URL Parameters

same as /route

Query Parameters

same as /route

Response JSON

same as /route

AIS Data

Current Vessel Position

curl "https://api.aquaplot.com/v1/vessels/mmsi/123456789/latest"
     -u "user:secret"

The above command returns JSON structured like this:

{
  "status": "ok",
  "mmsi": "123456789",
  "name": "VESSEL A",
  "latlng": {
    "lat": 56.78,
    "lng": 12.34
  },
  "signal_timestamp": "2017-08-16T08:30:52.150Z"
}

This endpoint will forcefully trigger an AIS data retrieval and return a vessels latest position.

HTTP Request

GET https://api.aquaplot.com/v1/vessels/mmsi/<mmsi>/latest

Token consumption

Every call requires 3 tokens.

URL Parameters

Parameter Description
mmsi MMSI identifier of vessel of interest.

Response JSON

Property Name Description
status String describing if call was successful (either “ok” or “error”). If “ok”, properties mmsi, name, latlng and signal_timestamp will be present in the response.
message Only present if status equals “error”.
mmsi MMSI identifier that was used as url_parameter.
name Vessel name if known. Can be an empty string.
latlng Reveived coordinates of vessel at time signal_timestamp.
signal_timestamp Time that AIS signal was received in UTC.

Vessel (MMSI) Subscriptions

You can subscribe to any valid MMSI number and specify a custom update interval. For example, you can subscribe to a vessel with a daily update interval (1440 minutes) or hourly update interval (60 minutes). Pricing depends directly on your chosen update interval as every update will consume X tokens (not yet defined). You can then retrieve the latest vessel position as often as you want at no extra cost so you only pay for what you really need.

Subscribe to MMSI Signal

curl "https://api.aquaplot.com/v1/vessels/mmsi/123456789/subscribe/interval/1440"
     -u "user:secret" --data ""

The above command returns JSON structured like this:

{
  "status": "ok",
  "subscription": {
    "uuid":   "417d90dd-3cab-4159-9c96-1f86b4432816",
    "mmsi": "123456789",
    "name": "VESSEL A",
    "interval": 1440
  }
}

This endpoint allows you to subscribe to a MMSI signal with a given update interval.

HTTP Request

POST https://api.aquaplot.com/v1/vessels/mmsi/<mmsi>/subscribe/interval/<interval>

This call itself will add a subscription and will trigger a AIS data retrieval which will consume X tokens (not yet defined). Every active subscription will consume X tokens for every update according to your chosen update frequency (interval).

URL Parameters

Parameter Value Description
mmsi String (9 characters) MMSI identifier of vessel of interest.
interval Integer, (currently) between 180 (3 hours) and 10,080 (1 week) Update interval in minutes.

Response JSON

Property Name Description
status String describing if call was successful (either “ok” or “error”).
message Only present if status equals “error”.
uuid Unique identifier (string) for a given subscription.
mmsi MMSI identifier that was used as url_parameter.
name Vessel name if known. Can be an empty string.
latest Object containing the latest position latlng and time signal_timestamp.
interval Your chosen update interval (same as the URL parameter) in minutes.

Get active MMSI Subscriptions

curl "https://api.aquaplot.com/v1/vessels/subscriptions"
     -u "user:secret"

The above command returns JSON structured like this:

{
  "status": "ok",
  "subscriptions": [
    {
        "uuid":   "417d90dd-3cab-4159-9c96-1f86b4432816",
        "mmsi": "123456789",
        "name": "VESSEL A",
        "interval": 1440,
        "latest": {
            "latlng": {
              "lat": 56.78,
              "lng": 12.34
            },
            "signal_timestamp": "2017-08-16T08:30:52.150Z"
        }
    },
    {
        "uuid": "65187e53-f6db-4887-8172-7904592a59ff",
        "mmsi": "987654321",
        "name": "VESSEL B",
        "interval": 1440,
        "latest": {
            "latlng": {
              "lat": 56.78,
              "lng": 12.34
            },
            "signal_timestamp": "2017-08-16T08:30:52.150Z"
        }
    },
    {
        "uuid": "7cd32530-e3a5-4e1a-a7bd-bcab548be867",
        "mmsi": "456789123",
        "name": "VESSEL C",
        "interval": 1440,
        "latest": {
            "latlng": {
              "lat": 56.78,
              "lng": 12.34
            },
            "signal_timestamp": "2017-08-16T08:30:52.150Z"
        }
    } 
  ]
}

This endpoint returns all your active mmsi subscriptions along with the latest position (latlng coordinate).

HTTP Request

GET https://api.aquaplot.com/v1/vessels/subscriptions

Token consumption

This endpoint is free. (Every call requires 0 tokens).

URL Parameters

Parameter Description
mmsi MMSI identifier of vessel of interest.

Response JSON

Property Name Description
status String describing if call was successful (either “ok” or “error”).
message Error message - only present if status equals “error”.
subscriptions Array with active subscription objects.
uuid Unique identifier (string) for a given subscription.
mmsi MMSI identifier that was used as url_parameter.
name Vessel name if known. Can be an empty string.
latest Object containing the latest position latlng and time signal_timestamp.
latlng Reveived coordinates of vessel at time signal_timestamp.
signal_timestamp Time that AIS signal was received in UTC.

Change active MMSI Subscription

Coming soon. In the meantime, deactivate your subscription and then add a new one.

Deactivate MMSI Subscription

curl -X DELETE "https://api.aquaplot.com/v1/vessels/subscriptions/417d90dd-3cab-4159-9c96-1f86b4432816"
     -u "user:secret"

The above command returns JSON structured like this:

{
  "status": "ok",
  "subscription": {
    "uuid":   "417d90dd-3cab-4159-9c96-1f86b4432816",
    "mmsi": "123456789",
    "name": "VESSEL A",
    "interval": 1440
  }
}

This endpoint allows you to unsubscribe one of your active subscriptions.

HTTP Request

DELETE https://api.aquaplot.com/v1/vessels/subscriptions/<uuid>

Token consumption

This endpoint is free. (Every call requires 0 tokens).

URL Parameters

Parameter Description
uuid Unique identifier (string) for a given subscription.

Response JSON

Property Name Description
status String describing if call was successful (either “ok” or “error”).
message Only present if status equals “error”.
uuid Unique identifier (string) for a given subscription.
mmsi MMSI identifier that was used as url_parameter.
name Vessel name if known. Can be an empty string.
interval Your chosen update interval (same as the URL parameter) in minutes.

Data & Sources

Locations Database

Our locations database is based on data from several publications. It includes for example data from the World Port Index, the Code for Trade and Transport Locations (UN/LOCODE), OSPAR Inventory of Offshore Installations as well as user generated and manually confirmed data.

We are integrating more port data over time. If you are missing ports that you expected, you can either create a POI or send us an email, with details about the port you are missing.

We always appreciate your help in improving our dataset. In return, we give every API user complete access to all data (except of course user specific Points of Interest as they are private).

(S)ECA Areas

Aquaplot currently supports these (S)ECA zones:

  1. Baltic Sea
  2. North Sea and English Channel
  3. US East Cost
  4. US West Cost
  5. Hawaiian Islands
  6. Caribbean (Puerto Rico and US Virgin Islands)
  7. Pearl River Delta
  8. Yangtze River Delta
  9. Bohai Gulf