Search Open menu

Vessels API

The Spire Vessels API is a REST API service that returns only the most recent information provided for each vessel, in JSON format.

It joins the position reports and static voyage reports which are transmitted in separate AIS messages into a single record. This saves the end user from having to join AIS messages and keep track of the MMSI identifiers linked to each IMO number.

Vessels API can be filtered to only return data for a specific list of vessels by IMO or MMSI number, as well as return only vessels updated since a point in time, among other filters.

Note the granularity of AIS tracks received using Vessels API depends on the frequency with which the Vessels API is called as well as the frequency of reception of AIS data for a vessel.

 

Postman App Icon

Get started now

Download our open source Postman collection, drop in your access token and you will be making Vessels API calls in seconds.

Get started now

Don’t have a token yet? Request a trial

Making API calls

Authentication

Vessels API uses Bearer tokens to authenticate requests. Attempting to make requests to the API without a valid API Key will result in the return of an HTTP 401 Not Authorized response code containing a WWW-Authenticate HTTP header with an error message.

In addition, to ensure transport layer security, all access or communication with the APIs must be made over HTTPS.

Note: if you have a long token (greater than 32 characters), all requests will be made through the https://ais.spire.com/ endpoint. The documentation below uses the short token (32 characters or less) endpoint https://api.sense.spire.com/ for all examples. Please substitute the appropriate endpoint for all requests made and all examples in the following documentation.

Not a Spire customer yet?

You’ll need a token to start using the API. Get in touch to become a customer or request a trial token.

Get a token

 
Quick access test (Bash)
curl -H "Authorization: Bearer {your_token}" -H "Accept: application/json" 'https://api.sense.spire.com/vessels?limit=1'

If you received a response containing one vessels entry, you are good to go.

Data types

There are a few basic data types that describe the resource properties returned within Vessels API. They are also used to specify the formatting of inputs to our APIs as query parameters.

string
String value
date
Dates conforming to ISO 8601 format. Time is represented in the UTC timezone.
The generic ISO 8601 timestamp representation is: YYYY-MM-DDTHH:MM:SS+00:00
Some timestamps are received with milliseconds or nanoseconds , when such data is received it is presented in the timestamp format.
Example with milliseconds "timestamp": "2020-07-30 07:40:41.750+00:00"
Example with microseconds "timestamp": "2021-07-18 23:35:29.068408+00:00"
integer
Integer value
number
Numeric value with variable precision; includes floats, decimals.
geometry
Input and response geometry as GeoJSON objects. Geometries can also be used to spatially filter your queries. Responses return latitude/longitude points while inputs accept polygons.
bool
Boolean value, having one of two possible values: true or false
array
JSON array
json
JSON object
 
Individual vessel entry response example
{
    "id": "1181c677-0c3b-4dac-8a7a-47404d865e74",
    "name": "PACIFIC BRAVERY 1",
    "mmsi": 357556000,
    "imo": 9200744,
    "call_sign": "3FMK9",
    "ship_type": "Tanker",
    "class": "A",
    "flag": "PA",
    "length": 221,
    "width": 32,
    "ais_version": 0,
    "created_at": "2017-08-23T14:18:38.063792+00:00",
    "updated_at": "2019-04-05T21:16:15.584033+00:00",
    "last_known_position": {
        "timestamp": "2019-04-05T20:26:09+00:00",
        "geometry": {
            "type": "Point",
            "coordinates": [
                39.52571,
                15.60624
            ]
        },
        "heading": 511,
        "speed": 0,
        "rot": -128,
        "accuracy": null,
        "collection_type": "satellite",
        "draught": 7.9,
        "maneuver": 0,
        "course": 82.6
    },
    "most_recent_voyage": {
        "eta": "2019-03-21T09:00:00+00:00",
        "destination": "ER MSW"
    },
    "general_classification": "Merchant",
    "individual_classification": "Tanker",
    "gross_tonnage": "38962",
    "lifeboats": null,
    "person_capacity": null,
    "navigational_status": "At anchor"
}

Sorting

You can specify your sort order by including sort={PROPERTY_NAME} in the query string. Use a minus sign (-) before the property name to denote descending sort order: sort=-{PROPERTY_NAME}.

By default, the Vessels API response is sorted by created_at date/time in ascending order. It can be sorted by updated_at and timestamp.

 
Ascending order sorting
GET https://api.sense.spire.com/vessels?sort=updated_at
Descending order sorting
GET https://api.sense.spire.com/vessels?sort=-updated_at

Filtering

We provide a variety of filters to make it easier to manage the amount of data to just what is needed.

