---
title: "Clipped swissSURFACE3D point cloud as GeoJSON points"
description: "Proxy for the Contoor 3D API (`project_res_3D_api`, FastAPI, systemd unit `contoor-3d-api` on the RES box, published at contoor-api-contabo.gisjoe.com). RES adds the RES token, the request allowlist and RES-hosted artifact URLs so one contract and one credential cover parcels and meshes.\n\nClips the swissSURFACE3D LiDAR tile(s) to a square of ± `bbox_radius_m` around the point, optionally filtered by LAS class, and returns the points as a GeoJSON FeatureCollection (WGS84 point features with elevation and class/height colour attributes). Large radii produce very large answers - start with 30–50 m. Proxy timeout 180 s (a first request for a tile downloads ~180 MB upstream)."
---

> 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) › Building3D

`POST /res_api/3d/pointcloud`

Proxy for the Contoor 3D API (`project_res_3D_api`, FastAPI, systemd unit `contoor-3d-api` on the RES box, published at contoor-api-contabo.gisjoe.com). RES adds the RES token, the request allowlist and RES-hosted artifact URLs so one contract and one credential cover parcels and meshes.

Clips the swissSURFACE3D LiDAR tile(s) to a square of ± `bbox_radius_m` around the point, optionally filtered by LAS class, and returns the points as a GeoJSON FeatureCollection (WGS84 point features with elevation and class/height colour attributes). Large radii produce very large answers - start with 30–50 m. Proxy timeout 180 s (a first request for a tile downloads ~180 MB upstream).

## Authentication

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

## Request body

_Required._

- `lat` (`getPointCloud.lat`; number, required): WGS84 latitude (inside Switzerland).
- `lng` (`getPointCloud.lng`; number, required): WGS84 longitude (inside Switzerland).
- `bbox_radius_m` (`getPointCloud.bbox_radius_m`; number, optional)
  - min 10; max 1000; default `50`
- `selected_classes` (`getPointCloud.selected_classes`; array<string>, optional): LAS classes to keep; omit for all points.
  - one of `"ground"`, `"vegetation"`, `"tree"`, `"trees"`, `"buildings"`
- `color_by` (`getPointCloud.color_by`; string, optional)
  - one of `"class"`, `"height"`; default `"class"`

## Example request

```json
{
  "lat": 47.640269,
  "lng": 9.193094,
  "bbox_radius_m": 30,
  "selected_classes": [
    "buildings"
  ]
}
```

## Code samples

### cURL

```bash
curl --request POST \
  --url https://res.aireon.ch/res_api/3d/pointcloud \
  --header 'Content-Type: application/json' \
  --header 'token: <token>' \
  --data '
{
  "lat": 47.640269,
  "lng": 9.193094,
  "bbox_radius_m": 30,
  "selected_classes": [
    "buildings"
  ]
}
'
```

### TypeScript

```typescript
const url = 'https://res.aireon.ch/res_api/3d/pointcloud';
const options = {
  method: 'POST',
  headers: {'Content-Type': 'application/json', token: '<token>'},
  body: JSON.stringify({
    lat: 47.640269,
    lng: 9.193094,
    bbox_radius_m: 30,
    selected_classes: ['buildings']
  })
};

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/3d/pointcloud"

payload = {
    "lat": 47.640269,
    "lng": 9.193094,
    "bbox_radius_m": 30,
    "selected_classes": ["buildings"]
}
headers = {
    "Content-Type": "application/json",
    "token": "<token>"
}

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

print(response.text)
```

## Responses

### 200

GeoJSON FeatureCollection of points.

#### Example

```json
{}
```

### 400

Invalid request.

#### Example

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

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

### 401

Authentication missing or invalid.

#### Example

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

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

### 403

Authenticated but not permitted.

#### Example

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

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

### 502

The 3D service is unreachable or answered with an error (its status and body are relayed in `upstream_status` / `upstream`).

#### Example

```json
{
  "error": "string",
  "upstream_status": 0,
  "upstream": null,
  "detail": "string"
}
```

- `error` (`getPointCloud.response.502.error`; string, optional)
- `upstream_status` (`getPointCloud.response.502.upstream_status`; integer, optional)
- `upstream` (`getPointCloud.response.502.upstream`; unknown, optional)
- `detail` (`getPointCloud.response.502.detail`; string, optional)

### 504

The 3D service did not answer within the proxy timeout.

#### Example

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

- `error` (`getPointCloud.response.504.error`; string, optional)
- `detail` (`getPointCloud.response.504.detail`; string, optional)


Source: https://docs.aireon.ch/res/get-point-cloud/index.md
