: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.
diff --git a/content/crowdsourced-data/getting-started/streaming-events.md b/content/crowdsourced-data/getting-started/streaming-events.md
new file mode 100644
index 0000000..d83b411
--- /dev/null
+++ b/content/crowdsourced-data/getting-started/streaming-events.md
@@ -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:
+
+
+wss://api.vectorcharts.com/api/v1/realtime?token=<token string>
+
+
+On OEM, replace the host with your instance URL (for example, `wss://<your-host>:9909/api/v1/realtime?token=<token string>`).
+
+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:
+
+
+{
+ "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
+}
+
+
+- **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.
diff --git a/content/crowdsourced-data/getting-started/submitting-user-data.md b/content/crowdsourced-data/getting-started/submitting-user-data.md
new file mode 100644
index 0000000..68058bb
--- /dev/null
+++ b/content/crowdsourced-data/getting-started/submitting-user-data.md
@@ -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=` to receive `event_user_report` messages when reports change, instead of polling list or tile endpoints.
diff --git a/content/crowdsourced-data/user-report-api-reference/_index.md b/content/crowdsourced-data/user-report-api-reference/_index.md
new file mode 100644
index 0000000..c8ec2b9
--- /dev/null
+++ b/content/crowdsourced-data/user-report-api-reference/_index.md
@@ -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/).
diff --git a/content/crowdsourced-data/user-report-api-reference/create.md b/content/crowdsourced-data/user-report-api-reference/create.md
new file mode 100644
index 0000000..6cce670
--- /dev/null
+++ b/content/crowdsourced-data/user-report-api-reference/create.md
@@ -0,0 +1,73 @@
+---
+title: "Create User Report"
+weight: 2
+menu:
+ crowdsourced:
+ parent: "user_report_api_reference"
+ pre: "POST
"
+---
+
+{{% apiEndpointCard method="POST" path="/api/v1/user-reports" title="Create User Report" request=`POST https://api.vectorcharts.com/api/v1/user-reports
+Authorization: Bearer
+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.
+
+Authentication
+
+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/).
+
+Base URL
+
+Cloud: `https://api.vectorcharts.com` — OEM: `https://<your-host>:9909`
+
+Request Body
+
+- **reportType** (Required): Category string.
+- **position** (Required): 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.
+
+Response Schema
+
+Returns a [User Report](/crowdsourced-data/user-report-api-reference/) object with vote counts set to zero.
+
+Error Responses
+
+- **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 %}}
diff --git a/content/crowdsourced-data/user-report-api-reference/delete.md b/content/crowdsourced-data/user-report-api-reference/delete.md
new file mode 100644
index 0000000..a11aa99
--- /dev/null
+++ b/content/crowdsourced-data/user-report-api-reference/delete.md
@@ -0,0 +1,51 @@
+---
+title: "Delete User Report"
+weight: 7
+menu:
+ crowdsourced:
+ parent: "user_report_api_reference"
+ pre: "DELETE
"
+---
+
+{{% 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 ` 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.
+
+Authentication
+
+Requires a Bearer token. Only the user who created the report or an admin may delete it.
+
+Path Parameters
+
+- **id**: UUID of the report to delete.
+
+Response
+
+Returns the soft-deleted [User Report](/crowdsourced-data/user-report-api-reference/) object.
+
+Error Responses
+
+- **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 %}}
diff --git a/content/crowdsourced-data/user-report-api-reference/list.md b/content/crowdsourced-data/user-report-api-reference/list.md
new file mode 100644
index 0000000..73ee682
--- /dev/null
+++ b/content/crowdsourced-data/user-report-api-reference/list.md
@@ -0,0 +1,60 @@
+---
+title: "List User Reports"
+weight: 3
+menu:
+ crowdsourced:
+ parent: "user_report_api_reference"
+ pre: "GET
"
+---
+
+{{% apiEndpointCard method="GET" path="/api/v1/user-reports" title="List User Reports" request=`GET https://api.vectorcharts.com/api/v1/user-reports?limit=50&offset=0
+Authorization: Bearer ` response=`Status Code: 200 OK
+Response Body:
+{
+ "reports": [
+ {
+ "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": 1718380900000,
+ "expiredAt": null,
+ "deletedAt": null
+ }
+ ],
+ "total": 1,
+ "limit": 50,
+ "offset": 0
+}` %}}
+
+List all user reports globally, ordered most recent first. Each report includes aggregated vote counts.
+
+Authentication
+
+Requires a Bearer token in the `Authorization` header or a `token` query parameter.
+
+Query Parameters
+
+- **limit** (Optional): Maximum number of reports to return. Defaults to `50`. Capped at `200`.
+- **offset** (Optional): Number of reports to skip. Defaults to `0`.
+- **includeDeleted** (Optional): If `true`, include soft-deleted reports. Defaults to `false`.
+- **includeExpired** (Optional): If `true`, include expired reports. Defaults to `false`.
+
+Response Schema
+
+- **reports**: Array of [User Report](/crowdsourced-data/user-report-api-reference/) objects.
+- **total**: Total number of reports matching the filter.
+- **limit**: Applied page size.
+- **offset**: Applied offset.
+
+Error Responses
+
+- **401 Unauthorized**: Token is missing or invalid.
+
+{{% /apiEndpointCard %}}
diff --git a/content/crowdsourced-data/user-report-api-reference/replication.md b/content/crowdsourced-data/user-report-api-reference/replication.md
new file mode 100644
index 0000000..de86c60
--- /dev/null
+++ b/content/crowdsourced-data/user-report-api-reference/replication.md
@@ -0,0 +1,58 @@
+---
+title: "Peer Replication"
+draft: true
+---
+
+User reports can be replicated across multiple OEM instances using a pull-only peer sync. Each instance periodically fetches reports and votes that changed since its last successful sync from configured peer URLs.
+
+Bidirectional replication requires peers to be configured on both sides. Peers only exchange reports in the same **namespace** — set `userReports.namespace` to the same value on each instance that should sync.
+
+## Configuration
+
+In `default.yml` (or environment overrides):
+
+```yaml
+userReports:
+ namespace: 'public'
+ replication:
+ enabled: true
+ tickIntervalMs: 60000
+ token: 'a1b2c3d4-e5f6-4789-a012-3456789abcde'
+ peers:
+ - name: peer-east
+ url: https://peer-east.example.com
+ - name: peer-west
+ url: https://peer-west.example.com
+```
+
+- **enabled**: When false, replication tick is disabled and the internal export endpoint returns 404.
+- **tickIntervalMs**: How often to pull from peers (default 60 seconds).
+- **token**: Shared UUIDv4 secret. Must match on all peers.
+- **peers**: List of remote instances to pull from.
+- **namespace**: Namespace to scope reports on this instance (default `public`). Only data in this namespace is exported, imported, or visible via the public API.
+
+Environment variables: `USER_REPORTS_NAMESPACE`, `USER_REPORTS_REPLICATION_ENABLED`, `USER_REPORTS_REPLICATION_TICK_INTERVAL_MS`, `USER_REPORTS_REPLICATION_TOKEN`.
+
+## Internal Export Endpoint
+
+Peers expose changed data at:
+
+
+GET /api/v1/internal/user-reports/replication?since=<timestamp>
+Authorization: Bearer <replication token>
+
+
+Query parameters:
+
+- **since** (required): ISO 8601 timestamp or epoch milliseconds. Returns rows with `updated_at` greater than this value.
+- **limit** (optional): Page size, default 500, max 2000.
+- **cursor** (optional): Report UUID for pagination tie-breaking.
+- **voteCursor** (optional): Vote UUID for pagination tie-breaking.
+
+The response includes `reports`, `votes`, `hasMore`, `nextCursor`, and `timestamp`.
+
+Replicated writes do not trigger WebSocket events on the receiving instance.
+
+## Cursor Tracking
+
+Each peer's last successfully ingested timestamp is stored in the `user_report_replication_peers` table. If a peer pull fails, the cursor is not advanced and the next tick retries from the last successful position.
diff --git a/content/crowdsourced-data/user-report-api-reference/tile-geojson.md b/content/crowdsourced-data/user-report-api-reference/tile-geojson.md
new file mode 100644
index 0000000..8c4380c
--- /dev/null
+++ b/content/crowdsourced-data/user-report-api-reference/tile-geojson.md
@@ -0,0 +1,61 @@
+---
+title: "Get User Reports Tile (GeoJSON)"
+weight: 4
+menu:
+ crowdsourced:
+ parent: "user_report_api_reference"
+ pre: "GET
"
+---
+
+{{% apiEndpointCard method="GET" path="/api/v1/user-reports/tiles/{z}/{x}/{y}.json" title="Get User Reports Tile" request=`GET https://api.vectorcharts.com/api/v1/user-reports/tiles/12/1240/1515.json?token=` response=`Status Code: 200 OK
+Response Body:
+{
+ "type": "FeatureCollection",
+ "features": [
+ {
+ "type": "Feature",
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-71.05, 42.36]
+ },
+ "properties": {
+ "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": 1718380900000,
+ "expiredAt": null,
+ "deletedAt": null
+ }
+ }
+ ]
+}` %}}
+
+Returns active (non-deleted, non-expired) user reports intersecting the given slippy-map tile as a GeoJSON FeatureCollection.
+
+Authentication
+
+Requires a Bearer token in the `Authorization` header or a `token` query parameter.
+
+Path Parameters
+
+- **z**: Tile zoom level.
+- **x**: Tile column.
+- **y**: Tile row.
+
+Response
+
+A GeoJSON FeatureCollection where each feature is a Point geometry. Feature `properties` include the report id, type, vote counts, timestamps, and client metadata.
+
+Error Responses
+
+- **400 Bad Request**: Invalid tile coordinates.
+- **401 Unauthorized**: Token is missing or invalid.
+
+{{% /apiEndpointCard %}}
diff --git a/content/crowdsourced-data/user-report-api-reference/tile-mvt.md b/content/crowdsourced-data/user-report-api-reference/tile-mvt.md
new file mode 100644
index 0000000..b2e8297
--- /dev/null
+++ b/content/crowdsourced-data/user-report-api-reference/tile-mvt.md
@@ -0,0 +1,37 @@
+---
+title: "Get User Reports MVT Tile"
+weight: 5
+menu:
+ crowdsourced:
+ parent: "user_report_api_reference"
+ pre: "GET
"
+---
+
+{{% apiEndpointCard method="GET" path="/api/v1/user-reports/tiles/{z}/{x}/{y}.mvt" title="Get User Reports MVT Tile" request=`GET https://api.vectorcharts.com/api/v1/user-reports/tiles/12/1240/1515.mvt?token=` response=`Status Code: 200 OK
+Content-Type: application/vnd.mapbox-vector-tile
+(binary Mapbox Vector Tile)` %}}
+
+Returns active (non-deleted, non-expired) user reports intersecting the given slippy-map tile as a Mapbox vector tile (MVT).
+
+The `user_reports` source layer includes point features with report attributes: `id`, `report_type`, `properties` (JSON string), `valid_vote_count`, `invalid_vote_count`, `external_user_id`, `namespace`, `created_at`, and `updated_at`.
+
+Map style integration
+
+The vector chart style (`/api/v1/styles/base.json`) includes a `userReports` vector source pointing at this endpoint and a symbol layer that renders each report with the `DANGER01` alert icon. Query feature properties in the client to show report details on click.
+
+Authentication
+
+Requires a Bearer token in the `Authorization` header or a `token` query parameter.
+
+Path Parameters
+
+- **z**: Tile zoom level.
+- **x**: Tile column.
+- **y**: Tile row.
+
+Error Responses
+
+- **400 Bad Request**: Invalid tile coordinates.
+- **401 Unauthorized**: Token is missing or invalid.
+
+{{% /apiEndpointCard %}}
diff --git a/content/crowdsourced-data/user-report-api-reference/vote.md b/content/crowdsourced-data/user-report-api-reference/vote.md
new file mode 100644
index 0000000..7e73426
--- /dev/null
+++ b/content/crowdsourced-data/user-report-api-reference/vote.md
@@ -0,0 +1,61 @@
+---
+title: "Vote on User Report"
+weight: 6
+menu:
+ crowdsourced:
+ parent: "user_report_api_reference"
+ pre: "POST
"
+---
+
+{{% apiEndpointCard method="POST" path="/api/v1/user-reports/{id}/votes" title="Vote on User Report" request=`POST https://api.vectorcharts.com/api/v1/user-reports/550e8400-e29b-41d4-a716-446655440000/votes
+Authorization: Bearer
+Content-Type: application/json
+
+{
+ "vote": "valid",
+ "externalUserId": "app-user-abc123"
+}` response=`Status Code: 200 OK
+Response Body:
+{
+ "id": "550e8400-e29b-41d4-a716-446655440000",
+ "reportType": "hazard",
+ "latitude": 42.36,
+ "longitude": -71.05,
+ "properties": {},
+ "validVoteCount": 4,
+ "invalidVoteCount": 1,
+ "externalUserId": "app-user-abc123",
+ "namespace": "public",
+ "createdAt": 1718380800000,
+ "updatedAt": 1718381000000,
+ "expiredAt": null,
+ "deletedAt": null
+}` %}}
+
+Vote that a user report is valid or invalid. Each authenticated user may have at most one vote per report; submitting again updates the existing vote.
+
+Authentication
+
+Requires a Bearer token in the `Authorization` header or a `token` query parameter.
+
+Path Parameters
+
+- **id**: UUID of the report to vote on.
+
+Request Body
+
+- **vote** (Required): Either `valid` or `invalid`.
+- **externalUserId** (Optional): Opaque user identifier from your application.
+
+Response
+
+Returns the updated [User Report](/crowdsourced-data/user-report-api-reference/) object with refreshed vote counts. Individual vote rows are not returned.
+
+Error Responses
+
+- **400 Bad Request**: Invalid report id or vote value.
+- **401 Unauthorized**: Token is missing or invalid.
+- **404 Not Found**: Report does not exist.
+- **410 Gone**: Report has been deleted or expired.
+
+{{% /apiEndpointCard %}}
diff --git a/content/oem/api-reference/_index.md b/content/oem/api-reference/_index.md
index cf34c51..9f5f7f3 100644
--- a/content/oem/api-reference/_index.md
+++ b/content/oem/api-reference/_index.md
@@ -44,3 +44,5 @@ const map = new mapboxgl.Map({
style: "https://<your-host>:9909/api/v1/styles/base.json?token=<token string>"
});
+
+Crowdsourced user reports and realtime event streaming are documented in the [Crowdsourced Data](/crowdsourced-data/) section.
diff --git a/themes/docs-theme/layouts/partials/headerSecondary.html b/themes/docs-theme/layouts/partials/headerSecondary.html
index 2a98902..58d2b7e 100644
--- a/themes/docs-theme/layouts/partials/headerSecondary.html
+++ b/themes/docs-theme/layouts/partials/headerSecondary.html
@@ -5,14 +5,18 @@
{{ if eq $currentPage.Section "oem" }}
{{ $menu = .Site.Menus.oem }}
{{ $menuName = "oem" }}
+ {{ else if eq $currentPage.Section "crowdsourced-data" }}
+ {{ $menu = .Site.Menus.crowdsourced }}
+ {{ $menuName = "crowdsourced" }}
{{ end }}