---
title: "Add Site Plan"
method: POST
path: "/api/v1/farms/{farm_id}/site-plans"
tags: ["site plans"]
---

# Add Site Plan

`POST /api/v1/farms/{farm_id}/site-plans`

## 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/farms/{farm_id}/site-plans`
- Auth: HTTP bearer

Store a planner run. It is a draft until a variant is chosen.

## Path parameters

- `farm_id` string, required

## Request body

- SitePlanCreate
  - `device_id` string, nullable
  - `name` string, nullable
  - `paddock_ids` string[]
  - `ring` array[]
    - number[]
  - `settings` PlanSettings: The knobs the run used. Mirrors `PlanSettings` in web/lib/rf/plan.ts. Radio settings are the planner's own `RfLink[]`; FleetOps stores them verbatim rather than modelling a radio it never talks to.
    - `links` object[]
    - `objective` 'rfd' | 'both' | 'hm', nullable
    - `quality` 'reliable' | 'marginal' | 'limit', nullable
    - `bufferKm` number, nullable
    - `altitudeM` number, nullable
    - `kFactor` number, nullable
    - `miscLossDb` number, nullable
    - `vegetation` string, nullable
    - `vegetationAtDock` string, nullable
    - `repeater` PlanRepeaterSettings
      - `mastM` number, nullable
      - `bufferKm` number, nullable
      - `backhaulMarginDb` number, nullable
      - `vegetation` string, nullable
    - `targetCov` number, nullable
    - `caps` integer[]
    - `current` number[], nullable
    - `cellular` boolean, nullable
  - `variants` PlanVariant[]
    - `cap` integer, required
    - `repeaters` integer, required
    - `met` boolean
    - `cov` number
    - `dockAloneCov` number, nullable
    - `dock` PlannedNode, required: One mast the planner placed. Mirrors `PlannedNode` in web/lib/rf/plan.ts. Extra keys are kept: the planner may learn to report more about a site than FleetOps knows to ask for, and dropping it would lose provenance.
      - `kind` 'dock' | 'repeater', required
      - `lat` number, required
      - `lon` number, required
      - `el` number, nullable
      - `mastM` number, nullable
      - `cov` number, nullable
      - `p10` number, nullable
      - `p50` number, nullable
      - `worst` number, nullable
      - `hops` integer, nullable
      - `via` union
        - integer
        - 'dock'
      - `backhaul` 'rf' | 'cell' | 'sat' | 'wired' | 'none', nullable
      - `rfMarginDb` number, nullable
      - `usable` boolean, nullable
      - `gain` number, nullable
      - `link` 'rfd' | 'hm', nullable
    - `reps` PlannedNode[]
      - `kind` 'dock' | 'repeater', required
      - `lat` number, required
      - `lon` number, required
      - `el` number, nullable
      - `mastM` number, nullable
      - `cov` number, nullable
      - `p10` number, nullable
      - `p50` number, nullable
      - `worst` number, nullable
      - `hops` integer, nullable
      - `via` union
        - integer
        - 'dock'
      - `backhaul` 'rf' | 'cell' | 'sat' | 'wired' | 'none', nullable
      - `rfMarginDb` number, nullable
      - `usable` boolean, nullable
      - `gain` number, nullable
      - `link` 'rfd' | 'hm', nullable
    - `blocked` PlannedNode[]
      - `kind` 'dock' | 'repeater', required
      - `lat` number, required
      - `lon` number, required
      - `el` number, nullable
      - `mastM` number, nullable
      - `cov` number, nullable
      - `p10` number, nullable
      - `p50` number, nullable
      - `worst` number, nullable
      - `hops` integer, nullable
      - `via` union
        - integer
        - 'dock'
      - `backhaul` 'rf' | 'cell' | 'sat' | 'wired' | 'none', nullable
      - `rfMarginDb` number, nullable
      - `usable` boolean, nullable
      - `gain` number, nullable
      - `link` 'rfd' | 'hm', nullable
    - `latencyMs` object, nullable
    - `moved` boolean
    - `hitCap` boolean
  - `engine` PlanEngine: Provenance for the numbers: which engine, at what terrain zoom, with how many tiles it could not fetch. A plan computed over holes in the terrain is not the same evidence as one computed over all of it.
    - `engine_version` string, nullable
    - `terrain_zoom` integer, nullable
    - `terrain_tiles_missing` integer, nullable
    - `computed_at` string, date-time, nullable

## Response `201`

Successful Response

- SitePlanResponse
  - `site_plan_id` string, uuid, required
  - `farm_id` string, required
  - `device_id` string, nullable, required
  - `name` string, nullable, required
  - `status` string, required
  - `paddock_ids` string[], required
  - `ring` array[], required
    - number[]
  - `settings` object, required
  - `variants` object[], required
  - `chosen_variant` integer, nullable, required
  - `engine` object, required
  - `base_stations` BaseStationResponse[]
    - `base_station_id` string, uuid, required
    - `farm_id` string, required
    - `name` string, required
    - `lat` number, required
    - `lon` number, required
    - `ground_elevation_m` number, nullable, required
    - `mast_height_m` number, required
    - `radios` unknown[], required
      - unknown
    - `source` string, required
    - `planning` object, nullable, required
    - `notes` string, nullable, required
    - `created_by` string, required
    - `archived_at` string, date-time, nullable, required
    - `created_at` string, date-time, required
    - `updated_at` string, date-time, required
    - `kind` string
    - `status` string
    - `device_id` string, nullable
    - `site_plan_id` string, uuid, nullable
    - `sort_order` integer
    - `backhaul` object, nullable
  - `created_by` string, required
  - `archived_at` string, date-time, nullable, required
  - `created_at` string, date-time, required
  - `updated_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)
