---
title: "Distributions and summary statistics for a zoning category in a commune"
description: "Returns the per-parcel metric distributions, summary statistics, age cohorts, and raw scatter inputs that drive the `room` Aireon app. Backed by an in-memory LRU keyed on `${fso}:${cz_local}` (capacity 500, TTL 1 hour).\n\nServer-side rules:\n- Nulls are dropped before computing distributions and summary.\n- Hard outliers (above p99.5 or below p0.5 within the zone) are trimmed from `distributions[*]`; raw min/max stay in `summary`.\n- `parcels[]` is unfiltered.\n- `other_zones` lists every distinct `cz_local` in the same FSO except the queried one, sorted by parcel count desc."
---

> Documentation Index
> Fetch the complete documentation index at: https://docs.aireon.ch/llms.txt
> Use this file to discover all available pages before exploring further.

Path: RES API (public) › Parcel

`POST /res_api/zone_stats`

Returns the per-parcel metric distributions, summary statistics, age cohorts, and raw scatter inputs that drive the `room` Aireon app. Backed by an in-memory LRU keyed on `${fso}:${cz_local}` (capacity 500, TTL 1 hour).

Server-side rules:
- Nulls are dropped before computing distributions and summary.
- Hard outliers (above p99.5 or below p0.5 within the zone) are trimmed from `distributions[*]`; raw min/max stay in `summary`.
- `parcels[]` is unfiltered.
- `other_zones` lists every distinct `cz_local` in the same FSO except the queried one, sorted by parcel count desc.

## Authentication

- `ResApiToken`, apiKey, in header, header `token`

## Request body

_Required._

- `fso` (`getZoneStats.fso`; integer, required): BFS commune number - matches parcel_2025_07.fso_num_2021.
- `cz_local` (`getZoneStats.cz_local`; string, required): Local zoning category, e.g. "W3" or "Industrie- und Gewerbezone 2".
- `lang` (`getZoneStats.lang`; string, optional): Locale hint for any localisable labels. Currently echoed back as _lang.
  - one of `"de"`, `"en"`, `"fr"`, `"it"`

## Example requests

### Industrial zone in Kreuzlingen

```json
{
  "fso": 4671,
  "cz_local": "Industrie- und Gewerbezone 2",
  "lang": "de"
}
```

## Code samples

### cURL

```bash
curl --request POST \
  --url https://res.aireon.ch/res_api/zone_stats \
  --header 'Content-Type: application/json' \
  --header 'token: <token>' \
  --data '
{
  "fso": 4671,
  "cz_local": "Industrie- und Gewerbezone 2",
  "lang": "de"
}
'
```

### TypeScript

```typescript
const url = 'https://res.aireon.ch/res_api/zone_stats';
const options = {
  method: 'POST',
  headers: {'Content-Type': 'application/json', token: '<token>'},
  body: JSON.stringify({fso: 4671, cz_local: 'Industrie- und Gewerbezone 2', lang: 'de'})
};

fetch(url, options)
  .then(res => res.json())
  .then(json => console.log(json))
  .catch(err => console.error(err));
```

### Python

```python
import requests

url = "https://res.aireon.ch/res_api/zone_stats"

payload = {
    "fso": 4671,
    "cz_local": "Industrie- und Gewerbezone 2",
    "lang": "de"
}
headers = {
    "Content-Type": "application/json",
    "token": "<token>"
}

response = requests.post(url, json=payload, headers=headers)

print(response.text)
```

## Responses

### 200

Zone statistics payload.

#### Example

