Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
504 changes: 494 additions & 10 deletions Terminal49-API.postman_collection.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -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}
---
---

<Note>
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.
</Note>
Original file line number Diff line number Diff line change
@@ -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}
---
---

<Note>
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.
</Note>
3 changes: 2 additions & 1 deletion docs/api-docs/in-depth-guides/terminal49-map.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
21 changes: 19 additions & 2 deletions docs/api-docs/useful-info/entitlements.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
24 changes: 18 additions & 6 deletions docs/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand Down Expand Up @@ -10335,7 +10338,7 @@
}
},
"operationId": "get-vessels-id",
"description": "Returns a vessel by id. <Note>`show_positions` is a paid feature. Please contact sales@terminal49.com.</Note>"
"description": "Returns a vessel by id, with its current position. Add `show_positions` to include its position history. <Note>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).</Note>"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Qualify the blanket 403 response claim

For callers on a free or paused plan, or those using an invalid key, this note promises that lacking Routing Data makes every vessel endpoint return 403, while the newly added access table specifies 401 for exactly those cases. Because this description is reused across all four vessel operations and their generated SDK/Postman documentation, it should say that 403 applies only when the caller has full API access but lacks Routing Data.

AGENTS.md reference: AGENTS.md:L60-L65

Useful? React with 👍 / 👎.

}
},
"/vessels/{imo}": {
Expand Down Expand Up @@ -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": {
Expand Down Expand Up @@ -10433,7 +10439,7 @@
}
},
"operationId": "get-vessels-imo",
"description": "Returns a vessel by the given IMO number. <Note>`show_positions` is a paid feature. Please contact sales@terminal49.com.</Note>",
"description": "Returns a vessel by the given IMO number, with its current position. Add `show_positions` to include its position history. <Note>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).</Note>",
"x-internal": true
}
},
Expand Down Expand Up @@ -10479,6 +10485,9 @@
}
}
},
"401": {
"$ref": "#/components/responses/Unauthorized"
},
"403": {
"description": "Forbidden - Routing data feature is not enabled for this account",
"content": {
Expand Down Expand Up @@ -10516,7 +10525,7 @@
}
},
"operationId": "get-vessels-id-future-positions",
"description": "Returns the estimated route between two ports for a given vessel. <Warning> The timestamp of the positions has fixed spacing of one minute.</Warning> <Note>This is a paid feature. Please contact sales@terminal49.com.</Note>",
"description": "Returns the estimated route between two ports for a given vessel. <Warning> The timestamp of the positions has fixed spacing of one minute.</Warning> <Note>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).</Note>",
"parameters": [
{
"schema": {
Expand Down Expand Up @@ -10583,6 +10592,9 @@
}
}
},
"401": {
"$ref": "#/components/responses/Unauthorized"
},
"403": {
"description": "Forbidden - Routing data feature is not enabled for this account",
"content": {
Expand Down Expand Up @@ -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. <Warning> The timestamp of the positions has fixed spacing of one minute.</Warning> <Note>This is a paid feature. Please contact sales@terminal49.com.</Note>",
"description": "Returns the estimated route between two ports for a given vessel from a set of coordinates. <Warning> The timestamp of the positions has fixed spacing of one minute.</Warning> <Note>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).</Note>",
"parameters": [
{
"schema": {
Expand Down
16 changes: 10 additions & 6 deletions sdks/typescript-sdk/src/generated/terminal49.ts
Original file line number Diff line number Diff line change
Expand Up @@ -663,7 +663,7 @@ export interface paths {
};
/**
* Get a vessel using the id
* @description Returns a vessel by id. <Note>`show_positions` is a paid feature. Please contact sales@terminal49.com.</Note>
* @description Returns a vessel by id, with its current position. Add `show_positions` to include its position history. <Note>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).</Note>
*/
get: operations["get-vessels-id"];
put?: never;
Expand All @@ -690,7 +690,7 @@ export interface paths {
};
/**
* Get a vessel using the imo
* @description Returns a vessel by the given IMO number. <Note>`show_positions` is a paid feature. Please contact sales@terminal49.com.</Note>
* @description Returns a vessel by the given IMO number, with its current position. Add `show_positions` to include its position history. <Note>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).</Note>
*/
get: operations["get-vessels-imo"];
put?: never;
Expand All @@ -712,7 +712,7 @@ export interface paths {
};
/**
* Get vessel future positions
* @description Returns the estimated route between two ports for a given vessel. <Warning> The timestamp of the positions has fixed spacing of one minute.</Warning> <Note>This is a paid feature. Please contact sales@terminal49.com.</Note>
* @description Returns the estimated route between two ports for a given vessel. <Warning> The timestamp of the positions has fixed spacing of one minute.</Warning> <Note>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).</Note>
*/
get: operations["get-vessels-id-future-positions"];
put?: never;
Expand All @@ -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. <Warning> The timestamp of the positions has fixed spacing of one minute.</Warning> <Note>This is a paid feature. Please contact sales@terminal49.com.</Note>
* @description Returns the estimated route between two ports for a given vessel from a set of coordinates. <Warning> The timestamp of the positions has fixed spacing of one minute.</Warning> <Note>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).</Note>
*/
get: operations["get-vessels-id-future-positions-with-coordinates"];
put?: never;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -7713,6 +7715,7 @@ export interface operations {
};
};
};
401: components["responses"]["Unauthorized"];
/** @description Forbidden - Routing data feature is not enabled for this account */
403: {
headers: {
Expand Down Expand Up @@ -7769,6 +7772,7 @@ export interface operations {
};
};
};
401: components["responses"]["Unauthorized"];
/** @description Forbidden - Routing data feature is not enabled for this account */
403: {
headers: {
Expand Down
Loading