Multi-Carrier Package Tracking — UPS & FedEx Status avatar

Multi-Carrier Package Tracking — UPS & FedEx Status

Pricing

from $32.00 / 1,000 package tracking results

Go to Apify Store
Multi-Carrier Package Tracking — UPS & FedEx Status

Multi-Carrier Package Tracking — UPS & FedEx Status

Run multi-carrier package tracking on mixed UPS and FedEx lists: normalized status, delivery estimates and scan events for ecommerce and support teams.

Pricing

from $32.00 / 1,000 package tracking results

Rating

0.0

(0)

Developer

Muhammad Afzal

Muhammad Afzal

Maintained by Community

Actor stats

0

Bookmarked

24

Total users

14

Monthly active users

8 days ago

Last modified

Categories

Security

Limited permissions

Share

Multi-Carrier Package Tracking checks a mixed list of up to 25 UPS and FedEx tracking numbers on the carriers' public tracking pages and returns one normalized record per shipment, with status, delivery estimate, latest scan and event history. It is built for ecommerce, customer-support and operations teams and AI agents, and costs USD 20 per 1,000 tracked shipments on the FREE tier (USD 40 per 1,000 from 2026-11-06), charged only for records delivered.

Current coverage (owner checks, 2026-10-15): UPS and FedEx International Connect numbers returned real shipment records. USPS lookups are refused and reported as BLOCKED. Standard 12- and 15-digit FedEx numbers are accepted, but a working data route is not yet verified, so failures are reported as FAILED. Neither outcome is charged.

What does this package tracking Actor return?

Each shipment the carrier confirms becomes one dataset record with the same fields for every carrier. Fields the carrier does not show are null; the Actor never guesses them.

FieldWhat it means
trackingNumberTracking number with spaces and hyphens removed
carrierUPS, FedEx or USPS
statusCross-carrier category: pre_advice, accepted, in_transit, out_for_delivery, delayed, delivery_attempted, ready_for_pickup, delivered, returned, exception or unknown
statusTextStatus text exactly as the carrier shows it
terminaltrue when delivered or returned, so you can stop polling
delivered / delayedYes/no flags for automations
estimatedDelivery / actualDeliveryDelivery estimate and delivery date or time when shown
serviceCarrier service name when shown
origin / destinationCity, state or province, postal code and country when shown
lastEventLatest scan: timestamp, status, description, location
eventsScan history in carrier order when includeDetailedEvents is on
sourceUrl / scrapedAtCarrier tracking page and UTC time of the lookup

Invalid, ambiguous, not-found, blocked or failed numbers never become fake rows. They appear as masked warnings in the OUTPUT record of the run's key-value store, with an overall outcome of DATA, EMPTY, BLOCKED, REJECTED or FAILED.

When should you use multi-carrier tracking, and when not?

Use it when one list mixes UPS and FedEx numbers and you want one status vocabulary for all of them: helpdesk ticket enrichment, delivery-exception checks, scheduled order monitoring, or a single tool an AI agent can call for any supported carrier.

Pick a different tool when:

  • Your list is FedEx only. FedEx Tracking Scraper takes up to 30 standard FedEx numbers per run and adds ship date, package count, scan event codes and special handling.
  • Your list is UPS only. UPS Tracking Scraper accepts UPS and InfoNotice numbers, lets you choose the UPS locale, and returns delivered-to and received-by text.
  • You ship with DHL. Use DHL Package Tracking Scraper.
  • You need other carriers or international postal services. 17TRACK Package Tracking Scraper reads 17TRACK's public tracker.
  • You need labels, rates, claims, delivery changes or proof-of-delivery signatures. Those require the carriers' authenticated APIs.

How do I track packages from several carriers in one run?

Paste up to 25 numbers into trackingNumbers and leave carrier on auto. Detection is deliberately conservative:

  • 1Z + 16 characters → UPS
  • KOT or PRO FedEx International Connect numbers, and 12- or 15-digit numbers → FedEx
  • Common USPS domestic and international formats → USPS