```json
{
  "zone": {
    "fso": 0,
    "municipality_name": "string",
    "cz_local": "string",
    "cz_canton": "string",
    "parcel_count": 0
  },
  "other_zones": [
    {
      "cz_local": "string",
      "parcel_count": 0
    }
  ],
  "distributions": {
    "ratio_s": [
      0
    ],
    "gfz": [
      0
    ],
    "bldg_height_m": [
      0
    ],
    "bldg_floors_n": [
      0
    ]
  },
  "summary": {
    "ratio_s": {
      "min": 0,
      "max": 0,
      "p5": 0,
      "p25": 0,
      "p50": 0,
      "p75": 0,
      "p95": 0,
      "mean": 0,
      "n": 0
    },
    "gfz": {
      "min": 0,
      "max": 0,
      "p5": 0,
      "p25": 0,
      "p50": 0,
      "p75": 0,
      "p95": 0,
      "mean": 0,
      "n": 0
    },
    "bldg_height_m": {
      "min": 0,
      "max": 0,
      "p5": 0,
      "p25": 0,
      "p50": 0,
      "p75": 0,
      "p95": 0,
      "mean": 0,
      "n": 0
    },
    "bldg_floors_n": {
      "min": 0,
      "max": 0,
      "p5": 0,
      "p25": 0,
      "p50": 0,
      "p75": 0,
      "p95": 0,
      "mean": 0,
      "n": 0
    }
  },
  "age_cohorts": {
    "now": {
      "cohort_label": "string",
      "n": 0,
      "p50_cz_util_now": 0,
      "p80_cz_util_now": 0,
      "n_cz_util_now": 0,
      "mean_cz_util_now": 0
    },
    "last60": {
      "cohort_label": "string",
      "n": 0,
      "p50_cz_util_now": 0,
      "p80_cz_util_now": 0,
      "n_cz_util_now": 0,
      "mean_cz_util_now": 0
    },
    "last40": {
      "cohort_label": "string",
      "n": 0,
      "p50_cz_util_now": 0,
      "p80_cz_util_now": 0,
      "n_cz_util_now": 0,
      "mean_cz_util_now": 0
    },
    "last20": {
      "cohort_label": "string",
      "n": 0,
      "p50_cz_util_now": 0,
      "p80_cz_util_now": 0,
      "n_cz_util_now": 0,
      "mean_cz_util_now": 0
    },
    "last15": {
      "cohort_label": "string",
      "n": 0,
      "p50_cz_util_now": 0,
      "p80_cz_util_now": 0,
      "n_cz_util_now": 0,
      "mean_cz_util_now": 0
    },
    "last10": {
      "cohort_label": "string",
      "n": 0,
      "p50_cz_util_now": 0,
      "p80_cz_util_now": 0,
      "n_cz_util_now": 0,
      "mean_cz_util_now": 0
    },
    "last5": {
      "cohort_label": "string",
      "n": 0,
      "p50_cz_util_now": 0,
      "p80_cz_util_now": 0,
      "n_cz_util_now": 0,
      "mean_cz_util_now": 0
    }
  },
  "parcels": [
    {
      "egrid": "string",
      "area": 0,
      "volume": 0,
      "year": 0
    }
  ],
  "_lang": "string"
}
```

- `zone` (`getZoneStats.response.200.zone`; object, required)
  - `fso` (`getZoneStats.response.200.zone.fso`; integer, required)
  - `cz_local` (`getZoneStats.response.200.zone.cz_local`; string, required)
  - `parcel_count` (`getZoneStats.response.200.zone.parcel_count`; integer, required)
  - `municipality_name` (`getZoneStats.response.200.zone.municipality_name`; string | null, optional)
  - `cz_canton` (`getZoneStats.response.200.zone.cz_canton`; string | null, optional)
- `other_zones` (`getZoneStats.response.200.other_zones`; array<object>, required): Sibling cz_local values in the same FSO, sorted by parcel count desc.
  - `cz_local` (`getZoneStats.response.200.other_zones.cz_local`; string, required)
  - `parcel_count` (`getZoneStats.response.200.other_zones.parcel_count`; integer, required)
- `distributions` (`getZoneStats.response.200.distributions`; object, required): Trimmed (p0.5–p99.5) per-parcel samples for each metric.
  - `ratio_s` (`getZoneStats.response.200.distributions.ratio_s`; array<number>, optional)
  - `gfz` (`getZoneStats.response.200.distributions.gfz`; array<number>, optional)
  - `bldg_height_m` (`getZoneStats.response.200.distributions.bldg_height_m`; array<number>, optional)
  - `bldg_floors_n` (`getZoneStats.response.200.distributions.bldg_floors_n`; array<number>, optional)
