Skip to content

Repository files navigation

GLS Parcel Tracker

Release Downloads HACS License

💬 Questions or feedback? Join the discussion on the Home Assistant community.

A custom Home Assistant integration that tracks your GLS parcels in Austria, Belgium, Canada, Croatia, the Czech Republic, Denmark, Finland, France, Germany, Hungary, Ireland, Italy, Luxembourg, the Netherlands, Poland, Serbia, Slovakia, Slovenia, Switzerland and the United States. No GLS account is needed — you enter the tracking number and delivery postal code yourself.

Contents

Features

  • Track multiple GLS parcels by tracking number — no account
  • Add parcels from the options, a service, or a dashboard button
  • Per-parcel sensor per tracked shipment, with full status details as attributes
  • Incoming, next-delivery, en-route and awaiting-pickup summary sensors
  • Delivered-parcels sensor and an optional per-parcel status history timeline
  • Weight and dimensions where GLS provides them
  • Automatic lifecycle management — per-parcel sensors appear and disappear as parcels move through delivery

Requirements

  • A GLS parcel delivered to a supported country. Austria, Belgium, Canada, Croatia, the Czech Republic, Denmark, Finland, France, Germany, Hungary, Ireland, Italy, Luxembourg, the Netherlands, Poland, Serbia, Slovakia, Slovenia, Switzerland and the United States are available today; the setup form links to the organisation discussion for requesting another country

Installation

HACS (recommended)

  1. Open HACS → Integrations → ⋮ → Custom repositories
  2. Add this repository URL and select category Integration
  3. Search for GLS and install it
  4. Restart Home Assistant

Manual

  1. Copy the gls folder into your config/custom_components/ directory
  2. Restart Home Assistant

Configuration

  1. Go to Settings → Devices & Services → Add Integration
  2. Search for GLS
  3. Pick your country and enter your delivery postal code (the one parcels usually go to)
  4. Click Submit

That's it — setup only asks for the country and postal code. The postcode becomes the default for parcels you add later, so adding a parcel usually only needs its number.

For Canada, the postal code is used for GLS Canada's enhanced tracking response. The carrier's complete native response is available in the parcel sensor's unrecorded raw attribute.

For the United States and Poland, GLS tracks on the number alone, so the postal code is only the hub's label there — setup still asks for it so every GLS hub works the same way. Both report status, delivery time and scan history, and neither publishes weight or dimensions. Polish parcels are tracked through GLS Poland's own national system, which also reports a parcel's arrival at a GLS Point separately from you collecting it.

You can add multiple hubs — one per delivery postal code (e.g. home and work). Each hub is its own GLS (postcode) device with its own parcels.

Adding parcels

A GLS hub holds your tracked parcels. Add them any of three ways — new per-parcel sensors appear immediately, no restart or manual refresh needed:

  • Options — integration card → Configure → Parcels → edit the list of tracking codes (add or remove any number, then save).
  • Service — call gls.track_parcel with a tracking_code (and optional postal_code, which picks the hub when you run several). gls.untrack_parcel removes one.
  • Dashboard — a text field + button that calls the service. See examples/dashboards/add_parcel_card.yaml.

You can use either identifier GLS gives out: the long parcel number (e.g. 13290054100304) or the short tracking ID (e.g. 00L1B3BX). Find them in the GLS track & trace mail/SMS or on gls-info.nl.

Options

Click Configure on the integration card — a menu with two pages:

Page Description
Parcels Your tracked codes as one editable list — add or remove any number, then save.
Settings Delivered-parcel retention and status history, described below.
Setting (on the Settings page) Description
Delivered parcels: filter by / amount Keep delivered parcels in the delivered sensor for the last N days, or keep only the N most recent (parcels). Default: 7 days. Parcels stay tracked — this only controls the sensor.
Include status history Add a per-parcel status history attribute. Off by default.

Dynamic polling

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).
  • 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 GLS hub out there polls at exactly the same second.

Removal

Standard HA removal applies: Settings → Devices & Services → GLS → ⋮ → Delete. Nothing is stored on GLS' side.

Sensors

Each hub is a GLS (postcode) device. The entities below show the friendly-name pattern (with multiple hubs each carries its own postcode):

Friendly name Description
GLS (postcode) Incoming parcels Number of active (not-yet-delivered) tracked parcels
GLS (postcode) Parcel <number> Canonical status of a single tracked parcel
GLS (postcode) Next delivery Earliest expected delivery datetime
GLS (postcode) En route to ParcelShop Active parcels still in transit to a GLS ParcelShop
GLS (postcode) Awaiting pickup Parcels that have arrived at a ParcelShop and are ready to collect
GLS (postcode) Delivered parcels Recently delivered tracked parcels (retention configurable)
GLS (postcode) Last successful update Diagnostic timestamp of the last successful poll

