Norvya Developers
Get a sandbox
API reference · Data in

Member data in: observations and workouts

Built — gated4 endpoints · OpenAPI tag member_data

Send what your own system measured for a member, keyed by your id so a resend replaces and a delete retracts: vitals, body measurements and lab results (practices, with a BAA; recorded with your organisation as the source and coded to LOINC / UCUM where Norvya is sure of the code), and completed workouts (gyms and fitness apps) that strength progress, weekly sets and readiness then read. Every value lands in the member's provenance-bearing observation record, never as a silent overwrite of something the member entered.

Who calls it
Core for Fitness chains; useful for Concierge doctors, Independent practices, EMR vendors, Hospitals and health systems, Rehab & nutrition practices
Before production
No gate of its own; your market's “Before production” applies.
Sandbox
Build against synthetic members first. What each sandbox holds
Standards
LOINC / UCUM where Norvya is sure of the code

Markets that use this family

Scopes

ScopeAllows
observations.writeWrite measurements to a member's own record: vitals, lab results and body composition (practices with a BAA on file), or body composition and the vitals a gym measures (gyms; never labs). Idempotent per item by your external_id; units converted, implausible values refused; DELETE retracts only your own item.
workouts.writeWrite completed training sessions (exercises, sets, reps, load, RPE, duration) to a member's record, so strength progress, weekly sets and readiness see them (gyms, fitness and personal-training organisations only).

Endpoints

Write measurements to a member's record

POST/v1/members/{member_ref}/observationsobservations.write

Vitals, lab results and body composition, one outcome per item (created | duplicate | rejected with a machine code). Practices (BAA on file): every type, recorded as your practice's own record. Gyms: body composition and weight / height / heart rate / blood pressure, while the member shares body measurements with you; never labs. Units are converted, never assumed; implausible values are refused. Idempotent per item by external_id.

Parameters

member_refpath · stringrequired

EMR vendors also pass vendor (the practice) with a vendor-issued token. EMR vendor tokens

Request body

Content type: application/json (required)

itemsarray of objectrequired

All responses

200Successful Response401Unauthorized403Forbidden404Not Found409Conflict422Unprocessable Entity429Too Many Requests503Service Unavailable

Codes every call can return are in Errors & limits.

curl -s -X POST "https://norvya.fly.dev/v1/members/$MEMBER_REF/observations" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "items": [
      {
        "external_id": "VS-2026-10-14-0001",
        "type": "vital",
        "code": "blood_pressure",
        "value": 128,
        "value_secondary": 82,
        "unit": "mmHg",
        "effective_at": "2026-10-14T09:30:00-04:00",
        "device": "InBody 570",
        "name": "LDL",
        "loinc": "13457-7",
        "collected_at": "2026-10-13T08:05:00-04:00",
        "reference_low": 0.0,
        "reference_high": 0.0,
        "reference_text": "<100 mg/dL",
        "interpretation": "string",
        "lab_name": "Example Reference Laboratory",
        "weight": {
          "value": 82.4,
          "unit": "kg"
        },
        "body_fat_pct": 21.4,
        "skeletal_muscle_mass": {
          "value": 82.4,
          "unit": "kg"
        },
        "bone_mass": {
          "value": 82.4,
          "unit": "kg"
        },
        "body_water_pct": 0.0,
        "visceral_fat": 9,
        "smi": 0.0,
        "ecw_tbw": 0.0
      }
    ]
  }'
Response 200
{
  "member_ref": "string",
  "created": 0,
  "duplicates": 0,
  "rejected": 0,
  "items": [
    {
      "external_id": "string",
      "type": "string",
      "status": "created",
      "code": "unit_unrecognised",
      "metrics": [
        "string"
      ]
    }
  ],
  "source": "practice_emr"
}

The response is the shape from the schema, not live data.

Retract one of your own measurement items

DELETE/v1/members/{member_ref}/observations/{external_id}observations.write

Removes the rows YOUR item created; their observations are marked entered-in-error in Norvya's ledger. Another source's data is never touched. The external_id is not reusable afterwards.

Parameters

member_refpath · stringrequired
external_idpath · stringrequired

EMR vendors also pass vendor (the practice) with a vendor-issued token. EMR vendor tokens

All responses

200Successful Response401Unauthorized403Forbidden404Not Found409Conflict422Unprocessable Entity429Too Many Requests503Service Unavailable

Codes every call can return are in Errors & limits.

curl -s -X DELETE "https://norvya.fly.dev/v1/members/$MEMBER_REF/observations/$EXTERNAL_ID" \
  -H "Authorization: Bearer $TOKEN"
Response 200
{
  "member_ref": "string",
  "external_id": "string",
  "status": "retracted",
  "already_retracted": false,
  "rows_removed": 0
}

The response is the shape from the schema, not live data.

Write completed training sessions to a member's record

POST/v1/members/{member_ref}/workoutsworkouts.write

Exercises, sets, reps, load and RPE, stored as a logged session so the member's strength progress (estimated 1RM), weekly hard sets and training readiness include it. Gyms, fitness and personal-training organisations, while the member shares activity with you.

Parameters

member_refpath · stringrequired

EMR vendors also pass vendor (the practice) with a vendor-issued token. EMR vendor tokens

Request body

Content type: application/json (required)

itemsarray of objectrequired

All responses

200Successful Response401Unauthorized403Forbidden404Not Found409Conflict422Unprocessable Entity429Too Many Requests503Service Unavailable

Codes every call can return are in Errors & limits.

curl -s -X POST "https://norvya.fly.dev/v1/members/$MEMBER_REF/workouts" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "items": [
      {
        "external_id": "GYM-SESSION-88412",
        "started_at": "2026-10-14T18:00:00-04:00",
        "duration_minutes": 55,
        "workout_type": "string",
        "session_rpe": 7,
        "device": "string",
        "exercises": [
          {}
        ]
      }
    ]
  }'
Response 200
{
  "member_ref": "string",
  "created": 0,
  "duplicates": 0,
  "rejected": 0,
  "items": [
    {
      "external_id": "string",
      "type": "string",
      "status": "created",
      "code": "unit_unrecognised",
      "metrics": [
        "string"
      ]
    }
  ],
  "source": "practice_emr"
}

The response is the shape from the schema, not live data.

Retract one of your own workout items

DELETE/v1/members/{member_ref}/workouts/{external_id}workouts.write

Parameters

member_refpath · stringrequired
external_idpath · stringrequired

EMR vendors also pass vendor (the practice) with a vendor-issued token. EMR vendor tokens

All responses

200Successful Response401Unauthorized403Forbidden404Not Found409Conflict422Unprocessable Entity429Too Many Requests503Service Unavailable

Codes every call can return are in Errors & limits.

curl -s -X DELETE "https://norvya.fly.dev/v1/members/$MEMBER_REF/workouts/$EXTERNAL_ID" \
  -H "Authorization: Bearer $TOKEN"
Response 200
{
  "member_ref": "string",
  "external_id": "string",
  "status": "retracted",
  "already_retracted": false,
  "rows_removed": 0
}

The response is the shape from the schema, not live data.

Generated from the Partner API router and developers_catalog.py. The router docstring is the source of each description.

↑ ↓ to moveEnter to open