1. Getting Started
FreightLens.io Public API
  • FreightLens Track & Trace API
    • Authentication
      • Get an access token
    • Shipments
      • Look up a shipment by reference
    • Schemas
      • Transmission
      • TransmissionHeader
      • ShipmentTracking
      • Location
      • Vessel
      • TransportCall
      • DocumentReference
      • ShipmentEvent
      • TransportEvent
      • EquipmentEvent
      • Container
      • Exception
      • Impact
      • SubscriptionRequest
      • Subscription
      • TokenResponse
      • Error
  • Getting Started
    • Getting Started with the FreightLens.io Track & Trace API
  • Authentication
    • Authentication
  • DCSA-aligned data elements
    • Data Elements & Enumerations (DCSA-aligned)
  1. Getting Started

Getting Started with the FreightLens.io Track & Trace API

The FreightLens.io Track & Trace API gives you a single, carrier-neutral stream of container shipment milestones across the world's major ocean carriers. Whatever a carrier speaks natively — DCSA, EDI, or a proprietary format — FreightLens.io normalizes every milestone into one DCSA-aligned event model and delivers it to you as a consistent JSON transmission. You integrate once and get uniform tracking across carriers, instead of building and maintaining a separate connection to each one yourself.
Coverage includes Hapag-Lloyd, Maersk, CMA CGM, COSCO, and ZIM, with additional carriers added on an ongoing basis.
This guide walks a new integrator from zero to their first shipment lookup:
how to authenticate, how to look up a shipment, the shape of a transmission, and
the three payload states you will handle most often — a standard event update,
a shipment with an exception detected, and one with an exception resolved.
Environments. Everything below works identically in test and production.
Point non-production traffic at the sandbox so you can integrate before your
shipments go live.
EnvironmentBase URL
Sandbox (test)https://api-test.freightlens.io
Productionhttps://api.freightlens.io

1. How tracking works#

The FreightLens.io Track & Trace API is read-only. You look up a shipment by
reference and receive its complete current state — identifiers, route, schedule,
every normalized event, and any active exceptions — as a single JSON
transmission. Shipments are enrolled for tracking inside FreightLens.io; your
integration simply reads them.
A typical lifecycle:
1.
Authenticate and obtain an access token (Section 2).
2.
Look up a shipment with GET /v2/shipments, by carrier booking number
(carrierCode + carrierBookingReference), Bill of Lading
(billOfLadingNumber), or container (equipmentReference).
3.
Read the returned transmission — the full milestone history and any
exceptions[] are inline in the payload.
4.
Poll the shipment on the cadence you need to pick up new milestones and
exception state changes.
Real-time webhook push (FreightLens posting transmissions to your endpoint as
events occur) is on the roadmap, not part of this read-only v1.

2. Authentication#

The FreightLens.io API uses OAuth 2.0 client credentials. FreightLens.io issues you
a client_id and client_secret for each environment. You exchange them for a
short-lived bearer token, then send that token on every request.

Step 1 — Request a token#

Step 2 — Read the response#

{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "track-and-trace.read"
}

Step 3 — Call the API with the token#

Token lifetime. Tokens are short-lived; the exact lifetime is returned in
expires_in (seconds). Cache the token and reuse it until shortly before it
expires, then request a new one — do not fetch a fresh token on every call.
Never expose your client_secret in browser or mobile code; keep it server-side.

3. The transmission envelope#

Every payload FreightLens sends — standard update, exception detected, exception
resolved — shares the same two-part envelope:
transmissionHeader — metadata about this delivery: a unique ID, when it
was sent, why it was sent (triggerType), which event triggered it
(triggeredByEvent), sender/receiver, and the schema version.
shipmentTracking — the shipment itself: identifiers, route, schedule, and
the normalized events.

Header fields#

FieldDescription
transmissionIDUnique ID for this transmission. Use it for idempotency and de-duplication.
transmissionDateTimeUTC timestamp (ISO 8601) when FreightLens sent the transmission.
triggerTypeWhy this transmission was sent — see the enum below.
triggeredByEventThe eventID that caused this transmission (null for manual/full snapshots).
senderIDAlways FREIGHTLENS.
receiverIDYour client identifier.
schemaVersionPayload schema version. Current: 1.2.

triggerType values#

