# COROS API to FHIR: sleep, heart rate and steps (with code)

> Get COROS data via the Partner API or the self-service COROS MCP and store sleep, heart rate and steps as FHIR R4 Observations.

Source: https://developers.anpheros.com/guides/coros-api

**COROS gives developers two ways in: the COROS Partner API, for established platforms that COROS approves, and the self-service COROS MCP server, where each person authorizes their own sleep, heart rate, HRV, steps and workouts over OAuth 2.0. You can store each reading as a LOINC-coded FHIR R4 Observation with one standard API call. Anpheros does not connect to COROS's cloud itself: your code reads COROS, and Anpheros keeps the record with the person's consent. On phones, the COROS app writes heart rate, sleep, steps and distances to Apple Health, and lists Health Connect as a sync target.**

## Read COROS data and store it in FHIR

COROS does not publish raw HTTP paths for either route. Partner API paths are shared after onboarding, and the self-service route is an MCP server: your MCP client calls tools such as `queryDailyHealthData` or `querySleepOverview` at `https://mcp.coros.com/mcp` with the person's OAuth token. The public part you can call today is the OAuth discovery document:

```bash
curl -s https://mcp.coros.com/.well-known/oauth-protected-resource/mcp
```

Then the day's steps as a FHIR Observation in the person's record (sandbox key `sk_test_…`):

```bash
curl -X POST https://platform.anpheros.com/fhir/R4/Observation \
  -H "Authorization: Bearer $ANPHEROS_KEY" \
  -H "Content-Type: application/fhir+json" \
  -H "X-Anpheros-Author-Type: device" \
  -d '{"resourceType":"Observation","status":"final",
       "category":[{"coding":[{"system":"http://terminology.hl7.org/CodeSystem/observation-category","code":"activity"}]}],
       "code":{"coding":[{"system":"http://loinc.org","code":"41950-7","display":"Number of steps in 24 hour Measured"}]},
       "subject":{"reference":"Patient/<id>"},
       "effectivePeriod":{"start":"2026-11-02T00:00:00+01:00","end":"2026-11-02T23:59:59+01:00"},
       "valueQuantity":{"value":11320,"unit":"{steps}","system":"http://unitsofmeasure.org","code":"{steps}"},
       "device":{"display":"COROS watch (COROS app)"}}'
```

The same in Python: daily step totals become one Observation per day, sent together in one transaction Bundle.

```python
import os, requests

FHIR = "https://platform.anpheros.com/fhir/R4"
fhir = {"Authorization": f"Bearer {os.environ['ANPHEROS_KEY']}", "Content-Type": "application/fhir+json",
        "X-Anpheros-Author-Type": "device"}
TZ = "+01:00"  # the person's UTC offset

# Daily step totals your backend already has from COROS:
# queryDailyHealthData (COROS MCP) or getDailyData (Partner API).
steps_by_day = {"2026-11-01": 9874, "2026-11-02": 11320}

entries = [{
    "request": {"method": "POST", "url": "Observation"},
    "resource": {
        "resourceType": "Observation", "status": "final",
        "category": [{"coding": [{"system": "http://terminology.hl7.org/CodeSystem/observation-category", "code": "activity"}]}],
        "code": {"coding": [{"system": "http://loinc.org", "code": "41950-7", "display": "Number of steps in 24 hour Measured"}]},
        "subject": {"reference": "Patient/<id>"},
        "effectivePeriod": {"start": f"{day}T00:00:00{TZ}", "end": f"{day}T23:59:59{TZ}"},
        "valueQuantity": {"value": steps, "unit": "{steps}", "system": "http://unitsofmeasure.org", "code": "{steps}"},
        "device": {"display": "COROS watch (COROS app)"},
    },
} for day, steps in steps_by_day.items()]

r = requests.post(FHIR, headers=fhir, json={"resourceType": "Bundle", "type": "transaction", "entry": entries})
print(r.status_code, len(entries), "days saved")
```

And in JavaScript (Node 18+), the day's resting heart rate:

