Skip to main content
Last Free Day (LFD) is the deadline to pick up a container before demurrage charges start. Terminals and shipping lines can change the LFD at any time. Terminal49 sends webhook events whenever the LFD changes or a container becomes available for pickup so you can act before costs accrue.

Events to subscribe to

EventWhen it fires
container.pickup_lfd.changedThe terminal’s Last Free Day changed
container.pickup_lfd_line.changedThe shipping line’s Last Free Day changed
container.transport.availableThe container is available for pickup at the destination
container.updatedContainer attributes changed (may include holds or availability updates)

Handle LFD change events

When a container.pickup_lfd.changed event fires, the included array contains the full container object with the updated pickup_lfd field:
app.post("/webhooks/terminal49", (req, res) => {
  const { data, included } = req.body;
  const event = data.attributes.event;

  if (event === "container.pickup_lfd.changed") {
    const container = included.find((obj) => obj.type === "container");
    const shipment = included.find((obj) => obj.type === "shipment");

    const containerNumber = container.attributes.number;
    const newLfd = container.attributes.pickup_lfd;
    const bolNumber = shipment.attributes.bill_of_lading_number;

    const daysUntilLfd = Math.ceil(
      (new Date(newLfd) - new Date()) / (1000 * 60 * 60 * 24)
    );

    if (daysUntilLfd <= 2) {
      await alertDispatch({
        priority: "urgent",
        message: `Container ${containerNumber} (${bolNumber}) β€” LFD is ${newLfd}, ${daysUntilLfd} days away`,
      });
    }
  }

  res.sendStatus(200);
});

Determine pickup readiness

A container is ready for pickup when available_for_pickup is true and there are no active holds. Combine the container.transport.available event with hold checking:
function isReadyForPickup(container) {
  const { available_for_pickup, holds_at_pod_terminal } = container.attributes;
  const hasActiveHolds = holds_at_pod_terminal?.some(
    (h) => h.status === "hold"
  );
  return available_for_pickup === true && !hasActiveHolds;
}
For a deeper explanation of holds, fees, and the available_for_pickup field, see Container Holds, Fees, and Release Readiness.
Subscribe to both container.transport.available and container.updated events. The available event fires when the terminal first marks the container as released, but subsequent hold changes arrive as container.updated events.

Common patterns

  • Demurrage prevention β€” alert when LFD is within 48 hours and the container has not been dispatched
  • Automated dispatch β€” trigger a drayage order as soon as the container clears holds
  • LFD comparison β€” track both terminal and shipping line LFDs; the earlier date is the one that matters
  • Hold monitoring β€” watch for container.updated events where holds_at_pod_terminal changes