Numbers that match none of these patterns, such as other all-numeric formats, are rejected as ambiguous rather than sent to the wrong company. Set carrier to UPS, FedEx or USPS when the whole batch belongs to one carrier.

InputDefaultNotes
trackingNumbers (required)["1Z999AA10123456784"]1–25 values; duplicates, spaces and hyphens are removed
carrierautoForce one carrier for ambiguous formats
includeDetailedEventstrueTurn off for smaller output; current status is always returned
requestTimeoutSecs2520–90 seconds per lookup

The prefill is UPS's widely published sample number; replace it with your own numbers.

{
"trackingNumbers": ["1Z999AA10123456784", "KOT1234AB12345678901"],
"carrier": "auto",
"includeDetailedEvents": true,
"requestTimeoutSecs": 25
}

Use it from an AI assistant

Multi-Carrier Package Tracking works from Claude, ChatGPT, Cursor or any MCP client through Apify's MCP server. Add https://mcp.apify.com/?tools=muhammadafzal/multi-carrier-package-tracking as a server, then ask in plain language, for example: "Check these UPS and FedEx tracking numbers and tell me which ones are delayed or out for delivery." The agent can read the input schema and the price per result before it runs.

How do I call it from code?

JavaScript (apify-client):

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('muhammadafzal/multi-carrier-package-tracking').call({
trackingNumbers: ['1Z999AA10123456784'],
carrier: 'auto',
includeDetailedEvents: true,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.map((i) => [i.trackingNumber, i.status, i.estimatedDelivery]));

Python (apify-client):

import os
from apify_client import ApifyClient
client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("muhammadafzal/multi-carrier-package-tracking").call(
run_input={"trackingNumbers": ["1Z999AA10123456784"], "carrier": "auto"}
)
for item in client.dataset(run.default_dataset_id).iterate_items():
print(item["trackingNumber"], item["status"], item["estimatedDelivery"])

Keep the Apify token in an environment variable or secret store, and keep tracking numbers out of public logs.

What does the output look like?

Two records, shortened (values are illustrative):

[
{
"trackingNumber": "1Z999AA10123456784",
"carrier": "UPS",
"status": "delivered",
"statusText": "Delivered",
"terminal": true,
"delivered": true,
"delayed": false,
"estimatedDelivery": null,
"actualDelivery": "10/21/2026 2:41 P.M.",
"service": null,
"origin": { "city": "Louisville", "stateOrProvince": "KY", "postalCode": null, "country": "US" },
"destination": { "city": "Austin", "stateOrProvince": "TX", "postalCode": null, "country": "US" },
"lastEvent": { "timestamp": "10/21/2026 2:41 P.M.", "status": "Delivered", "description": "Front Door", "location": "Austin, TX, United States" },
"events": ["... full scan history ..."],
"sourceUrl": "https://www.ups.com/track?loc=en_US&tracknum=1Z999AA10123456784&requester=ST%2Ftrackdetails",
"scrapedAt": "2026-10-22T09:15:04.000Z"
},
{
"trackingNumber": "KOT1234AB12345678901",
"carrier": "FedEx",
"status": "in_transit",
"statusText": "IN TRANSIT",
"terminal": false,
"delivered": false,
"delayed": false,
"estimatedDelivery": null,
"actualDelivery": null,
"service": "FedEx International Connect Plus",
"origin": null,
"destination": { "city": null, "stateOrProvince": null, "postalCode": null, "country": "United Kingdom" },
"lastEvent": { "timestamp": "20th October 2026 18:02", "status": "IN TRANSIT", "description": null, "location": "Leipzig, DE" },
"events": ["..."],
"sourceUrl": "https://fictracking.fedex.com/?MyFICNumber=KOT1234AB12345678901",
"scrapedAt": "2026-10-22T09:15:31.000Z"
}
]

How much does it cost? Pricing per tracked shipment

You pay per delivered tracking record plus a small start fee. Apify platform usage is included. Invalid, ambiguous, not-found, blocked and failed lookups are not charged.

Event (USD)FREEBRONZESILVERGOLD, PLATINUM, DIAMOND
Package tracking result, until 2026-11-060.0200.01950.0190.016
Package tracking result, from 2026-11-060.0400.0390.0380.032
Actor start, per started GB of allocated memory0.0050.0050.0050.005

At the default 256 MB, a run has one start event.

Worked totals:

  • 10 shipments found, FREE tier: USD 0.005 + 10 × 0.020 = USD 0.205 today; USD 0.405 from 2026-11-06.
  • 25 shipments found, GOLD tier: USD 0.005 + 25 × 0.016 = USD 0.405 today; USD 0.805 from 2026-11-06.

The price rises on 2026-11-06 because each UPS lookup loads a full carrier page in a managed remote browser, which costs more than the current result price.

What happens when a number is blocked, invalid or not found?

Each number gets a truthful outcome and only confirmed shipments are written. A carrier-confirmed inactive or expired number counts as EMPTY, a malformed or ambiguous one as REJECTED, an access challenge as BLOCKED, and a timeout or page defect as FAILED. The Actor does not solve CAPTCHAs or log in anywhere.

The run status matches the outcome. A run that delivers at least one record, or where every number is confirmed not found (EMPTY), ends SUCCEEDED. A run that delivers nothing because every number was rejected, blocked or failed ends FAILED. Either way, OUTPUT is written first.

Limits that keep runs fast and cheap:

  • Lookups run one at a time, each capped by requestTimeoutSecs plus a hard per-lookup budget for browser start-up. Every browser step (connecting, opening a tab, navigating, reading the page, closing) has its own timeout. A lookup that stalls ends as FAILED and is not charged, and the next lookup gets a fresh browser session.
  • All lookups stop after about four minutes. A runtime guard writes OUTPUT and ends the run before the platform timeout, so a run cannot hang until it times out.
  • After two consecutive access or service failures for one carrier, remaining numbers for that carrier are skipped; results from other carriers are kept.
  • The Actor checks your maximum charge before each lookup and stops when it is reached.
  • OUTPUT lists counts, masked warnings, the effective result limit and the stop reason.

Carriers can hide details based on shipment age, service or destination, and public tracking records expire.

FAQ

Can I track hundreds of packages at once?

Yes, in batches. One run accepts 25 numbers; for larger lists, start several runs from the API or a schedule. For FedEx-only lists, FedEx Tracking Scraper takes 30 numbers per run.

Do I need a UPS or FedEx developer account or API key?

No. You only need an Apify account. The Actor reads the carriers' public tracking pages, and carrier logins, OAuth credentials and proxy settings are not required.

Can I export tracking statuses to a spreadsheet?

Yes. Export any run's dataset as CSV, Excel or JSON from Apify Console, or push it to Google Sheets with Make, Zapier or n8n.

Can it check tracking status automatically every day?

Yes. Save your input as an Apify schedule (hourly, daily or any cron), and use terminal to drop delivered or returned shipments from the next run's list.

Does it track USPS?

Not at the moment. USPS numbers are detected, but the lookup is currently refused, so it ends as BLOCKED with no result charge.

Why did my run return zero records?

Open the OUTPUT record. It explains every number, for example not found, ambiguous carrier, blocked or timed out. You pay only the start fee for such a run. If every number was rejected, blocked or timed out, the run also ends with FAILED status.

Track only shipments you own, handle or are authorized to monitor. Tracking numbers and delivery locations can be personal data, so keep datasets private and retain them only as long as needed. The Actor masks tracking numbers in diagnostics and never requests proof-of-delivery images or signatures. It is unofficial and not affiliated with UPS, FedEx or USPS; carrier names identify the public sources. When reporting a problem, share the run ID and only the first two and last four characters of a tracking number.

Last verified: 2026-10-27