Comparing Maritime 2.0 graphQL API to the Vessels API that it replaces
Maritime 2.0 graphQL replaces the Vessels API REST API that was launched by Spire in 2018. The Vessels API service has become obsolete and unable to scale with the increasing volumes of data now available in Spire Maritime data services. Maritime 2.0 graphQL is built to scale and serve and expanding set of API features.
API Request Type
Maritime 2.0 graphQL API makes an HTTPS POST Request.
Vessels API GET Request makes a HTTPS GET Request
API Request Examples
The example API calls below use the curl command, a common command line utility for calling and testing APIs.
Example Maritime 2.0 graphQL API call
(HTTP POST Request, query defined by request body)
curl --location --request POST \
'https://api.spire.com/graphql' \
--header 'Authorization: Bearer aAAAaaA1AaAaa1A1A1AaaaA1aaaAaAAa' \
--header 'Content-Type: application/json' \
--data-raw '{"query":"query { vessels( imo:9430222) {pageInfo {hasNextPage endCursor} nodes {id updateTimestamp staticData {aisClass flag name callsign timestamp updateTimestamp shipType shipSubType mmsi imo callsign dimensions {a b c d width length } } \
lastPositionUpdate {accuracy collectionType course heading latitude longitude maneuver navigationalStatus rot speed timestamp updateTimestamp } \
currentVoyage { destination draught eta timestamp updateTimestamp matchedPort {matchScore port { name unlocode centerPoint { latitude longitude} } } } } } }","variables":{}}'
Compare this to the simpler but less flexible Vessels API request
Example Vessels API call
(HTTP GET Request, query defined by request parameters)
curl --location --request GET \
'https://ais.spire.com/vessels/?imo=9430222' \
--header 'Authorization: Bearer {Your token here}'
Comparing API Response Format
The response from Maritime 2,0 graphQL is similar to that from Vessels API. The data that is returned is in a similar JSON format but the data model for the graphQL response is slightly different. There are equivalent data items for all AIS data items that were available from the Vessels API.
Sample Maritime 2.0 graphQL API response
{"id": "4263b0ab-9ccd-4f84-82b9-65e7d75243b8",
"updateTimestamp": "2022-02-16T00:44:48.306Z",
"staticData": { "aisClass": "A","flag": "PA",
"name": "BBC RIO","callsign": "3E3336",
"timestamp": "2021-08-31T07:24:41.208Z",
"updateTimestamp": "2022-02-15T08:39:37.033Z",
"shipType": "GENERAL_CARGO",
"imo": 9430222,"mmsi": 352978219,
"dimensions": {"a": 144,"b": 17,"c": 15,"d": 10,
"width": 25,"length": 161} },
"lastPositionUpdate": {
"accuracy": "LOW","collectionType": "DYNAMIC",
"course": 86.1,"heading": 86,
"latitude": 1.267245,"longitude": 104.22576833333332,
"maneuver": "NOT_AVAILABLE",
"navigationalStatus": "UNDER_WAY_USING_ENGINE",
"rot": 1.1160072,"speed": 12.9,
"timestamp": "2022-02-14T20:18:27.000Z",
"updateTimestamp": "2022-02-16T00:44:48.306Z" },
"currentVoyage": {
"destination": "SINGAPORE", "draught": 8.2,
"eta": "2021-10-17T12:00:00.000Z",
"timestamp": "2021-10-17T09:37:17.099Z",
"updateTimestamp": "2022-02-15T08:39:37.033Z"
} },
Sample Vessels API Response
{ "id": "fd096ff2-0d1b-48d8-88f5-0fadada65139",
"name": "DIYYINAH-I",
"mmsi": 636014943, "imo": 9487251,
"call_sign": "A8XN8",
"ship_type": "Tanker", "class": "A", "flag": "LR",
"length": 228, "width": 32, "ais_version": 0,
"created_at": "2017-08-11T19:24:21.193385+00:00",
"updated_at": "2019-09-04T16:40:09.386823+00:00",
"static_updated_at": "2019-09-02T17:26:19+00:00",
"position_updated_at": "2019-09-04T16:40:09.386823+00:00",
"last_known_position": {
"timestamp": "2019-09-04T14:59:17+00:00",
"geometry": {"type": "Point", "coordinates":[96.11947,5.95611]},
"heading": 285.0, "speed": 13.2, "rot": 0.0,
"accuracy": null, "collection_type": "satellite",
"draught": 8.5, "maneuver": 0.0, "course": 284.5 },
"most_recent_voyage": {
"eta": "2019-09-16T12:00:00+00:00",
"destination": "FUJAIRAH"},
Comparing API Calls
graphQL requires a more detailed "query" to be submitted when requesting data.
Vessels API is a fairly fixed GET request, where the only values passed are specific filters being applied to the query. The response format is fixed and does not need specifying.
The graphQL request requires all filters to be specified, but also all required data fields for the response to be listed.
Vessels API v1. (http GET) API call for a list of vessels by IMO number
https://ais.spire.com/vessels/?limit=1&imo=9758428,9729269,9596272
Maritime 2.0 graphQL (http POST) API call for a list of vessels by IMO number
query { vessels(imo:[9758428,9729269,9596272] first:1000 ) {
pageInfo { hasNextPage endCursor }
nodes { id updateTimestamp
staticData { aisClass flag name callsign timestamp updateTimestamp shipType shipSubType
mmsi imo callsign dimensions { a b c d width length } }
lastPositionUpdate { accuracy collectionType course heading latitude longitude maneuver navigationalStatus
rot speed timestamp updateTimestamp }
currentVoyage { destination draught eta
matchedPort { matchScore port { name unlocode centerPoint { latitude longitude } } }
timestamp updateTimestamp
} } } }
Query What You Want
graphQL allows specification of only the required data to be returned.
Below is a sample graphQL query listing all available fields.
Note. fields in bold italics are not actually required.
nodes {id updateTimestamp
staticData {aisClass flag name callsign timestamp updateTimestamp shipType shipSubType mmsi imo dimensions { a b c d width length } }
lastPositionUpdate { accuracy collectionType course heading
latitude longitude maneuver navigationalStatus rot speed
timestamp updateTimestamp }
currentVoyage { destination draught eta
matchedPort {matchScore port {name unlocode
centerPoint { latitude longitude } } } timestamp updateTimestamp }
} } }
Here is the same graphQL query but with the unrequired fields removed. Showing that graphQL allows specification of only the required data items to be returned
nodes {id updateTimestamp
staticData { name callsign updateTimestamp shipType mmsi imo
dimensions {width length } }
lastPositionUpdate { collectionType course heading
latitude longitude navigationalStatus rot speed
timestamp }
currentVoyage { destination draught eta
matchedPort {port {name unlocode } }
updateTimestamp }
}
} }