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
33 changes: 33 additions & 0 deletions docs/api-docs/in-depth-guides/rail-integration-guide.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,39 @@ Finally, there is a webhook notification for when the destination ETA changes.

Integrate these notifications by subscribing to the webhooks and handling the incoming data to update your systems.

#### Set up a webhook for rail events

Rail events use the same webhook infrastructure as ocean events — there is no separate rail-only endpoint or configuration. Create one webhook and subscribe it to the rail events you care about.

You can create a webhook either from the [Developer Webhooks](https://app.terminal49.com/developers/webhooks) page in the dashboard or by calling [`POST /webhooks`](/api-docs/api-reference/webhooks/create-a-webhook) with the rail events in the `events` array:

```json
{
"data": {
"type": "webhook",
"attributes": {
"url": "https://your-endpoint.example.com/webhooks/terminal49",
"active": true,
"events": [
"container.transport.rail_loaded",
"container.transport.rail_departed",
"container.transport.rail_arrived",
"container.transport.arrived_at_inland_destination",
"container.transport.rail_unloaded",
"container.transport.estimated.arrived_at_inland_destination",
"container.pickup_lfd_rail.changed"
]
}
}
}
```

Notes:

- `container.pickup_lfd_rail.changed` requires the [Rail Plan entitlement](/api-docs/useful-info/entitlements). Other rail events are available on standard API access.
- `container.transport.rail_arrived` fires **every time** a container arrives at a rail terminal — including intermediate interchanges, not just the final inland destination. Use the included location data (terminal name, city, FIRMS code, LOCODE) to identify each stop.
- Store the `secret` returned in the create response and verify the `X-T49-Webhook-Signature` header on each delivery. See the [Webhooks in-depth guide](/api-docs/in-depth-guides/webhooks) and [Webhooks best practices](/api-docs/webhooks/best-practices).

### Rail container attributes

The following attributes are specific to rail container tracking and live on the [container object](/api-docs/api-reference/containers/get-a-container).
Expand Down
4 changes: 4 additions & 0 deletions docs/api-docs/in-depth-guides/terminal49-map.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ keywords:
The following examples pass `containerId` and `shipmentId` variables to the embedded map.
They relate to `id` attributes of the container and shipment objects that are returned by the API.

<Note>
The map embed works from a local development environment. Open your HTML file directly in a browser or serve it from `http://localhost` — there is no domain allowlisting on the embed itself. Your page just needs internet access to load `bundle.js` and `bundle.css` from `https://map.terminal49.com`, and a valid publishable API key.
</Note>
Comment on lines +23 to +25

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 File-Origin Support Is Unqualified

Loading the hosted script and stylesheet does not prove that the embed works from file://: requests made by the bundle use the browser's null origin and fail unless the map API explicitly permits it. If that API only allows normal HTTP origins, the assets load but the map remains blank, so this claim should be limited to verified origins or state the required CORS support.

Prompt To Fix With AI
This is a comment left during a code review.
Path: docs/api-docs/in-depth-guides/terminal49-map.mdx
Line: 23-25

Comment:
**File-Origin Support Is Unqualified**

Loading the hosted script and stylesheet does not prove that the embed works from `file://`: requests made by the bundle use the browser's `null` origin and fail unless the map API explicitly permits it. If that API only allows normal HTTP origins, the assets load but the map remains blank, so this claim should be limited to verified origins or state the required CORS support.

How can I resolve this? If you propose a fix, please make it concise.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Fix in Codex


## Embed the map on your website

Once you have the API key, you can embed the map on your website.
Expand Down
10 changes: 10 additions & 0 deletions docs/api-docs/webhooks/best-practices.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,16 @@ If your endpoint goes down, Terminal49 retries failed deliveries. When your endp
2. Re-fetch the current state of the affected shipments and containers from the REST API. Webhook notifications cannot be replayed — the [Trigger Webhook](/api-docs/api-reference/webhooks/trigger-a-webhook) endpoint only sends a one-time sample payload for testing.
3. For longer outages, list recent shipments via the API to catch up on any missed state changes.

### Recover events you were never subscribed to

If you add a new event to a webhook subscription after it has already fired for a shipment or container (for example, subscribing to `shipment.estimated.arrival` after the ETA has already changed several times), Terminal49 will **not** send those historical notifications retroactively.

To recover state you missed:

- Re-fetch the affected shipments and containers via the [Shipments](/api-docs/api-reference/shipments/list-shipments) and [Containers](/api-docs/api-reference/containers/list-containers) endpoints. This returns the **current** value of fields such as `pod_eta_at`, `pod_ata_at`, and the `import_deadlines` object.
- You will only see the latest value, not the history of intermediate changes that occurred before you subscribed. If auditing every change matters to your workflow, subscribe to the event before you start ingesting the shipment.
- The [Trigger Webhook](/api-docs/api-reference/webhooks/trigger-a-webhook) endpoint sends a **sample** payload only. It is intended for testing your handler and does not replay real historical events for your shipments.

## Keep your webhook active

Terminal49 may deactivate a webhook after repeated delivery failures. Check your webhook's `active` status periodically:
Expand Down
2 changes: 1 addition & 1 deletion docs/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -602,7 +602,7 @@
},
"in": "query",
"name": "number",
"description": "Search shipments by the original request tracking `request_number`"
"description": "Search shipments by the original tracking `request_number` — typically a master bill of lading or booking number. This filter does **not** match container numbers; to look up a shipment by container number, use `GET /containers?filter[number]={container_number}` and include the related shipment via `include=shipment`."

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Container Lookup Uses Unsupported Filter

A client following this description will call GET /containers?filter[number]=..., but the containers operation does not define that parameter and the typed SDK cannot emit it. The server may reject the request or ignore the filter and return a paginated list instead of the requested container; the documented cross-resource lookup for container numbers is /search?query=....

Prompt To Fix With AI
This is a comment left during a code review.
Path: docs/openapi.json
Line: 605

Comment:
**Container Lookup Uses Unsupported Filter**

A client following this description will call `GET /containers?filter[number]=...`, but the containers operation does not define that parameter and the typed SDK cannot emit it. The server may reject the request or ignore the filter and return a paginated list instead of the requested container; the documented cross-resource lookup for container numbers is `/search?query=...`.

How can I resolve this? If you propose a fix, please make it concise.

Fix in Codex

},
{
"schema": {
Expand Down
Loading