RotorLabDevelopers
RotorLab API

Build with the physics engine

A small, key-authenticated HTTP API over the same momentum-theory engine the app uses. Analyze any build, read the parts catalog and airframe types, and manage your own saved builds — from your scripts, notebooks, or apps.

Download OpenAPI spec Download Postman collection Get an API key

Import the OpenAPI file into editor.swagger.io or any client to get a full interactive reference, or load the Postman collection and set base_url + api_key.

Quickstart

1 · Create your key

Sign in, open My account → API access, and click Create API key. The key is shown once — copy it somewhere safe. It looks like rl_…. You can hold one active key; regenerating replaces it.

2 · Authenticate

Send your key as a bearer token (the header X-API-Key is also accepted). Base URL for this instance is /api/v1.

curl -H "Authorization: Bearer rl_your_key" \
  http://127.0.0.1:8765/api/v1/version

3 · Analyze a build

curl -X POST http://127.0.0.1:8765/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}'

The response has out (headline numbers — AUW, TWR, hover/cruise endurance, currents, top speed…), charts (inline SVG), and checks ([level, message] pairs).

Python

import requests
BASE = "http://127.0.0.1:8765/api/v1"
h = {"Authorization": "Bearer rl_your_key"}

r = requests.post(f"{BASE}/analyze", headers=h,
                  json={"airframe_type": "Quad X", "motor_count": 4, "prop_diameter_in": 7})
out = r.json()["out"]
print(f"AUW {out['auw_g']:.0f} g · TWR {out['twr']:.2f} · hover {out['hover_min']:.1f} min")

# save it to your library
requests.post(f"{BASE}/builds", headers=h,
              json={"name": "My quad", "params": {"airframe_type": "Quad X", "motor_count": 4}})

JavaScript (fetch)

const BASE = "http://127.0.0.1:8765/api/v1";
const h = { "Authorization": "Bearer rl_your_key", "Content-Type": "application/json" };
const res = await fetch(`${BASE}/analyze`, { method: "POST", headers: h,
  body: JSON.stringify({ airframe_type: "Quad X", motor_count: 4, prop_diameter_in: 7 }) });
const { out } = await res.json();
console.log(out.twr, out.hover_min);

Endpoints

All paths are under /api/v1 and scoped to the calling user. Builds you don't own return 404.

MethodPathDescriptionMetered
GET/versionAPI name, version, authorno
GET/usageYour quota, remaining, credit balanceno
GET/airframesSupported airframe typesyes
GET/catalogPayload parts catalogyes
POST/analyzeAnalyze a build → full resultsyes
GET/buildsList your saved buildsyes
GET/builds/{id}Fetch one of your buildsyes
POST/buildsCreate or overwrite a build by nameyes
DELETE/builds/{id}Delete one of your buildsyes

Quotas, credits & purchasing

Every request except version and usage spends one unit. Your plan sets a daily quota (resets at 00:00 UTC), spent first. Once it's gone, requests draw from your credit balance — credits come included with some plans, can be granted by an admin, or purchased from My account when monetization is enabled. When both are exhausted the API returns 429.

Every metered response carries X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Credits. A 429 also includes Retry-After (seconds until the daily reset). Check GET /api/v1/usage any time — it's free.

Errors

StatusMeaning
401Missing or invalid API key
404Unknown endpoint, or a build you don't own
400Malformed request body
429Daily quota and credits exhausted
RotorLab API · authored by KizzMyAnthia · the API is available when the server runs in multi-user mode (--web --auth).