```js
const fhir = { Authorization: `Bearer ${process.env.ANPHEROS_KEY}`, 'Content-Type': 'application/fhir+json' };

// From COROS: the queryRestingHeartRate MCP tool, or daily data from the Partner API.
const restingHeartRateForDay = { day: '2026-11-02', bpm: 48 };

await fetch('https://platform.anpheros.com/fhir/R4/Observation', {
  method: 'POST', headers: fhir,
  body: JSON.stringify({
    resourceType: 'Observation', status: 'final',
    category: [{ coding: [{ system: 'http://terminology.hl7.org/CodeSystem/observation-category', code: 'vital-signs' }] }],
    code: { coding: [{ system: 'http://loinc.org', code: '40443-4', display: 'Heart rate --resting' }] },
    subject: { reference: 'Patient/<id>' },
    effectivePeriod: { start: `${restingHeartRateForDay.day}T00:00:00+01:00`, end: `${restingHeartRateForDay.day}T23:59:59+01:00` },
    valueQuantity: { value: restingHeartRateForDay.bpm, unit: '/min', system: 'http://unitsofmeasure.org', code: '/min' },
    device: { display: 'COROS watch (COROS app)' },
  }),
});
```

COROS does not publish response field names for its MCP tools or Partner API, so the examples start from values your code has already read. The Anpheros side is standard FHIR R4, so the same requests work with any FHIR server. To avoid copies when a day is read again, give each Observation a stable identifier, as shown in [Wearable data in FHIR](https://developers.anpheros.com/guides/wearable-data-fhir).

## Ways to get COROS data into FHIR

| Path | Status | What you need |
|---|---|---|
| Your backend reads the COROS Partner API, then writes FHIR to Anpheros | **Works today** | Partner approval: an established platform with users, a registered company, security and privacy compliance, the COROS API Terms of Use |
| Your code reads the COROS MCP server, then writes FHIR to Anpheros | **Works today** | No application. Single-user access (each person authorizes their own data), polling only, no webhooks |
| COROS app → Apple Health → your iPhone app reads HealthKit → Anpheros | **Works today** | HealthKit permissions. Heart rate, sleep, steps and distances. See [Apple Health to FHIR](https://developers.anpheros.com/guides/apple-health-fhir) |
| COROS app → Health Connect → your Android app → Anpheros | **Works today** | Health Connect permissions. COROS lists Health Connect as a sync target but not the data types. See [Health Connect to FHIR](https://developers.anpheros.com/guides/health-connect-fhir) |
| A direct COROS connector inside Anpheros | **On our roadmap** | Not available yet. Use the button below to tell us you need it |

<!-- visual:cta-wear-coros -->

## The COROS API in short

**Access.** COROS offers three routes: people can connect COROS to an AI assistant; developers can build on the COROS MCP server without applying; and established platforms can apply for the Partner API. The MCP route is single-user (each person authorizes their own data), has no webhooks, no GPX import or export and no two-way activity sync. For the Partner API, email api@coros.com with company details, technical contacts and OAuth redirect URIs, and fill in the application form; COROS issues a client ID and secret after checking identity and security. COROS says it grants partner access to any platform that meets its requirements, in line with the GDPR and the EU Data Act. The COROS MCP is free; COROS does not state a Partner API price.

**Auth.** Both routes use OAuth 2.0. On the MCP server, access tokens last 30 days and refresh tokens 180 days, rotated on each refresh. The live OAuth metadata lists `/oauth2/authorize`, `/oauth2/token`, `/oauth2/revoke`, dynamic client registration at `/connect/register`, PKCE with S256, and the scopes `openid`, `mcp.tools` and `offline_access`. MCP hosts are region-specific: `mcpeu.coros.com` (Europe), `mcpus.coros.com` (US) and `mcpcn.coros.com` (Mainland China). Partner API token lifetimes and scope names are not public.

| Data | Endpoint (MCP tool or Partner API function) | Fields |
|---|---|---|
| Sleep | `querySleepOverview`, `querySleepHrv` | sleep, night HRV (up to 7 days per call) |
| Heart rate | `queryAvgHeartRate`, `queryRestingHeartRate` | average and resting heart rate |
| Steps and daily summary | `queryDailyHealthData` (MCP), `getDailyData` (Partner) | steps, calories, stress, sleep, heart rate (MCP default 7 days) |
| Workouts | `querySportRecords`, `getActivityDetail`, `downloadActivityFitFiles` (MCP); `getWorkoutRecords`, `getWorkoutDetailFit` (Partner) | Partner: 30-day window, 3-month lookback |
| Also | `queryStressTimeSeries`, `queryRecoveryStatus`, `queryMenstruationCycles`, training plans | |

The Partner API allows 1,000 calls per minute and pushes a webhook about 5 minutes after a workout, with retries. On the MCP server, FIT file downloads are capped at 50 per 24 hours per connected person; COROS publishes no other MCP limit. COROS published its self-service and Partner API pages in September 2026; the MCP changelog added training plan writes in September 2026 and GPX/KML route import in October 2026.

Sources: [COROS: connect your data](https://support.coros.com/hc/en-us/articles/53181260265492-Connect-Your-Data), [Build on COROS MCP](https://support.coros.com/hc/en-us/articles/53181619102996-Build-on-COROS-MCP), [Partner API access](https://support.coros.com/hc/en-us/articles/53181766856724-Partner-API-Access), [COROS MCP on GitHub](https://github.com/coroslab/COROS-MCP), [COROS and Apple Health](https://support.coros.com/hc/en-us/articles/360041549551-Connecting-Apple-Health-with-COROS-App), [supported third-party apps](https://support.coros.com/hc/en-us/articles/360040256531-Supported-3rd-Party-Apps), November 2026.

## COROS data as FHIR Observations

| COROS data | LOINC | UCUM unit | Note |
|---|---|---|---|
| Sleep duration | 93832-4 | `min` | one per night |
| Steps | 41950-7 | `{steps}` | one per day |
| Average heart rate | 8867-4 | `/min` | one per day |
| Resting heart rate | 40443-4 | `/min` | one per day |
| HRV (`querySleepHrv`) | see note | `ms` | COROS does not name the statistic in its public docs; do not file it under LOINC 80404-7 unless it is SDNN. See [Wearable data in FHIR](https://developers.anpheros.com/guides/wearable-data-fhir) |
| Stress, recovery status, training load | none | | COROS scores with no LOINC code; keep them under your own code system or leave them out |

## Frequently asked questions

### Is there a public COROS API?
Not an open REST API. The COROS Partner API is for approved, established platforms, and the self-service COROS MCP server lets each person authorize their own data without an application.

### How do I get access to the COROS API?
For the Partner API, email api@coros.com with your company details, technical contacts and OAuth redirect URIs, and fill in COROS's application form. For the MCP server, no application is needed.

### Is the COROS API free?
The COROS MCP server is free; AI platforms you use with it may charge separately. COROS does not state a price for the Partner API.

### What is the COROS API rate limit?
The Partner API allows 1,000 calls per minute. The MCP server caps FIT file downloads at 50 per 24 hours per person.

### Does COROS sync to Apple Health?
Yes. The COROS app writes heart rate, sleep analysis, steps and walking, running, cycling and swimming distances to Apple Health. COROS also lists Health Connect as a sync target.

### Does Anpheros connect to COROS directly?
Not yet. Today your code reads COROS (or HealthKit / Health Connect on the phone) and writes standard FHIR to Anpheros. A direct COROS connector is on our roadmap; tell us with the button on this page if you need it.

## Related

- [Wearable APIs: every brand compared](https://developers.anpheros.com/guides/wearable-apis)
- [Wearable data in FHIR (Apple Health, Health Connect)](https://developers.anpheros.com/guides/wearable-data-fhir)
- [Apple Health (HealthKit) to FHIR](https://developers.anpheros.com/guides/apple-health-fhir)
- [Health Connect to FHIR](https://developers.anpheros.com/guides/health-connect-fhir)
- [Garmin API to FHIR](https://developers.anpheros.com/guides/garmin-api) · [Polar AccessLink API to FHIR](https://developers.anpheros.com/guides/polar-api) · [Suunto API to FHIR](https://developers.anpheros.com/guides/suunto-api)
