A custom Home Assistant integration for Ocado that provides sensors for your deliveries, orders, cart, and account information.
⚠️ Alpha Release — This integration is in early development. Expect breaking changes between versions.
This integration does NOT support username/password login.
Ocado's login flow uses reCAPTCHA and QueueIT bot protection, making headless authentication impossible. Instead, you must provide pre-captured session and refresh tokens obtained by intercepting traffic from the official Ocado iOS or Android app.
The refresh token (an RS256 JWT with ~1 year expiry) allows the integration to maintain your session indefinitely by automatically refreshing the session token every hour.
You'll need a proxy tool to intercept HTTPS traffic from the Ocado app:
- Install a proxy tool — Charles Proxy, mitmproxy, or Proxyman
- Configure SSL proxying for
api.mol.osp.tech - Install the proxy's CA certificate on your phone
- Open the Ocado app and log in normally
- Find the
Authorizationheader in any API request — it will look liketoken:0WqFY0...- The part after
token:is your Session Token
- The part after
- Find the refresh call (
POST /v1/authorize/refresh) — the request body contains your Refresh Token (a long JWT starting witheyJ...)
Tip: The refresh token is also sent in the
Authorizationheader of the refresh request itself.
- Open HACS in Home Assistant
- Click the three dots menu → Custom repositories
- Add
https://github.com/stormsys/ha-ocadowith category Integration - Click Install
- Restart Home Assistant
- Download the
custom_components/ocadofolder from this repository - Copy it to your Home Assistant
config/custom_components/directory - Restart Home Assistant
- Go to Settings → Devices & Services → Add Integration
- Search for Ocado
- Enter your Session Token and Refresh Token
- The integration will validate your tokens and create the device
Each Ocado account appears as a device with the following sensors:
| Sensor | Description | Type |
|---|---|---|
| Upcoming Orders | Number of upcoming deliveries | Count |
| Next Delivery | Date/time of next delivery slot | Timestamp |
| Next Delivery Slot | Human-readable delivery window | Text |
| Next Delivery Items | Number of items in next order | Count |
| Next Delivery Total | Total cost of next order | Monetary (GBP) |
| Next Delivery Status | Status of next order (e.g. "Picking in progress") | Text |
| Active Orders | Total non-cancelled order count | Count |
| Last Delivery | Date of most recent completed delivery | Timestamp |
| Sensor | Description | Type |
|---|---|---|
| Cart Items | Number of items in your current cart | Count |
| Cart Total | Current cart value | Monetary (GBP) |
| Sensor | Description | Type |
|---|---|---|
| Next Available Slot | Next bookable delivery slot | Timestamp |
| Sensor | Description | Type |
|---|---|---|
| Delivery Subscription | Smart Pass / delivery subscription status | Text |
| Account Name | Account holder name | Diagnostic |
| Account Email | Account email address | Diagnostic |
The integration automatically handles token lifecycle:
- Session token is refreshed every 1 hour (configurable)
- Data polling occurs every 10 minutes (configurable)
- On any
401 Unauthorizedresponse, an immediate refresh is attempted - Refreshed tokens are persisted to the config entry so they survive HA restarts
- If the refresh token itself expires (~1 year), a re-authentication flow will prompt you to provide new tokens
Example automation — notify when a delivery is on its way:
automation:
- alias: "Ocado delivery arriving"
trigger:
- platform: state
entity_id: sensor.ocado_next_delivery_status
to: "Out for delivery"
action:
- service: notify.mobile_app
data:
title: "🚚 Ocado delivery on its way!"
message: >
Your order with {{ states('sensor.ocado_next_delivery_items') }} items
(£{{ states('sensor.ocado_next_delivery_total') }}) is out for delivery.The integration supports Home Assistant's diagnostics download feature. All sensitive data (tokens, email addresses, delivery addresses) is automatically redacted in diagnostic exports.
- Ensure you're copying the full token strings without any extra whitespace
- Session tokens are ~100 characters of URL-safe base64
- Refresh tokens are JWTs starting with
eyJand are much longer - Tokens may have expired — try capturing fresh ones from the app
- Your refresh token has expired (this happens after ~1 year)
- Capture new tokens from the Ocado app using your proxy tool
- Check Settings → System → Logs for errors from
custom_components.ocado - The integration polls every 10 minutes — wait for the first update cycle
- Download diagnostics from the device page to inspect raw data
This integration uses a reverse-engineered, unofficial API. It is not affiliated with, endorsed by, or supported by Ocado Group plc. Use at your own risk.
Your tokens are stored locally in your Home Assistant config and are never sent to any third party. The integration only communicates with Ocado's own API servers.
MIT