From a08880daab8dd262bdf1c1f43caed3d4802a0360 Mon Sep 17 00:00:00 2001 From: Akshay Dodeja Date: Mon, 19 Oct 2026 13:33:23 -0700 Subject: [PATCH] docs(api): document who can access vessel endpoints Every /v2/vessels endpoint now requires Routing Data and returns only vessels on the caller's actively tracked shipments. Document the 401, 403 and 404 responses, the nulled position fields in included vessels and webhooks, the removed /vessels/{id}/location endpoint, and that the map embed needs Routing Data for vessel positions. Regenerate Postman and SDK types from the spec. Co-Authored-By: Claude Opus 5.5 --- Terminal49-API.postman_collection.json | 504 +++++++++++++++++- .../vessels/get-a-vessel-using-the-id.mdx | 8 +- .../vessels/get-a-vessel-using-the-imo.mdx | 8 +- .../in-depth-guides/terminal49-map.mdx | 3 +- docs/api-docs/useful-info/entitlements.mdx | 21 +- docs/openapi.json | 24 +- .../src/generated/terminal49.ts | 16 +- 7 files changed, 555 insertions(+), 29 deletions(-) diff --git a/Terminal49-API.postman_collection.json b/Terminal49-API.postman_collection.json index c9c159ad0..665c4cbce 100644 --- a/Terminal49-API.postman_collection.json +++ b/Terminal49-API.postman_collection.json @@ -21406,7 +21406,7 @@ "request": { "name": "Get vessel future positions", "description": { - "content": "Returns the estimated route between two ports for a given vessel. The timestamp of the positions has fixed spacing of one minute. This is a paid feature. Please contact sales@terminal49.com.", + "content": "Returns the estimated route between two ports for a given vessel. The timestamp of the positions has fixed spacing of one minute. Requires the Routing Data entitlement for API keys, including publishable keys. Without it, every vessel endpoint returns `403`. Only vessels on your account's actively tracked shipments are returned; any other vessel returns `404`. See [Entitlements and Paid Features](/api-docs/useful-info/entitlements#vessel-data-access).", "type": "text/plain" }, "url": { @@ -21537,6 +21537,81 @@ "cookie": [], "_postman_previewlanguage": "json" }, + { + "id": "bd2c476d-2705-5524-9099-f4d2975e60e4", + "name": "Unauthorized. The API token is missing or invalid, or the account may not perform this action.", + "originalRequest": { + "url": { + "path": [ + "vessels", + ":id", + "future_positions" + ], + "host": [ + "{{baseUrl}}" + ], + "query": [ + { + "disabled": false, + "description": { + "content": "(Required) The destination port id", + "type": "text/plain" + }, + "key": "port_id", + "value": "" + }, + { + "disabled": false, + "description": { + "content": "(Required) The previous port id", + "type": "text/plain" + }, + "key": "previous_port_id", + "value": "" + } + ], + "variable": [ + { + "disabled": false, + "description": { + "content": "(Required) ", + "type": "text/plain" + }, + "type": "any", + "value": "", + "key": "id" + } + ] + }, + "header": [ + { + "key": "Accept", + "value": "application/json" + }, + { + "description": { + "content": "Added as a part of security scheme: apikey", + "type": "text/plain" + }, + "key": "Authorization", + "value": "" + } + ], + "method": "GET", + "body": {} + }, + "status": "Unauthorized", + "code": 401, + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": "{\n \"errors\": [\n {\n \"detail\": \"\",\n \"title\": \"\",\n \"source\": {\n \"pointer\": \"\",\n \"parameter\": \"\"\n },\n \"code\": \"\",\n \"status\": \"\",\n \"meta\": {\n \"key_0\": \"string\"\n }\n },\n {\n \"detail\": \"\",\n \"title\": \"\",\n \"source\": {\n \"pointer\": \"\",\n \"parameter\": \"\"\n },\n \"code\": \"\",\n \"status\": \"\",\n \"meta\": {\n \"key_0\": 65,\n \"key_1\": \"string\"\n }\n }\n ]\n}", + "cookie": [], + "_postman_previewlanguage": "json" + }, { "id": "6e5a14bd-16a4-57f5-966e-f26a253df8db", "name": "Forbidden - Routing data feature is not enabled for this account", @@ -21699,7 +21774,7 @@ "request": { "name": "Get vessel future positions from coordinates", "description": { - "content": "Returns the estimated route between two ports for a given vessel from a set of coordinates. The timestamp of the positions has fixed spacing of one minute. This is a paid feature. Please contact sales@terminal49.com.", + "content": "Returns the estimated route between two ports for a given vessel from a set of coordinates. The timestamp of the positions has fixed spacing of one minute. Requires the Routing Data entitlement for API keys, including publishable keys. Without it, every vessel endpoint returns `403`. Only vessels on your account's actively tracked shipments are returned; any other vessel returns `404`. See [Entitlements and Paid Features](/api-docs/useful-info/entitlements#vessel-data-access).", "type": "text/plain" }, "url": { @@ -21866,6 +21941,99 @@ "cookie": [], "_postman_previewlanguage": "json" }, + { + "id": "f2fe9f41-2849-5629-9b4f-54355f9bbdbe", + "name": "Unauthorized. The API token is missing or invalid, or the account may not perform this action.", + "originalRequest": { + "url": { + "path": [ + "vessels", + ":id", + "future_positions_with_coordinates" + ], + "host": [ + "{{baseUrl}}" + ], + "query": [ + { + "disabled": false, + "description": { + "content": "(Required) The destination port id", + "type": "text/plain" + }, + "key": "port_id", + "value": "" + }, + { + "disabled": false, + "description": { + "content": "(Required) The previous port id", + "type": "text/plain" + }, + "key": "previous_port_id", + "value": "" + }, + { + "disabled": false, + "description": { + "content": "(Required) Starting latitude coordinate", + "type": "text/plain" + }, + "key": "latitude", + "value": "" + }, + { + "disabled": false, + "description": { + "content": "(Required) Starting longitude coordinate", + "type": "text/plain" + }, + "key": "longitude", + "value": "" + } + ], + "variable": [ + { + "disabled": false, + "description": { + "content": "(Required) ", + "type": "text/plain" + }, + "type": "any", + "value": "", + "key": "id" + } + ] + }, + "header": [ + { + "key": "Accept", + "value": "application/json" + }, + { + "description": { + "content": "Added as a part of security scheme: apikey", + "type": "text/plain" + }, + "key": "Authorization", + "value": "" + } + ], + "method": "GET", + "body": {} + }, + "status": "Unauthorized", + "code": 401, + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": "{\n \"errors\": [\n {\n \"detail\": \"\",\n \"title\": \"\",\n \"source\": {\n \"pointer\": \"\",\n \"parameter\": \"\"\n },\n \"code\": \"\",\n \"status\": \"\",\n \"meta\": {\n \"key_0\": \"string\"\n }\n },\n {\n \"detail\": \"\",\n \"title\": \"\",\n \"source\": {\n \"pointer\": \"\",\n \"parameter\": \"\"\n },\n \"code\": \"\",\n \"status\": \"\",\n \"meta\": {\n \"key_0\": 65,\n \"key_1\": \"string\"\n }\n }\n ]\n}", + "cookie": [], + "_postman_previewlanguage": "json" + }, { "id": "e47d2a13-9dff-5358-ab1c-e5d9ee1d76f0", "name": "Forbidden - Routing data feature is not enabled for this account", @@ -32724,7 +32892,7 @@ "request": { "name": "Get a vessel using the id", "description": { - "content": "Returns a vessel by id. `show_positions` is a paid feature. Please contact sales@terminal49.com.", + "content": "Returns a vessel by id, with its current position. Add `show_positions` to include its position history. Requires the Routing Data entitlement for API keys, including publishable keys. Without it, every vessel endpoint returns `403`. Only vessels on your account's actively tracked shipments are returned; any other vessel returns `404`. See [Entitlements and Paid Features](/api-docs/useful-info/entitlements#vessel-data-access).", "type": "text/plain" }, "url": { @@ -32854,8 +33022,82 @@ "_postman_previewlanguage": "json" }, { - "id": "44f4fa24-27e0-507d-bb5f-4535deb95d67", - "name": "Forbidden - Feature not enabled", + "id": "0323d989-3209-5640-9e77-3fca5e974087", + "name": "Unauthorized. The API token is missing or invalid, or the account may not perform this action.", + "originalRequest": { + "url": { + "path": [ + "vessels", + ":id" + ], + "host": [ + "{{baseUrl}}" + ], + "query": [ + { + "disabled": true, + "description": { + "content": "ISO 8601 timestamp to filter positions from. 7 days by default.", + "type": "text/plain" + }, + "key": "show_positions[from_timestamp]", + "value": "" + }, + { + "disabled": true, + "description": { + "content": "ISO 8601 timestamp to filter positions up to. Current time by default.", + "type": "text/plain" + }, + "key": "show_positions[to_timestamp]", + "value": "" + } + ], + "variable": [ + { + "disabled": false, + "description": { + "content": "(Required) ", + "type": "text/plain" + }, + "type": "any", + "value": "", + "key": "id" + } + ] + }, + "header": [ + { + "key": "Accept", + "value": "application/json" + }, + { + "description": { + "content": "Added as a part of security scheme: apikey", + "type": "text/plain" + }, + "key": "Authorization", + "value": "" + } + ], + "method": "GET", + "body": {} + }, + "status": "Unauthorized", + "code": 401, + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": "{\n \"errors\": [\n {\n \"detail\": \"\",\n \"title\": \"\",\n \"source\": {\n \"pointer\": \"\",\n \"parameter\": \"\"\n },\n \"code\": \"\",\n \"status\": \"\",\n \"meta\": {\n \"key_0\": \"string\"\n }\n },\n {\n \"detail\": \"\",\n \"title\": \"\",\n \"source\": {\n \"pointer\": \"\",\n \"parameter\": \"\"\n },\n \"code\": \"\",\n \"status\": \"\",\n \"meta\": {\n \"key_0\": 65,\n \"key_1\": \"string\"\n }\n }\n ]\n}", + "cookie": [], + "_postman_previewlanguage": "json" + }, + { + "id": "4051a105-f0c7-5c6d-8556-3eb3fe7ca51d", + "name": "Forbidden - Routing data feature is not enabled for this account", "originalRequest": { "url": { "path": [ @@ -33013,7 +33255,7 @@ "request": { "name": "Get a vessel using the imo", "description": { - "content": "Returns a vessel by the given IMO number. `show_positions` is a paid feature. Please contact sales@terminal49.com.", + "content": "Returns a vessel by the given IMO number, with its current position. Add `show_positions` to include its position history. Requires the Routing Data entitlement for API keys, including publishable keys. Without it, every vessel endpoint returns `403`. Only vessels on your account's actively tracked shipments are returned; any other vessel returns `404`. See [Entitlements and Paid Features](/api-docs/useful-info/entitlements#vessel-data-access).", "type": "text/plain" }, "url": { @@ -33143,8 +33385,82 @@ "_postman_previewlanguage": "json" }, { - "id": "312b25b5-4f65-5c53-a55c-89ea5149365d", - "name": "Forbidden - Feature not enabled", + "id": "f51e2fca-eecc-5b64-bbdf-caa1529d32ce", + "name": "Unauthorized. The API token is missing or invalid, or the account may not perform this action.", + "originalRequest": { + "url": { + "path": [ + "vessels", + ":imo" + ], + "host": [ + "{{baseUrl}}" + ], + "query": [ + { + "disabled": true, + "description": { + "content": "ISO 8601 timestamp to filter positions from. 7 days by default.", + "type": "text/plain" + }, + "key": "show_positions[from_timestamp]", + "value": "" + }, + { + "disabled": true, + "description": { + "content": "ISO 8601 timestamp to filter positions up to. Current time by default.", + "type": "text/plain" + }, + "key": "show_positions[to_timestamp]", + "value": "" + } + ], + "variable": [ + { + "disabled": false, + "description": { + "content": "(Required) ", + "type": "text/plain" + }, + "type": "any", + "value": "", + "key": "imo" + } + ] + }, + "header": [ + { + "key": "Accept", + "value": "application/json" + }, + { + "description": { + "content": "Added as a part of security scheme: apikey", + "type": "text/plain" + }, + "key": "Authorization", + "value": "" + } + ], + "method": "GET", + "body": {} + }, + "status": "Unauthorized", + "code": 401, + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": "{\n \"errors\": [\n {\n \"detail\": \"\",\n \"title\": \"\",\n \"source\": {\n \"pointer\": \"\",\n \"parameter\": \"\"\n },\n \"code\": \"\",\n \"status\": \"\",\n \"meta\": {\n \"key_0\": \"string\"\n }\n },\n {\n \"detail\": \"\",\n \"title\": \"\",\n \"source\": {\n \"pointer\": \"\",\n \"parameter\": \"\"\n },\n \"code\": \"\",\n \"status\": \"\",\n \"meta\": {\n \"key_0\": 65,\n \"key_1\": \"string\"\n }\n }\n ]\n}", + "cookie": [], + "_postman_previewlanguage": "json" + }, + { + "id": "99605076-8739-5e9b-8bc4-77fd54415536", + "name": "Forbidden - Routing data feature is not enabled for this account", "originalRequest": { "url": { "path": [ @@ -33302,7 +33618,7 @@ "request": { "name": "Get vessel future positions", "description": { - "content": "Returns the estimated route between two ports for a given vessel. The timestamp of the positions has fixed spacing of one minute. This is a paid feature. Please contact sales@terminal49.com.", + "content": "Returns the estimated route between two ports for a given vessel. The timestamp of the positions has fixed spacing of one minute. Requires the Routing Data entitlement for API keys, including publishable keys. Without it, every vessel endpoint returns `403`. Only vessels on your account's actively tracked shipments are returned; any other vessel returns `404`. See [Entitlements and Paid Features](/api-docs/useful-info/entitlements#vessel-data-access).", "type": "text/plain" }, "url": { @@ -33433,6 +33749,81 @@ "cookie": [], "_postman_previewlanguage": "json" }, + { + "id": "003571b6-a82e-547b-99b5-0f8019d60c18", + "name": "Unauthorized. The API token is missing or invalid, or the account may not perform this action.", + "originalRequest": { + "url": { + "path": [ + "vessels", + ":id", + "future_positions" + ], + "host": [ + "{{baseUrl}}" + ], + "query": [ + { + "disabled": false, + "description": { + "content": "(Required) The destination port id", + "type": "text/plain" + }, + "key": "port_id", + "value": "" + }, + { + "disabled": false, + "description": { + "content": "(Required) The previous port id", + "type": "text/plain" + }, + "key": "previous_port_id", + "value": "" + } + ], + "variable": [ + { + "disabled": false, + "description": { + "content": "(Required) ", + "type": "text/plain" + }, + "type": "any", + "value": "", + "key": "id" + } + ] + }, + "header": [ + { + "key": "Accept", + "value": "application/json" + }, + { + "description": { + "content": "Added as a part of security scheme: apikey", + "type": "text/plain" + }, + "key": "Authorization", + "value": "" + } + ], + "method": "GET", + "body": {} + }, + "status": "Unauthorized", + "code": 401, + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": "{\n \"errors\": [\n {\n \"detail\": \"\",\n \"title\": \"\",\n \"source\": {\n \"pointer\": \"\",\n \"parameter\": \"\"\n },\n \"code\": \"\",\n \"status\": \"\",\n \"meta\": {\n \"key_0\": \"string\"\n }\n },\n {\n \"detail\": \"\",\n \"title\": \"\",\n \"source\": {\n \"pointer\": \"\",\n \"parameter\": \"\"\n },\n \"code\": \"\",\n \"status\": \"\",\n \"meta\": {\n \"key_0\": 65,\n \"key_1\": \"string\"\n }\n }\n ]\n}", + "cookie": [], + "_postman_previewlanguage": "json" + }, { "id": "9270dab1-39d5-5d5f-b7af-f95ada6706e6", "name": "Forbidden - Routing data feature is not enabled for this account", @@ -33595,7 +33986,7 @@ "request": { "name": "Get vessel future positions from coordinates", "description": { - "content": "Returns the estimated route between two ports for a given vessel from a set of coordinates. The timestamp of the positions has fixed spacing of one minute. This is a paid feature. Please contact sales@terminal49.com.", + "content": "Returns the estimated route between two ports for a given vessel from a set of coordinates. The timestamp of the positions has fixed spacing of one minute. Requires the Routing Data entitlement for API keys, including publishable keys. Without it, every vessel endpoint returns `403`. Only vessels on your account's actively tracked shipments are returned; any other vessel returns `404`. See [Entitlements and Paid Features](/api-docs/useful-info/entitlements#vessel-data-access).", "type": "text/plain" }, "url": { @@ -33762,6 +34153,99 @@ "cookie": [], "_postman_previewlanguage": "json" }, + { + "id": "c62c3838-4f77-5072-89db-ee5ff96d445d", + "name": "Unauthorized. The API token is missing or invalid, or the account may not perform this action.", + "originalRequest": { + "url": { + "path": [ + "vessels", + ":id", + "future_positions_with_coordinates" + ], + "host": [ + "{{baseUrl}}" + ], + "query": [ + { + "disabled": false, + "description": { + "content": "(Required) The destination port id", + "type": "text/plain" + }, + "key": "port_id", + "value": "" + }, + { + "disabled": false, + "description": { + "content": "(Required) The previous port id", + "type": "text/plain" + }, + "key": "previous_port_id", + "value": "" + }, + { + "disabled": false, + "description": { + "content": "(Required) Starting latitude coordinate", + "type": "text/plain" + }, + "key": "latitude", + "value": "" + }, + { + "disabled": false, + "description": { + "content": "(Required) Starting longitude coordinate", + "type": "text/plain" + }, + "key": "longitude", + "value": "" + } + ], + "variable": [ + { + "disabled": false, + "description": { + "content": "(Required) ", + "type": "text/plain" + }, + "type": "any", + "value": "", + "key": "id" + } + ] + }, + "header": [ + { + "key": "Accept", + "value": "application/json" + }, + { + "description": { + "content": "Added as a part of security scheme: apikey", + "type": "text/plain" + }, + "key": "Authorization", + "value": "" + } + ], + "method": "GET", + "body": {} + }, + "status": "Unauthorized", + "code": 401, + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": "{\n \"errors\": [\n {\n \"detail\": \"\",\n \"title\": \"\",\n \"source\": {\n \"pointer\": \"\",\n \"parameter\": \"\"\n },\n \"code\": \"\",\n \"status\": \"\",\n \"meta\": {\n \"key_0\": \"string\"\n }\n },\n {\n \"detail\": \"\",\n \"title\": \"\",\n \"source\": {\n \"pointer\": \"\",\n \"parameter\": \"\"\n },\n \"code\": \"\",\n \"status\": \"\",\n \"meta\": {\n \"key_0\": 65,\n \"key_1\": \"string\"\n }\n }\n ]\n}", + "cookie": [], + "_postman_previewlanguage": "json" + }, { "id": "c9a455cf-2da7-5680-8961-8d718a0c6bc0", "name": "Forbidden - Routing data feature is not enabled for this account", diff --git a/docs/api-docs/api-reference/vessels/get-a-vessel-using-the-id.mdx b/docs/api-docs/api-reference/vessels/get-a-vessel-using-the-id.mdx index 826ebcc6e..e05ff4981 100644 --- a/docs/api-docs/api-reference/vessels/get-a-vessel-using-the-id.mdx +++ b/docs/api-docs/api-reference/vessels/get-a-vessel-using-the-id.mdx @@ -1,7 +1,11 @@ --- title: "Get a vessel by ID" -description: "Retrieve a vessel from the Terminal49 API using its internal vessel ID, including name, IMO number, and optional position data for paid plan accounts." +description: "Retrieve a vessel on one of your actively tracked shipments by its Terminal49 vessel ID, including name, IMO number, and current position. Requires Routing Data." og:title: Get a Vessel by ID | Terminal49 API og:description: Retrieve vessel details by Terminal49 resource ID. Returns the vessel name, IMO number, current position, flag, and linked shipment information. openapi: get /vessels/{id} ---- \ No newline at end of file +--- + + + This is a paid Routing Data endpoint. It returns only vessels on your account's actively tracked shipments. See [Vessel data access](/api-docs/useful-info/entitlements#vessel-data-access) for the `401`, `403`, and `404` responses. + diff --git a/docs/api-docs/api-reference/vessels/get-a-vessel-using-the-imo.mdx b/docs/api-docs/api-reference/vessels/get-a-vessel-using-the-imo.mdx index 05163be52..33c5900b0 100644 --- a/docs/api-docs/api-reference/vessels/get-a-vessel-using-the-imo.mdx +++ b/docs/api-docs/api-reference/vessels/get-a-vessel-using-the-imo.mdx @@ -1,7 +1,11 @@ --- title: "Get a vessel by IMO" -description: "Retrieve a vessel from the Terminal49 API by IMO number, including the vessel name, internal ID, and optional AIS position data on paid plan accounts." +description: "Retrieve a vessel on one of your actively tracked shipments by its IMO number, including name, Terminal49 vessel ID, and current position. Requires Routing Data." og:title: Get a Vessel by IMO Number | Terminal49 API og:description: Look up vessel details by IMO number using the Terminal49 API. Returns the vessel name, current position, flag, and associated shipment data. openapi: get /vessels/{imo} ---- \ No newline at end of file +--- + + + This is a paid Routing Data endpoint. It returns only vessels on your account's actively tracked shipments. See [Vessel data access](/api-docs/useful-info/entitlements#vessel-data-access) for the `401`, `403`, and `404` responses. + diff --git a/docs/api-docs/in-depth-guides/terminal49-map.mdx b/docs/api-docs/in-depth-guides/terminal49-map.mdx index ed72a62ac..e518a5126 100644 --- a/docs/api-docs/in-depth-guides/terminal49-map.mdx +++ b/docs/api-docs/in-depth-guides/terminal49-map.mdx @@ -14,7 +14,8 @@ keywords: ## Prerequisites - A Terminal49 account. -- A publishable map API key. See [Entitlements and Paid Features](/api-docs/useful-info/entitlements) for access requirements. +- A publishable map API key. +- Routing Data enabled on your account. The embed reads vessel positions, which require it. See [Entitlements and Paid Features](/api-docs/useful-info/entitlements#vessel-data-access). - Familiarity with the [Shipments API](/api-docs/api-reference/shipments/list-shipments) and [Containers API](/api-docs/api-reference/containers/list-containers). The following examples pass `containerId` and `shipmentId` variables to the embedded map. diff --git a/docs/api-docs/useful-info/entitlements.mdx b/docs/api-docs/useful-info/entitlements.mdx index 46df5da05..5d3f81cba 100644 --- a/docs/api-docs/useful-info/entitlements.mdx +++ b/docs/api-docs/useful-info/entitlements.mdx @@ -19,13 +19,30 @@ Some Terminal49 features require account enablement beyond standard API access. | --- | --- | --- | --- | | Read endpoints (`GET /v2/shipments`, `GET /v2/containers`, `GET /v2/tracking_requests/{id}`, and other GETs) | Full API access (paid plan or 7-day API trial) | Open [Developers](https://app.terminal49.com/developers) and click **Start trial** for 7 days with the same 10-active-container limit, or see [Pricing](/api-docs/useful-info/pricing) for ongoing access | `401 Unauthorized` with `You do not have permissions for using the API, except for creating tracking requests. All other permissions require a paid plan. See https://app.terminal49.com/settings/billing`. `POST /v2/tracking_requests` still works. | | Container Map GeoJSON API (`GET /v2/containers/{id}/map_geojson`) | Routing Data | Contact sales@terminal49.com | `403 Forbidden` with `Routing data feature is not enabled for this account` | -| Vessel position and future-position endpoints | Routing Data / vessel positions | Contact sales@terminal49.com | `403 Forbidden` with `Routing data feature is not enabled for this account` | +| Vessel endpoints (`GET /v2/vessels/{id}`, IMO lookup, position history, and future positions) | Routing Data | Contact sales@terminal49.com | `403 Forbidden` with `Routing data feature is not enabled for this account`. Vessels outside your actively tracked shipments return `404`. See [Vessel data access](#vessel-data-access). | | MCP `get_container_route` tool | Routing Data | Contact sales@terminal49.com | The tool returns a feature-not-enabled response; use `get_container_transport_events` for historical milestones | -| Terminal49 Map Embed | Publishable map API key | Contact support@terminal49.com | The browser embed cannot authenticate without a valid publishable key | +| Terminal49 Map Embed | Publishable map API key, plus Routing Data for vessel positions | Contact support@terminal49.com | The browser embed cannot authenticate without a valid publishable key. Without Routing Data, vessel requests from the embed return `403`. | | Tracking Widget Embed | Publishable widget API key | Contact support@terminal49.com | The browser widget cannot authenticate without a valid publishable key | | Container refresh (`PATCH /v2/containers/{id}/refresh`) | On-demand refresh | Contact sales@terminal49.com | `403 Forbidden`; the endpoint is also rate-limited to 10 requests per minute for entitled accounts | | Rail LFD data (`import_deadlines.pickup_lfd_rail` and the `container.pickup_lfd_rail.changed` webhook event) | Rail Plan | Contact sales@terminal49.com | `container.pickup_lfd_rail.changed` notifications are not delivered, and rail-carrier LFD updates are not surfaced on the container | +## Vessel data access + +Vessel data is part of Routing Data. These rules apply to every `/v2/vessels` endpoint, whether you call it with an API key or, where the endpoint allows it, a publishable API key. + +| Your account | Response | +| --- | --- | +| No full API access (free plan, paused API access, or an invalid key) | `401 Unauthorized` | +| Full API access without Routing Data | `403 Forbidden` with `Routing data feature is not enabled for this account` | +| Routing Data, vessel on one of your actively tracked shipments | `200 OK` with the vessel and its current position | +| Routing Data, any other vessel | `404 Not Found` | + +A vessel counts as yours while at least one of your actively tracked shipments references it, including transshipment vessels and vessels for upcoming legs. When you stop tracking every shipment that references a vessel, its endpoints return `404` for you. + +The same rules apply to vessel positions inside other responses. In included vessel resources and webhook payloads, the vessel's position fields (`latitude`, `longitude`, `nautical_speed_knots`, `navigational_heading_degrees`, and `position_timestamp`) are `null` when your account does not have Routing Data or the vessel is not on one of your actively tracked shipments. The field names stay the same, so your parser does not need to change. + +The standalone `GET /v2/vessels/{id}/location` endpoint has been removed. Read the current position from [`GET /v2/vessels/{id}`](/api-docs/api-reference/vessels/get-a-vessel-using-the-id) instead. + ## Pricing See [Pricing](/api-docs/useful-info/pricing) for current public pricing pointers. If a page says to contact sales or support, treat that feature as account-gated until the entitlement appears on your account. diff --git a/docs/openapi.json b/docs/openapi.json index b43ba2b1f..f4a55534c 100644 --- a/docs/openapi.json +++ b/docs/openapi.json @@ -10294,8 +10294,11 @@ } } }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, "403": { - "description": "Forbidden - Feature not enabled", + "description": "Forbidden - Routing data feature is not enabled for this account", "content": { "application/json": { "schema": { @@ -10335,7 +10338,7 @@ } }, "operationId": "get-vessels-id", - "description": "Returns a vessel by id. `show_positions` is a paid feature. Please contact sales@terminal49.com." + "description": "Returns a vessel by id, with its current position. Add `show_positions` to include its position history. Requires the Routing Data entitlement for API keys, including publishable keys. Without it, every vessel endpoint returns `403`. Only vessels on your account's actively tracked shipments are returned; any other vessel returns `404`. See [Entitlements and Paid Features](/api-docs/useful-info/entitlements#vessel-data-access)." } }, "/vessels/{imo}": { @@ -10392,8 +10395,11 @@ } } }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, "403": { - "description": "Forbidden - Feature not enabled", + "description": "Forbidden - Routing data feature is not enabled for this account", "content": { "application/json": { "schema": { @@ -10433,7 +10439,7 @@ } }, "operationId": "get-vessels-imo", - "description": "Returns a vessel by the given IMO number. `show_positions` is a paid feature. Please contact sales@terminal49.com.", + "description": "Returns a vessel by the given IMO number, with its current position. Add `show_positions` to include its position history. Requires the Routing Data entitlement for API keys, including publishable keys. Without it, every vessel endpoint returns `403`. Only vessels on your account's actively tracked shipments are returned; any other vessel returns `404`. See [Entitlements and Paid Features](/api-docs/useful-info/entitlements#vessel-data-access).", "x-internal": true } }, @@ -10479,6 +10485,9 @@ } } }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, "403": { "description": "Forbidden - Routing data feature is not enabled for this account", "content": { @@ -10516,7 +10525,7 @@ } }, "operationId": "get-vessels-id-future-positions", - "description": "Returns the estimated route between two ports for a given vessel. The timestamp of the positions has fixed spacing of one minute. This is a paid feature. Please contact sales@terminal49.com.", + "description": "Returns the estimated route between two ports for a given vessel. The timestamp of the positions has fixed spacing of one minute. Requires the Routing Data entitlement for API keys, including publishable keys. Without it, every vessel endpoint returns `403`. Only vessels on your account's actively tracked shipments are returned; any other vessel returns `404`. See [Entitlements and Paid Features](/api-docs/useful-info/entitlements#vessel-data-access).", "parameters": [ { "schema": { @@ -10583,6 +10592,9 @@ } } }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, "403": { "description": "Forbidden - Routing data feature is not enabled for this account", "content": { @@ -10620,7 +10632,7 @@ } }, "operationId": "get-vessels-id-future-positions-with-coordinates", - "description": "Returns the estimated route between two ports for a given vessel from a set of coordinates. The timestamp of the positions has fixed spacing of one minute. This is a paid feature. Please contact sales@terminal49.com.", + "description": "Returns the estimated route between two ports for a given vessel from a set of coordinates. The timestamp of the positions has fixed spacing of one minute. Requires the Routing Data entitlement for API keys, including publishable keys. Without it, every vessel endpoint returns `403`. Only vessels on your account's actively tracked shipments are returned; any other vessel returns `404`. See [Entitlements and Paid Features](/api-docs/useful-info/entitlements#vessel-data-access).", "parameters": [ { "schema": { diff --git a/sdks/typescript-sdk/src/generated/terminal49.ts b/sdks/typescript-sdk/src/generated/terminal49.ts index 7324dfe82..aae7f9020 100644 --- a/sdks/typescript-sdk/src/generated/terminal49.ts +++ b/sdks/typescript-sdk/src/generated/terminal49.ts @@ -663,7 +663,7 @@ export interface paths { }; /** * Get a vessel using the id - * @description Returns a vessel by id. `show_positions` is a paid feature. Please contact sales@terminal49.com. + * @description Returns a vessel by id, with its current position. Add `show_positions` to include its position history. Requires the Routing Data entitlement for API keys, including publishable keys. Without it, every vessel endpoint returns `403`. Only vessels on your account's actively tracked shipments are returned; any other vessel returns `404`. See [Entitlements and Paid Features](/api-docs/useful-info/entitlements#vessel-data-access). */ get: operations["get-vessels-id"]; put?: never; @@ -690,7 +690,7 @@ export interface paths { }; /** * Get a vessel using the imo - * @description Returns a vessel by the given IMO number. `show_positions` is a paid feature. Please contact sales@terminal49.com. + * @description Returns a vessel by the given IMO number, with its current position. Add `show_positions` to include its position history. Requires the Routing Data entitlement for API keys, including publishable keys. Without it, every vessel endpoint returns `403`. Only vessels on your account's actively tracked shipments are returned; any other vessel returns `404`. See [Entitlements and Paid Features](/api-docs/useful-info/entitlements#vessel-data-access). */ get: operations["get-vessels-imo"]; put?: never; @@ -712,7 +712,7 @@ export interface paths { }; /** * Get vessel future positions - * @description Returns the estimated route between two ports for a given vessel. The timestamp of the positions has fixed spacing of one minute. This is a paid feature. Please contact sales@terminal49.com. + * @description Returns the estimated route between two ports for a given vessel. The timestamp of the positions has fixed spacing of one minute. Requires the Routing Data entitlement for API keys, including publishable keys. Without it, every vessel endpoint returns `403`. Only vessels on your account's actively tracked shipments are returned; any other vessel returns `404`. See [Entitlements and Paid Features](/api-docs/useful-info/entitlements#vessel-data-access). */ get: operations["get-vessels-id-future-positions"]; put?: never; @@ -734,7 +734,7 @@ export interface paths { }; /** * Get vessel future positions from coordinates - * @description Returns the estimated route between two ports for a given vessel from a set of coordinates. The timestamp of the positions has fixed spacing of one minute. This is a paid feature. Please contact sales@terminal49.com. + * @description Returns the estimated route between two ports for a given vessel from a set of coordinates. The timestamp of the positions has fixed spacing of one minute. Requires the Routing Data entitlement for API keys, including publishable keys. Without it, every vessel endpoint returns `403`. Only vessels on your account's actively tracked shipments are returned; any other vessel returns `404`. See [Entitlements and Paid Features](/api-docs/useful-info/entitlements#vessel-data-access). */ get: operations["get-vessels-id-future-positions-with-coordinates"]; put?: never; @@ -7611,7 +7611,8 @@ export interface operations { }; }; }; - /** @description Forbidden - Feature not enabled */ + 401: components["responses"]["Unauthorized"]; + /** @description Forbidden - Routing data feature is not enabled for this account */ 403: { headers: { [name: string]: unknown; @@ -7660,7 +7661,8 @@ export interface operations { }; }; }; - /** @description Forbidden - Feature not enabled */ + 401: components["responses"]["Unauthorized"]; + /** @description Forbidden - Routing data feature is not enabled for this account */ 403: { headers: { [name: string]: unknown; @@ -7713,6 +7715,7 @@ export interface operations { }; }; }; + 401: components["responses"]["Unauthorized"]; /** @description Forbidden - Routing data feature is not enabled for this account */ 403: { headers: { @@ -7769,6 +7772,7 @@ export interface operations { }; }; }; + 401: components["responses"]["Unauthorized"]; /** @description Forbidden - Routing data feature is not enabled for this account */ 403: { headers: {