Live occupancy
Show how full your lots, zones and parking places are, and keep the numbers live. This guide covers the counts, the per-place status, the realtime events, history and analytics, and public lot share views.
Prerequisites
- An API token; see Authentication.
- A source of occupancy on the lot. Parking detection (cameras or sensors) is set up by Parklio technicians; you read the results, you don't configure detection. LPR cameras and payment machines also move the counts as vehicles enter and leave.
- For per-place status and history: the
PARKING_DETECTIONfeature; see Plans and permissions.
Where the numbers come from
| Level | Fields | Updated by |
|---|---|---|
| Lot | spot_count, occupied_count | Every change in one of its zones |
| Zone | spot_count, occupied_count | Detection sensors, LPR entries and exits, payment machines |
| Parking place | occupancy_status: free, occupied or unknown | Detection sensors only |
- Counts move by one on each entry or exit, and are kept between
0andspot_count. - On lots with parking detection, Parklio also recounts every 5 minutes from the
parking places: a zone's
occupied_countbecomes the number of its places that aren'tfree, and the lot's becomes the sum of its zones. - Free spaces =
spot_count−occupied_count.
1. Read the counts
curl -s "https://api.parklio.com/v2/zones?filter=lot_id:eq:7&size=100" \
-H "Authorization: Bearer $PARKLIO_API_TOKEN"
{
"id": 9,
"lot_id": 7,
"name": "Level -1",
"spot_count": 120,
"occupied_count": 42
}
The lot totals are on GET /v2/lots/{id}.
2. Read parking places
With parking detection, each space is a parking place with its own status:
curl -s "https://api.parklio.com/v2/parking-places?filter=zone_id:eq:9&filter=occupancy_status:eq:occupied&size=300" \
-H "Authorization: Bearer $PARKLIO_API_TOKEN"
GET /v2/parking-places can also filter by
lot_id, name, uuid and external_id. Without the PARKING_DETECTION feature,
every place's occupancy_status reads unknown.
3. Keep it live
Each time a detection sensor sees a change, three events arrive, in this order:
| Event | Contains |
|---|---|
lot_detection_change | The lot's new occupied_count |
zone_change | The zone, with spot_count and occupied_count |
parking_place_change | The place and its occupancy_status |
Shapes are in Events.
const zones = new Map<number, { spot_count: number; occupied_count: number }>();
socket.on('zone_change', (raw: string) => {
for (const zone of JSON.parse(raw).zones) {
zones.set(zone.id, { spot_count: zone.spot_count, occupied_count: zone.occupied_count });
render(zone.id); // your UI
}
});
function render(zoneId: number) {
const zone = zones.get(zoneId);
if (zone) console.log(`zone ${zoneId}: ${zone.spot_count - zone.occupied_count} free`);
}
:::warning Not every change is pushed Count changes from LPR entries and exits and payment machines, and the 5-minute recount, send no event. If your lots count vehicles that way, re-read the zones every minute or so, as well as listening for events. Always re-read after a reconnect. :::
4. Set counts from your own system
If you count vehicles yourself, you can write a zone's counts with
PATCH /v2/zones/{id}; the lot follows by the
difference:
curl -s -X PATCH https://api.parklio.com/v2/zones/9 \
-H "Authorization: Bearer $PARKLIO_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"occupied_count": 40}'
- Keep
occupied_countat or belowspot_countyourself; this call doesn't enforce it. - On lots with parking detection, the 5-minute recount overwrites what you set.
- Lot counts can't be set directly.
5. History and analytics
GET /v2/parking-place-changes: every status change of every place, with itsdurationin seconds. Filter bylot_id,zone_id,parking_place_id,occupancy_statusorcreated_at; export as CSV. NeedsPARKING_DETECTION.GET /v2/parking-analytics: average and total occupancy duration, turnover and peak hour, per lot, zone or place, over a date range, optionally per hour, day or month. Every option is afilter:
curl -s "https://api.parklio.com/v2/parking-analytics?filter=metric:eq:turnover_rate&filter=scope:eq:zone&filter=interval:eq:day&filter=lot_ids:eq:7&filter=created_at:gte:2026-03-01T00:00:00.000Z&filter=created_at:lte:2026-04-01T00:00:00.000Z" \
-H "Authorization: Bearer $PARKLIO_API_TOKEN"
lot_ids, zone_ids and parking_place_ids take comma-separated ids, such as
lot_ids:eq:7,8. Metrics: average_duration, average_duration_percentage, total_duration,
turnover_rate and peak_occupancy_hour (which can't be combined with interval).
6. Share a live view
A lot share view is a public web page showing live occupancy for some zones of a lot, with no login. Use it for a screen at the entrance, or a link on your website.
curl -s -X POST https://api.parklio.com/v2/lot-share-views \
-H "Authorization: Bearer $PARKLIO_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"lot_id": 7, "zone_ids": [9, 10], "lot_share_view_type": "counts_only"}'
- The response's
urlis the public page. Anyone with it can see the page, so share it as you would a password. lot_share_view_type:counts_only(free, occupied and total per zone),live_camera(adds a camera frame; needs a parking-detection camera in a zone) orvector_map(adds a map of the places; needs zones with a map).- Add
?navbar=hiddenor?darkmode=trueto the URL to change how it looks. - To turn a link off, revoke it:
PATCH /v2/lot-share-views/{id}with{"revoked": true}. The page then returns 404.
Verify it worked
GET /v2/zones?filter=lot_id:eq:<lot>showsspot_countandoccupied_countfor each zone.- Park a car on a detected space:
lot_detection_change,zone_changeandparking_place_changearrive, andoccupied_countis one higher. - The share view's
urlopens in a browser without logging in.
Common errors
| Symptom | Cause | Fix |
|---|---|---|
Every place is unknown | No PARKING_DETECTION feature. | See Plans and permissions. |
| Counts change but no event arrives | The change came from LPR, a payment machine or the recount. | Poll zones as well (step 3). |
| A count you set came back different | The 5-minute recount on a detection lot. | Don't set counts on detection lots. |
403 code 30 on place history | No PARKING_DETECTION feature. | As above. |
400 code 33 | A filter that endpoint doesn't accept. | Check the endpoint's filters. |
| Share view returns 404 | It was revoked. | Create a new one. |