Follow a USPS shipment from its public tracking result. Collect the current summary and the expanded history together, so a caller can distinguish a delivery estimate from a completed delivery and a purchased label from an accepted shipment. Return what USPS displays, retaining missing fields and ambiguous outcomes instead of filling them from assumptions.
Use Cases
- Answer where a shipment was last scanned and what USPS currently says about its progress.
- Retrieve a delivery estimate alongside the events supporting the current status.
- Identify a delivery attempt, pickup instruction, or other exception that needs the caller's attention.
- Check several supplied identifiers independently without combining their shipment histories.
Automation Flow
Prepare one lookup. Keep the requested identifier as a string and remove formatting whitespace without dropping leading zeroes. Do not reject it solely because it exceeds a presumed domestic length. If the input appears to contain several identifiers, separate the lookups before navigation; never choose a candidate result on the caller's behalf.
Open the public result in a browser. Start with
https://tools.usps.com/go/TrackConfirmAction?qtc_tLabels1={encoded-tracking-id}, URL-encoding the cleaned identifier. If USPS redirects to/tracking/{tracking-id}, follow that navigation. If it returns an empty entry form, use the visible tracking input and submit once. The homepage's#home-inputis an alternative starting point; when duplicate submit controls interfere, submit the visible input's own form.Check access and rendering before interpreting the shipment. Inspect both the page title and the result region. An access-denied screen, challenge, or blank document is a retrieval failure, not a package status. Wait for the result region to settle rather than relying only on the navigation load event. If the session remains blocked, report that limitation; a different browser or permitted proxy configuration is a troubleshooting option, not a guaranteed prerequisite or cure.
Bind the result to the request. Read the identifier displayed with the shipment, normalize its whitespace, and compare it with the requested value. The URL alone is insufficient proof of identity. If the displayed number differs, stop and retry a fresh lookup. If several shipments are offered, return their candidate identifiers for selection. If a populated result has no readable identifier, report that identity could not be verified rather than attaching its events to the request.
Capture the current summary. Locate the status within the matching result region, not a general page heading or help article. The
.tracking-progress-bar-status-containeranchor from the source notes is a candidate to inspect, not a required selector: use the current DOM and accessible labels if that structure has changed. Record the exact status text and explanatory text before assigning a broad category:Evidence in the shipment result Category and interpretation A completed delivery statement delivered; preserve the actual delivery time separately from any estimate.An explicit out-for-delivery statement out_for_delivery; do not count it as delivered.Acceptance, possession, facility movement, or transit information in_transit; possession of the item must not be classified as label creation.A label or pre-shipment statement explicitly saying USPS is awaiting the item awaiting_item; do not infer a physical scan.A failed attempt, notice, or availability-for-pickup statement delivery_action; preserve the instruction without initiating an action.A delay or routing/address problem that does not fit the categories above exception; include USPS's wording so the category does not conceal the cause.An unavailable-status message without a usable shipment summary unavailable; retain the explanation without asserting the number is invalid or that USPS has never received the item.An explicit statement that the lookup could not locate the requested information not_found; describe this lookup outcome, not the package's existence.A readable status whose meaning is unclear unknown; return its exact wording for interpretation.A populated result must not fall through to “not loaded” simply because its heading differs from an unavailable-result heading.
Read locations and delivery timing as separate fields. Capture the location associated with the latest scan, using city, state, and postal code when available. Keep a facility label separately if USPS supplies one; do not turn it into an inferred street address. For an estimate, retain the displayed date and time window verbatim. For completed delivery, retain the actual delivery text instead. Do not invent an ISO timestamp or timezone from a date-only label, and do not treat an old estimate as proof of delivery.
Expand the event history. Find the visible history control and open it only if collapsed. Read every loaded event row within this shipment, including its status, date/time text, and location. If a “more” control loads additional events, continue until no additional rows appear or retrieval fails. Preserve the displayed order and state which order it is; reverse or sort only when the timestamps establish chronology. Keep distinct scans even when they share a status label. Open Product Information separately when needed to read the service name.
Return the shipment with an extraction report. Include these fields, keeping unavailable values null:
trackingId,displayedTrackingId, andidentityVerified.statusCategory,statusText, andmessage.currentLocation,expectedDeliveryText,deliveredAtText, andserviceType.events, with each row'sstatusText,timestampText, andlocationText.historyState:loaded,partial,unavailable, ornot_extracted; also includeeventOrder,sourceUrl, andretrievedAt.
Use
events: nullwhen the history was not extracted or could not be opened. Use an empty array only when the inspected result actually presents no events. If some rows were collected before an interruption, keep them withhistoryState: partial. “Loaded” describes the available page content, not a guarantee that USPS exposes every scan it holds internally.Finish without changing delivery preferences. Leave notification enrollment, delivery instructions, holds, and redelivery untouched. Close or release a session created solely for this lookup. When sharing debug output, mask tracking identifiers in URLs, page captures, and logs, and omit street-level delivery details.
Params
| Param | Purpose | Handling |
|---|---|---|
| tracking-id | The identifier supplied by the caller | Preserve as text; remove whitespace and URL-encode for navigation. |
| include-history | Whether the caller needs the available scan rows | When omitted, include history; when false, return historyState: not_extracted. |
| include-service | Whether to inspect Product Information | Return null if the service is not displayed. |
Possible Friction Points
| Observation | Response |
|---|---|
| The page contains a valid delivery or transit result | Read the summary and history. An unavailable-only heading check is not a tracking extractor. |
| A general FAQ mentions an unavailable status | Ignore it; classification must come from the matching shipment's result region. |
| The result number cannot be matched to the input | Stop before returning shipment fields. Report the mismatch or missing identity evidence. |
| A history control expands but rows are still appearing | Wait and inspect again. Mark a partial collection if loading never finishes. |
| USPS presents an unavailable heading without a displayed number | Preserve the message and requested identifier, but set identityVerified: false; do not claim a verified shipment record. |
| Dates omit a year, timezone, or time of day | Preserve their text and report the missing precision. Do not manufacture a sortable timestamp. |
| Direct requests to a page-internal JSON endpoint fail | Continue through the rendered browser interface; this recipe does not assume an anonymous API contract for internal endpoints. |
| Repeated lookups encounter challenges or access failures | Reduce request frequency and stop sustained retries. No tested universal request quota or proxy requirement is established here. |
| The application needs an authenticated tracking integration | Consult the current USPS developer portal. Do not build a new integration around legacy Web Tools, whose registration site reports its retirement. |
Before moving this draft into the published catalog, validate a real populated lookup end to end: matching identifier, current summary, location/timing fields when present, and expanded scan rows. Also exercise an unavailable result and an access or loading failure. Record which states were actually observed; fabricated fixtures and source notes can check logic but cannot establish live coverage.