Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 15 additions & 5 deletions config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ unsafe = true
weight = 1
[[menu.main]]
identifier = "api_reference"
title = "Core API Reference"
title = "Core API"
pre = "<span class='bp3-icon bp3-icon-code'></span>"
weight = 2
[[menu.main]]
identifier = "chart_api_reference"
title = "Chart API Reference"
title = "Chart API"
pre = "<span class='bp3-icon bp3-icon-map'></span>"
weight = 3
[[menu.main]]
Expand All @@ -41,16 +41,26 @@ unsafe = true
weight = 1
[[menu.oem]]
identifier = "portal_api_reference"
title = "Vector Charts Portal"
title = "Admin API"
pre = "<span class='bp3-icon bp3-icon-code'></span>"
weight = 2
[[menu.oem]]
identifier = "api_reference"
title = "Vector Charts Core"
title = "Core API"
pre = "<span class='bp3-icon bp3-icon-code'></span>"
weight = 3
[[menu.oem]]
identifier = "examples"
title = "Examples"
pre = "<span class='bp3-icon bp3-icon-learning'></span>"
weight = 3
weight = 4
[[menu.crowdsourced]]
identifier = "getting_started"
title = "Getting Started"
pre = "<span class='bp3-icon bp3-icon-learning'></span>"
weight = 1
[[menu.crowdsourced]]
identifier = "user_report_api_reference"
title = "User Report API"
pre = "<span class='bp3-icon bp3-icon-code'></span>"
weight = 2
41 changes: 41 additions & 0 deletions content/crowdsourced-data/_index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
---
title: "Crowdsourced Data API"
weight: 1
menu:
crowdsourced:
title: "Overview"
parent: "getting_started"
weight: 1
---

Crowdsourced data lets end users contribute location-based observations that other users can discover, validate, and act on. Vector Charts currently supports this through **user reports**: spatially-defined suggestions about chart data submitted at a specific latitude and longitude.

User reports are available on both **Vector Charts Cloud** and **Vector Charts OEM**. The REST API and WebSocket event format are the same on both platforms; only the base URL differs.

Each deployment is configured with a **namespace** (default `public`). All reports created on that instance belong to its namespace. When replicating between OEM peers, only reports in matching namespaces are exchanged.

## Base URLs

| Platform | Base URL |
|----------|----------|
| Cloud | `https://api.vectorcharts.com` |
| OEM | `https://<your-host>:9909` |

All paths in the [User Report API](/crowdsourced-data/user-report-api-reference/) are relative to the base URL for your deployment.

## What You Can Build

- Let users flag hazards, data quality issues, incidents, closures, or SOS situations on the chart
- Display nearby reports as GeoJSON tile overlays on a slippy map
- Let users vote reports up or down to surface consensus
- Receive streaming updates when reports are created, updated, deleted, or expired

## Next Steps

- [Submitting User Data](/crowdsourced-data/getting-started/submitting-user-data/) — integration patterns for client applications
- [Streaming Events](/crowdsourced-data/getting-started/streaming-events/) — WebSocket event format
- [User Report API](/crowdsourced-data/user-report-api-reference/) — endpoint reference

## Authentication

User report endpoints require a valid API token on both Cloud and OEM. See [Cloud authentication](/api-reference/api-authentication/) or the [OEM Core API overview](/oem/api-reference/) for how to pass tokens in headers or query parameters.
59 changes: 59 additions & 0 deletions content/crowdsourced-data/getting-started/streaming-events.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
---
title: "Streaming Events"
weight: 3
menu:
crowdsourced:
title: "Streaming Events"
parent: "getting_started"
weight: 3
---

The Realtime API delivers JSON event messages over WebSocket when user reports are created, updated, deleted, or expired. This is available on both Vector Charts Cloud and Vector Charts OEM.

## Connection

Connect to:

<pre>
wss://api.vectorcharts.com/api/v1/realtime?token=&lt;token string&gt;
</pre>

On OEM, replace the host with your instance URL (for example, `wss://&lt;your-host&gt;:9909/api/v1/realtime?token=&lt;token string&gt;`).

Authentication uses the same API token as REST endpoints, passed as the `token` query parameter. Unauthenticated connections are rejected.

## Message Format

Each message is a JSON object:

<pre>
{
"type": "event_user_report",
"data": {
"action": "created",
"report": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"reportType": "hazard",
"latitude": 42.36,
"longitude": -71.05,
"properties": {},
"validVoteCount": 0,
"invalidVoteCount": 0,
"externalUserId": "app-user-abc123",
"namespace": "public",
"createdAt": 1718380800000,
"updatedAt": 1718380800000,
"expiredAt": null,
"deletedAt": null
}
},
"eventAt": 1718380800000
}
</pre>