Below is a list of common types; the actual filter parameters are listed under Query Parameters section.

Exact match
Returns records where there is a specific match for the value provided.
Example: GET https://api.sense.spire.com/messages?collection_type=satellite
List
Returns results that match multiple values. Any field that support list also supports exact match.
Example: GET https://api.sense.spire.com/messages?mmsi=239245000,273216800,249810000
Range
Range filters work on some fields that are dates and strings.
Example:  GET https://api.sense.spire.com/messages?received_after=2019-02-01T20:56:15&received_before=2019-02-04T22:34:20
Geospatial
Returns data that has a geospatial intersection with the provided input geometry. Input geometries should be valid GeoJSON polygons.
Example: GET https://api.sense.spire.com/messages?position="type":"Polygon","coordinates":[[[-122.41269350051881,37.76058796575955],[-122.41269350051881,37.764124860544094][-122.40750074386597,37.764124860544094],[-122.40750074386597,37.76058796575955],[-122.41269350051881,37.76058796575955]]]}

Query parameters

mmsi integer
Vessel Maritime Mobile Service Identity number. Valid values: 000000000 - 999999999
Supported filters: Exact Match, List
imo integer
Vessel unique International Maritime Organization number. Valid values: 0 (not available; default), 0001000000 - 0009999999, 0010000000 - 1073741823 (office flag state number)
Supported filters: Exact Match, List
name string
Vessel name
Supported filters: string present in the name
call_sign string
Vessel call sign
Supported filters: Exact Match, List
ship_type string
Category of vessel. Valid values: cargo, fishing, passenger, pleasure craft, sailing, tanker, tug, other
Supported filters: Exact Match, List
class string
Shipborne AIS transponder class. Valid values: A or B
Supported filters: Exact Match, List
flag string
Vessel country flag using 2-letter country codes (derived from MMSI)
Supported filters: Exact Match, List
updated_after number
Returns all vessels with an updated_at greater than or equal to the time specified
Supported filters: Range
updated_before number
Returns all vessels with an updated_at less than or equal to the time specified
Supported filters: Range
last_known_position geometry
Returns all vessels with a last_known_position point within provided GeoJSON polygon
Supported filters: Geospatial

Pagination

When using ranged-based historical queries in any Vessels API query, we use a fairly standard limit & offset pagination through a provided ID for the next and previous pages of results.

All API responses above a certain size get “paginated” to make the response handling manageable. The default page limit for the Vessels APIs is 100 vessels.

"paging": {
    "limit": 100,
    "total": 312511,
    "next": "dGltZT0xNTAyNTc5MzE1Ljc3NTU4NSxpZD1jNGExY2U1ZS04MzA3LTRjZGQtODg3ZS1lOTBjNmVlNWY0MWI="
}
#[vessels follow ...]
 

Move to the next page of results by appending the after query parameter:

GET https://api.sense.spire.com/vessels?next=dGltZT0xNTAyNTc5MzE1Ljc4ODA4LGlkPTA4MGRkYTM2LWU1MTktNDExNC1iZGRmLTJiNGM2ODk3YWRhMw==

Move to the previous page of results by appending the previous query parameter:

GET https://api.sense.spire.com/vessels?previous=dGltZT0xNTAyNTc5MzE1Ljc4ODM1NyxpZD02YTc1ZTFmZC01NmUzLTQ4NmQtYTE2My1jMGQ2MjFkNjU4OTY=

Limits

Vessels API requests may lead to thousands of available results; therefore, when a request is made, all of the results usually aren’t received in a single response.

Response limits can be customized to help limit the amount of data returned using the limit filter parameter.

The Vessels API has a default limit of 100 with a max of 1000.

 
GET https://api.sense.spire.com/messages?limit=10

Rate limiting

We recommend keeping the frequency of your API calls below 30 per minute. If you attempt to query one of the Spire Sense APIs more often than that, you may encounter the following error:

"Spire API rate limit exceeded. Please limit your requests to 30 per minute to avoid future issues."

If you encounter this error, it should clear within about 30 seconds.

Handling API responses

Response fields

Vessels particulars

Vessel particulars include the highest-level information about a ship in our vessels database.

The information contained here is a combination of data from AIS messages and external data sources.

The records within provide an up-to-date snapshot of the ship when possible.

