Carriers

The Courier Guy (South Africa) Tracking API & MCP

Query live The Courier Guy (thecourierguy) package status and scan history in a single synchronous GET request or MCP tool call. The Courier Guy numbers are not auto-detected: waybill numbers have no format that is unique to the carrier, so pass ?carrier=thecourierguy.

Overview & Quick Facts

PropertyValue
Carrier slug (?carrier=)thecourierguy
Brand & service aliasesThe Courier Guy, TCG, ShipLogic (thecourierguy.co.za)
CategorySouth African courier and parcel carrier
Single-package REST endpointGET https://api.lastscanned.com/v1/track/{trackingNumber}?carrier=thecourierguy
Batch REST endpointGET https://api.lastscanned.com/v1/track?numbers=TCG123456789,...&carrier=thecourierguy
MCP server (https://mcp.lastscanned.com)track_package, track_packages, list_carriers (claude mcp add --transport http lastscanned https://mcp.lastscanned.com)
Authentication & pricingAuthorization: Bearer lsk_live_... · 1 free keyless lookup/day per IP · Free tier (5 unique numbers/day, $0) · Pro ($4.99/mo for 1,000 unique numbers, unlimited re-polls, $0.015/extra) · HTTP 402 Stripe MPP ($0.50 for 25-number lsk_pack_ key or $0.02/number in USDC on Tempo)

Why developers use lastscanned for The Courier Guy

  • Behind the Cloudflare page: thecourierguy.co.za challenges plain requests, but the tracking portal's own API does not, so lookups need no browser.
  • Waybill history: collection, hub, out-for-delivery and delivery scans with their messages and locations.

Tracking Number Formats & Auto-Detection

PassRule / RegexCheck DigitExamples
Pass 1 (matches)None——
Pass 2 (mayMatch)None——
Explicit (?carrier=thecourierguy)The Courier Guy waybill number—TCG123456789

Synchronous GET Request & Normalized JSON Response

curl

curl -s "https://api.lastscanned.com/v1/track/TCG123456789?carrier=thecourierguy" \
  -H "Authorization: Bearer $LASTSCANNED_API_KEY"

JavaScript / TypeScript (fetch)

const res = await fetch("https://api.lastscanned.com/v1/track/TCG123456789?carrier=thecourierguy", {
  headers: { Authorization: `Bearer ${process.env.LASTSCANNED_API_KEY}` },
});
const pkg = await res.json();
console.log(pkg.status, pkg.events[0]);

MCP track_package tool call

{
  "tool": "track_package",
  "arguments": {
    "tracking_number": "TCG123456789",
    "carrier": "thecourierguy"
  }
}

Normalized TrackingResult JSON response

{
  "carrier": "thecourierguy",
  "trackingNumber": "TCG123456789",
  "status": "out_for_delivery",
  "statusDescription": "Out for delivery",
  "service": null,
  "deliveredAt": null,
  "deliveredAtLocal": null,
  "signedBy": null,
  "destination": null,
  "events": [
    {
      "timestamp": "2026-10-26T06:45:00Z",
      "localTime": "2026-10-26T08:45:00",
      "status": "out_for_delivery",
      "description": "Out for delivery",
      "location": "Johannesburg",
      "code": "out-for-delivery"
    },
    {
      "timestamp": "2026-10-25T14:10:00Z",
      "localTime": "2026-10-25T16:10:00",
      "status": "in_transit",
      "description": "Arrived at the Johannesburg hub",
      "location": "Johannesburg",
      "code": "at-hub"
    },
    {
      "timestamp": "2026-10-23T09:30:00Z",
      "localTime": "2026-10-23T11:30:00",
      "status": "in_transit",
      "description": "Collected from sender",
      "location": "Cape Town",
      "code": "collected"
    }
  ]
}

Notes

  • Times carry their own offset; a time without one is read as South African time (Africa/Johannesburg).
  • Shipment vs parcel events: scans for the whole shipment are used; if there are none, the parcel scans are.

On this page