- **type**: Event namespace. User report events use `event_user_report`.
- **data.action**: One of `created`, `updated`, `deleted`, or `expired`.
- **data.report**: Full report object with vote counts, matching the [User Report API](/crowdsourced-data/user-report-api-reference/) schema.
- **eventAt**: Event timestamp in milliseconds since Unix epoch.

Future event types may use different `type` values on the same WebSocket connection.
43 changes: 43 additions & 0 deletions content/crowdsourced-data/getting-started/submitting-user-data.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
title: "Submitting User Data"
weight: 2
menu:
crowdsourced:
title: "Submitting User Data"
parent: "getting_started"
weight: 2
---

This guide covers the typical client workflow for crowdsourced user reports on Cloud and OEM.

## 1. Create a Report

When a user marks a location on the chart, call [Create User Report](/crowdsourced-data/user-report-api-reference/create/) with:

- **reportType** — category string (for example `hazard`)
- **position** — `{ latitude, longitude }` in WGS84 decimal degrees (request body only)
- **properties** (optional) — free-form JSON such as a description or heading
- **externalUserId** (optional) — your app's user identifier (not used for authorization)
- **id** (optional) — a client-generated UUID version 4 for offline-first sync

The server returns the report with vote counts initialized to zero. Reports expire after the configured `expirationAgeMs` (default 24 hours).

## 2. Display Reports on the Map

Fetch reports for the current viewport using [Get User Reports MVT Tile](/crowdsourced-data/user-report-api-reference/tile-mvt/). The vector chart style includes this source automatically and renders reports with an alert icon. Each point feature carries the full report attributes for popups and inspection.

For GeoJSON polling without the built-in style layer, use [Get User Reports Tile (GeoJSON)](/crowdsourced-data/user-report-api-reference/tile-geojson/).

For a global or paginated feed, use [List User Reports](/crowdsourced-data/user-report-api-reference/list/).

## 3. Vote on Reports

When a user confirms or disputes a report, call [Vote on User Report](/crowdsourced-data/user-report-api-reference/vote/) with `vote` set to `valid` or `invalid`. Each authenticated user may have at most one vote per report; submitting again updates the existing vote.

## 4. Delete Reports

The user who created a report (or an admin) can [Delete User Report](/crowdsourced-data/user-report-api-reference/delete/) to soft-delete it. Deleted reports are excluded from default list and tile queries.

## 5. Streaming Updates

Subscribe to [Streaming Events](/crowdsourced-data/getting-started/streaming-events/) at `/api/v1/realtime?token=<token>` to receive `event_user_report` messages when reports change, instead of polling list or tile endpoints.
43 changes: 43 additions & 0 deletions content/crowdsourced-data/user-report-api-reference/_index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
title: "User Report API Overview"
weight: 1
menu:
crowdsourced:
title: "Overview"
parent: "user_report_api_reference"
weight: 1
---

Crowdsourced user reports are spatially-defined suggestions about chart data submitted by users at a specific location. Each report has a fixed type, a latitude/longitude position, optional client metadata, and vote counts aggregated from other users.

Reports are scoped to a server-configured **namespace** (default `public`). Only reports in the configured namespace are visible via the API, included in streaming events, and replicated between peers. Peer instances must use the same namespace to exchange data.

Reports expire automatically after a server-configured age (default 24 hours). Expired reports have `expiredAt` set and remain in the database.