id string
Unique identifier of the vessel in the Spire database
name string
Vessel name
mmsi integer
Vessel Maritime Mobile Service Identity. Possible values: 000000000 - 999999999
imo integer
International Maritime Organization number. Possible values: 0 (not available; default), 0001000000 - 0009999999, 0010000000 - 1073741823 (office flag state number)
call_sign string
Vessel call sign
ship_type string
Category of vessel
class string
Shipborne AIS transponder class. Possible values: A or B
flag string
Vessel country flag using 2-letter country codes (derived from MMSI)
length number
Vessel length extracted from ship dimensions to_bow and to_stern in meters
width number
Vessel width extracted from ship dimensions to_port and to_starboard in meters
ais_version integer
Vessel AIS version. Possible values: 0 (compliant with Recommendation ITU-R M.1371-1), 1 (compliant with Recommendation ITU-R M.1371-3), 2 (compliant with Recommendation ITU-R M.1371-5 or later), 3 (compliant with future editions)
created_at date
ISO 8601 formatted timestamp in UTC of the time the vessel record was created
updated_at date
ISO 8601 formatted timestamp in UTC of the last time any field in the vessel record was updated
static_updated_at date
ISO 8601 formatted timestamp in UTC of the time the vessel static information was updated (updates coming from AIS messages 5 or 24)
position_updated_at date
ISO 8601 formatted timestamp in UTC of the last time position field in the vessel record was updated (updates coming from AIS messages 1,2,3,18,19 or 27)
general_classification string
Broad category of vessel
individual_classification string
Specific category and purpose of vessel
person_capacity number
Capacity of person on board (passengers and crew)
gross_tonnage number
A common measurement of the internal volume of a ship
lifeboats number
Indicates the number of lifeboats onboard fitted with radio apparatus

Last known position

The last_known_position object contains the location information from the most recent AIS position message for a particular vessel.

timestamp string
ISO 8601 formatted timestamp of position message collection in UTC at the time of broadcast
geometry geometry
Vessel position coordinates represented in GeoJSON
heading number
Vessel true heading in degrees. Possible values: 0 – 359 degrees, 511 (not available)
speed number
Vessel speed over ground represented in knots. Possible values: 0 - 102.2 knots, 102.3 (not available)
rot number
Vessel rate of turn in degrees per minute Possible values: -127 to 127; -128 (not available)
accuracy integer
Vessel GPS geolocation accuracy in meters. Possible values: 1 (high, <=10 meters); 0 (low, >10 meters, default)
collection_type string
How the data was captured Possible values: satellite, terrestrial, or dynamic
draught number
Vessel draught represented in 1/10 meters. Possible values: 0.1 - 255, 0 (not available; default)
maneuver integer
Vessel maneuver code. Valid values: 0 (not available; default), 1 (not engaged in special maneuver), 2 (engaged in special maneuver)
course number
Vessel course over ground in degrees. Possible values: 0 - 359.9 degrees, 360.0 (not available)

Matched port

The matched_port object contains the details of the port that has been matched to the vessels reported destination.

unlocode string
UN LOCODE of the port recognised as the vessel’s reported destination. UN LOCODES are defined here xxx and consitute of 5 characters, the first 2 characters are the 2 character ISO code for the country and the last 3 charaters are the LOCODE of the Port location
port_name string
Name of the port identified by the UN LOCODE, matched to the vessel’s reported destination
center_point geometry
GeoJSON Point specifying the coordinates in Longitude, Latitude of the approximate central point of the area of the identified port.
How does port matching work?

Each port has a recognised international code which is the United Nations Code for Trade and Transport Locations( UN/LOCODE); however, vessels report their destination port in AIS static voyage messages (message type 5 for class A and message type 24 for class B AIS) as free text values; and since there is no standard for these values, they can take many variations on port names, sometimes including locodes, country codes or local variations of port names, among other values.

The Vessels API port matching algorithm takes that destination text value and tries to match it to a UN/LOCODE. When it is successful, the matched port fields above will be added to the standard Vessels API response.

 
Example

Below are different port name values entered by captains for the KR PUS port (Busan, in South Korea), along with the matched destination port’s unlocode and port_name fields:

Input destinationMatched unlocodeMatched port_name
KR PUSKR PUSBusan
BUSANKR PUSBusan
AUBNE>KRPUSKR PUSBusan
BUSAN=========JEJUKR PUSBusan
KR PUSKR PUSBusan
RU VNN > KR PUSKR PUSBusan
KRPUSKR PUSBusan
BUSAN KRKR PUSBusan
PUSANKR PUSBusan
BU-SANKR PUSBusan
KR_PUSKR PUSBusan

Most recent voyage

The most_recent_voyage object contains the voyage information for a particular vessel based on the most recent AIS information as entered by the captain of a ship.

