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

# POST /v1/spatial/stream — Streaming API Reference

> Subscribe to a real-time JSON stream of ground truth events for a defined area of interest. Receives push updates from the Vangrid edge network.

The Vangrid Streaming API delivers a continuous, real-time feed of ground truth events for a geographic zone you define. Unlike polling the spatial query endpoint, streaming gives you push-based updates the moment new observations are available from the edge network — essential for autonomous systems, live monitoring dashboards, and world model pipelines.

<Note>
  All endpoint URLs, request examples, and sample responses on this page are illustrative. The Vangrid API is not yet publicly available — [contact us](mailto:hello@vangrid.io) to join early access.
</Note>

## Endpoint

```text theme={null}
POST https://api.vangrid.io/v1/spatial/stream
```

The connection stays open and the server pushes newline-delimited JSON (`\n`) events as they arrive. The client reads the response body as a stream.

## Request

### Headers

| Header          | Value                 |
| --------------- | --------------------- |
| `Authorization` | `Bearer your-api-key` |
| `Content-Type`  | `application/json`    |

### Body parameters

<ParamField body="aoi" type="object" required>
  GeoJSON geometry defining the zone to monitor. Supports `Polygon` and `MultiPolygon`. Maximum area is 50 km².
</ParamField>

<ParamField body="min_ground_truth_score" type="number">
  Filter events to those above this confidence threshold. Defaults to `0.5`.
</ParamField>

<ParamField body="observation_types" type="array">
  Limit events to specific observation types. If omitted, all types are streamed.
</ParamField>

### Example — open a stream

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST https://api.vangrid.io/v1/spatial/stream \
    -H "Authorization: Bearer your-api-key" \
    -H "Content-Type: application/json" \
    -d '{
      "aoi": {
        "type": "Polygon",
        "coordinates": [[
          [-122.4194, 37.7749],
          [-122.4094, 37.7749],
          [-122.4094, 37.7849],
          [-122.4194, 37.7849],
          [-122.4194, 37.7749]
        ]]
      },
      "min_ground_truth_score": 0.75
    }'
  ```

  ```python Python theme={null}
  import requests
  import json

  API_KEY = "your-api-key"

  aoi = {
      "type": "Polygon",
      "coordinates": [[
          [-122.4194, 37.7749],
          [-122.4094, 37.7749],
          [-122.4094, 37.7849],
          [-122.4194, 37.7849],
          [-122.4194, 37.7749]
      ]]
  }

  with requests.post(
      "https://api.vangrid.io/v1/spatial/stream",
      headers={"Authorization": f"Bearer {API_KEY}"},
      json={"aoi": aoi, "min_ground_truth_score": 0.75},
      stream=True
  ) as response:
      for line in response.iter_lines():
          if line:
              event = json.loads(line)
              print(event)
  ```
</CodeGroup>

## Stream events

Each line in the stream is a JSON object representing a single ground truth event:

```json theme={null}
{
  "event_id": "evt_8f3a2c1d",
  "timestamp": "2026-05-22T10:14:33.412Z",
  "geometry": {
    "type": "Point",
    "coordinates": [-122.4150, 37.7800]
  },
  "observation_type": "vehicle",
  "ground_truth_score": 0.94,
  "node_count": 12,
  "provenance_hash": "sha256:a3f8e2c1b4d7f9e0a2b5c8d1e4f7a0b3c6d9e2f5"
}
```

### Event fields

<ResponseField name="event_id" type="string">
  Unique identifier for this event.
</ResponseField>

<ResponseField name="timestamp" type="string">
  ISO 8601 UTC timestamp when the observation was captured.
</ResponseField>

<ResponseField name="geometry" type="object">
  GeoJSON geometry of the observed feature.
</ResponseField>

<ResponseField name="observation_type" type="string">
  Classification of the observation.
</ResponseField>

<ResponseField name="ground_truth_score" type="number">
  Confidence score (0.0–1.0) based on multi-node corroboration.
</ResponseField>

<ResponseField name="node_count" type="integer">
  Number of edge nodes that contributed to this observation.
</ResponseField>

<ResponseField name="provenance_hash" type="string">
  Cryptographic proof of data origin, verifiable via the provenance endpoint.
</ResponseField>

## Heartbeat events

Every 30 seconds with no new observations, the server sends a heartbeat to keep the connection alive:

```json theme={null}
{"type": "heartbeat", "timestamp": "2026-05-22T10:15:03.000Z"}
```

Skip heartbeat events in your processing logic by checking `event.get("type") == "heartbeat"`.

## Connection limits and reconnection

* Maximum one concurrent stream per API key by default
* Streams time out after 24 hours; reconnect to resume
* On disconnect, reconnect immediately — no data is buffered server-side during disconnection

<Warning>
  Data is not buffered if your client disconnects. Events that arrive while you are disconnected are not replayed. Design your system to tolerate gaps and rely on the spatial query endpoint to backfill if needed.
</Warning>

<Note>
  Contact [hello@vangrid.io](mailto:hello@vangrid.io) to request higher concurrent stream limits or dedicated streaming infrastructure for production deployments.
</Note>