Read-only lookups return MANUAL_TRIGGER (a full current snapshot). The remaining
values describe why a transmission was generated and apply to roadmap webhook
delivery; you will not see them on a GET response in v1.
ValueMeaning
MANUAL_TRIGGERA full snapshot — what GET /v2/shipments returns.
SCHEDULED_TRIGGERA periodic refresh of the shipment state (webhook, roadmap).
EVENT_TRIGGERA new milestone arrived (webhook, roadmap).
EXCEPTION_DETECTEDA new exception was raised (webhook, roadmap).
EXCEPTION_RESOLVEDA previously raised exception cleared (webhook, roadmap).

Shipment identifiers#

shipmentTracking always carries the identifiers you use to match the shipment to
your own records:
FieldDescription
bookingReferenceFreightLens / forwarder booking reference.
carrierBookingReferenceThe carrier's booking number.
billOfLadingNumberBill of Lading (B/L) number.
carrierCodeCarrier SCAC (e.g. HLCU = Hapag-Lloyd).
carrierNameHuman-readable carrier name.
serviceTypeScope of carriage (e.g. PORT_TO_DOOR, DOOR_TO_DOOR).
etd / etaCurrent estimated departure / arrival (UTC, ISO 8601).
Locations (portOfLoading, portOfDischarge, placeOfReceipt, placeOfDelivery)
carry a locationName and a UN/LOCODE (unLocationCode), plus an optional
terminal facilityCode and its code-list provider (BIC, SMDG).

4. The event model (DCSA-aligned)#

FreightLens.io groups milestones into three DCSA-aligned event categories:
shipmentEvents — document and booking milestones. Carry a
shipmentEventTypeCode (e.g. CONF = booking confirmed, ISSU = B/L issued).
transportEvents — vessel movements at a port call. Carry a
transportEventTypeCode (DEPA = departure, ARRI = arrival) and a
transportCall describing the vessel, location, and voyage.
Equipment events (inside each containers[] entry, as latestEvent and
eventHistory[]) — container movements. Carry an equipmentEventTypeCode
(GTOT = gate out, GTIN = gate in, LOAD = loaded, DISC = discharged) and
an emptyIndicatorCode (LADEN / EMPTY).
Every event carries an eventClassifierCode that tells you how firm the
timestamp is:
CodeMeaning
ACTActual — the event has happened.
ESTEstimated — a forward-looking prediction.
PLNPlanned — from the carrier's schedule.
Key point for consumers: when an event's eventClassifierCode changes from
EST/PLN to ACT, the milestone has actually occurred. When an EST
timestamp moves, the schedule has shifted — which is what raises the schedule
exceptions in Section 6.

5. Standard event payload#

A standard transmission is the complete current state of a shipment: identifiers,
route, schedule, and the full set of normalized events. Below is an abbreviated
example (event history trimmed for readability). The complete file is
01_standard_event_v1.json.
{
  "transmissionHeader": {
    "transmissionID": "TXN-1783526651038",
    "transmissionDateTime": "2026-07-29T00:00:00Z",
    "triggerType": "MANUAL_TRIGGER",
    "triggeredByEvent": null,
    "senderID": "FREIGHTLENS",
    "receiverID": "CLIENT",
    "schemaVersion": "1.2"
  },
  "shipmentTracking": {
    "bookingReference": "29402735",
    "carrierBookingReference": "95954888",
    "billOfLadingNumber": "HLCUBSC2606CBSF8",
    "carrierCode": "HLCU",
    "carrierName": "Hapag-Lloyd",
    "vesselName": "ULSAN EXPRESS",
    "voyageNumber": "631W",
    "portOfLoading":   { "locationName": "NEW YORK, NY", "unLocationCode": "USNYC" },
    "portOfDischarge": { "locationName": "VUNG TAU",     "unLocationCode": "VNVUT" },
    "placeOfDelivery": { "locationName": "CAN THO",      "unLocationCode": "VNVCA" },
    "serviceType": "PORT_TO_DOOR",
    "etd": "2026-07-28T12:15:00Z",
    "eta": "2026-10-01T01:00:00Z",
    "shipmentEvents": [
      {
        "eventID": "9714eff8-9043-44f0-a6dc-14327f12e532",
        "eventType": "SHIPMENT",
        "eventDateTime": "2026-07-15T16:36:27Z",
        "eventClassifierCode": "ACT",
        "shipmentEventTypeCode": "CONF"
      }
    ],
    "transportEvents": [
      {
        "eventID": "a77e8aff-613a-4534-8233-025bd983412d",
        "eventType": "TRANSPORT",
        "eventDateTime": "2026-07-28T12:15:00Z",
        "eventClassifierCode": "ACT",
        "transportEventTypeCode": "DEPA",
        "transportCall": {
          "vessel": { "vesselName": "ULSAN EXPRESS", "vesselIMONumber": "9613020" },
          "location": { "locationName": "NEW YORK, NY", "unLocationCode": "USNYC" },
          "modeOfTransport": "VESSEL",
          "exportVoyageNumber": "631W",
          "transportCallSequenceNumber": 1
        }
      }
    ],
    "containers": [
      {
        "containerNumber": "HAMU4486106",
        "isoType": "45GP",
        "latestEvent": {
          "eventID": "9d68e872-5eed-4430-8f89-960d266164d0",
          "eventType": "EQUIPMENT",
          "eventDateTime": "2026-10-03T17:00:00Z",
          "equipmentEventTypeCode": "GTOT",
          "emptyIndicatorCode": "LADEN",
          "eventClassifierCode": "PLN",
          "equipmentReference": "HAMU4486106"
        }
      }
    ]
  }
}
How to read it: the booking is confirmed (CONF, ACT), the vessel has
departed New York (DEPA, ACT), and the container's next planned move is a gate
-out at destination (GTOT, PLN). The eta of 2026-10-01T01:00:00Z is the
figure the exception examples below will move.

