FreightTrackingAPI

API Reference

The FreightTrackingAPI REST API. All responses are JSON. GET /track/{bookingNumber} requires an API key; GET / and GET /health do not.

Authentication

Tracking requests require an API key in the x-api-key header. Create and manage keys in your dashboard. Publishable keys may only call GET /track/… and are restricted to domains you configure.

curl https://api.freighttrackingapi.com.au/track/2751234567 \
  -H "x-api-key: YOUR_API_KEY"

Base URL

https://api.freighttrackingapi.com.au

Endpoints

MethodPathAuthDescription
GET/track/{bookingNumber}x-api-keyTrack by carrier booking or reference number
GET/NoneAPI metadata: name, env, version (JSON)
GET/healthNoneLiveness: JSON { healthy: true } when the service is ready

Example GET /: { "name": "Freight Tracker API", "env": "production", "version": "…" }

GET /track/{bookingNumber}

Resolves the carrier from the booking number format and returns voyage steps. Responses are cached for 24 hours. When a step has modeOfTransport is "VESSEL" and a non-empty vesselName, the response always includes vesselPosition: an object if a position was resolved from AIS-style data (automated lookup by vessel name), or null if lookup failed or no match. Other legs do not include vesselPosition.

Path parameters

ParameterTypeDescription
bookingNumberstringThe booking or reference number issued by the carrier (OOCL example: 2751234567)

Supported carriers

COSCO, Evergreen, Hapag-Lloyd, Maersk, OOCL, ZIM, ANL. The carrier is inferred from the booking number format — you do not pass a carrier code. The JSON carrier field uses uppercase underscore codes, e.g. HAPAG_LLOYD, EVERGREEN.

Example request

curl https://api.freighttrackingapi.com.au/track/2751234567 \
  -H "x-api-key: YOUR_API_KEY"

Example response

{
  "bookingNumber": "2751234567",
  "mode": "ocean",
  "carrier": "OOCL",
  "cached": false,
  "fetchedAt": "2024-11-01T08:00:00.000Z",
  "expiresAt": "2024-11-02T08:00:00.000Z",
  "steps": [
    {
      "stepIndex": 0,
      "modeOfTransport": "VESSEL",
      "vesselName": "OOCL EXAMPLE VESSEL",
      "voyageNumber": "042E",
      "portOfLoadingCode": "CNSHA",
      "portOfLoadingName": "Shanghai",
      "portOfDischargeCode": "USNYC",
      "portOfDischargeName": "New York",
      "etd": "2024-10-20T14:00:00.000Z",
      "eta": "2024-11-10T08:00:00.000Z",
      "vesselPosition": {
        "mmsi": 211331640,
        "imo": 9811000,
        "lat": 1.29,
        "lng": 104.05,
        "speed": "14.2",
        "status": "Underway",
        "lastUpdated": "2024-11-01T07:45:00.000Z"
      }
    }
  ]
}

Response fields

FieldTypeDescription
bookingNumberstringThe booking number as provided
mode"ocean" | "air"Transport mode (currently always ocean)
carrierstringResolved carrier code: COSCO, EVERGREEN, HAPAG_LLOYD, MAERSK, OOCL, ZIM, or ANL (uppercase, as returned in JSON)
cachedbooleantrue if this response was served from cache
fetchedAtISO 8601When this payload was last obtained from the carrier; unchanged on cache hits (still the original fetch time)
expiresAtISO 8601When the cache entry expires (24h TTL)
stepsarrayOrdered voyage legs — see Step object below

Step object

FieldTypeDescription
stepIndexnumberZero-based leg index
modeOfTransport"VESSEL" | "TRUCK" | "RAIL" | "UNKNOWN"Transport mode for this leg
vesselNamestring | nullVessel name when the carrier provides it; may be null or omitted per leg
voyageNumberstring | nullVoyage or service code when provided; may be null or omitted
portOfLoadingCodestring | nullPort of loading code when provided (often UN/LOCODE); may be null or omitted
portOfLoadingNamestring | nullHuman-readable port of loading; may be null or omitted
portOfDischargeCodestring | nullPort of discharge code when provided (often UN/LOCODE); may be null or omitted
portOfDischargeNamestring | nullHuman-readable port of discharge; may be null or omitted
etdISO 8601 | nullEstimated departure; null or omitted if unknown
etaISO 8601 | nullEstimated arrival; null or omitted if unknown
vesselPositionobject | nullOnly on steps with modeOfTransport VESSEL and a non-empty vesselName. Always present for those steps: object if resolved, otherwise null. See Vessel position object below.

Vessel position object

Populated when our systems can match the step's vesselName to a current position (trimmed, case-insensitive). Lat/lng are decimal degrees. All timestamps in JSON are ISO 8601 strings.

FieldTypeDescription
mmsinumberMaritime Mobile Service Identity
imonumber | nullIMO number from the matched vessel, or null when not provided
latnumberLatitude in decimal degrees
lngnumberLongitude in decimal degrees
speedstringSpeed over ground as a decimal string with one fractional digit (e.g. "14.2")
statusstringNavigation status label (e.g. Underway, At Anchor); may be an empty string if unknown
lastUpdatedISO 8601Time associated with the position snapshot

Error codes

StatusDescription
400Bad request — missing or empty booking number after trimming, unknown or ambiguous carrier format, or carrier not available on this API
401Unauthorized — missing or invalid API key
403Forbidden — e.g. no active subscription on the key's account, monthly distinct-booking limit reached, or publishable key used outside an allowed domain/origin
429Too many requests — per-key rate limit; response may include a Retry-After header (seconds) and JSON body with message and retryAfterSec
500Internal server error — carrier or system failure

Error response shape

Most errors use Nest's JSON shape: statusCode and message (string or string array).

{
  "statusCode": 401,
  "message": "Invalid API key"
}

Example rate limit body:

{
  "statusCode": 429,
  "message": "Rate limit exceeded",
  "retryAfterSec": 42
}

Billing & rate limits

Subscribed plans include a monthly limit on distinct booking numbers successfully tracked (HTTP 2xx) for your account in that billing period. The first successful track for a given booking in the period counts toward the limit; further successful requests for the same booking in the same period do not consume another slot. Failed requests (non-2xx) do not add usage toward that distinct-booking count.

Rate limits (requests per minute) apply per API key. On 429, honor Retry-After and backoff. Contact us at hello@recargo.com.au if you need a higher limit.