← Developers

TrackJet API v1

A read-only REST API over TrackJet's detection engine and carrier directory — the same logic that powers the website and the MCP server. Multi-vertical: air cargo (MAWB), ocean containers (ISO 6346), Bill of Lading (SCAC), parcels, and postal (UPU S10). EU-hosted. No scraping of third-party aggregators.

Base URL: https://trackjet.world/api/v1
OpenAPI 3.1: /api/v1/openapi.json
Rate limits: free: 60/min · pro: 600/min · enterprise: 6000/min (per API key). Responses carry X-RateLimit-* headers; over-limit returns 429.
Billing: disabled (all plans free).

Authentication

Send your API key as a Bearer token (the X-Api-Key header is also accepted):

Authorization: Bearer tjk_live_xxxxxxxxxxxxxxxxxxxxxxxx

Keys are issued by the TrackJet team. Treat a key like a password — it grants read access under your plan's rate limit. Every response includes an X-Request-Id you can quote in support requests.

Endpoints

MethodPathDescription
GET/api/v1/detectDetect a number's format/vertical. Query: number.
GET/api/v1/track/{number}Detect + resolve where to track (carrier URL + TrackJet URL).
GET/api/v1/carriersList production carriers. Query: type, limit, offset.
GET/api/v1/carrier/{id}A single carrier's metadata.
GET/api/v1/capabilitiesCoverage snapshot (formats, counts, MCP info).
GET/api/v1/carbonRough freight CO2e estimate (GLEC/ISO 14083). Query: mode, weight_kg, distance_km.
GET/api/v1/track/{number}/qrQR image (SVG/PNG) that opens the tracking page. No key required; embeddable in <img>.
GET/api/v1/track/{number}/streamServer-Sent Events live stream (text/event-stream). Emits status events; closes with event: closed + a reason (no_live_feed when the carrier has no licensed event feed — DHL Group numbers stream real updates).
GET·POST/api/v1/webhooksList / register webhooks (HMAC-signed deliveries). POST honours Idempotency-Key.
POST/api/graphqlGraphQL (alongside REST). Same key auth. Query: detect, carriers, carrier, capabilities.
GET/api/v1Service descriptor (no key required).

Response envelope

{
  "ok": true,
  "data": { "...": "endpoint-specific" },
  "meta": { "request_id": "…", "api_version": "v1" }
}

// errors:
{ "ok": false, "error": { "code": "unauthorized", "message": "…", "status": 401 }, "meta": { … } }

Examples

curl

curl -H "Authorization: Bearer $TRACKJET_API_KEY" \
  "https://trackjet.world/api/v1/detect?number=020-12345675"

JavaScript (fetch)

const res = await fetch("https://trackjet.world/api/v1/detect?number=020-12345675", {
  headers: { Authorization: `Bearer ${process.env.TRACKJET_API_KEY}` },
});
const { data } = await res.json();
console.log(data.primary, data.normalized);

PHP

$ch = curl_init("https://trackjet.world/api/v1/detect?number=020-12345675");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ["Authorization: Bearer " . getenv("TRACKJET_API_KEY")],
]);
$data = json_decode(curl_exec($ch), true);
echo $data["data"]["normalized"];

Python

import os, requests
r = requests.get(
    "https://trackjet.world/api/v1/detect",
    params={"number": "020-12345675"},
    headers={"Authorization": f"Bearer {os.environ['TRACKJET_API_KEY']}"},
)
print(r.json()["data"]["primary"])

GraphQL

curl -X POST "https://trackjet.world/api/graphql" \
  -H "Authorization: Bearer $TRACKJET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"query":"{ detect(number:\"020-12345675\"){ normalized matched matches{ type label } } }"}'

EPCIS 2.0 repository

Minimal conformant subset of GS1 EPCIS 2.0 (honest scope: ObjectEvent JSON only — no XML, no subscriptions, no full query language). Events are isolated per API key. EPCs whose digit-run matches a tracked shipment appear on its public page as "EPCIS (partner)", separate from the carrier chain.

curl -X POST "https://trackjet.world/api/v1/epcis/capture" \
  -H "Authorization: Bearer $TRACKJET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"type":"ObjectEvent","eventTime":"2026-06-11T09:00:00Z",
       "eventTimeZoneOffset":"+00:00","action":"OBSERVE",
       "bizStep":"urn:epcglobal:cbv:bizstep:shipping",
       "epcList":["urn:epc:id:sscc:0037000.0123456789"],
       "readPoint":{"id":"urn:epc:id:sgln:0037000.00729.0"}}'

curl -H "Authorization: Bearer $TRACKJET_API_KEY" \
  "https://trackjet.world/api/v1/epcis/events?EPC=urn:epc:id:sscc:0037000.0123456789"

Webhooks

Register an HTTPS endpoint to receive shipment.status_changed events. Each delivery is signed:

curl -X POST "https://trackjet.world/api/v1/webhooks" \
  -H "Authorization: Bearer $TRACKJET_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://you.example/hook","events":"shipment.status_changed"}'
# response includes a one-time "secret".

Verify each delivery's X-TrackJet-Signature: sha256=<hmac>:

expected = "sha256=" + hmac_sha256(raw_request_body, your_secret)
if not hmac_compare(expected, header["X-TrackJet-Signature"]): reject()

Sandbox

Reserved TJTEST-* tracking numbers return deterministic, fully-synthetic lifecycles (timestamps in 2030, sandbox:true), so you can build and pin integration tests without a real parcel — happy path and edge cases:

NumberScenario
TJTEST-DELIVEREDFull happy path ending delivered.
TJTEST-IN-TRANSITMid-journey, latest event in_transit.
TJTEST-EXCEPTIONCarrier exception (damaged label), no delivery.
TJTEST-CUSTOMS-HOLDHeld at customs awaiting import duties.
TJTEST-RETURNEDRefused at the door, returned to sender.
TJTEST-STALENo scans for 14 days — exercise your staleness logic.
TJTEST-NOT-FOUNDAlways "no data" — exercise your empty state.
curl -H "Authorization: Bearer $TRACKJET_API_KEY" \
  "https://trackjet.world/api/v1/track/TJTEST-DELIVERED"

Webhook dry-run — fire one signed sandbox.test event at your registered endpoint through the real delivery pipeline (same X-TrackJet-Signature, same retry/log path):

curl -X POST "https://trackjet.world/api/v1/webhooks/<id>/test" \
  -H "Authorization: Bearer $TRACKJET_API_KEY"

Transparency & verification

Every tracked chain's history is sealed into a SHA-256 hash chain (tjvt1), and all sealed heads are anchored in a public, append-only Merkle log (tjmt1). Three endpoints are public — no API key — because a transparency log is only credible when anyone can verify:

curl "https://trackjet.world/api/v1/shipments/<uuid>/proof"       # tjvt1 chain proof
curl "https://trackjet.world/api/v1/shipments/<uuid>/inclusion"   # tjmt1 Merkle inclusion proof
curl "https://trackjet.world/api/v1/transparency/roots"            # append-only root history

Verify offline with the single-file, dependency-free tjverify CLI.

Notes