6. Exception detected payload#

When FreightLens detects a problem — a schedule slip, a rollover, a demurrage or
detention risk — the shipment's exceptions[] array carries it with
status: DETECTED. You see it inline the next time you GET the shipment. (The
example below shows the exception block in isolation for clarity; in a real
response it rides inside the full shipment payload.) FreightLens sorts exceptions
into two categories that mirror the alerting in the app:
SCHEDULE — timing problems such as ETA delays and missed connections
(shown amber in FreightLens).
OPERATIONAL — action-required problems such as rollovers, demurrage, or
detention risk (shown red in FreightLens).
Each exception carries a severity (WARNING / CRITICAL), a status
(DETECTED / RESOLVED), the affectedContainers, an impact block showing
what changed, and a recommendedAction.
In this example the carrier pushed the arrival at Vung Tau out by seven days, so
the shipment eta is updated and a SCHEDULE / ETA_DELAY exception is raised.
Full file: 02_exception_detected_v1.json.
{
  "transmissionHeader": {
    "transmissionID": "TXN-1783794512661",
    "transmissionDateTime": "2026-09-14T08:42:00Z",
    "triggerType": "EXCEPTION_DETECTED",
    "triggeredByEvent": "5d06372d-1f66-48f9-882c-45802b9a9225",
    "senderID": "FREIGHTLENS",
    "receiverID": "CLIENT",
    "schemaVersion": "1.2"
  },
  "shipmentTracking": {
    "bookingReference": "29402735",
    "carrierBookingReference": "95954888",
    "billOfLadingNumber": "HLCUBSC2606CBSF8",
    "carrierCode": "HLCU",
    "carrierName": "Hapag-Lloyd",
    "eta": "2026-10-08T09:00:00Z",
    "exceptions": [
      {
        "exceptionID": "3f2a91c4-6b0e-4a77-9d21-8c4e0f5a71bd",
        "exceptionType": "ETA_DELAY",
        "exceptionCategory": "SCHEDULE",
        "severity": "WARNING",
        "status": "DETECTED",
        "detectedDateTime": "2026-09-14T08:42:00Z",
        "title": "Arrival at Vung Tau delayed by 7 days",
        "description": "Carrier schedule update for ULSAN EXPRESS voyage 631W pushed the estimated arrival at Vung Tau (VNVUT) from 2026-10-01T01:00:00Z to 2026-10-08T09:00:00Z.",
        "relatedEventID": "5d06372d-1f66-48f9-882c-45802b9a9225",
        "affectedContainers": ["HAMU4486106"],
        "impact": {
          "field": "eta",
          "previousValue": "2026-10-01T01:00:00Z",
          "revisedValue": "2026-10-08T09:00:00Z",
          "delayHours": 176
        },
        "recommendedAction": "Notify the consignee of the revised arrival window and review any downstream delivery or free-time commitments at Can Tho (VNVCA)."
      }
    ]
  }
}
Exception fields
FieldDescription
exceptionIDStable ID for the exception. The matching EXCEPTION_RESOLVED reuses this same ID.
exceptionTypeSpecific issue — e.g. ETA_DELAY, ROLLOVER, DEMURRAGE_RISK, DETENTION_RISK, MISSED_CONNECTION.
exceptionCategorySCHEDULE (amber) or OPERATIONAL (red).
severityWARNING or CRITICAL.
statusDETECTED or RESOLVED.
detectedDateTimeWhen FreightLens first raised the exception.
relatedEventIDThe event that triggered the exception.
affectedContainersContainer numbers impacted.
impactWhat changed: field, previousValue, revisedValue, and (for delays) delayHours.
recommendedActionSuggested next step.
Idempotency tip: key your handling on exceptionID. If the delay worsens,
the next GET returns an updated DETECTED exception with the same
exceptionID — update your record rather than creating a duplicate.