These endpoints are available on both [Vector Charts Cloud](https://api.vectorcharts.com) and Vector Charts OEM. Replace the host in examples with your deployment's base URL.

## Report Types

Common examples include `data_quality`, `hazard`, `incident`, `closure`, and `sos`. The server does not enforce a fixed list.

## Report Object

REST endpoints return a report object with these fields:

- **id**: UUID version 4
- **reportType**: Free-form string label for the report category
- **latitude** / **longitude**: WGS84 decimal degrees
- **properties**: Arbitrary JSON metadata
- **validVoteCount** / **invalidVoteCount**: Aggregated vote totals
- **externalUserId**: Optional opaque client user identifier
- **createdAt** / **updatedAt**: Milliseconds since Unix epoch
- **expiredAt** / **deletedAt**: Null when active; set when expired or soft-deleted
- **namespace**: Namespace this report belongs to (matches server config)

For Mapbox vector tiles (recommended for map styles), see [Get User Reports MVT Tile](/crowdsourced-data/user-report-api-reference/tile-mvt/).

## Authentication

All user report endpoints require a valid API token. See [Cloud authentication](/api-reference/api-authentication/) or the [OEM Core API overview](/oem/api-reference/) for header and query-parameter auth.

For WebSocket streaming, see [Streaming Events](/crowdsourced-data/getting-started/streaming-events/).
73 changes: 73 additions & 0 deletions content/crowdsourced-data/user-report-api-reference/create.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
---
title: "Create User Report"
weight: 2
menu:
crowdsourced:
parent: "user_report_api_reference"
pre: "<div class=\"bp3-tag bp3-minimal bp3-intent-primary\">POST</div>"
---

{{% apiEndpointCard method="POST" path="/api/v1/user-reports" title="Create User Report" request=`POST https://api.vectorcharts.com/api/v1/user-reports
Authorization: Bearer <token>
Content-Type: application/json

{
"id": "550e8400-e29b-41d4-a716-446655440000",
"reportType": "hazard",
"position": {
"latitude": 42.36,
"longitude": -71.05
},
"properties": {
"description": "Shallow area reported"
},
"externalUserId": "app-user-abc123"
}` response=`Status Code: 201 Created
Response Body:
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"reportType": "hazard",
"latitude": 42.36,
"longitude": -71.05,
"properties": {
"description": "Shallow area reported"
},
"validVoteCount": 0,
"invalidVoteCount": 0,
"externalUserId": "app-user-abc123",
"namespace": "public",
"createdAt": 1718380800000,
"updatedAt": 1718380800000,
"expiredAt": null,
"deletedAt": null
}` %}}

Create a new crowdsourced user report at the given position.

<b>Authentication</b>

Requires a Bearer token in the `Authorization` header or a `token` query parameter. On OEM, use a token from your instance's [Admin API](/oem/portal-api-reference/api-tokens/).

<b>Base URL</b>

Cloud: `https://api.vectorcharts.com` — OEM: `https://&lt;your-host&gt;:9909`

<b>Request Body</b>

- **reportType** <span style="color:red;">(Required)</span>: Category string.
- **position** <span style="color:red;">(Required)</span>: Object with `latitude` and `longitude` (WGS84 decimal degrees).
- **id** (Optional): Client-supplied UUID version 4. When omitted, the server assigns one. Useful for offline-first clients that pre-generate IDs before sync.
- **properties** (Optional): Arbitrary JSON metadata (for example, a description or heading).
- **externalUserId** (Optional): Opaque user identifier from your application. Not used for authorization.

<b>Response Schema</b>

Returns a [User Report](/crowdsourced-data/user-report-api-reference/) object with vote counts set to zero.

<b>Error Responses</b>

- **400 Bad Request**: Invalid `reportType`, position, or `id` is not a valid UUIDv4.
- **401 Unauthorized**: Token is missing or invalid.
- **409 Conflict**: A report with the supplied `id` already exists.

{{% /apiEndpointCard %}}
51 changes: 51 additions & 0 deletions content/crowdsourced-data/user-report-api-reference/delete.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
---
title: "Delete User Report"
weight: 7
menu:
crowdsourced:
parent: "user_report_api_reference"
pre: "<div class=\"bp3-tag bp3-minimal bp3-intent-danger\">DELETE</div>"
---

{{% apiEndpointCard method="DELETE" path="/api/v1/user-reports/{id}" title="Delete User Report" request=`DELETE https://api.vectorcharts.com/api/v1/user-reports/550e8400-e29b-41d4-a716-446655440000
Authorization: Bearer <token>` response=`Status Code: 200 OK
Response Body:
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"reportType": "hazard",
"latitude": 42.36,
"longitude": -71.05,
"properties": {},
"validVoteCount": 3,
"invalidVoteCount": 1,
"externalUserId": "app-user-abc123",
"namespace": "public",
"createdAt": 1718380800000,
"updatedAt": 1718381100000,
"expiredAt": null,
"deletedAt": 1718381100000
}` %}}

Soft-delete a user report. The report remains in the database with `deletedAt` set and is excluded from default list and tile queries.

<b>Authentication</b>

Requires a Bearer token. Only the user who created the report or an admin may delete it.

<b>Path Parameters</b>

- **id**: UUID of the report to delete.

<b>Response</b>

Returns the soft-deleted [User Report](/crowdsourced-data/user-report-api-reference/) object.

<b>Error Responses</b>

- **400 Bad Request**: Invalid report id.
- **401 Unauthorized**: Token is missing or invalid.
- **403 Forbidden**: Caller is not the report owner or an admin.
- **404 Not Found**: Report does not exist.
- **410 Gone**: Report has already been deleted.

{{% /apiEndpointCard %}}
Loading