{"openapi":"3.1.0","info":{"title":"Cycling Performance API","version":"1.0.0","description":"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.","contact":{"name":"PremiumApi","url":"https://www.oanor.com/by/premiumapi"}},"servers":[{"url":"https://api.oanor.com/cycling-api","description":"oanor gateway"}],"tags":[{"name":"Cycling"},{"name":"Meta"}],"components":{"securitySchemes":{"oanorKey":{"type":"apiKey","in":"header","name":"x-oanor-key","description":"Get your key at https://www.oanor.com/developer/keys"}}},"security":[{"oanorKey":[]}],"paths":{"/v1/ftp-zones":{"get":{"operationId":"get_v1_ftp_zones","tags":["Cycling"],"summary":"Coggan FTP power zones","description":"","parameters":[{"name":"ftp","in":"query","required":true,"description":"FTP watts","schema":{"type":"string"},"example":"250"}],"security":[{"oanorKey":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"example":{"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%+","min_watts":378}],"ftp_watts":250},"meta":{"timestamp":"2026-06-03T17:42:04.540Z","request_id":"9993966a-9b3a-4bed-afa3-2b518d2e25e9"},"status":"ok","message":"FTP zones","success":true}}}},"401":{"description":"Missing or invalid x-oanor-key header"},"402":{"description":"Active subscription required"},"429":{"description":"Rate-limit or monthly quota reached"},"502":{"description":"Upstream did not respond"}}}},"/v1/power":{"get":{"operationId":"get_v1_power","tags":["Cycling"],"summary":"Estimate cycling power","description":"","parameters":[{"name":"speed","in":"query","required":true,"description":"km/h","schema":{"type":"string"},"example":"30"},{"name":"weight","in":"query","required":true,"description":"Rider+bike kg","schema":{"type":"string"},"example":"75"},{"name":"grade","in":"query","required":false,"description":"Gradient %","schema":{"type":"string"},"example":"0"},{"name":"cda","in":"query","required":false,"description":"Drag area m²","schema":{"type":"string"},"example":"0.3"},{"name":"crr","in":"query","required":false,"description":"Rolling coeff","schema":{"type":"string"},"example":"0.005"}],"security":[{"oanorKey":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"example":{"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}}}},"401":{"description":"Missing or invalid x-oanor-key header"},"402":{"description":"Active subscription required"},"429":{"description":"Rate-limit or monthly quota reached"},"502":{"description":"Upstream did not respond"}}}},"/v1/vam":{"get":{"operationId":"get_v1_vam","tags":["Cycling"],"summary":"Vertical ascent metres/hour","description":"","parameters":[{"name":"elevation","in":"query","required":false,"description":"m climbed","schema":{"type":"string"},"example":"1000"},{"name":"time","in":"query","required":false,"description":"minutes","schema":{"type":"string"},"example":"60"},{"name":"speed","in":"query","required":false,"description":"or km/h","schema":{"type":"string"}},{"name":"grade","in":"query","required":false,"description":"and %","schema":{"type":"string"}}],"security":[{"oanorKey":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"example":{"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}}}},"401":{"description":"Missing or invalid x-oanor-key header"},"402":{"description":"Active subscription required"},"429":{"description":"Rate-limit or monthly quota reached"},"502":{"description":"Upstream did not respond"}}}},"/v1/meta":{"get":{"operationId":"get_v1_meta","tags":["Meta"],"summary":"Spec","description":"","parameters":[],"security":[{"oanorKey":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"example":{"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":[],"returns":"this document"}],"description":"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 zones use a heart-rate API."},"meta":{"timestamp":"2026-06-03T17:42:04.808Z","request_id":"dc10b5a2-1a91-4d6e-9f41-41216ca4bfa3"},"status":"ok","message":"Meta","success":true}}}},"401":{"description":"Missing or invalid x-oanor-key header"},"402":{"description":"Active subscription required"},"429":{"description":"Rate-limit or monthly quota reached"},"502":{"description":"Upstream did not respond"}}}}},"x-oanor-pricing":[{"slug":"free","name":"Free","price_cents_month":0,"monthly_call_quota":8335,"rps_limit":2,"hard_limit":true},{"slug":"starter","name":"Starter","price_cents_month":985,"monthly_call_quota":17850,"rps_limit":8,"hard_limit":true},{"slug":"pro","name":"Pro","price_cents_month":2975,"monthly_call_quota":229500,"rps_limit":20,"hard_limit":true},{"slug":"mega","name":"Mega","price_cents_month":6775,"monthly_call_quota":1190000,"rps_limit":50,"hard_limit":true}],"x-oanor-marketplace-url":"https://www.oanor.com/api/cycling-api"}