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.
Get started now
Download our open source Postman collection, drop in your access token and you will be making Vessels API calls in seconds.
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.
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
orfalse
array
- JSON array
json
- JSON object
{
"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
.
GET https://api.sense.spire.com/vessels?sort=updated_at
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
andto_stern
in meters width
number- Vessel width extracted from ship dimensions
to_port
andto_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
to127
;-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 destination | Matched unlocode | Matched port_name |
---|---|---|
KR PUS | KR PUS | Busan |
BUSAN | KR PUS | Busan |
AUBNE>KRPUS | KR PUS | Busan |
BUSAN=========JEJU | KR PUS | Busan |
KR PUS | KR PUS | Busan |
RU VNN > KR PUS | KR PUS | Busan |
KRPUS | KR PUS | Busan |
BUSAN KR | KR PUS | Busan |
PUSAN | KR PUS | Busan |
BU-SAN | KR PUS | Busan |
KR_PUS | KR PUS | Busan |
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.
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.
curl - i - H "Authorization: Bearer {your_token}" - X GET https://api.sense.spire.com/vessels
{
"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.
curl - i - H "Authorization: Bearer {your_token}" - X GET https://api.sense.spire.com/vessels/?ship_type=cargo
{
"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:
curl - i - H "Authorization: Bearer {your_token}" - X GET https://api.sense.spire.com/vessels?mmsi=219002418,244710824,244780327,457545000
{
"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:
curl - i - H "Authorization: Bearer {your_token}" - X GET https://api.sense.spire.com/vessels?imo=9799666,9363273,9180011
{
"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
):
curl - i - H "Authorization: Bearer {your_token}" - X GET 'https://api.sense.spire.com/vessels/?ship_type=cargo&flag=CN'
{
"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:
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]]]}
{
"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:
Timestamp | Field | Value |
---|---|---|
2020-06-01 01:00:00 | name | SIR DAVID ATTENBOROUGH |
2020-06-01 02:00:00 | name | S1R DAVID ATTENBOROUGH |
2020-06-01 03:00:00 | name | SIR DAVID ATTENBOROUGH |
2020-06-01 04:00:00 | name | SIR 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:
Timestamp | Field | Value |
---|---|---|
2020-06-01 01:00:00 | destination | SINGAPORE |
2020-06-01 02:00:00 | destination | GOTHENBURG |
2020-06-01 03:00:00 | destination | SINGAPORE |
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