- `summary` (`getZoneStats.response.200.summary`; object, required)
  - `ratio_s` (`getZoneStats.response.200.summary.ratio_s`; object, optional): Summary statistics for one metric across the zone. Computed on the raw (non-trimmed) sample; min/max are honest to the underlying data.
    - `n` (`getZoneStats.response.200.summary.ratio_s.n`; integer, required)
    - `min` (`getZoneStats.response.200.summary.ratio_s.min`; number | null, optional)
    - `max` (`getZoneStats.response.200.summary.ratio_s.max`; number | null, optional)
    - `p5` (`getZoneStats.response.200.summary.ratio_s.p5`; number | null, optional)
    - `p25` (`getZoneStats.response.200.summary.ratio_s.p25`; number | null, optional)
    - `p50` (`getZoneStats.response.200.summary.ratio_s.p50`; number | null, optional)
    - `p75` (`getZoneStats.response.200.summary.ratio_s.p75`; number | null, optional)
    - `p95` (`getZoneStats.response.200.summary.ratio_s.p95`; number | null, optional)
    - `mean` (`getZoneStats.response.200.summary.ratio_s.mean`; number | null, optional)
  - `gfz` (`getZoneStats.response.200.summary.gfz`; object, optional): Summary statistics for one metric across the zone. Computed on the raw (non-trimmed) sample; min/max are honest to the underlying data.
    - `n` (`getZoneStats.response.200.summary.gfz.n`; integer, required)
    - `min` (`getZoneStats.response.200.summary.gfz.min`; number | null, optional)
    - `max` (`getZoneStats.response.200.summary.gfz.max`; number | null, optional)
    - `p5` (`getZoneStats.response.200.summary.gfz.p5`; number | null, optional)
    - `p25` (`getZoneStats.response.200.summary.gfz.p25`; number | null, optional)
    - `p50` (`getZoneStats.response.200.summary.gfz.p50`; number | null, optional)
    - `p75` (`getZoneStats.response.200.summary.gfz.p75`; number | null, optional)
    - `p95` (`getZoneStats.response.200.summary.gfz.p95`; number | null, optional)
    - `mean` (`getZoneStats.response.200.summary.gfz.mean`; number | null, optional)
  - `bldg_height_m` (`getZoneStats.response.200.summary.bldg_height_m`; object, optional): Summary statistics for one metric across the zone. Computed on the raw (non-trimmed) sample; min/max are honest to the underlying data.
    - `n` (`getZoneStats.response.200.summary.bldg_height_m.n`; integer, required)
    - `min` (`getZoneStats.response.200.summary.bldg_height_m.min`; number | null, optional)
    - `max` (`getZoneStats.response.200.summary.bldg_height_m.max`; number | null, optional)
    - `p5` (`getZoneStats.response.200.summary.bldg_height_m.p5`; number | null, optional)
    - `p25` (`getZoneStats.response.200.summary.bldg_height_m.p25`; number | null, optional)
    - `p50` (`getZoneStats.response.200.summary.bldg_height_m.p50`; number | null, optional)
    - `p75` (`getZoneStats.response.200.summary.bldg_height_m.p75`; number | null, optional)
    - `p95` (`getZoneStats.response.200.summary.bldg_height_m.p95`; number | null, optional)
    - `mean` (`getZoneStats.response.200.summary.bldg_height_m.mean`; number | null, optional)
  - `bldg_floors_n` (`getZoneStats.response.200.summary.bldg_floors_n`; object, optional): Summary statistics for one metric across the zone. Computed on the raw (non-trimmed) sample; min/max are honest to the underlying data.
    - `n` (`getZoneStats.response.200.summary.bldg_floors_n.n`; integer, required)
    - `min` (`getZoneStats.response.200.summary.bldg_floors_n.min`; number | null, optional)
    - `max` (`getZoneStats.response.200.summary.bldg_floors_n.max`; number | null, optional)
    - `p5` (`getZoneStats.response.200.summary.bldg_floors_n.p5`; number | null, optional)
    - `p25` (`getZoneStats.response.200.summary.bldg_floors_n.p25`; number | null, optional)
    - `p50` (`getZoneStats.response.200.summary.bldg_floors_n.p50`; number | null, optional)
    - `p75` (`getZoneStats.response.200.summary.bldg_floors_n.p75`; number | null, optional)
    - `p95` (`getZoneStats.response.200.summary.bldg_floors_n.p95`; number | null, optional)
    - `mean` (`getZoneStats.response.200.summary.bldg_floors_n.mean`; number | null, optional)
