---
title: "Schedule Sim Batch"
method: POST
path: "/api/v1/sim-batches"
tags: ["simulated runs"]
---

# Schedule Sim Batch

`POST /api/v1/sim-batches`

## Request

- Base URL: `https://api.brumby.com` (the document declares no server; this is the origin it was published from)
- URL: `https://api.brumby.com/api/v1/sim-batches`
- Auth: HTTP bearer

## Request body

- SimBatchCreate: Schedule a sweep.
  - `name` string, required
  - `weather` SimWeather
    - `wind` SimWind
      - `speed_ms` number
      - `from_deg` number
      - `vertical_ms` number
      - `gust` SimGust
        - `enabled` boolean
        - `magnitude_sigma_ms` number
        - `direction_sigma_deg` number
        - `magnitude_time_constant_s` number
        - `direction_time_constant_s` number
        - `peak_sigma` number
    - `air` SimAir
      - `temperature_c` number
      - `humidity_pct` number
      - `rain` boolean
      - `visibility_m` number
      - `cloud_base_ft` number
    - `time_of_day_h` number
  - `farm_id` string, required
  - `device_id` string, required
  - `dispatch` 'launch' | 'headless': How a simulated run reaches an aircraft, and therefore who authorises it. LAUNCH is the ordinary path and the only one that flies anything: the run schedules a mission request exactly as the customer app does, a pilot signs the JSA and presses LAUNCH, and the dock delivers. FleetOps adds nothing to that sequence and skips nothing in it. HEADLESS never asks a dock for anything. The bench composes the same mission config from the same farm and runs it against a stub dock, so there is no clearance to grant, no aircraft to arm and nothing to authorise -- which is why there is no JSA on it. A sweep of two hundred seeds is this one; a run you want a flight record for is the other.
  - `autonomy_host` 'bench' | 'jetson'
  - `matrix` SimMatrix: The axes of a sweep. The cells are their product, in this order. Empty list means "the one default": no paddock given flies the farm's default; no seed given assigns a fresh recorded seed to each cell. So a matrix with nothing in it is one run, which is what makes a single run and a sweep the same object rather than two.
    - `paddocks` string[]
    - `seeds` integer[]
    - `cows` integer[]
    - `repeats` integer
    - `herd` SimHerd: How many head, placed how, for one run. Every field is optional and an omitted one means "whatever the sim's own cattle sheet says". That matters: a sweep over seeds should not have to restate the mob profiles to leave them alone, and a run with an empty herd spec is exactly the run `pixi run sim` gives you today.
      - `seed` integer, nullable
      - `cows` integer, nullable
      - `clusters` integer, nullable
      - `cluster_spread_m` number, nullable
      - `stragglers` integer, nullable
      - `profile_mix` object, nullable
  - `notes` string, nullable
  - `mission_id` string, nullable

## Response `201`

Successful Response

- SimBatchDetailResponse
  - `batch_id` string, uuid, required
  - `name` string, required
  - `farm_id` string, required
  - `device_id` string, required
  - `dispatch` 'launch' | 'headless', required: How a simulated run reaches an aircraft, and therefore who authorises it. LAUNCH is the ordinary path and the only one that flies anything: the run schedules a mission request exactly as the customer app does, a pilot signs the JSA and presses LAUNCH, and the dock delivers. FleetOps adds nothing to that sequence and skips nothing in it. HEADLESS never asks a dock for anything. The bench composes the same mission config from the same farm and runs it against a stub dock, so there is no clearance to grant, no aircraft to arm and nothing to authorise -- which is why there is no JSA on it. A sweep of two hundred seeds is this one; a run you want a flight record for is the other.
  - `matrix` object, required
  - `notes` string, nullable, required
  - `created_by` string, required
  - `created_at` string, date-time, required
  - `cancelled_at` string, date-time, nullable, required
  - `run_count` integer, required
  - `state_counts` object, required
  - `runs` SimRunResponse[], required
    - `run_id` string, uuid, required
    - `batch_id` string, uuid, nullable, required
    - `ordinal` integer, required
    - `farm_id` string, required
    - `device_id` string, required
    - `world_slug` string, required
    - `paddock` string, nullable, required
    - `autonomy_host` 'bench' | 'jetson'
    - `simulator_host` string, nullable
    - `runner_launch_mode` 'worker' | 'command'
    - `weather` object
    - `mission_config` object, nullable
    - `mission_plan_id` string, uuid, nullable
    - `mission_plan_revision` integer, nullable
    - `claim_token` string, uuid, nullable
    - `lease_expires_at` string, date-time, nullable
    - `cancel_requested` boolean
    - `herd` object, required
    - `dispatch` 'launch' | 'headless', required: How a simulated run reaches an aircraft, and therefore who authorises it. LAUNCH is the ordinary path and the only one that flies anything: the run schedules a mission request exactly as the customer app does, a pilot signs the JSA and presses LAUNCH, and the dock delivers. FleetOps adds nothing to that sequence and skips nothing in it. HEADLESS never asks a dock for anything. The bench composes the same mission config from the same farm and runs it against a stub dock, so there is no clearance to grant, no aircraft to arm and nothing to authorise -- which is why there is no JSA on it. A sweep of two hundred seeds is this one; a run you want a flight record for is the other.
    - `state` 'pending' | 'requested' | 'claimed' | 'running' | 'succeeded' | 'failed' | 'cancelled', required: Where one cell of a sweep has got to. PENDING through FINISHED is the bench's own progress. REQUESTED is where a LAUNCH run waits: its mission request exists and the pilot's queue owns it from there, so FleetOps deliberately stops describing it -- the request's own state is the answer, and a copy here would be a second one.
    - `mission_request_id` string, uuid, nullable, required
    - `simulation_run_id` string, uuid, nullable, required
    - `claimed_by` string, nullable, required
    - `claimed_at` string, date-time, nullable, required
    - `started_at` string, date-time, nullable, required
    - `finished_at` string, date-time, nullable, required
    - `outcome` object, nullable, required
    - `failure` string, nullable, required
    - `created_by` string, required
    - `created_at` string, date-time, required

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/brumby/apis/brumby-platform-api.md) - [All operations](https://skmtc.dev/brumby/apis/brumby-platform-api/llms.txt) - [OpenAPI document](https://skmtc.dev/brumby/apis/brumby-platform-api/revisions/fe185e20813e?raw)
