Skip to main content

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_DETECTION feature; see Plans and permissions.

Where the numbers come from​

LevelFieldsUpdated by
Lotspot_count, occupied_countEvery change in one of its zones
Zonespot_count, occupied_countDetection sensors, LPR entries and exits, payment machines
Parking placeoccupancy_status: free, occupied or unknownDetection sensors only
  • Counts move by one on each entry or exit, and are kept between 0 and spot_count.
  • On lots with parking detection, Parklio also recounts every 5 minutes from the parking places: a zone's occupied_count becomes the number of its places that aren't free, and the lot's becomes the sum of its zones.
  • Free spaces = spot_count − occupied_count.

1. Read the counts​

All zones of lot 7
curl -s "https://api.parklio.com/v2/zones?filter=lot_id:eq:7&size=100" \
-H "Authorization: Bearer $PARKLIO_API_TOKEN"
One zone in the response
{
"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:

Occupied places in zone 9
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:

EventContains
lot_detection_changeThe lot's new occupied_count
zone_changeThe zone, with spot_count and occupied_count
parking_place_changeThe place and its occupancy_status

Shapes are in Events.

live-occupancy.ts
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:

Set zone 9 to 40 occupied
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_count at or below spot_count yourself; 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 its duration in seconds. Filter by lot_id, zone_id, parking_place_id, occupancy_status or created_at; export as CSV. Needs PARKING_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 a filter:
Daily turnover per zone for March
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.

Create a share view
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 url is 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) or vector_map (adds a map of the places; needs zones with a map).
  • Add ?navbar=hidden or ?darkmode=true to 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​

  1. GET /v2/zones?filter=lot_id:eq:<lot> shows spot_count and occupied_count for each zone.
  2. Park a car on a detected space: lot_detection_change, zone_change and parking_place_change arrive, and occupied_count is one higher.
  3. The share view's url opens in a browser without logging in.

Common errors​

SymptomCauseFix
Every place is unknownNo PARKING_DETECTION feature.See Plans and permissions.
Counts change but no event arrivesThe change came from LPR, a payment machine or the recount.Poll zones as well (step 3).
A count you set came back differentThe 5-minute recount on a detection lot.Don't set counts on detection lots.
403 code 30 on place historyNo PARKING_DETECTION feature.As above.
400 code 33A filter that endpoint doesn't accept.Check the endpoint's filters.
Share view returns 404It was revoked.Create a new one.

Next​