Read API
The dashboard itself uses only the read API, so everything it shows is also available to you. The API returns totals
only, never single page views or visitor hashes. The full description is at /api/v1/openapi.json on your dashboard
address.
Get a key
Section titled “Get a key”In the dashboard settings, or on the server:
docker compose run --rm ingest token:create homeassistant --scope read --site myblogIt prints Key 1 created. Key (shown once): and a key starting with lk_. A read key can read reports; an admin
key can also change settings and keys. --site limits the key to one site.
Send it in the Authorization header:
curl -H "Authorization: Bearer lk_…" "http://192.168.1.10:8788/api/v1/sites/myblog/summary?range=7d"The API is on the dashboard’s address, so the same rules apply: LOOKU_API_HOSTS, LOOKU_API_ALLOW and, on a home
server, your home network.
Reports
Section titled “Reports”All report paths start with /api/v1/sites/<site>/. Choose the period with range (24h is the last 24 hours up
to now; 7d, 28d, 3m and 12m end today in the site’s time zone; default 28d), with from and to
(YYYY-MM-DD), or with a time window since and until (ISO 8601 times, at most 31 days apart). With a time window,
reading time and cart events, which are kept by day only, cover the whole days the window touches.
Paths are returned decoded, as people read them: /opas/lämpö, not /opas/l%C3%A4mp%C3%B6.
| Path | Returns |
|---|---|
summary |
page views, visitors, sessions, pages per session; compare=previous adds the previous period |
timeseries |
totals per interval: hour (at most 31 days), day, week or month |
breakdown/<dimension> |
totals by page, entry, exit, referrer, utm_source, utm_medium, utm_campaign, device, browser, os, country or page_group; limit (default 50), sort |
reports/<module>/<report> |
module reports: perus/missing (addresses the site answered with “not found”, see Pages that do not exist; limit), shop/summary, shop/timeseries, shop/funnel, shop/products, campaigns/overview, content/engagement, content/rising. Only for modules that are on for the site (site:modules); otherwise the answer is Unknown report. |
export.csv?report=… |
any of the above as CSV |
summary, timeseries and breakdown also take filters. page (one page path), page_group, device and
country keep the page views that match. referrer (a host such as www.google.com, empty for direct),
utm_source and utm_campaign keep whole sessions that started with that value, so breakdown/page?referrer=…
lists every page those visitors saw.
Every answer has meta (site, time zone, period) and data. When meta.sample is true, the numbers come only from
consenting visitors (reading time).
Other paths
Section titled “Other paths”| Path | |
|---|---|
GET /api/v1/health |
status and version, no key needed |
GET /api/v1/sites |
sites this key can read, with the time of each site’s newest page view (last_pageview) |
GET /api/v1/modules |
modules and their reports |
GET /api/v1/me |
what the current key may do |
GET, PUT /api/v1/sites/<site>/config |
dashboard settings of a site (PUT needs an admin key) |
GET, POST /api/v1/tokens, DELETE /api/v1/tokens/<id> |
manage keys (admin) |
Home Assistant example
Section titled “Home Assistant example”For sensors of every site, use the Looku integration
(ha-looku on GitHub). Without it, a sensor for the
last seven days’ page views, in configuration.yaml:
rest: - resource: http://192.168.1.10:8788/api/v1/sites/myblog/summary?range=7d headers: Authorization: !secret looku_key scan_interval: 900 sensor: - name: Looku page views 7 days value_template: "{{ value_json.data.pageviews }}"and in secrets.yaml: looku_key: "Bearer lk_…". The summary answer looks like this (shortened), so other fields work the
same way (value_json.data.visitors):
{"meta":{"site":"myblog","timezone":"Europe/Helsinki","range":{"from":"2026-10-28","to":"2026-11-03"},"sample":false}, "data":{"pageviews":412,"visitors":198,"sessions":231,"pages_per_session":1.8}}