Skip to content
Get Started

Data Plane

Device Data

Cookbook: write wearable and device data into Mirobody — daily aggregation, batched POST /v1/data, episodes with end_time.

You’ve already integrated a wearable — through Terra, Junction, or a vendor API — and samples are flowing into your backend. This page is the recipe for getting them into Mirobody, so the standardization pipeline and the agent treat them like any other health record.

Receive

Your vendor integration delivers samples — a webhook push or a periodic pull, whatever the vendor offers.

Aggregate to daily (recommended)

Roll high-frequency series up to one record per day before writing — lower cost, and a series that stays legible. Episodes keep their own period.

Write with POST /v1/data

Batches of up to 500 records per request, retention required — same contract as any other structured write.

Section titled “1. Aggregate before you write (recommended)”

POST /v1/data accepts any granularity, but for most products one row per meaningful reading is enough — less write volume (and cost), and a series that’s easy to reason about:

  • Daily totals (steps, calories, distance) — one record per day.
  • Continuous series (heart rate, SpO₂ sampled every few minutes) — aggregate to a daily value first (e.g. resting or mean heart rate), and write min/max as their own indicators if you need them. Go finer only where your product genuinely needs it.
  • Episodes (sleep, workouts) — one record per episode, carrying its period via time + end_time (below).
Terminal window
curl https://api.mirobody.ai/v1/data \
-H "Authorization: Bearer $MIROBODY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"user": "alice",
"retention": "permanent",
"records": [
{"indicator": "steps", "value": 12450, "time": "2026-07-10T00:00:00Z", "source": "garmin"},
{"indicator": "resting_heart_rate", "value": 58, "unit": "/min", "time": "2026-07-10T00:00:00Z", "source": "garmin"}
]
}'

Up to 500 records per request — batch a full day (or a backfill window) per Subject into one call. Tag the vendor in source — your vendor tag comes back in the comment field when you read the record.

3. Episodes: carry the period with end_time

Section titled “3. Episodes: carry the period with end_time”

Sleep and workouts are not point-in-time readings — they span a period. Put the start in time and the end in the optional end_time (both ISO timestamps):

Terminal window
curl https://api.mirobody.ai/v1/data \
-H "Authorization: Bearer $MIROBODY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"user": "alice",
"retention": "permanent",
"records": [
{"indicator": "sleep_duration", "value": 7.5, "unit": "h",
"time": "2026-07-09T23:10:00Z", "end_time": "2026-07-10T06:40:00Z",
"source": "garmin"}
]
}'

GET /v1/data returns end_time on every row (null for point-in-time readings), so your app can render the episode as a span.

Every structured write runs the same standardization pipeline as manual records and stored extractions: recognized indicator names resolve to LOINC deterministically, values are parsed into UCUM units, and records are mirrored into FHIR. Low-confidence names remain uncoded rather than guessed. Read the series back with GET /v1/data — and the agent reads the same data when it answers.

Hosted device OAuth. Connecting devices — vendor consent screens, token refresh, webhook plumbing — stays in your product; every vendor’s flow is different and it belongs next to your UX. What happens after the data is in — storage, standardization, retention, deletes, AI — is Mirobody’s job.