- `age_cohorts` (`getZoneStats.response.200.age_cohorts`; object, required): Mean, p50 and p80 of cz_util_now (utilization) per building-age cohort, widest window first. Seven precision steps: the all-years baseline plus six trailing windows (60/40/20/15/10/5 years). The 15/10/5 steps were added 2026-08-24. Windows are relative to the current year. Each cohort carries `n` - the narrower the window the thinner the sample, so read `n` before trusting a cohort mean.
  - `now` (`getZoneStats.response.200.age_cohorts.now`; object, optional): One age cohort of the zone, on utilization: the mean, p50 and p80 of cz_util_now (gfa_now / parcel_area, the floor-area utilization) over the same parcels, with n_cz_util_now as their sample size. mean_cz_util_now was added in v0.0.323. The deprecated mean_ratio_v (not utilization) was removed in v0.0.324.
    - `cohort_label` (`getZoneStats.response.200.age_cohorts.now.cohort_label`; string, required)
    - `n` (`getZoneStats.response.200.age_cohorts.now.n`; integer, required)
    - `p50_cz_util_now` (`getZoneStats.response.200.age_cohorts.now.p50_cz_util_now`; number | null, optional): Median cz_util_now (gfa_now / parcel_area) of the cohort, percentile_cont(0.5). Null when n_cz_util_now is 0.
    - `p80_cz_util_now` (`getZoneStats.response.200.age_cohorts.now.p80_cz_util_now`; number | null, optional): 80th percentile of cz_util_now of the cohort, percentile_cont(0.8). Null when n_cz_util_now is 0.
    - `n_cz_util_now` (`getZoneStats.response.200.age_cohorts.now.n_cz_util_now`; integer, optional): Parcels in the cohort with a usable cz_util_now (the sample behind the mean and the two percentiles).
    - `mean_cz_util_now` (`getZoneStats.response.200.age_cohorts.now.mean_cz_util_now`; number | null, optional): Mean cz_util_now (gfa_now / parcel_area) of the cohort, over the same rows as the percentiles (weight: n_cz_util_now). Null when n_cz_util_now is 0.
  - `last60` (`getZoneStats.response.200.age_cohorts.last60`; object, optional): One age cohort of the zone, on utilization: the mean, p50 and p80 of cz_util_now (gfa_now / parcel_area, the floor-area utilization) over the same parcels, with n_cz_util_now as their sample size. mean_cz_util_now was added in v0.0.323. The deprecated mean_ratio_v (not utilization) was removed in v0.0.324.
    - `cohort_label` (`getZoneStats.response.200.age_cohorts.last60.cohort_label`; string, required)
    - `n` (`getZoneStats.response.200.age_cohorts.last60.n`; integer, required)
    - `p50_cz_util_now` (`getZoneStats.response.200.age_cohorts.last60.p50_cz_util_now`; number | null, optional): Median cz_util_now (gfa_now / parcel_area) of the cohort, percentile_cont(0.5). Null when n_cz_util_now is 0.
    - `p80_cz_util_now` (`getZoneStats.response.200.age_cohorts.last60.p80_cz_util_now`; number | null, optional): 80th percentile of cz_util_now of the cohort, percentile_cont(0.8). Null when n_cz_util_now is 0.
    - `n_cz_util_now` (`getZoneStats.response.200.age_cohorts.last60.n_cz_util_now`; integer, optional): Parcels in the cohort with a usable cz_util_now (the sample behind the mean and the two percentiles).
    - `mean_cz_util_now` (`getZoneStats.response.200.age_cohorts.last60.mean_cz_util_now`; number | null, optional): Mean cz_util_now (gfa_now / parcel_area) of the cohort, over the same rows as the percentiles (weight: n_cz_util_now). Null when n_cz_util_now is 0.
  - `last40` (`getZoneStats.response.200.age_cohorts.last40`; object, optional): One age cohort of the zone, on utilization: the mean, p50 and p80 of cz_util_now (gfa_now / parcel_area, the floor-area utilization) over the same parcels, with n_cz_util_now as their sample size. mean_cz_util_now was added in v0.0.323. The deprecated mean_ratio_v (not utilization) was removed in v0.0.324.
    - `cohort_label` (`getZoneStats.response.200.age_cohorts.last40.cohort_label`; string, required)
    - `n` (`getZoneStats.response.200.age_cohorts.last40.n`; integer, required)
    - `p50_cz_util_now` (`getZoneStats.response.200.age_cohorts.last40.p50_cz_util_now`; number | null, optional): Median cz_util_now (gfa_now / parcel_area) of the cohort, percentile_cont(0.5). Null when n_cz_util_now is 0.
    - `p80_cz_util_now` (`getZoneStats.response.200.age_cohorts.last40.p80_cz_util_now`; number | null, optional): 80th percentile of cz_util_now of the cohort, percentile_cont(0.8). Null when n_cz_util_now is 0.
    - `n_cz_util_now` (`getZoneStats.response.200.age_cohorts.last40.n_cz_util_now`; integer, optional): Parcels in the cohort with a usable cz_util_now (the sample behind the mean and the two percentiles).
    - `mean_cz_util_now` (`getZoneStats.response.200.age_cohorts.last40.mean_cz_util_now`; number | null, optional): Mean cz_util_now (gfa_now / parcel_area) of the cohort, over the same rows as the percentiles (weight: n_cz_util_now). Null when n_cz_util_now is 0.
  - `last20` (`getZoneStats.response.200.age_cohorts.last20`; object, optional): One age cohort of the zone, on utilization: the mean, p50 and p80 of cz_util_now (gfa_now / parcel_area, the floor-area utilization) over the same parcels, with n_cz_util_now as their sample size. mean_cz_util_now was added in v0.0.323. The deprecated mean_ratio_v (not utilization) was removed in v0.0.324.
    - `cohort_label` (`getZoneStats.response.200.age_cohorts.last20.cohort_label`; string, required)
    - `n` (`getZoneStats.response.200.age_cohorts.last20.n`; integer, required)
    - `p50_cz_util_now` (`getZoneStats.response.200.age_cohorts.last20.p50_cz_util_now`; number | null, optional): Median cz_util_now (gfa_now / parcel_area) of the cohort, percentile_cont(0.5). Null when n_cz_util_now is 0.
    - `p80_cz_util_now` (`getZoneStats.response.200.age_cohorts.last20.p80_cz_util_now`; number | null, optional): 80th percentile of cz_util_now of the cohort, percentile_cont(0.8). Null when n_cz_util_now is 0.
    - `n_cz_util_now` (`getZoneStats.response.200.age_cohorts.last20.n_cz_util_now`; integer, optional): Parcels in the cohort with a usable cz_util_now (the sample behind the mean and the two percentiles).
    - `mean_cz_util_now` (`getZoneStats.response.200.age_cohorts.last20.mean_cz_util_now`; number | null, optional): Mean cz_util_now (gfa_now / parcel_area) of the cohort, over the same rows as the percentiles (weight: n_cz_util_now). Null when n_cz_util_now is 0.
  - `last15` (`getZoneStats.response.200.age_cohorts.last15`; object, optional): One age cohort of the zone, on utilization: the mean, p50 and p80 of cz_util_now (gfa_now / parcel_area, the floor-area utilization) over the same parcels, with n_cz_util_now as their sample size. mean_cz_util_now was added in v0.0.323. The deprecated mean_ratio_v (not utilization) was removed in v0.0.324.
    - `cohort_label` (`getZoneStats.response.200.age_cohorts.last15.cohort_label`; string, required)
    - `n` (`getZoneStats.response.200.age_cohorts.last15.n`; integer, required)
    - `p50_cz_util_now` (`getZoneStats.response.200.age_cohorts.last15.p50_cz_util_now`; number | null, optional): Median cz_util_now (gfa_now / parcel_area) of the cohort, percentile_cont(0.5). Null when n_cz_util_now is 0.
    - `p80_cz_util_now` (`getZoneStats.response.200.age_cohorts.last15.p80_cz_util_now`; number | null, optional): 80th percentile of cz_util_now of the cohort, percentile_cont(0.8). Null when n_cz_util_now is 0.
    - `n_cz_util_now` (`getZoneStats.response.200.age_cohorts.last15.n_cz_util_now`; integer, optional): Parcels in the cohort with a usable cz_util_now (the sample behind the mean and the two percentiles).
    - `mean_cz_util_now` (`getZoneStats.response.200.age_cohorts.last15.mean_cz_util_now`; number | null, optional): Mean cz_util_now (gfa_now / parcel_area) of the cohort, over the same rows as the percentiles (weight: n_cz_util_now). Null when n_cz_util_now is 0.
  - `last10` (`getZoneStats.response.200.age_cohorts.last10`; object, optional): One age cohort of the zone, on utilization: the mean, p50 and p80 of cz_util_now (gfa_now / parcel_area, the floor-area utilization) over the same parcels, with n_cz_util_now as their sample size. mean_cz_util_now was added in v0.0.323. The deprecated mean_ratio_v (not utilization) was removed in v0.0.324.
    - `cohort_label` (`getZoneStats.response.200.age_cohorts.last10.cohort_label`; string, required)
    - `n` (`getZoneStats.response.200.age_cohorts.last10.n`; integer, required)
    - `p50_cz_util_now` (`getZoneStats.response.200.age_cohorts.last10.p50_cz_util_now`; number | null, optional): Median cz_util_now (gfa_now / parcel_area) of the cohort, percentile_cont(0.5). Null when n_cz_util_now is 0.
    - `p80_cz_util_now` (`getZoneStats.response.200.age_cohorts.last10.p80_cz_util_now`; number | null, optional): 80th percentile of cz_util_now of the cohort, percentile_cont(0.8). Null when n_cz_util_now is 0.
    - `n_cz_util_now` (`getZoneStats.response.200.age_cohorts.last10.n_cz_util_now`; integer, optional): Parcels in the cohort with a usable cz_util_now (the sample behind the mean and the two percentiles).
    - `mean_cz_util_now` (`getZoneStats.response.200.age_cohorts.last10.mean_cz_util_now`; number | null, optional): Mean cz_util_now (gfa_now / parcel_area) of the cohort, over the same rows as the percentiles (weight: n_cz_util_now). Null when n_cz_util_now is 0.
  - `last5` (`getZoneStats.response.200.age_cohorts.last5`; object, optional): One age cohort of the zone, on utilization: the mean, p50 and p80 of cz_util_now (gfa_now / parcel_area, the floor-area utilization) over the same parcels, with n_cz_util_now as their sample size. mean_cz_util_now was added in v0.0.323. The deprecated mean_ratio_v (not utilization) was removed in v0.0.324.
    - `cohort_label` (`getZoneStats.response.200.age_cohorts.last5.cohort_label`; string, required)
    - `n` (`getZoneStats.response.200.age_cohorts.last5.n`; integer, required)
    - `p50_cz_util_now` (`getZoneStats.response.200.age_cohorts.last5.p50_cz_util_now`; number | null, optional): Median cz_util_now (gfa_now / parcel_area) of the cohort, percentile_cont(0.5). Null when n_cz_util_now is 0.
    - `p80_cz_util_now` (`getZoneStats.response.200.age_cohorts.last5.p80_cz_util_now`; number | null, optional): 80th percentile of cz_util_now of the cohort, percentile_cont(0.8). Null when n_cz_util_now is 0.
    - `n_cz_util_now` (`getZoneStats.response.200.age_cohorts.last5.n_cz_util_now`; integer, optional): Parcels in the cohort with a usable cz_util_now (the sample behind the mean and the two percentiles).
    - `mean_cz_util_now` (`getZoneStats.response.200.age_cohorts.last5.mean_cz_util_now`; number | null, optional): Mean cz_util_now (gfa_now / parcel_area) of the cohort, over the same rows as the percentiles (weight: n_cz_util_now). Null when n_cz_util_now is 0.