destination string
Vessel destination as entered by the vessel captain
eta string
Vessel estimated time of arrival as entered by the captain, represented in ISO 8601 format. Possible values: Month: 1 - 12, 0 (not available; default); Day: 1 - 31, 0 (not available; default); Hour: 0 - 23, 24 (not available; default); Minute: 0 - 59, 60 (not available; default)

Vessel Characteristics

Vessel Characteristics (formerly called Enhanced Vessel Data), is a set of additional data that provides further vessel information within the Vessels API for a variety of commercial vessels.

This further vessel info relates to:

  • Capacity
  • Design
  • Dimensions
  • History
  • Propulsion
  • Registration
  • Vessel and Trading Type

This data is updated on a regular basis. The fields exist within two sets: Default and Extended.

Default VC fields
dwt integer
Deadweight; difference between displacement and the empty vessel (lightweight) at any given draught
Category: capacity
gross_tonnage integer
Vessel gross tonnage
Category: capacity
built_year integer
Year vessel was delivered from the shipyard to its owner
Category: history
vessel_type string
Broad type of vessel
Category: vessel_and_trading_type
subtype string
Specific subtype of vessel
Category: vessel_and_trading_type
Extended VC fields
isplacement integer
The amount of water (in tons) displaced by the ship
Category: capacity
grain_cubic_capacity integer
Cubic capacity of cargo holds for grain (and other loose dry commodities)
Category: capacity
liquid_cubic_98_percent integer
The liquid cubic capacity of the cargo tanks when filled to 98% of capacity
Category: capacity
net_tonnage integer
Vessel net tonnage
Category: capacity
teu integer
“Twentyfoot Equivalent Unit” (measurement of container carrying capacity)
Category: capacity
tpcmi integer
Tons per Centimeter – how many tons are required to increase the draught by 1 cm – (useful for trying to estimate the volume of cargo onboard)
Category: capacity
engine_designation string
Engine model
Category: propulsions
main_engine_designer string
Engine designer
Category: propulsions
main_engines integer
Number of engines
Category: propulsions
mco integer
Maximum continuous output (power)
Category: propulsions
mco_unit string
Maximum continuous output (power unit (e.g. KW))
Category: propulsions
mcorpm integer
Maximum continuous output RPM
Category: propulsions
propeller_type string
Propeller type
Category: propulsions
propellers integer
Number of propellers
Category: propulsions
propulsion_type string
Propulsion type code (e.g. Motor, Gas Turbine)
Category: propulsions
class_1_code string
The name of the classification society who inspects the vessel and awards statutory certificates
Category: registration
ice_class integer
Ice class ID
Category: registration
ice_classed boolean
Indicates if the vessel ice classed (Yes/No)
Category: registration
commercial_owner string
Vessel commercial owner
Category: history
dead_year integer
Year vessel was scrapped or destroyed
Category: history
hull_number integer
Hull number assigned by the shipyard
Category: history
ship_builder string
Full name of ship builder history
name_date date
Vessel name date (for history of name changes, etc.)
Category: history
coated boolean
Indicated if the vessel tanks are coated (Yes/No)
Category: design
air_draught number
Maximum air draught of the ship. Air draught is the distance from the surface of the water to the highest point on a ship.
Category: dimensions
draught number
Maximum draught of the ship. Draught is the distance between the waterline and the bottom of the hull (keel).
Category: dimensions
ktm number
KTM. Keel To Mast of the ship.
Category: dimensions
loa number
LOA. Length Over All of the ship.
Category: dimensions
trading_category number
Vessel trading category
Category: vessel_and_trading_type
trading_status number
Vessel trading status
Category: vessel_and_trading_type

Need access to extended vessel characteristics?

Get in touch with our team to activate the Extended set of Vessel Characteristics fields for your token.

Request access

 

Include an embed=enhanced_data parameter within a Vessels API call to request these fields:

GET https://api.sense.spire.com/vessels?embed=enhanced_data

To further filter down the categories returned, specify the category of interest:

GET https://api.sense.spire.com/vessels?embed=enhanced_data.capacity

Or categories of interest in a comma separated list:

GET https://api.sense.spire.com/vessels?embed=enhanced_data.capacity,enhanced_data.propulsions

Errors

When there is an error with your request, the response header will contain a status code to help you determine what the issue is.

Additionally, the response body will contain a more detailed message.

Our APIs may respond with the following errors:

400 – Bad Request
A request made with a malformed HTTP Authorization Header or query parameters. Unaccepted query parameters will simply be ignored.
401 – Unauthorized
A request made with an invalid, unrecognized or missing access token.
403 – Forbidden
The metadata associated to a JWT is no longer valid and access to the API is denied.
404 – Not Found
A request made to an unknown or supported resource.
406 – Not acceptable
A request made with invalid HTTP headers.
414 – URI Too Long
The request was well-formed but is too large.
422 – Unprocessable
The request was well-formed but was unable to be followed due to semantic errors.
429 – Too many requests
Exceeding the rate limit will result in a 429 error response until a rate limit refresh threshold has been met.
502 – Bad gateway
If the API encounters any technical difficulties while processing a request, it will respond with a description detailing the status of the API.
503 – Service unavailable
If the API encounters any technical difficulties while processing a request, it will respond with a description detailing the status of the API.

Handling last page of results

The next cursor turns through each returned page of vessels:

"paging": {
    "limit": 100,
    "total": 312363,
    "next": "dGltZT0xNTAyNTc5MzE1Ljc3OTYxNyxpZD1kNmYyZjMxYS1kNWQyLTRmN2QtOWNkNS1lMGJkZjFmMDM4ZmE="
}

However, eventually, the last page is reached and no cursor is returned:

"paging": {
    "limit": 100,
    "total": 312363
}

This indicates that you’ve viewed the last vessel record within your results.

Once you’ve requested every vessel record of interest, the updated_after API parameter can be used to only request vessels from which we’ve recently received updated information.

Let’s say 2022-10-18T00:00:00 is the time at which the following request was made:

GET https://ais.spire.com/vessels/?ship_type=cargo

If you wanted to check for hourly updates, at 2022-10-18T01:00:00 , send the following request to fetch any cargo vessels with updates within the past hour:

GET https://ais.spire.com/vessels/?ship_type=cargo&updated_after=2022-10-18T00:00:00

At this point, turn through paginated results via next until you’ve reached the last page. Repeat again an hour later.

Querying examples

Query all vessels

This is an example of an unfiltered, default call to Vessels. Note the structure of the request query, as well as the vessel example in the API response.

Request (bash)
curl - i - H "Authorization: Bearer {your_token}" - X GET https://api.sense.spire.com/vessels
Response
{
  "paging": {
    "limit": 100,
    "total": 292453,
    "next": "dGltZT0xNTAyNTc5MzE1Ljc4ODA4LGlkPTA4MGRkYTM2LWU1MTktNDExNC1iZGRmLTJiNGM2ODk3YWRhMw=="
  },
  "data": [
    {
      "id": "b2c2626d-ff0b-4892-8262-5acae60946a4",
      "name": "JUPITER II",
      "mmsi": 701000533,
      "imo": 9123726,
      "call_sign": "LW 9897",
      "ship_type": "Fishing",
      "class": "A",
      "flag": "AR",
      "length": 27,
      "width": 7,
      "ais_version": 0,
      "created_at": "2017-08-11T19:35:18.200135+00:00",
      "updated_at": "2018-07-02T18:04:11.279030+00:00",
      "last_known_position": {
        "timestamp": "2018-07-02T14:57:58+00:00",
        "geometry": {
          "type": "Point",
          "coordinates": [-62.82619,-45.29533]
        },
        "heading": 511,
        "speed": 4.3,
        "rot": - 128,
        "accuracy": null,
        "collection_type": "satellite",
        "draught": null,
        "maneuver": 0,
        "course": 154.6
      },
      "most_recent_voyage": {
        "eta": "2019-06-12T17:00:00+00:00",
        "destination": "MAR DEL PLATA"
      },
      "general_classification": "Fishing Industry",
      "individual_classification": "Fishing Vessel",
      "gross_tonnage": "148",
      "lifeboats": null,
      "person_capacity": 8,
      "navigational_status": "Moored"
    }
  ]
}

Filter vessels by ship type

Here is an example of a Vessels API call that filters vessels by ship_type; in this example, we list cargo vessels – note the parameter in the request url.