A GLS (postcode) Deliveries calendar entity is also created, showing expected delivery dates for active parcels — read-only, no extra API calls.

A GLS (postcode) Refresh button entity forces an immediate poll, without waiting for the next scheduled interval.

Not every field is populated by every country — weight/dimensions/ sender/receiver/pickup_point and the delivery window vary by which data GLS' own backend for that country exposes. Every parcel exposed on a sensor attribute uses the same carrier-agnostic shape regardless:

Key Type Meaning
carrier string "GLS"
barcode string Parcel tracking number
sender string | null Sender name
receiver string | null Recipient name
status ParcelStatus Canonical status — see the status reference
raw_status string | null Original GLS status description
delivered bool Whether the parcel has been delivered
delivered_at ISO 8601 | null Delivery moment, if known
planned_from ISO 8601 | null Expected delivery window start
planned_to ISO 8601 | null Expected delivery window end
pickup bool Destined for a ParcelShop rather than a home address
pickup_point string | null ParcelShop name when pickup is true
url string | null Deep link to the parcel's tracking page
weight float | null Parcel weight in kilograms
dimensions dict | null {length, width, height, text} in centimeters
history list | null Ordered status timeline (oldest → newest), each {timestamp, status, raw_status}. null unless the status history option is enabled — see Options.
raw dict The original GLS API payload

Parcel status reference

status on every parcel is one of the canonical ParcelStatus values below — use these in automations rather than GLS' raw Dutch strings.

status Meaning GLS state
registered GLS was notified of the parcel 0 (Aangekondigd bij GLS)
in_transit In GLS' network 1, 2 (ontvangen / op depot)
out_for_delivery On the delivery vehicle today 3 (Onderweg - geladen voor aflevering)
at_pickup_point Arrived at a ParcelShop, ready to collect (mapped once observed)
delivered Handed over 4 (Afgeleverd)
returning On the way back to the sender (mapped once observed)
problem Carrier reports an exception (mapped once observed)
unknown A state we have not mapped yet anything else — logged once at warning level with a ready-to-paste issue link

Events

The coordinator fires events on the HA event bus when something interesting happens to a parcel, so automations can react without polling per-parcel sensors.

Event When Payload
gls_parcel_registered A new parcel appears in the active list The full parcel dict (see the table above)
gls_parcel_status_changed A parcel's canonical status value changes, except the final hop to delivered Same payload plus old_status and new_status
gls_parcel_delivered An incoming parcel is delivered The full parcel dict
gls_parcel_delivery_time_changed A parcel's expected delivery time changes to a new value Same payload plus old_planned_from, new_planned_from, old_planned_to, new_planned_to

Every payload also carries a device_id. Events do not fire for parcels that were already tracked when HA first started.

If you build automations in the UI, these same events are also available as no-code device triggers (Settings → Automations → Create → Add trigger → Device).

See examples/automations/ for ready-to-paste event-driven automations.

Services

Service Description
gls.track_parcel Start tracking a parcel — tracking_code (required) and postal_code (optional, defaults to the hub postal code).
gls.untrack_parcel Stop tracking a parcel — tracking_code.

Examples

Ready-to-paste automations and dashboard snippets live in examples/, including a card that adds a parcel from a dashboard.

Community Lovelace cards

Third-party cards that work with this integration's sensors:

Debugging

To capture the raw GLS API response, enable debug logging:

logger:
  default: warning
  logs:
    custom_components.gls: debug

Restart Home Assistant, wait for the next poll (or press the Refresh button), and check Settings → System → Logs.

Troubleshooting

Symptom Likely cause
cannot_connect during setup GLS is unreachable; check your network
A parcel shows unknown GLS has not scanned it yet, or its state is not mapped — check the logs for a ready-to-paste issue link
Sensors not updating Check Settings → System → Logs for gls entries

Related integrations

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.

Disclaimer

This is an independent, community-built project. It is not affiliated with, endorsed by, sponsored by, or supported by GLS, Home Assistant, or any other third party referenced in this project. Please don't contact GLS 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 GLS's terms. Data is sent only to GLS'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.

Contributing

Pull requests and issues are welcome. Please open an issue before submitting a large change.

License

MIT

Releases

Sponsor this project

Used by

Contributors

Languages