- `parcels` (`getZoneStats.response.200.parcels`; array<object>, required): Unfiltered per-parcel scatter input - egrid, parcel area, built volume, latest construction year.
  - `egrid` (`getZoneStats.response.200.parcels.egrid`; string, optional)
  - `area` (`getZoneStats.response.200.parcels.area`; number | null, optional)
  - `volume` (`getZoneStats.response.200.parcels.volume`; number | null, optional)
  - `year` (`getZoneStats.response.200.parcels.year`; integer | null, optional)
- `_lang` (`getZoneStats.response.200._lang`; string | null, optional)

### 400

Missing or invalid `fso` / `cz_local`.

#### Example

```json
{
  "error": "string",
  "message": "string"
}
```

- `error` (`getZoneStats.response.400.error`; string, required): Human-readable error description.
- `message` (`getZoneStats.response.400.message`; string, optional): Optional underlying error message.

### 401

Missing token.

#### Example

```json
{
  "error": "string",
  "message": "string"
}
```

- `error` (`getZoneStats.response.401.error`; string, required): Human-readable error description.
- `message` (`getZoneStats.response.401.message`; string, optional): Optional underlying error message.

### 403

Wrong token.

#### Example

```json
{
  "error": "string",
  "message": "string"
}
```

- `error` (`getZoneStats.response.403.error`; string, required): Human-readable error description.
- `message` (`getZoneStats.response.403.message`; string, optional): Optional underlying error message.

### 500

Server error.

#### Example

```json
{
  "error": "string",
  "message": "string"
}
```

- `error` (`getZoneStats.response.500.error`; string, required): Human-readable error description.
- `message` (`getZoneStats.response.500.message`; string, optional): Optional underlying error message.


Source: https://docs.aireon.ch/res/get-zone-stats/index.md
