Broadpath API · v1

Build on live
cargo intelligence.

A REST API for everything in the Broadpath platform — container tracking, vessel positions, port intelligence. Bearer auth, JSON in, JSON out, generous rate limits, webhooks for the things you'd rather not poll.

~/track.sh
# Fetch a container's latest snapshot
curl https://api.broadpathlogistics.com/v1/containers/MEDU9091004 \
  -H "Authorization: Bearer bp_live_•••"

# Response (200 OK)
{
  "container_id": "MEDU9091004",
  "carrier": "MSC",
  "status": "in_transit",
  "vessel": { "name": "MSC OSCAR", "imo": "9703291" },
  "last_location": "Mediterranean Sea",
  "eta": "2026-05-20",
  "last_updated": "2026-05-14T03:00Z"
}
12
Endpoints
600/min
Rate limit
<120ms
P95 latency
JSON
Format
Quickstart

Three steps. Five minutes.

No client library required — every endpoint is a plain HTTPS call returning JSON. Use whatever HTTP client your stack already has.

STEP 01

Sign up & create a key

Free account, no card needed. Generate a live or test key from the dashboard. Test keys hit cached/synthetic data so you don't burn quota.

→ app.broadpathlogistics.com/api-keys
STEP 02

Make your first call

Authenticate with a Bearer header. Every response includes x-ratelimit-* headers so you can throttle proactively.

curl https://api.broadpathlogistics.com/v1/health \
  -H "Authorization: Bearer bp_live_…"
STEP 03

Subscribe to webhooks

Skip polling. Register an HTTPS endpoint and we'll POST events (container.update, vessel.enter, port.arrival) as they happen.

POST /v1/webhooks {
  "url": "https://you.example.com/hook",
  "events": ["container.update"]
}

Authentication

Bearer tokens. Send your API key in the Authorization header on every request.

  • Live key prefix bp_live_*
  • Test key prefix bp_test_*
  • Header Authorization: Bearer …
  • Rotation Self-serve in dashboard

Keys can be scoped (read-only, write, admin) and IP-allowlisted from the dashboard.

Rate limits

Per-key limits, with headroom for bursts. Anonymous calls (no key) are heavily throttled.

  • Authenticated 600 req/min
  • Anonymous 60 req/min/IP
  • Burst window 10 sec
  • 429 reset header x-ratelimit-reset

Hitting limits returns 429 with {"error":"rate_limited"} and a reset epoch.

Reference

Endpoints.

All endpoints are at https://api.broadpathlogistics.com/v1 and return JSON. Errors follow RFC 7807 problem-details format.

GET /v1/containers/:number Container snapshot

Returns the latest known state of a single container — status, current location, current carrying vessel, ETA, and most recent event.

Query parameters

shipping_linestringrequired for some prefixes
Use the carrier code (MAERSK, MSC, CMA_CGM, …) when the container prefix is ambiguous.

Returns

Object with container_id, carrier, status, last_location, vessel, eta, last_updated.

curl
curl https://api.broadpathlogistics.com/v1/containers/MEDU9091004?shipping_line=MSC \
  -H "Authorization: Bearer bp_live_•••"

{
  "container_id": "MEDU9091004",
  "carrier": "MSC",
  "status": "in_transit",
  "last_location": "Mediterranean Sea",
  "vessel": {
    "name": "MSC OSCAR",
    "imo": "9703291",
    "mmsi": "636016432"
  },
  "origin": "Guayaquil, EC",
  "destination": "Tripoli, LY",
  "eta": "2026-05-20",
  "last_updated": "2026-05-14T03:00Z"
}
GET /v1/containers/:number/events Event timeline

Full event timeline for a container — every booking confirmation, gate-in, load, transhipment, arrival, customs clearance, and gate-out we've observed.

Query parameters

sinceISO date
Only return events occurring at or after this date.
limitinteger · default 50, max 200
events
{
  "container_id": "MEDU9091004",
  "events": [
    {
      "type": "departed",
      "location": "Guayaquil, EC",
      "vessel": "MSC OSCAR",
      "occurred_at": "2026-05-04T02:00Z"
    },
    {
      "type": "transhipment",
      "location": "Singapore PSA",
      "new_vessel": "EVER ACE",
      "occurred_at": "2026-05-10T09:00Z"
    }
  ]
}
POST /v1/containers Add to tracking

