v1
sweeps

Create Sweep V1

Submit a batch parameter sweep (one Cartesian grid of operating points).

Every grid point is one powertrain solve; a sweep can range from a handful to the 10,000-point ceiling.

Submit the grid as ONE sweep rather than N single-point POSTs: the batch is prepared once and reused across every compatible point, so a large grid returns far sooner than the same points submitted one at a time. One request replaces N, with no offsetting cost.

It is not a price advantage. A sweep bills one compute unit per evaluation point per physical rotor — the same as running those points individually — so a 400-point grid on a quad costs 1,600 CU either way. Two limits bound a submission: at most 10,000 points per sweep, and rotors x points <= max_sweep_work for the caller's plan (422 sweep_limit_exceeded names the plan's ceiling and the requested figure).

Example — one numeric axis (7 points)::

POST /v1/sweeps
Idempotency-Key: <uuid>
{
  "project_id": "proj_…",
  "rotors": [{"label": "Main",
              "motor_component_id": "comp_…",
              "propeller_component_id": "comp_…",
              "throttle_pct": 100}],
  "battery_component_id": "comp_…",
  "density_kg_m3": 1.225,
  "airspeed_m_s": 0,
  "cooling_source": "prop_slipstream",
  "sweep": {"throttle": {"mode": "range", "start": 40, "stop": 100, "steps": 7},
            "rotor_sweep_mask": [true]}
}

Example — a propeller axis crossed with throttle (20 x 13 = 260 points)::

POST /v1/sweeps
Idempotency-Key: <uuid>
{
  "project_id": "proj_…",
  "rotors": [{"label": "Main",
              "motor_component_id": "comp_…",
              "propeller_component_id": "comp_…",
              "throttle_pct": 100}],
  "battery_component_id": "comp_…",
  "density_kg_m3": 1.225,
  "airspeed_m_s": 0,
  "sweep": {
    "throttle": {"mode": "range", "start": 40, "stop": 100, "steps": 13},
    "rotor_sweep_mask": [true],
    "component_axes": [
      {"axis": "propeller", "slots": [0],
       "component_ids": ["comp_…", "comp_…", "…20 ids…"]}
    ]
  }
}

A component axis is a full grid dimension: it crosses every numeric axis, so the example above solves each of the 20 propellers at all 13 throttles. slots names the rotor positions the chosen component is swapped into — list more than one to move them together as ONE shared dimension rather than a cross-product. Each point's inputs.component[] names which component it used, and GET /v1/sweeps/{id} echoes the axis as component id + name references.

Returns 202 Accepted with the sweep resource (total_points, completed_points, credits_breakdown); poll GET /v1/sweeps/{id} or stream progress via SSE.

post/v1/sweeps

Request

  • Base URL: https://thrustlab.com
  • URL: https://thrustlab.com/v1/sweeps
  • Auth: HTTP bearer

Headers

Idempotency-Keystring required

Unique key (max 255 chars) making this POST safe to retry. Required on all v1 write requests; replays return the cached response.

Request body

airspeed_m_snumber required
ambient_temp_cnumber
battery_charge_pctnumber
battery_component_idstring nullable
battery_esc_wire_resistance_mohmnumber
cooling_source'static' | 'airspeed' | 'prop_slipstream' | 'forced_air' nullable

Cooling source for the battery convection coefficient — static (natural only) | airspeed (free-stream v_inf) | prop_slipstream (prop induced velocity) | forced_air (fixed velocity). Supersedes the fixed cooling-regime h-table; omit it to resolve the value from the deprecated flight_regime..

density_kg_m3number required
flight_durationnumber nullable

Flight time (seconds) for the time-bounded steady-state thermal solve. 0 ≤ x ≤ 86400 (24 h). null disables time-bounding (infinite-hover baseline)..

flight_regime'static_bench' | 'prop_wash_mild' | 'prop_wash_strong' | 'forced_air'

DEPRECATED — use cooling_source instead. Still accepted: when cooling_source is omitted, this value is mapped to the equivalent battery cooling source (prop_wash_mild and prop_wash_strong → prop_slipstream, forced_air → forced_air, static_bench → static). cooling_source wins whenever both are supplied.

forced_air_velocity_m_snumber nullable

Fixed cooling velocity (m/s) for cooling_source='forced_air' (fan/duct). Ignored for the other cooling sources; defaults to 10 m/s when omitted..

inflow_mode'ground' | 'components'
launch_intent'run' | 'queue' | 'draft'

What to do with the sweep once it is stored. run (the default) reserves the credits and hands it to a worker immediately. queue reserves the credits but parks the sweep — it stays queued with dispatched_at null until you dispatch it with POST /v1/simulations/run-queued (every parked run) or POST /v1/simulations/run-selected (named ids; a sweep id is accepted there). draft stores it with no credit reservation and no dispatch; promote it later with POST /v1/sweeps/{id}/promote. Dynamic runs have no parked state — they always dispatch.

namestring nullable
project_idstring nullable

Project to file this sweep in (raw UUID or proj_<ksuid>). Omit to use the account's default project, which is created if absent.

propeller_model'fast' | 'full'

Propeller model for every rotor and every point of this sweep. 'full' runs from measured blade geometry; 'fast' runs from the printed label and accepts a propeller_label per rotor.

vertical_speed_m_snumber

Response

Successful Response

analysis_typestring required
battery_component_idstring required
cancel_requested_atstring nullable

When a cancel was requested for a RUNNING sweep. The status stays running until the worker honours it at its next point, keeping the points already solved. Null when no cancel was requested; a QUEUED sweep cancels immediately instead and never sets this.

completed_atstring nullable

When the sweep reached a terminal state — completed, failed or canceled. Null until then.

completed_pointsinteger required
created_atstring nullable

When the sweep was submitted.

credits_costinteger required
dispatched_atstring nullable

When the sweep was handed to the worker queue. Null while it is parked and has never been dispatched. NOT the start of execution: launch_intent=run dispatches at submit, so this can equal created_at while the sweep waits for a slot.

errorobject nullable required
idstring required
input_snapshotobject nullable
is_starredboolean required
namestring nullable required
object'sweep' required
plot_config_jsonobject[] nullable required
progressnumber nullable required
project_idstring required
propeller_modelstring
snapshot_versioninteger
solver_enginestring
started_atstring nullable

When a worker claimed the sweep and solving began. Null until then. started_at - dispatched_at is the wait for a slot; completed_at - started_at is the solve itself.

status'draft' | 'queued' | 'running' | 'completed' | 'failed' | 'canceled' required
summaryobject nullable required
sweep_configobject nullable required
total_pointsinteger required

Changes

No recorded changes to this operation across all 1 revision of this API.