๐ฌ Questions or feedback? Join the discussion on the Home Assistant community.
A custom Home Assistant integration that tracks your UniUni packages and parcels in Canada and the United States. No account is needed: enter the tracking code yourself.
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 UniUni parcels by tracking code โ no account needed
- Per-parcel sensor with the canonical status and UniUni's numeric source status
- Summary sensors: incoming parcels, next delivery, recently delivered parcels
- Read-only Deliveries calendar with the expected delivery windows
uniuni.track_parcel/uniuni.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
- An UniUni 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-uniunias an Integration. - Install UniUni and restart Home Assistant.
Copy custom_components/uniuni into your config/custom_components/ folder and restart Home Assistant.
Add the integration via Settings โ Devices & Services โ Add Integration โ UniUni. There is nothing to fill in: the hub is created immediately (UniUni tracking needs no account).
Then add parcels via the integration's Configure dialog, the uniuni.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 UniUni, whose estimated delivery date is date-only and never populates a delivery window).
- 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 UniUni hub out there polls at exactly the same second.
Standard HA removal applies: Settings โ Devices & Services โ UniUni โ โฎ โ Delete. Nothing is stored on UniUni's side.
| Entity | Description |
|---|---|
sensor.uniuni_incoming_parcels |
Number of active tracked parcels, full list under the parcels attribute |
sensor.uniuni_awaiting_pickup |
Number of parcels waiting to be collected (at_pickup_point), full list under the parcels attribute |
sensor.uniuni_parcel_<code> |
One per tracked parcel; state is the canonical status, attributes carry the full normalised parcel |
sensor.uniuni_next_delivery |
Earliest expected delivery moment across all active parcels |
sensor.uniuni_delivered_parcels |
Recently delivered parcels (see the retention option) |
sensor.uniuni_last_successful_update |
Diagnostic: when UniUni was last polled successfully |
A delivered parcel moves from its per-parcel sensor to the delivered sensor automatically.
A Deliveries calendar entity is also created, showing expected delivery windows for active parcels โ read-only, no extra API calls.
A Refresh button entity forces an immediate poll, without waiting for the next scheduled interval.
The status field is the carrier-agnostic enum shared by the whole integration family:
| Status | Meaning |
|---|---|
registered |
Announced / received by UniUni |
in_transit |
In the sorting network |
out_for_delivery |
With the courier today |
at_pickup_point |
Waiting for you at a pickup location |
delivered |
Delivered |
returning |
Going back to the sender |
problem |
UniUni reports an exception |
unknown |
Not yet scanned, or a status we have not mapped yet |
The carrier's own human-readable text is always available as raw_status.
The integration fires these on the event bus (also available as device triggers on the UniUni device):
| Event | When |
|---|---|
uniuni_parcel_registered |
A new parcel appears in the active list |
uniuni_parcel_status_changed |
A parcel's canonical status changes (old_status / new_status in the payload), except the final hop to delivered |
uniuni_parcel_delivered |
A parcel is delivered |
uniuni_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 |
|---|---|---|
uniuni.track_parcel |
tracking_code |
Start tracking a parcel |
uniuni.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.uniuni: debug- A parcel shows
unknownโ UniUni has not scanned it yet, the code is wrong, or UniUni has introduced a source state that is not mapped yet. - A status logs "Unrecognised UniUni 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 UniUni, Home Assistant, or any other third party referenced in this project. Please don't contact UniUni 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 UniUni's terms. Data is sent only to UniUni'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 UniUni consumer website.
Pull requests and issues are welcome. Please open an issue before submitting a large change.