Request (bash)
curl - i - H "Authorization: Bearer {your_token}" - X GET https://api.sense.spire.com/vessels/?ship_type=cargo
Response
{
  "paging": {
  "limit": 100,
  "total": 89138,
  "next": "dGltZT0xNTAyNTc5NTY0Ljc3MjgwOSxpZD0xYjRhODI3OC0xMjc0LTQ3YTUtYjU1Mi1hMTMxODc5ZjhhYTI="
},
"data": [
  {
    "id": "b6ed4851-c629-4f0a-9c90-9e1874ced280",
    "name": "ELENI D",
    "mmsi": 636014651,
    "imo": 9577410,
    "call_sign": "A8VQ4",
    "ship_type": "Cargo",
    "class": "A",
    "flag": "LR",
    "length": 196,
    "width": 33,
    "ais_version": 0,
    "created_at": "2017-08-11T19:24:21.193385+00:00",
    "updated_at": "2018-07-02T18:24:12.171463+00:00",
    "last_known_position": {
      "timestamp": "2018-07-02T18:23:40+00:00",
      "geometry": {
        "type": "Point",
        "coordinates": [101.30614,2.9555]
      },
      "heading": 210,
      "speed": 0,
      "rot": 0,
      "accuracy": null,
      "collection_type": "terrestrial",
      "draught": null,
      "maneuver": 0,
      "course": 105.1
    },
    "most_recent_voyage": {
      "eta": "2018-06-30T10:00:00+00:00",
      "destination": "KLANG"
    },
    "general_classification": "Merchant",
    "individual_classification": "Bulk Carrier",
    "gross_tonnage": "0",
    "lifeboats": null,
    "person_capacity": null,
    "navigational_status": "Moored"
  }
]
}

Filter vessels by MMSI

The following example filters specific vessels by their mmsi identifier. You can provide a list of mmsi values, separated by commas, to obtain a list of vessels:

Request (bash)
curl - i - H "Authorization: Bearer {your_token}" - X GET https://api.sense.spire.com/vessels?mmsi=219002418,244710824,244780327,457545000
Response
{
  "paging": {
  "total": 4,
  "limit": 100
},
"data": [
  {
    "individual_classification": "Passenger Ship",
    "most_recent_position": {
      "maneuver": 0,
      "course": 47,
      "draught": null,
      "timestamp": "2017-08-24T08:17:40+00:00",
      "rot": - 128,
      "geometry": {
        "type": "Point",
        "coordinates": [15.03868,55.25095]
      },
      "collection_type": "terrestrial",
      "speed": 9.8,
      "heading": 511,
      "accuracy": null
    },
    "name": "PETER",
    "width": 7,
    "updated_at": "2017-08-27T15:08:00.477696+00:00",
    "person_capacity": null,
    "mmsi": 219002418,
    "ais_version": 0,
    "length": 23,
    "imo": null,
    "id": "9eccf900-b252-4056-8740-e989e368f4e1",
    "gross_tonnage": "0",
    "class": "A",
    "flag": "DK",
    "ship_type": "Passenger",
    "general_classification": "Merchant",
    "most_recent_voyage": {
      "destination": null,
      "eta": null
    },
    "lifeboats": null,
    "call_sign": "OUQD"
  }
]
}

Filter vessels by IMO

The following example filters specific vessels by their imo identifier. You can provide a list of imo values, separated by commas, to obtain a list of vessels:

Request (bash)
curl - i - H "Authorization: Bearer {your_token}" - X GET https://api.sense.spire.com/vessels?imo=9799666,9363273,9180011
Response
{
  "paging": {
  "total": 3,
  "limit": 100,
},
"data": [
  {
    "individual_classification": null,
    "most_recent_position": {
      "maneuver": 0,
      "course": 167.9,
      "draught": 4.2,
      "timestamp": "2017-08-25T14:25:53+00:00",
      "rot": 1,
      "geometry": {
        "type": "Point",
        "coordinates": [103.80757,1.24418]
      },
      "collection_type": "terrestrial",
      "speed": 0.1,
      "heading": 128,
      "accuracy": null
    },
    "name": "ASPIRE",
    "width": 17,
    "updated_at": "2017-08-29T20:52:26.288859+00:00",
    "person_capacity": null,
    "mmsi": 563006700,
    "ais_version": 0,
    "length": 97,
    "imo": 9799666,
    "id": "dbf8e47a-f937-4ced-9aca-807026a6c46a",
    "gross_tonnage": null,
    "class": "A",
    "flag": "SG",
    "ship_type": "Tanker",
    "general_classification": null,
    "most_recent_voyage": {
      "destination": "AWPA",
      "eta": "2017-08-23T12:30:00+00:00"
    },
    "lifeboats": null,
    "call_sign": "9V5139"
  }
]
}
​

Filter vessels by multiple parameters

Here is an example of a Vessels API call that combines multiple filters: ship_type and flag; in this example, we list cargo vessels with a Chinese flag (CN):