Start tracking a new container. Spends one credit. Polled daily for 30 days from the call timestamp; can be paused or extended via PATCH.

Request body

container_numberstringrequired
4-letter prefix + 7 digits (e.g. MEDU9091004).
shipping_linestring
Optional but recommended; we infer when omitted.
aliasstring
Your internal nickname.
POST
curl -X POST https://api.broadpathlogistics.com/v1/containers \
  -H "Authorization: Bearer bp_live_•••" \
  -H "Content-Type: application/json" \
  -d '{
    "container_number": "MEDU9091004",
    "shipping_line": "MSC",
    "alias": "Q3 reefer #14"
  }'

# 201 Created
GET /v1/vessels/:imo Vessel snapshot

Current AIS snapshot for a vessel by IMO number — position, speed, course, heading, current and next ports.

Returns

imo, mmsi, name, flag, lat, lng, sog, cog, heading, nav_status, destination, last_seen.

vessel
{
  "imo": "9703291",
  "mmsi": "636016432",
  "name": "MSC OSCAR",
  "flag": "PA",
  "lat": 30.2,
  "lng": 32.5,
  "sog": 18.2,
  "cog": 145,
  "nav_status": "underway",
  "destination": "SGSIN",
  "last_seen": "2026-05-14T09:30Z"
}
GET /v1/vessels/:imo/track Historical track

Historical position data, downsampled to a reasonable number of points. Useful for playback, route analysis, dispute evidence.

Query parameters

hoursinteger · default 24, max 8760 (1y)
Lookback window. Long windows are returned downsampled to ~500 points.
pointsinteger · default 500
Max points returned. Capped at 5000.
track
{
  "imo": "9703291",
  "hours": 168,
  "points": [
    ["2026-05-07T00:00Z", 14.2, 78.5, 22.1, 92],
    ["2026-05-08T00:00Z", 18.6, 64.9, 21.7, 95],
    // [ts, lat, lng, sog, cog]
    …
  ]
}
GET /v1/ports List tracked ports

All 32 deep-water ports we monitor, with UN/LOCODE, country, lat/lng, and current vessel count.

ports
{
  "ports": [
    {"unlocode":"SGSIN", "name":"Singapore", "vessels_now":1247},
    {"unlocode":"CNSHA", "name":"Shanghai", "vessels_now":1108},
    …
  ]
}
GET /v1/ports/:unlocode Port detail + nearby vessels

Port metadata plus every vessel currently within the configured radius, with berth/anchor/inbound classification.

Query parameters

radius_kminteger · default 10, max 50
Radius from the port's published terminal coordinates.
port
{
  "unlocode": "SGSIN",
  "name": "Singapore",
  "country": "SG",
  "lat": 1.27, "lng": 103.85,
  "vessels": [
    {"name":"EVER ACE", "classification":"berthed"},
    {"name":"MAERSK MADRID", "classification":"anchored"},
    …
  ]
}
Webhooks

Push, don't pull.

Register an HTTPS endpoint; we send signed POSTs as events happen. Replaces ~95% of the polling people instinctively write.

Event types

  • container.updateStatus / location changed
  • container.eventNew event in timeline
  • container.deliveredTerminal status
  • vessel.positionAIS position update (filterable)
  • vessel.port_arrivalEntered a port polygon
  • vessel.port_departureLeft a port polygon
  • vessel.detainedPSC detention recorded

Signature

Every POST includes x-broadpath-signature — HMAC-SHA256 of (secret + raw_body). Verify before processing.

  • AlgorithmHMAC-SHA256
  • Timeout5 sec to ack
  • Retries5x with exponential backoff
  • IdempotencyDedupe on event.id

Signing secrets rotate without breaking existing endpoints — both old and new secrets accepted for 24h after rotation.

Ready to build?

Free tier covers most early integrations. Production tier kicks in around 600 req/min sustained.