---
title: "Bulk, idempotent ingest of a device's blood pressure readings, by day"
method: POST
path: "/blood-pressure/days"
tags: ["Blood pressure"]
---

# Bulk, idempotent ingest of a device's blood pressure readings, by day

`POST /blood-pressure/days`

## Request

- Base URL: `https://bodylab.lol/api/v1`
- URL: `https://bodylab.lol/api/v1/blood-pressure/days`
- Auth: HTTP bearer

For Apple Health/Health Connect syncing. Each item replaces one source's readings for one local day, so sending a day again is a no-op and re-walking a history stores nothing twice: a reading is identified by its instant within its source. At most 500 days per request and 48 readings per day; a day whose readings can't all be stored is reported "rejected" on its own rather than failing the batch. Body Lab keeps every reading and says nothing about any of them.

## Headers

- `X-Client-Platform` string
- `X-Client-Version` string

## Request body

- object
  - `days` object[], required
    - `source` string, required: Which device integration a batch ingest item came from. Known values: apple_health, health_connect. Treat unknown values as "other".
    - `date` string, date, required: The athlete's local day these readings belong to, in their time zone.
    - `readings` object[], required: Every reading this source has for the day, in any order. Empty means the source has none, and the day is emptied.
      - `measuredAt` string, date-time, required: When the cuff read. Two readings minutes apart are two readings, and this is what tells them apart — it is also the key a re-sync matches on, so send the source's own instant for the reading and not the time it was synced.
      - `systolicMmHg` number, required: The upper number, millimetres of mercury, 60-260. Rounded to a whole number, which is what a cuff reports.
      - `diastolicMmHg` number, required: The lower number of the same reading, millimetres of mercury, 30-160. Has to be below the upper number.
      - `pulseBpm` number, nullable: The pulse the cuff printed beside the two numbers, where the source gives one, 20-250. Apple Health doesn't: its blood pressure correlation carries the two numbers and nothing else.

## Response `200`

OK

- object
  - `results` object[], required
    - `date` string, required: The item's date as it was sent, so a caller can match the result to what it sent.
    - `result` string, required: created: the day held nothing and now holds readings. updated: what the day holds changed. unchanged: the server already had exactly these readings, which is what a re-sync should get. deleted: the day held readings and now holds none. rejected: nothing in this day was stored, see reason.
    - `reason` string, nullable, required: Why a day's readings were rejected. unsupported_source: not an allowed device source. value_out_of_range: a number outside its plausible range. implausible_pair: the upper number wasn't above the lower one, which is what a swapped mapping looks like. duplicate_instant: two readings in the day claimed the same instant, so which one the day holds is undecidable. malformed: the item didn't match the schema, so the rest of the batch ran without it. Known values: unsupported_source, value_out_of_range, implausible_pair, duplicate_instant, malformed. Treat unknown values as "other".

## Other responses

- `401`: Error: UNAUTHORIZED.

---

[API](https://skmtc.dev/bodylab/apis/body-lab-api.md) · [All operations](https://skmtc.dev/bodylab/apis/body-lab-api/llms.txt) · [OpenAPI document](https://skmtc.dev/bodylab/apis/body-lab-api/revisions/544c201eaf88?raw)
