---
title: "Batch Create Measurements"
method: POST
path: "/api/v1/measurements/batch"
tags: ["measurements"]
---

# Batch Create Measurements

`POST /api/v1/measurements/batch`

All-or-nothing batch insert. Used by copy/paste and, with `link: true`, by
the RUD-263 linked draw.

Iterates the items inside one transaction; any per-item validation
failure surfaces as 422 and the whole transaction rolls back. Order
of `items` in the response matches the request order so the client
can map each result back to its originating temp id.

With `link: true` the items become one locked link group. Per the repo's
existing key-becomes-identity idiom (`routes/annotated_pdf_exports.py`,
`routes/pdf_markup_imports.py`), an `Idempotency-Key` header BECOMES the
group id; without one the server mints a uuid4. A retry carrying the same key
finds the group already populated and returns those rows with 200 instead of
minting a second group and duplicating N rows.

## Headers

- `Idempotency-Key` string, uuid, nullable

## Request body

- BatchCreateMeasurementRequest — All-or-nothing batch insert. Used by copy/paste; the server runs every item inside one transaction. `min_length=1` rejects an empty paste at the boundary; `max_length=500` is a defensive cap, not user-facing — the v1 UI cannot realistically drive a batch this large.
  - `items` CreateMeasurementRequest[], required
    - `condition_id` string, uuid, required
    - `page_id` string, uuid, required
    - `geometry` union, required
      - PointGeometryInput
        - `type` 'point', required
        - `x` union, required
          - number
          - string
        - `y` union, required
          - number
          - string
        - `rotation` union
          - number
          - string
      - PolylineGeometryInput
        - `type` 'polyline', required
        - `points` array[], required
          - unknown[]
            - unknown
        - `bulges` union[], nullable
          - union
            - number
            - string
      - PolygonGeometryInput
        - `type` 'polygon', required
        - `points` array[], required
          - unknown[]
            - unknown
        - `holes` array[], nullable
          - array[]
            - unknown[]
              - …
        - `grid` GridAlignmentInput — Rebar-grid pose for an area measurement (spec 2026-07-13 §5.2). Stored inside geometry JSONB — additive, no DDL (ADR-0097 precedent). angle_deg is CCW-positive PDF user-space, normalized to [0, 180): a line family has 180° symmetry, unlike marker glyphs' [0, 360). New normalizer — borrows only the round-then-normalize technique from ADR-0097.
          - `origin` unknown[], required
            - unknown
          - `angle_deg` union
            - number
            - string
    - `name` string, nullable
    - `bid_area_id` string, uuid, nullable
  - `revision_set_id` string, uuid, nullable, required
  - `link` boolean, nullable

## Response `201`

Successful Response

- BatchCreateMeasurementResponse — Server response. Preserves request order so the client can match each result with its originating temp id.
  - `items` Measurement[], required
    - `id` string, uuid, required
    - `condition_id` string, uuid, required
    - `page_id` string, uuid, required
    - `scale_region_id` string, uuid, nullable
    - `geometry` union, required
      - PointGeometryOutput
        - `type` 'point', required
        - `x` string, required
        - `y` string, required
        - `rotation` string, nullable
      - PolylineGeometryOutput
        - `type` 'polyline', required
        - `points` array[], required
          - unknown[]
            - unknown
        - `bulges` string[], nullable
      - PolygonGeometryOutput
        - `type` 'polygon', required
        - `points` array[], required
          - unknown[]
            - unknown
        - `holes` array[], nullable
          - array[]
            - unknown[]
              - …
        - `grid` GridAlignmentOutput — Rebar-grid pose for an area measurement (spec 2026-07-13 §5.2). Stored inside geometry JSONB — additive, no DDL (ADR-0097 precedent). angle_deg is CCW-positive PDF user-space, normalized to [0, 180): a line family has 180° symmetry, unlike marker glyphs' [0, 360). New normalizer — borrows only the round-then-normalize technique from ADR-0097.
          - `origin` unknown[], required
            - unknown
          - `angle_deg` string
    - `name` string, nullable
    - `computed_value` string, nullable, required
    - `computed_derivations` DerivationValue[]
      - `ordinal` integer, required
      - `result_type` 'count' | 'total_height' | 'perimeter' | 'surface_area_top_or_bottom' | 'surface_area_top_and_bottom' | 'surface_area_all_sides' | 'surface_area_full' | 'volume' | 'length' | 'segment_count' | 'surface_area_single_side' | 'surface_area_both_sides' | 'surface_area_single_end' | 'surface_area_both_ends' | 'surface_area_all_side_duct' | 'area' | 'grid_length_visible' | 'grid_length_x_visible' | 'grid_length_y_visible' | 'grid_intersection_count' | 'tile_count_average' | 'tile_count_visible' | 'area_counts', required
      - `uom` 'EA' | 'LF' | 'IN' | 'FT' | 'SF' | 'SY' | 'CF' | 'CY', required
      - `value` number, required
    - `effective_multiplier` string
    - `extension_values` object
    - `bid_area_id` string, uuid, nullable
    - `ambiguous` boolean
    - `link_group_id` string, uuid, nullable
    - `created_at` string, date-time, required

## Other responses

- `4XX` — Client Error
- `5XX` — Server Error

---

[API](https://skmtc.dev/rudus/apis/rudus-api.md) · [All operations](https://skmtc.dev/rudus/apis/rudus-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/rudus/rudus-api/revisions/f149124a4d80/schema)
