# Cycling Performance API
> Cycling performance maths as an API. The power endpoint estimates the power in watts needed to ride at a given speed on a given gradient, from a physical model — rolling resistance, gravity on the climb, and aerodynamic drag — with sensible defaults you can override (rolling-resistance coefficient, drag area CdA, air density, drivetrain efficiency and headwind), and breaks the power down into its rolling, gravity and aero components plus watts-per-kilogram. The ftp-zones endpoint turns a Functional Threshold Power into the seven Coggan training zones, from active recovery to neuromuscular power, as watt ranges. The vam endpoint computes VAM — vertical ascent metres per hour, the climbing-speed metric — either from elevation gained and time, or from speed and gradient. Everything is computed locally and deterministically, so it is instant and private. Ideal for cycling and training apps, bike computers and power-meter tools, coaching, and route and climb analysis. Pure local computation — no key, no third-party service, instant. Live, nothing stored. 4 endpoints. This is cycling maths; for running pace use a pace API and for heart-rate training zones use a heart-rate API.

## Authentication
All requests require your oanor API key in the `x-oanor-key` header. Get one at https://www.oanor.com/developer/keys.

```bash
curl -H "x-oanor-key: oanor_live_…" "https://api.oanor.com/cycling-api/..."
```

## Pricing
- **Free** (Free) — 8,335 calls/Mo, 2 req/s
- **Starter** ($10/Mo) — 17,850 calls/Mo, 8 req/s
- **Pro** ($30/Mo) — 229,500 calls/Mo, 20 req/s
- **Mega** ($68/Mo) — 1,190,000 calls/Mo, 50 req/s

## Endpoints

### Cycling

#### `GET /v1/ftp-zones` — Coggan FTP power zones

**Parameters:**
- `ftp` (query, required, string) — FTP watts Example: `250`

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/cycling-api/v1/ftp-zones?ftp=250"
```

**Response:**
```json
{
    "data": {
        "zones": [
            {
                "name": "Active Recovery",
                "zone": 1,
                "percent": "0–55%",
                "max_watts": 138,
                "min_watts": 0
            },
            {
                "name": "Endurance",
                "zone": 2,
                "percent": "56–75%",
                "max_watts": 188,
                "min_watts": 140
            },
            {
                "name": "Tempo",
                "zone": 3,
                "percent": "76–90%",
                "max_watts": 225,
                "min_watts": 190
            },
            {
                "name": "Lactate Threshold",
                "zone": 4,
                "percent": "91–105%",
                "max_watts": 263,
                "min_watts": 228
            },
            {
                "name": "VO2 Max",
                "zone": 5,
                "percent": "106–120%",
                "max_watts": 300,
                "min_watts": 265
            },
            {
                "name": "Anaerobic Capacity",
                "zone": 6,
                "percent": "121–150%",
                "max_watts": 375,
                "min_watts": 303
            },
            {
                "name": "Neuromuscular Power",
                "zone": 7,
                "percent": "151%+",
                "max_watts": null,
                "min_watts": 378
            }
        ],
        "ftp_watts": 250
    },
   
…(truncated, see openapi.json for full schema)
```

#### `GET /v1/power` — Estimate cycling power

**Parameters:**
- `speed` (query, required, string) — km/h Example: `30`
- `weight` (query, required, string) — Rider+bike kg Example: `75`
- `grade` (query, optional, string) — Gradient % Example: `0`
- `cda` (query, optional, string) — Drag area m² Example: `0.3`
- `crr` (query, optional, string) — Rolling coeff Example: `0.005`

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/cycling-api/v1/power?speed=30&weight=75&grade=0&cda=0.3&crr=0.005"
```

**Response:**
```json
{
    "data": {
        "speed_kmh": 30,
        "weight_kg": 75,
        "parameters": {
            "cda": 0.3,
            "crr": 0.005,
            "efficiency": 0.97,
            "air_density": 1.225,
            "headwind_kmh": 0
        },
        "power_watts": 141.22,
        "watts_per_kg": 1.883,
        "grade_percent": 0,
        "breakdown_watts": {
            "gravity": 0,
            "rolling": 31.594,
            "aerodynamic": 109.63
        }
    },
    "meta": {
        "timestamp": "2026-06-03T17:42:04.650Z",
        "request_id": "4fc5c651-5b28-491f-903a-abecf1f4e749"
    },
    "status": "ok",
    "message": "Power",
    "success": true
}
```

#### `GET /v1/vam` — Vertical ascent metres/hour

**Parameters:**
- `elevation` (query, optional, string) — m climbed Example: `1000`
- `time` (query, optional, string) — minutes Example: `60`
- `speed` (query, optional, string) — or km/h
- `grade` (query, optional, string) — and %

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/cycling-api/v1/vam?elevation=1000&time=60"
```

**Response:**
```json
{
    "data": {
        "mode": "from elevation & time",
        "time_min": 60,
        "elevation_m": 1000,
        "vam_m_per_h": 1000
    },
    "meta": {
        "timestamp": "2026-06-03T17:42:04.739Z",
        "request_id": "43aa179f-0bb7-4835-86cd-cb4673c3fd24"
    },
    "status": "ok",
    "message": "VAM",
    "success": true
}
```

### Meta

#### `GET /v1/meta` — Spec

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/cycling-api/v1/meta"
```

**Response:**
```json
{
    "data": {
        "name": "Cycling Performance API",
        "notes": "Power model: (Crr·m·g·cosθ + m·g·sinθ + ½·ρ·CdA·v_air²)·v / efficiency. FTP zones are the Coggan/Allen levels. Nothing is stored.",
        "version": "v1",
        "endpoints": [
            {
                "path": "/v1/power",
                "params": {
                    "cda": "drag area m² (0.3)",
                    "crr": "rolling coeff (0.005)",
                    "grade": "% (default 0)",
                    "speed": "km/h",
                    "weight": "rider+bike kg",
                    "headwind": "km/h",
                    "efficiency": "0-1 (0.97)",
                    "air_density": "kg/m³ (1.225)"
                },
                "returns": "the power in watts and its breakdown"
            },
            {
                "path": "/v1/ftp-zones",
                "params": {
                    "ftp": "Functional Threshold Power in watts"
                },
                "returns": "the seven Coggan power zones"
            },
            {
                "path": "/v1/vam",
                "params": {
                    "time": "minutes",
                    "grade": "and %",
                    "speed": "or km/h",
                    "elevation": "m climbed"
                },
                "returns": "VAM (vertical ascent metres per hour)"
            },
            {
                "path": "/v1/meta",
                "params": [],
                "r
…(truncated, see openapi.json for full schema)
```


---
Marketplace page: https://www.oanor.com/api/cycling-api
OpenAPI spec: https://www.oanor.com/api/cycling-api/openapi.json
