> ## Documentation Index
> Fetch the complete documentation index at: https://terminal49.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Integrate Rail Container Tracking Data

> Integrate North American rail container tracking data with Terminal49 for unified shipment visibility across Class I rail and intermodal carriers.

This is a technical article about rail data within Terminal49's API and DataSync.

For a broader overview, including the reasons why you'd want rail visibility and how to use it in the Terminal49 dashboard,
[read the Terminal49 announcement post](https://www.terminal49.com/blog/launching-north-american-intermodal-rail-visibility-on-terminal49/).

## Table of contents

* [Supported rail carriers](#supported-rail-carriers)
* [Supported rail events and data attributes](#supported-rail-events-and-data-attributes)
  * [Rail-specific transport events](#rail-specific-transport-events)
  * [Webhook notifications](#webhook-notifications)
  * [Rail container attributes](#rail-container-attributes)
* [Integration methods](#integration-methods)
  * [Integration via API](#a-integration-via-api)
  * [Integration via DataSync](#b-integration-via-datasync)

## Supported rail carriers

Terminal49's container tracking platform integrates with all North American Class I railroads that handle container shipping, providing comprehensive visibility into your rail container movements.

* BNSF Railway
* Canadian National Railway (CN)
* Canadian Pacific Railway (CP)
* CSX Transportation
* Norfolk Southern Railway (NS)
* Union Pacific Railroad (UP)

By integrating with these carriers, Terminal49 ensures that you have direct access to critical tracking data, enabling better decision-making and operational efficiency.

## Supported rail events and data attributes

Terminal49 seamlessly tracks your containers as they go from container ship, to ocean terminal, to rail carrier.

Terminal49 provides a [set of transport events](#webhook-notifications) that let you track the status of your containers as they move through the rail system. You can receive webhook notifications whenever these events occur.

Terminal49 also provides a set of attributes [on the container model](/api-docs/api-reference/containers/get-a-container) with the current status of your container at any given time, including ETA, pickup facility, and availability information. For details on hold types, fee types, and how to determine release readiness at the port or an inland destination, see [Container Holds, Fees, and Release Readiness](/api-docs/in-depth-guides/holds-and-fees).

### Rail-specific transport events

Several core transport events occur on most rail journeys. Some rail carriers do not share all events, but in general these are the key events for a container.

```mermaid theme={null}
graph LR
A[Rail Loaded] --> B[Rail Departed]
B --> C[Arrived at Inland Destination]
C --> D[Rail Unloaded]
D --> G[Available for Pickup]
G --> E[Full Out]
E --> F[Empty Return]
```

`Available for Pickup`, `Full Out` and `Empty Return` are not specific to rail, but are included here since they are a key part of the rail journey.

{/* ```mermaid
graph LR
  C[Previous events] --> D[Rail Unloaded]
  D --> G[Available for Pickup]
  D --> H[Not Available]
  G --> H
  H --> G
  H -- Holds and Fees Updated --> H
  G --> E[Full Out]
``` */}

### Webhook notifications

Terminal49 provides webhook notifications to keep you updated on key transport events in a container's rail journey. These notifications let you integrate near real-time tracking data directly into your applications.

Here's a list of the rail-specific events which support webhook notifications:

| Transport Event               | Webhook Notification                                | Description                                                                                                        | Example                                                                                                    |
| ----------------------------- | --------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------- |
| Rail Loaded                   | `container.transport.rail_loaded`                   | The container is loaded onto a railcar.                                                                            | [Example](/api-docs/useful-info/webhook-events-examples#container-transport-rail_loaded)                   |
| Rail Departed                 | `container.transport.rail_departed`                 | The container departs on the railcar (not always from port of discharge).                                          | [Example](/api-docs/useful-info/webhook-events-examples#container-transport-rail_departed)                 |
| Rail Arrived                  | `container.transport.rail_arrived`                  | The container arrives at a rail terminal (not always at the destination terminal).                                 | [Example](/api-docs/useful-info/webhook-events-examples#container-transport-rail_arrived)                  |
| Arrived At Inland Destination | `container.transport.arrived_at_inland_destination` | The container arrives at the destination terminal.                                                                 | [Example](/api-docs/useful-info/webhook-events-examples#container-transport-arrived_at_inland_destination) |
| Rail Unloaded                 | `container.transport.rail_unloaded`                 | The container is unloaded from a railcar.                                                                          | [Example](/api-docs/useful-info/webhook-events-examples#container-transport-rail_unloaded)                 |
| Rail LFD Changed              | `container.pickup_lfd_rail.changed`                 | The Rail Last Free Day (LFD) for the container has changed ([Rail Plan only](/api-docs/useful-info/entitlements)). | [Example](/api-docs/useful-info/webhook-events-examples#container-pickup_lfd_rail-changed)                 |

An additional set of events triggers when the container's status changes at the destination rail terminal. For containers without rail, these events fire at the ocean terminal instead.

| Transport Event | Webhook Notification           | Description                                      | Example                                                                               |
| --------------- | ------------------------------ | ------------------------------------------------ | ------------------------------------------------------------------------------------- |
| Full Out        | `container.transport.full_out` | The full container leaves the rail terminal.     | [Example](/api-docs/useful-info/webhook-events-examples#container-transport-full_out) |
| Empty In        | `container.transport.empty_in` | The empty container is returned to the terminal. | [Example](/api-docs/useful-info/webhook-events-examples#container-transport-empty_in) |

Finally, there is a webhook notification for when the destination ETA changes.

| Transport Event               | Webhook Notification                                          | Description                                                                   | Example                                                                                                              |
| ----------------------------- | ------------------------------------------------------------- | ----------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| Estimated Destination Arrival | `container.transport.estimated.arrived_at_inland_destination` | Estimated time of arrival for the container at the destination rail terminal. | [Example](/api-docs/useful-info/webhook-events-examples#container-transport-estimated-arrived_at_inland_destination) |

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

### 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).

* **pod\_rail\_loaded\_at**: Time when the container is loaded onto a railcar at the POD.
* **pod\_rail\_departed\_at**: Time when the container departs from the POD.
* **ind\_eta\_at**: Estimated Time of Arrival at the inland destination, sourced from the rail carrier.
* **ind\_ata\_at**: Actual Time of Arrival at the inland destination, sourced from the rail carrier.
* **ind\_rail\_unloaded\_at**: Time when the container is unloaded from rail at the inland destination.
* **ind\_facility\_lfd\_on**: **Deprecated.** Last Free Day for demurrage charges at the inland destination terminal. Use `import_deadlines.pickup_lfd_rail` instead (timezone: `final_destination_timezone`).
* **pod\_rail\_carrier\_scac**: SCAC code of the rail carrier that picks up the container from the POD (this could be different than the rail carrier that delivers to the inland destination).
* **ind\_rail\_carrier\_scac**: SCAC code of the rail carrier that delivers the container to the inland destination.

#### Inland destination ETA/ATA: rail carrier vs. shipping line

For an inland (rail) move, two pairs of arrival fields exist and can differ:

| Field                                       | Lives on  | Source              | Notes                                                                                                                                                            |
| ------------------------------------------- | --------- | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ind_eta_at` / `ind_ata_at`                 | container | Rail carrier        | Estimated and actual arrival at the inland destination, reported directly by the rail carrier.                                                                   |
| `destination_eta_at` / `destination_ata_at` | shipment  | Shipping line (SSL) | Estimated and actual arrival at the shipment's destination as reported by the ocean carrier. For inland moves, this is the SSL's view of the inland destination. |

Use `ind_*` when you want the rail carrier's view (typically more granular and updated more frequently for inland legs). Use `destination_*` when you want the SSL-reported view on the shipment. The corresponding timezone for `ind_*` fields is `final_destination_timezone` (on the container); for `destination_*` fields it is `destination_timezone` (on the shipment).

#### Rail Last Free Day (LFD)

The container's top-level `pickup_lfd` attribute is a coalesced value derived from the `import_deadlines` object, in this order of preference:

1. `import_deadlines.pickup_lfd_line` — LFD as reported by the shipping line (preferred).
2. `import_deadlines.pickup_lfd_terminal` — LFD from the POD terminal (timezone: `pod_timezone`).
3. `import_deadlines.pickup_lfd_rail` — LFD from the rail carrier at the inland destination (timezone: `final_destination_timezone`).

For rail moves, subscribe to the `container.pickup_lfd_rail.changed` webhook to be notified when the rail carrier updates the inland LFD. The legacy `ind_facility_lfd_on` field is deprecated — read `import_deadlines.pickup_lfd_rail` instead.

## Integration methods

There are two methods to integrate Terminal49's rail tracking data programmatically: via API and DataSync.

### A. Integration via API

Terminal49 provides a robust API that allows you to programmatically access rail container tracking data and receive updates via webhooks. You will receive rail events and attributes alongside events and attributes from the ocean terminal and carrier.

[Here's a step-by-step guide to get started](/api-docs/getting-started/start-here).

### B. Integration via DataSync

Terminal49's DataSync service automatically syncs up-to-date tracking data with your system. The rail data lives in the same tables alongside the ocean terminal and carrier data.

[Learn more about DataSync](/datasync/overview)
