API quickstart
The RotorLab API is a key-authenticated HTTP API over the same physics engine the app uses. You can analyze any build (multirotor, fixed wing, or VTOL), work out radio link budgets and center of gravity, read the parts catalog and airframe types, manage your saved builds, run log forensics, and file flight records, all from your own scripts and applications.
Every endpoint lives under one base URL:
https://rotorlab.app/api/v1Get a key#
- Sign in and open My account, then the API access section.
- Type a label in the What will use this key? field and press Create API key.
- Copy the key immediately. It is displayed once, at creation, and only its SHA-256 hash is stored. The key looks like
rl_....
Issue a separate named key for each integration, so revoking a compromised key does not affect the others. The list in API access shows each key's prefix, label, creation date, and when it was last used. Revoke removes one key; Revoke all keys removes every key on the account at once. See API access for the full key management page.
Device credentials
Ground stations and other equipment use a device credential instead of a personal key. A device credential belongs to your organization rather than to an individual, so it stays valid after the person who created it leaves, and it reaches only the flight, checklist, pilot roster, and aircraft registry endpoints.
Authenticate#
Send the key as a bearer token. The header X-API-Key is also accepted.
Authorization: Bearer rl_your_keyor
X-API-Key: rl_your_keyA missing or invalid key returns 401 with {"error": "Invalid or missing API key"}.
Your first call#
GET /version is free and unmetered, so it is the right endpoint to confirm your key works:
curl -H "Authorization: Bearer rl_your_key" \
https://rotorlab.app/api/v1/version{"name": "RotorLab", "version": "1.59.0", "author": "RotorLab.app"}Then read your own quota with GET /usage, also free:
curl -H "Authorization: Bearer rl_your_key" \
https://rotorlab.app/api/v1/usageThe response reports limit (requests per day from your plan), used, remaining, credits, the current UTC day, and a key object with your key's prefix, creation date, and last use.
Metering in brief#
- Every request spends one unit, except
versionandusage(so a blocked client can still read its own status) and the flight-record endpoints (flights,checklists,pilots,aircraft), because filing your own records is never metered. - Your plan sets a daily quota, spent first. It resets at 00:00 UTC.
- Once the quota is gone, requests draw from your credit balance. Credits come included with some plans, can be granted by an admin, or can be purchased from My account.
- When both are exhausted, the API returns
429with aRetry-Afterheader giving the seconds until the daily reset. - Every metered response carries
X-RateLimit-Limit,X-RateLimit-Remaining, andX-RateLimit-Credits, so your client always knows where it stands without spending a request. - A key whose trial or billing period has ended is refused with
403on metered endpoints;versionandusagestay open.
Worked example: analyze a build#
POST /analyze takes a build-parameters object and returns full performance results. Every field is optional; anything you leave out falls back to the example profile's defaults, so a minimal body is enough to get numbers.
curl#
curl -X POST https://rotorlab.app/api/v1/analyze \
-H "Authorization: Bearer rl_your_key" \
-H "Content-Type: application/json" \
-d '{"airframe_type":"Quad X","motor_count":4,"prop_diameter_in":7,"motor_kv":1700}'Python (standard library only)#
import json
import urllib.request
BASE = "https://rotorlab.app/api/v1"
KEY = "rl_your_key"
body = json.dumps({
"airframe_type": "Quad X",
"motor_count": 4,
"prop_diameter_in": 7,
"motor_kv": 1700,
}).encode("utf-8")
req = urllib.request.Request(
f"{BASE}/analyze", data=body, method="POST",
headers={"Authorization": f"Bearer {KEY}",
"Content-Type": "application/json"})
with urllib.request.urlopen(req) as resp:
result = json.load(resp)
out = result["out"]
print(f"AUW {out['auw_g']:.0f} g, TWR {out['twr']:.2f}, hover {out['hover_min']:.1f} min")
for level, message in result["checks"]:
print(f" [{level}] {message}")Reading the response#
| Key | What it holds |
|---|---|
out | Headline numbers: auw_g, twr, hover_min, currents, top speed, sag and thermal margins, and for winged builds stall_speed_kmh, cruise_speed_kmh, climb_rate_ms, wing_loading_n_m2 |
charts | Inline SVG chart strings, ready to embed |
checks | [level, message] pairs, where level is ok, warn, or bad |
lint | The same findings as checks, machine readable |
platform | Resolved platform description: airframe class, motor groups, layout |
cg | Center of gravity and balance result |
Which fields appear in out depends on the airframe: multirotors report hover figures, wings report stall, cruise, and climb, and VTOLs report both. Send a fixed-wing or VTOL airframe_type with your wing dimensions and the same endpoint returns the winged figures. GET /airframes lists every supported type.
Where to go next#
- The full endpoint list is in the API reference.
- Download the OpenAPI spec from https://rotorlab.app/openapi.json and import it into Swagger Editor or any OpenAPI client for an interactive reference.
- Download the Postman collection from https://rotorlab.app/rotorlab.postman_collection.json, then set the collection variables
base_urlandapi_key. Auth is applied at the collection level as a bearer token. - The in-app developer page at https://rotorlab.app/developers carries the same quickstart with copy-ready examples in curl, Python, and JavaScript.