Request (bash)
curl - i - H "Authorization: Bearer {your_token}" - X GET 'https://api.sense.spire.com/vessels/?ship_type=cargo&flag=CN'
Response
{
  "paging": {
  "total": 24904,
  "limit": 100,
  "next": "dGltZT0xNTAyODI5MDk2LjgyNDQ2NyxpZD0wMDU0OGIxNS0xNGU3LTQ5MmYtYmM5MC1kMTZhNjUxZWY5ODE="
},
"data": [
  {
    "individual_classification": "Bulk Carrier",
    "most_recent_position": {
      "maneuver": 0,
      "course": 302.7,
      "draught": 10.7,
      "timestamp": "2017-08-25T14:38:08+00:00",
      "rot": 0,
      "geometry": {
        "type": "Point",
        "coordinates": [120.83391,27.99017]
      },
      "collection_type": "terrestrial",
      "speed": 0,
      "heading": 241,
      "accuracy": null
    },
  "name": "PU SHENG 8",
  "width": 24,
  "updated_at": "2017-08-29T20:28:25.609064+00:00",
  "person_capacity": null,
  "mmsi": 413440220,
  "ais_version": 0,
  "length": 173,
  "imo": null,
  "id": "c186473e-7a8d-4274-bf2a-7bfb7395e2a7",
  "gross_tonnage": "16539",
  "class": "A",
  "flag": "CN",
  "ship_type": "Cargo",
  "general_classification": "Merchant",
  "most_recent_voyage": {
    "destination": "WEN ZHOU",
    "eta": "2017-08-24T12:30:00+00:00"
  },
  "lifeboats": null,
  "call_sign": "BKSZ6"
  }
]
}

Filter known vessels inside geographical area

This example combines a ship_type filter (querying for tanker vessels) with a geographical filter using the last_known_position_within query parameter. In this specific example the provided polygon corresponds to the North Sea:

Request (bash)
curl -g -H "Authorization: Bearer {your_token}" -X GET 'https://api.sense.spire.com/vessels/'?ship_type=tanker&last_known_position_within={"type": "Polygon","coordinates": [[[-5.9765625,51.31688050404585],[12.12890625,51.31688050404585],[12.12890625,61.39671887310411],[-5.9765625,61.39671887310411],[-5.9765625,51.31688050404585]]]}
Response
{
  "paging": {
  "total": 1416,
  "limit": 100,
  "next": "dGltZT0xNTA4MjgyNDMzLjM3ODU3LGlkPTJiZjYxNjM0LThlNDAtNDEzYi05MDJiLTM4YTBjNmYzMzc4NA=="
},
"data": [
  {
    "individual_classification": "Buoy Ship",
    "most_recent_position": {
      "maneuver": 1,
      "course": 0,
      "draught": 6.7,
      "timestamp": "2017-08-25T14:46:12+00:00",
      "rot": 0,
      "geometry": {
        "type": "Point",
        "coordinates": [
          12.08969,
          54.11197
        ]
      },
      "collection_type": "terrestrial",
      "speed": 0,
      "heading": 253,
      "accuracy": null
    },
    "name": "KREBS DC 0",
    "width": 26,
    "updated_at": "2017-08-29T21:36:26.029021+00:00",
    "person_capacity": null,
    "mmsi": 211638130,
    "ais_version": 0,
    "length": 168,
    "imo": 6818617,
    "id": "b20b3d61-5e6f-45f3-82e2-a9cd5119d109",
    "gross_tonnage": "4937.0",
    "class": "A",
    "flag": "DE",
    "ship_type": "Tanker",
    "general_classification": "Merchant",
    "most_recent_voyage": {
      "destination": "TALLINN_ANCHORAGE",
      "eta": "2017-08-27T15:00:00+00:00"
    },
    "lifeboats": null,
    "call_sign": "DJFO2"
  }
]
}

Understanding field update rules

The goal of Vessels API is to provide the most accurate snapshot of a vessel possible. To mitigate the uncertainties of AIS data, we created rules that have to be met to make data responses more trustworthy. These rules are subject to change based on observed behaviour.

  • Fields originating from static messages will only update on Vessels API when the same value has been observed three times and corresponds to 90% of all observed updates since the last registered change on Vessels API.
  • Voyage related fields, which are likely to be updated more frequently, are updated after the same value has been observed twice after the last registered change.

This means that an update to the name field of a vessel will require at least three updates with the new name before we use it, whereas an update to the destination or ETA fields will only require two updates.

Example: We have a vessel with the name BOATY MCBOATFACE, with MMSI 123456789 and IMO 7654321. The last updated destination was STOCKHOLM and this was set on 2020-06-01 00:00:00Z.

If the subsequent messages contained the following values:

TimestampFieldValue
2020-06-01 01:00:00nameSIR DAVID ATTENBOROUGH
2020-06-01 02:00:00nameS1R DAVID ATTENBOROUGH
2020-06-01 03:00:00nameSIR DAVID ATTENBOROUGH
2020-06-01 04:00:00nameSIR DAVID ATTENBOROUGH