7. Exception resolved payload#

When the problem clears, the exception in the shipment payload flips to
status: RESOLVED, carrying the same exceptionID plus a resolvedDateTime,
a resolutionType, and a resolutionNote. Here the carrier recovered most of the
delay, so the eta moves back in and the exception closes. Full file:
03_exception_resolved_v1.json.
{
  "transmissionHeader": {
    "transmissionID": "TXN-1783969347902",
    "transmissionDateTime": "2026-09-22T15:10:00Z",
    "triggerType": "EXCEPTION_RESOLVED",
    "triggeredByEvent": "5d06372d-1f66-48f9-882c-45802b9a9225",
    "senderID": "FREIGHTLENS",
    "receiverID": "CLIENT",
    "schemaVersion": "1.2"
  },
  "shipmentTracking": {
    "bookingReference": "29402735",
    "carrierBookingReference": "95954888",
    "billOfLadingNumber": "HLCUBSC2606CBSF8",
    "carrierCode": "HLCU",
    "carrierName": "Hapag-Lloyd",
    "eta": "2026-10-02T14:00:00Z",
    "exceptions": [
      {
        "exceptionID": "3f2a91c4-6b0e-4a77-9d21-8c4e0f5a71bd",
        "exceptionType": "ETA_DELAY",
        "exceptionCategory": "SCHEDULE",
        "severity": "WARNING",
        "status": "RESOLVED",
        "detectedDateTime": "2026-09-14T08:42:00Z",
        "resolvedDateTime": "2026-09-22T15:10:00Z",
        "resolutionType": "SCHEDULE_RECOVERED",
        "resolutionNote": "Carrier re-optimized the rotation for ULSAN EXPRESS voyage 631W. Estimated arrival at Vung Tau (VNVUT) recovered from 2026-10-08T09:00:00Z to 2026-10-02T14:00:00Z, reducing the delay against the original plan to 37 hours.",
        "relatedEventID": "5d06372d-1f66-48f9-882c-45802b9a9225",
        "affectedContainers": ["HAMU4486106"],
        "impact": {
          "field": "eta",
          "previousValue": "2026-10-08T09:00:00Z",
          "revisedValue": "2026-10-02T14:00:00Z",
          "delayHours": 37
        }
      }
    ]
  }
}
Resolution fields (added on resolve)
FieldDescription
resolvedDateTimeWhen the exception cleared.
resolutionTypeHow it cleared — e.g. SCHEDULE_RECOVERED, REBOOKED, MANUAL_CLEAR, EVENT_ACTUALIZED.
resolutionNoteHuman-readable explanation.
The impact on a resolved exception shows the movement from the exception
state to the recovered state, so you can display "delay reduced from 176h to
37h" without recomputing it.

8. Polling for updates#

Because the API is read-only, you pick up new milestones and exception changes by
calling GET /v2/shipments again on a cadence that suits the shipment's stage. A
practical pattern:
In transit / near an ETA: poll more frequently (e.g. every few hours) to
catch schedule changes and exceptions early.
Booked but not yet sailed, or already delivered: poll less often (e.g. daily).
Key handling on exceptionID so a re-reported exception updates the same
record rather than duplicating it, and watch eventClassifierCode flipping to
ACT to know a milestone actually happened.
Real-time webhook push — FreightLens POSTing each change to a callback URL of
yours, signed with an X-FreightLens-Signature (HMAC-SHA256) header — is on the
roadmap. Until then, polling is the supported model.

9. Quick reference#

TaskCall
Get an access tokenPOST /oauth/token
Look up a shipment by carrier bookingGET /v2/shipments?carrierCode=…&carrierBookingReference=…
Look up a shipment by B/LGET /v2/shipments?billOfLadingNumber=…
Look up a shipment by containerGET /v2/shipments?equipmentReference=…

Schema version 1.2. Endpoint paths and auth scopes shown here define the
published contract; confirm them against your final backend configuration before
go-live. Sandbox: https://api-test.freightlens.io · Production:
https://api.freightlens.io.
Modified at 2026-09-03 21:22:53
Previous
Error
Next
Authentication
Built with