๐ฌ Questions or feedback? Join the discussion on the Home Assistant community.
A custom Home Assistant integration that tracks your SpeedX packages in the United States. No account is needed: enter a tracking code just as you would on the SpeedX tracking page.
Part of the ha-parcel-integrations family: it publishes the same canonical parcel format, statuses and events as the other carrier integrations, so it plugs straight into the Parcel Aggregator and cross-carrier automations.
- Features
- Requirements
- Installation
- Configuration
- Options
- Removal
- Sensors
- Parcel status reference
- Events
- Services
- Examples
- Debugging
- Troubleshooting
- Related integrations
- Disclaimer
- Contributing
- License
- Track any number of SpeedX parcels by tracking code โ no account needed
- Per-parcel sensor with canonical status, a delivery timestamp when confirmed, and a tracking deep-link
- Summary sensors: incoming parcels, next delivery, recently delivered parcels
- Read-only Deliveries calendar with the expected delivery windows
speedx.track_parcel/speedx.untrack_parcelservices, so a dashboard button can add a parcel- Events + device triggers for no-code automations (parcel registered, status changed, delivered, delivery time changed)
- Opt-in per-parcel status history
- Manual refresh button and a diagnostic last-update sensor
- A SpeedX parcel and its tracking code (from the shipping confirmation email or the missed-delivery card) โ no account needed
- In HACS, choose the three-dot menu โ Custom repositories.
- Add
https://github.com/ha-parcel-integrations/ha-speedxas an Integration. - Install SpeedX and restart Home Assistant.
Copy custom_components/speedx into your config/custom_components/ folder and restart Home Assistant.
Add the integration via Settings โ Devices & Services โ Add Integration โ SpeedX. There is nothing to fill in: the hub is created immediately (SpeedX tracking needs no account).
Then add parcels via the integration's Configure dialog, the speedx.track_parcel service, or a dashboard button. The tracking code is on your shipping confirmation email or the missed-delivery card.
Open Configure on the integration entry:
| Section | Option | Default | Description |
|---|---|---|---|
| Parcels | Add / remove | โ | Manage the tracked tracking codes. Changes apply immediately, no restart. |
| Delivered parcels | Filter by / amount | last 7 days | How long delivered parcels stay visible on the delivered sensor. |
| Parcel history | Include status history | off | Adds a history attribute per parcel with each status update. |
Polling isn't one of these settings: the integration polls on a dynamic, status-driven schedule with nothing to configure.
Polling isn't a setting here โ the integration adjusts its own cadence to what your tracked parcels are actually doing:
- Quiet hours โ no polling between 00:00โ06:00 local time, aside from one catch-up check at each end of that window (around midnight and around 6 AM), so an overnight update is never missed.
- Hot (every 15 minutes) โ while any tracked parcel is out for delivery today, starting an hour before its delivery window opens (or immediately if no window is known yet โ this is the fallback that fires in practice for SpeedX, whose tracking surface reports no delivery window at all).
- Normal (every 45 minutes) โ for anything else still on its way.
- Fully paused โ once every tracked parcel has been delivered, or nothing is tracked at all, polling stops until you add a parcel back (adding one always triggers an immediate check, regardless of the pause).
- A small, fixed per-hub offset is added on top, so not every SpeedX hub out there polls at exactly the same second.
Standard HA removal applies: Settings โ Devices & Services โ SpeedX โ โฎ โ Delete. Nothing is stored on SpeedX's side.
| Entity | Description |
|---|---|
sensor.speedx_incoming_parcels |
Number of active tracked parcels, full list under the parcels attribute |
sensor.speedx_parcel_<code> |
One per tracked parcel; state is the canonical status, attributes carry the full normalised parcel |
sensor.speedx_next_delivery |
Earliest expected delivery moment across all active parcels |
sensor.speedx_delivered_parcels |
Recently delivered parcels (see the retention option) |
sensor.speedx_last_successful_update |
Diagnostic: when SpeedX was last polled successfully |
A delivered parcel moves from its per-parcel sensor to the delivered sensor automatically.
A button.speedx_refresh entity triggers an immediate poll outside the
regular interval, and a calendar.speedx_deliveries entity shows expected
delivery dates for active parcels โ read-only, no extra API calls.
The status field is the carrier-agnostic enum shared by the whole integration family:
| Status | Meaning |
|---|---|
registered |
Announced / received by SpeedX |
in_transit |
In the sorting network |
out_for_delivery |
With the courier today |
delivered |
Delivered |
problem |
SpeedX reports an exception |
unknown |
Not yet scanned, or a status we have not mapped yet |
raw_status contains SpeedX's event code. Event prose and location data are deliberately not exposed.
The integration fires these on the event bus (also available as device triggers on the SpeedX device):
| Event | When |
|---|---|
speedx_parcel_registered |
A new parcel appears in the active list |
speedx_parcel_status_changed |
A parcel's canonical status changes (old_status / new_status in the payload), except the final hop to delivered |
speedx_parcel_delivered |
A parcel is delivered |
speedx_parcel_delivery_time_changed |
The expected delivery window changes |
Every payload is the full normalised parcel plus the hub's device_id. Events are suppressed on the first refresh after start-up.
| Service | Fields | Description |
|---|---|---|
speedx.track_parcel |
tracking_code |
Start tracking a parcel |
speedx.untrack_parcel |
tracking_code |
Stop tracking a parcel |
Ready-to-paste automations and dashboard snippets live in examples/, including tracking a new parcel straight from a dashboard.
Third-party cards that work with this integration's sensors:
logger:
logs:
custom_components.speedx: debug- A parcel shows
unknownโ SpeedX has not scanned it yet (their API answersnot_founduntil the first scan), or the code is wrong. It will pick up automatically once scanned. - A status logs "Unrecognised SpeedX status" โ please open an issue with the logged line so the mapping can be extended.
This integration is part of ha-parcel-integrations โ a family of parcel-carrier integrations that all publish the same canonical parcel format, statuses and events.
- Parcel Aggregator rolls every installed carrier up into one set of sensors.
- Browse the organisation for the current list of supported carriers.
This is an independent, community-built project. It is not affiliated with, endorsed by, sponsored by, or supported by SpeedX, Home Assistant, or any other third party referenced in this project. Please don't contact SpeedX for support with this integration.
All third-party trademarks, trade names, product names, logos, and other brand assets are the property of their respective owners. References to them are solely to identify the relevant carrier or service and do not imply affiliation, sponsorship, or endorsement. Nothing in this project grants or implies any licence or right to use third-party brand assets.
This integration may rely on public, unofficial, or undocumented carrier interfaces, accessed with your own account or API key where required. These may change or be withdrawn without notice and may be subject to SpeedX's terms. Data is sent only to SpeedX's own services or those of its group; this project operates no servers of its own. You are responsible for ensuring that your use complies with applicable law and those terms. Use is at your own risk; see the licence for warranty limitations.
This integration uses the same public tracking endpoint as the SpeedX consumer website.
Pull requests and issues are welcome. Please open an issue before submitting a large change.