… the name property would not be updated on Vessels API because the rule of 90% of all observed updates being the new value is not met; while the three updates part of the rule was met (even if their instances are not in chronological order), the extra, different name update means the update percentage of all received messages is 75%.

Continuing with the same example, vessel let’s assume the same messages contained the following destination values:

TimestampFieldValue
2020-06-01 01:00:00destinationSINGAPORE
2020-06-01 02:00:00destinationGOTHENBURG
2020-06-01 03:00:00destinationSINGAPORE

Because the original destination was STOCKHOLM, upon observation of the second message with a destination value of SINGAPORE, the vessel’s destination field on Vessels API will be updated to SINGAPORE, since these are voyage related fields and the 2x observation rule applies.

Understanding duplicate entries

Sometimes, the messages we collect have malformed fields, or unexpected values due to any of the following reasons:

  • Message corruption (somewhere in the message transmit/receive path)
  • AIS equipment misconfiguration by the vessel captain
  • Fields manually input by the vessel captain contain typos, shorthand notation, unexpected messages, etc.

Any of the above reasons can make it difficult to identify whether the unexpected value is from an already identified vessel, or from a new vessel, especially when they affect fields like mmsi , imo , call_sign , or name.

This can sometimes result in a single vessel getting multiple entries in the vessels database.

 

How Vessels API accounts for duplicates

As of December 2017, less than 3% of MMSIs in the Vessels API have duplicate entries.

The intelligence built within Vessels API becomes increasingly able to determine a unique source of truth for ships in the ocean as it receives more AIS messages over time.

Understanding how ship types are assigned

Vessels API provides a more complete representation of each ship typology as compared with Messages API, as this classificiation is based on AIS messages, external data sources, and ship behavior analysis. This is reflected in the ship_type , general_classification , and individual_classification field.

ship_type Values

  • Fishing
  • Tug
  • Sailing
  • Pleasure Craft
  • Passenger
  • Cargo
  • Tanker
  • Other

general_classification Values

  • Fishing industry
  • Service vessels
  • Merchant
  • Inland waterways
  • Naval
  • Offshore
  • Pleasure / Leisure
  • Rescue
  • All other Activities

individual_classification Values

  • Air-cushion vehicle
  • Auxiliary ship
  • Despatch vessel
  • Lighter
  • Bulk carrier
  • Whaler
  • Buoy ship
  • Factory ship
  • Cargo ship
  • Coaster
  • Cable ship
  • Coast-guard
  • Barge
  • Chemical carrier
  • Trawler
  • Cement carrier
  • Tanker
  • Collier
  • Container ship
  • Corvette
  • Cruiser
  • Cutter
  • Destroyer
  • Ship used by divers
  • Minesweeper
  • Customs launch
  • Dredger
  • Dry cargo
  • Ketch
  • Training ship
  • Escort ship
  • Research ship/ Survey ship
  • Ferry
  • Fast patrol ship
  • Reefer
  • Weather
  • Frigate
  • Fruit carrier
  • Floating storage, offtake
  • General cargo
  • Schooner
  • Grain carrier
  • Floating crane
  • Warship
  • Hospital ship
  • Hydrographic ship
  • Ice breaker
  • Waste incinerator
  • Inspection ship
  • Lobster ship
  • Lugger
  • Banker
  • Mine layer
  • Motor boat
  • Pollution and surface clearance vessel
  • Naviplane
  • Ore-bulk-oil carrier
  • Oil tanker
  • Oceanographic ship
  • Ocean-station vessel
  • Passenger ship
  • Liner
  • Livestock carrier
  • Barge carrier
  • Drilling unit
  • Fishing vessel
  • Lightship
  • Lighthouse tender
  • Fishing guard
  • Platform
  • Pilot tender
  • Firefloat
  • Cargo and passenger
  • Pontoon
  • Aircraft carrier
  • Helicopter carrier
  • Salvage ship
  • Supply vessel
  • Rock breaker
  • RoRo ship
  • Rescue vessel
  • Stand-by-safety vessel
  • Sloop
  • Submarine
  • Support vessel
  • Patrol ship
  • Tunny ship
  • Liquefied gas carrier
  • Ore carrier
  • Solvent carrier
  • Transport
  • Forest-product carrier
  • Tramp
  • Pusher / Tug
  • Vehicle carrier
  • Launch
  • Hydrofoil
  • Sailing ship
  • Unspecified
  • Yacht