---
title: "Quickstart"
description: "Model a device, send your first telemetry reading, and map a raw payload with a template."
icon: "rocket"
---

> **For AI agents:** the complete documentation index is at [llms.txt](/llms.txt). Append `.md` to any page URL for its markdown version.

## Prerequisites

- An **API key** (prefix `avy`) with `write` scopes covering the resources in this guide
  (see [Resource filters](/platform/resource-filters)). Send it in the `X-Api-Key` header on
  every request.
- A JSON-capable HTTP client. The examples below use `curl`.

<Note>
  Your organization is derived from your API key: you don't pass it explicitly when
  creating resources. See [API fundamentals](/platform/api-fundamentals) for auth, IDs, and
  error formats.
</Note>

Set these once so you can paste the steps as-is:

```bash
export AEROVY_API_KEY="avy..."
export AEROVY_API="https://spectra.dev.aerovy.com"
```

## Steps

<Steps>
  <Step title="Define a metric">
    Create the quantity your device measures. Note the returned id (`mdef_…`).

    ```bash
    curl -X POST "$AEROVY_API/v2/definitions/metrics" \
      -H "X-Api-Key: $AEROVY_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "soc",
        "displayName": "State of Charge",
        "dataType": "Double",
        "defaultAggregation": "Last",
        "unitLabel": "%"
      }'
    ```
  </Step>

  <Step title="Define a Thing Type">
    Tie your metric(s) into a device type. Note the returned **stable type id** (`tdefi_…`).

    ```bash
    curl -X POST "$AEROVY_API/v2/definitions/thing-types" \
      -H "X-Api-Key: $AEROVY_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "displayName": "Battery",
        "metricIds": ["mdef_<soc>"]
      }'
    ```
  </Step>

  <Step title="Create a Site">
    A device needs a **Place** to live in. Create a Site and note its id (`<siteId>`).

    ```bash
    curl -X POST "$AEROVY_API/v2/sites" \
      -H "X-Api-Key: $AEROVY_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "siteName": "Depot 1",
        "latitude": 37.7749,
        "longitude": -122.4194,
        "address": "1 Market St, San Francisco, CA"
      }'
    ```
  </Step>

  <Step title="Register a Thing">
    Create the device in that Site, referencing the type from step 2. Note its id (`<thingId>`).

    ```bash
    curl -X POST "$AEROVY_API/v2/sites/<siteId>/things" \
      -H "X-Api-Key: $AEROVY_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "thingName": "Battery A1",
        "thingType": "Battery",
        "thingTypeId": "tdefi_<battery>"
      }'
    ```
  </Step>

  <Step title="Send a reading">
    POST telemetry for the Thing. The body is a batch of `frames`: each frame has a
    `timestamp` (Unix epoch milliseconds) and a `metrics` map of metric name to value.

    ```bash
    curl -X POST "$AEROVY_API/v2/thing/<thingId>/data" \
      -H "X-Api-Key: $AEROVY_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "frames": [
          {
            "timestamp": 1718884800000,
            "metrics": { "soc": 87.4 }
          }
        ]
      }'
    ```

    A successful call returns **`200 OK`** with an ingest summary: the `thingId`,
    `framesIngested`, and the distinct `metrics` written.
  </Step>

  <Step title="Define a template">
    Real payloads rarely match the `frames` shape. A [Template](/platform/templates) maps an
    external payload onto your metrics, so you can ingest data in its native shape. Create a
    `ThingData` template with JSON Pointer mappings and note its id (`tmpl_…`).

    ```bash
    curl -X POST "$AEROVY_API/v2/templates" \
      -H "X-Api-Key: $AEROVY_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "Acme Telemetry v1",
        "target": "ThingData",
        "format": "JsonPointer",
        "spec": {
          "recordsPointer": "/readings",
          "timestamp": { "source": { "pointer": "/ts" }, "format": "iso8601" },
          "mappings": [
            { "metricId": "mdef_<soc>", "source": { "pointer": "/soc" } }
          ]
        }
      }'
    ```
  </Step>

  <Step title="Ingest with the template">
    POST the **raw external payload** to the template-apply endpoint. The platform maps it
    through the template and writes the readings. Add `?previewOnly=true` to validate the
    mapping without persisting.

    ```bash
    curl -X POST "$AEROVY_API/v2/thing/<thingId>/data/template/<templateId>?previewOnly=false" \
      -H "X-Api-Key: $AEROVY_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "readings": [
          { "ts": "2026-06-20T12:00:00Z", "soc": 87.4 }
        ]
      }'
    ```

    The response is a processing report: records parsed, readings written, and any skipped
    records or fields. See [Templates](/platform/templates) for the full mapping spec.
  </Step>
</Steps>

## Verify

Read the latest reading back:

```bash
curl "$AEROVY_API/v2/things/<thingId>/latest-event" \
  -H "X-Api-Key: $AEROVY_API_KEY"
```

<Tip>
  Next: [Ingesting data](/platform/ingesting-data) covers batch creation, property validation,
  templates, and integrations. [Templates](/platform/templates) details the mapping spec, and
  [Querying data](/platform/querying-data) covers reads.
</Tip>
