The FreightTrackingAPI REST API. All responses are JSON. GET /track/{bookingNumber} requires an API key; GET / and GET /health do not.
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"https://api.freighttrackingapi.com.au| Method | Path | Auth | Description |
|---|---|---|---|
GET | /track/{bookingNumber} | x-api-key | Track by carrier booking or reference number |
GET | / | None | API metadata: name, env, version (JSON) |
GET | /health | None | Liveness: JSON { healthy: true } when the service is ready |
Example GET /: { "name": "Freight Tracker API", "env": "production", "version": "…" }
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.
| Parameter | Type | Description |
|---|---|---|
bookingNumber | string | The booking or reference number issued by the carrier (OOCL example: 2751234567) |
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.
curl https://api.freighttrackingapi.com.au/track/2751234567 \
-H "x-api-key: YOUR_API_KEY"{
"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"
}
}
]
}| Field | Type | Description |
|---|---|---|
bookingNumber | string | The booking number as provided |
mode | "ocean" | "air" | Transport mode (currently always ocean) |
carrier | string | Resolved carrier code: COSCO, EVERGREEN, HAPAG_LLOYD, MAERSK, OOCL, ZIM, or ANL (uppercase, as returned in JSON) |
cached | boolean | true if this response was served from cache |
fetchedAt | ISO 8601 | When this payload was last obtained from the carrier; unchanged on cache hits (still the original fetch time) |
expiresAt | ISO 8601 | When the cache entry expires (24h TTL) |
steps | array | Ordered voyage legs — see Step object below |
| Field | Type | Description |
|---|---|---|
stepIndex | number | Zero-based leg index |
modeOfTransport | "VESSEL" | "TRUCK" | "RAIL" | "UNKNOWN" | Transport mode for this leg |
vesselName | string | null | Vessel name when the carrier provides it; may be null or omitted per leg |
voyageNumber | string | null | Voyage or service code when provided; may be null or omitted |
portOfLoadingCode | string | null | Port of loading code when provided (often UN/LOCODE); may be null or omitted |
portOfLoadingName | string | null | Human-readable port of loading; may be null or omitted |
portOfDischargeCode | string | null | Port of discharge code when provided (often UN/LOCODE); may be null or omitted |
portOfDischargeName | string | null | Human-readable port of discharge; may be null or omitted |
etd | ISO 8601 | null | Estimated departure; null or omitted if unknown |
eta | ISO 8601 | null | Estimated arrival; null or omitted if unknown |
vesselPosition | object | null | Only 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. |
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.
| Field | Type | Description |
|---|---|---|
mmsi | number | Maritime Mobile Service Identity |
imo | number | null | IMO number from the matched vessel, or null when not provided |
lat | number | Latitude in decimal degrees |
lng | number | Longitude in decimal degrees |
speed | string | Speed over ground as a decimal string with one fractional digit (e.g. "14.2") |
status | string | Navigation status label (e.g. Underway, At Anchor); may be an empty string if unknown |
lastUpdated | ISO 8601 | Time associated with the position snapshot |
| Status | Description |
|---|---|
400 | Bad request — missing or empty booking number after trimming, unknown or ambiguous carrier format, or carrier not available on this API |
401 | Unauthorized — missing or invalid API key |
403 | Forbidden — e.g. no active subscription on the key's account, monthly distinct-booking limit reached, or publishable key used outside an allowed domain/origin |
429 | Too many requests — per-key rate limit; response may include a Retry-After header (seconds) and JSON body with message and retryAfterSec |
500 | Internal server error — carrier or system failure |
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
}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.