How do I track a few hundred hardware kit deliveries without checking each one?

A launch or onboarding wave of about 200 kits is too many for carrier sites and for free tiers: keyless lookups are 1 a day and a free key is 5 a day. On Pro ($4.99/mo for 1,000 unique numbers) the 200 numbers go out in 6 requests of up to 35, and re-checks that month are free, so you can rerun the list daily or watch every number and get a webhook on delivery or an exception. 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

Node: 200 kit numbers from a CSV, 35 per request
// 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. 1Z000Y770414233027, 1ZG2242W6822298280, 1Z54V8630394427740

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(","));
  url.searchParams.set("carrier", "ups");
  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(","));
  }
}
curl: watch a batch of kits
curl -X POST https://api.lastscanned.com/v1/watches \
  -H "Authorization: Bearer lsk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"trackingNumbers": ["1Z000Y770414233027", "1ZG2242W6822298280", "1Z54V8630394427740"], "metadata": {"wave": "kits-nov"}}'

Ways to check a few hundred kits

OptionHow it worksPriceNotes
Carrier sitesPaste numbers into the carrier's site in its batch size.FreeManual, and the result is a screen, not a file.
Batch from the spreadsheetSend the kit numbers 35 per request and write a status column.Pro $4.99 covers 1,000 numbersRerun as often as you like; re-checks are free.
Watch every kitPOST /v1/watches with up to 100 numbers per call.Each number counts onceWebhook on delivered, exception, or no scan after 14 days.

Details

Why free tiers don't fit

Keyless tracking is 1 number a day, then paid per use through MPP. A free key is 5 a day. A 200-kit wave needs Pro, which has no daily limit.

Six requests, not 200 searches

35 numbers per carrier per request means 200 UPS numbers is 6 requests. A mixed UPS and FedEx list can go 100 per request.

Find the stuck ones

Sort the output by status: exception and label_created rows are the kits to chase. The no-scan alerts guide adds a check for kits that stop moving.

Same file every day

On Pro a number counts once a month however often it's checked, so a daily rerun of the same 200 kits stays at $4.99.

FAQ

How many numbers can I check at once?
100 per request, with no more than 35 for any one carrier.
Is the free key enough for 200 kits?
No. It tracks 5 numbers a day. Pro at $4.99/mo covers 1,000 numbers with no daily limit.
Can I get alerts instead of rerunning the list?
Yes. Watch the numbers and set a webhook URL, or see them on app.lastscanned.com/watches.
Do the kits all need the same carrier?
No. Any mix of 549 carriers works in one list.