How do I track multiple DHL tracking numbers at once?

On dhl.com you can enter several tracking IDs separated by commas, spaces, tabs or semicolons. DHL's Shipment Tracking - Unified API documents one trackingNumber per call, and a new key starts at 250 calls a day with at most one call every 5 seconds until DHL grants more. With lastscanned you send up to 35 DHL numbers in one GET /v1/track request, or 100 when the list mixes carriers. Pro is $4.99/mo for 1,000 unique numbers, then $0.015 each, with no daily limit. A free key tracks 5 numbers a day. With no key you get 1 lookup a day, then pay per request over MPP: $0.50 by card for a 25-number pack, or $0.02 a number in USDC on Tempo.

Try it

curl: DHL numbers in one request
curl "https://api.lastscanned.com/v1/track?numbers=JJD149150000000340699,JJD000030247489000000075290" \
  -H "Authorization: Bearer lsk_live_YOUR_KEY"
Node: a long DHL list, 35 per request, written out as CSV
// node track-list.mjs < numbers.txt > results.csv   (one number per line)
import { stdin } from "node:process";

let text = "";
for await (const chunk of stdin) text += chunk;
const numbers = [...new Set(text.split(/[\s,]+/).map((n) => n.trim().toUpperCase()).filter(Boolean))];
// e.g. JJD149150000000340699, JJD000030247489000000075290

console.log("tracking_number,carrier,status,last_scan_utc,last_scan,location,error");
for (let i = 0; i < numbers.length; i += 35) {
  const batch = numbers.slice(i, i + 35);
  const url = new URL("https://api.lastscanned.com/v1/track");
  url.searchParams.set("numbers", batch.join(","));
  const res = await fetch(url, { headers: { Authorization: `Bearer ${process.env.LASTSCANNED_KEY}` } });
  if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
  for (const { trackingNumber, result, error } of (await res.json()).results) {
    const last = result?.events?.[0]; // events are newest first
    const row = [trackingNumber, result?.carrier, result?.status, last?.timestamp, last?.description, last?.location, error?.code];
    console.log(row.map((v) => JSON.stringify(v ?? "")).join(","));
  }
}

Ways to track DHL numbers in bulk

OptionHow it worksPriceNotes
dhl.com trackingEnter several IDs separated by commas, spaces, tabs or semicolons.FreeMade for reading on screen.
DHL Shipment Tracking - Unified APIGET /track/shipments?trackingNumber= with a DHL-API-Key header.Through your DHL developer accountNew keys: 250 calls a day, 1 call every 5 seconds; more on request.
lastscannedGET /v1/track?numbers=a,b,c with up to 35 DHL numbers (100 in all), one Bearer key.Free: 5 numbers a day. Pro: $4.99/mo for 1,000 unique numbers, then $0.015 each, no daily limit.DHL and 542 other carriers in one response shape.

Carrier limits from DHL Developer: Shipment Tracking - Unified and DHL: tracking, read on November 3, 2026. They can change.

Details

The starter limit, in hours

At one call every 5 seconds, 1,000 DHL numbers take about 83 minutes through a new Unified API key, and 250 a day caps the list before that. Here 1,000 numbers is 29 requests of 35.

Scan times

DHL Express scans usually carry an offset, so timestamp is exact UTC. DHL eCommerce and Parcel scans often don't, and timestamp is then null; localTime keeps the time as DHL printed it.

Re-checks are free on Pro

A number counts once a month on Pro, however many times you poll it, so re-checking open DHL shipments every hour costs nothing extra.

Stop polling, get a webhook

Watch DHL numbers with POST /v1/watches and get a signed webhook when the status, newest scan or estimate changes.

FAQ

Does the DHL tracking API take more than one number per call?
DHL's Unified API documents one trackingNumber per call. lastscanned takes up to 35 DHL numbers per request.
What is the DHL API rate limit?
DHL starts new Shipment Tracking - Unified keys at 250 calls a day and one call every 5 seconds, and grants more on request.
Can I mix DHL with other carriers?
Yes. Up to 100 numbers per request, no more than 35 for any one carrier.