---
title: "Turn a sheet for display"
method: PUT
path: "/v1/blueprints/{blueprint_id}/rotation"
tags: ["Blueprints"]
---

# Turn a sheet for display

`PUT /v1/blueprints/{blueprint_id}/rotation`

## Request

- Base URL: `https://api.kamai.io` (the document declares no server; this is the origin it was published from)
- URL: `https://api.kamai.io/v1/blueprints/{blueprint_id}/rotation`
- Auth: HTTP bearer

Set how far the sheet is turned for display: `rotation` is 0, 90, 180 or 270 degrees clockwise,
relative to the tiles as served. The value is absolute, so repeating a call changes nothing.

A view setting only. Tiles, the PDF, `url_width`/`url_height`, every `geometry` and the words stay
exactly as they were, in the same coordinates, and so does `revision`: a `base_revision` read before
the turn still saves. Apply `rotation` yourself when you draw the sheet, to the image and the overlays
alike. `auto_rotation` (read-only) is how far Kamai already turned the page at upload; it is inside the
tiles and geometry. To undo a wrong upload turn, set `rotation` to `(360 - auto_rotation) % 360`.

Any other value is refused with 422. The answer is the sheet as `GET` returns it.

## Path parameters

- `blueprint_id` string, required

## Request body

- BlueprintRotationRequest
  - `rotation` 0 | 90 | 180 | 270, required: Degrees clockwise to turn the sheet for display, relative to the tiles as served: 0, 90, 180 or 270. Absolute: sending the same value twice is a no-op.

## Response `200`

Successful Response

- BlueprintUploadResponse
  - `blueprint` BlueprintPublic
    - `id` string, required: The sheet's id (blueprint id).
    - `name` string, required: The sheet's stored name, usually its upload file name; GET /v1/projects/{id}/sheets gives the name the app shows.
    - `scale` BlueprintScalePublic: The sheet's drawing scale: real length = drawing length × real ÷ drawing.
      - `drawing` number, required: The drawing side of the scale ratio: the 1 in "1:50", or the ¼ inch in 1/4" = 1'-0". Read it together with `real`; only the ratio real ÷ drawing matters.
      - `real` number, required: The real-world length that `drawing` stands for: the 50 in "1:50". The scale factor is real ÷ drawing, e.g. 50 for 1:50, or 48 for 1/4" = 1'-0".
      - `label` string, nullable: The scale as printed on the sheet or entered by a person, e.g. "1:50" or 1/4" = 1'-0". It can be `null`; the ratio is always in `drawing` and `real`.
      - `type` 'architectural' | 'metric' | 'civil' | 'custom', required
      - `units` 'si' | 'imperial' | 'inches', required
      - `manual_scaling_needed` boolean, nullable: `true` when Kamai set this scale automatically and no person has confirmed it yet: either the scale read from the sheet's title block, or a default for the detected measurement system when none could be read. Measurements use it normally. It clears when someone sets the scale in the Kamai app; a PUT stores the scale exactly as sent. `false` or `null` means a person set or confirmed it.
    - `url_height` number, nullable: The sheet's height in blueprint units, the coordinate space of every `geometry`.
    - `url_width` number, nullable: The sheet's width in blueprint units, the coordinate space of every `geometry`.
    - `url_dpi` number, nullable: The resolution of the sheet image that feature coordinates are measured in (blueprint units per inch of paper). Together with the scale it converts drawing units to real ones. A sheet without `url_dpi` cannot be measured even if it has a scale: every `measurements` value is then `null`, never zero.
    - `geojson` BlueprintGeoJSONPublic
      - `type` string, required
      - `features` BlueprintFeaturePublic[]
        - `type` string
        - `id` string, nullable
        - `geometry` object, nullable: GeoJSON geometry in blueprint units (see the blueprint's `url_width` and `url_height`), origin at the page's top-left corner. `null` for folders.
        - `properties` BlueprintFeaturePropertiesPublic, required: One feature's properties in the coarse feature shape.
          - `id` string, required: The feature's id, unique on this sheet. A re-analysis of the sheet issues new ids.
          - `kind` 'area' | 'line' | 'object' | 'text' | 'folder', required
          - `class` 'room' | 'wall' | 'wall_centerline' | 'wall_surface' | 'wall_surface_with_opening' | 'opening' | 'footprint' | 'other', required
          - `sub_class` 'window' | 'swing window' | 'safe room window' | 'single swing door' | 'double swing door' | 'sliding door' | 'toilet' | 'sink' | 'bathtub' | 'shower' | 'cooktop' | 'stairs' | 'elevator' | 'wet room' | 'wet wall'
          - `name` string, nullable: The label shown in the Kamai app, e.g. a room's name.
          - `color` FeatureColorPublic: Display colour, 0-255 per channel.
            - `r` integer, required
            - `g` integer, required
            - `b` integer, required
            - `a` integer, required
          - `visible` boolean, nullable: Visibility in this hierarchy.
          - `is_user_drawn` boolean, nullable: True when a user drew it rather than the detector.
          - `parent_id` string, nullable: Parent feature id; `null` on the root folder. With `position`, this is the ONLY hierarchy source — there is no reverse index.
          - `position` number, nullable: Sort order among siblings. A float so an item can be inserted between two others without renumbering.
          - `folder` string, nullable: The parent's NAME — the group this feature lives under, resolved so grouping needs no client-side join over `parent_id`. `null` on roots and features outside the hierarchy.
          - `opening_width_units` number, nullable: Door/window clear width in blueprint units (the coordinate space of `geometry`). See `measurements.opening_width_m` for metres.
          - `wall_thickness_units` number, nullable: Walls (`class` `wall`) only: thickness face to face as drawn, in blueprint units. See `measurements.wall_thickness_m` for metres. `null` on every other class and where it was not measured. On PUT: a value replaces it, `null` clears it, and a wall that omits the key keeps its stored thickness while its geometry is unchanged (a reshaped wall drops it). A value on any other class is refused (422).
          - `height_units` number, nullable: Optional vertical height in blueprint units, e.g. a room's or an opening's height read off the drawing. Send it back on a PUT to keep it.
          - `tag` string, nullable: The mark printed beside a door or window on the drawing, e.g. 'D-01', 'W2' or '80/210'; `null` when none was read. Free text, and NOT an identifier: openings often share a mark, so never join or de-duplicate on it.
          - `handing` string, nullable: Single swing doors only: 'LH' or 'RH', read off the drawing's swing arc. It is the hinge side seen from the side the door swings away from (the push side, the North-American convention; European DIN handing is the mirror image). 'LHR'/'RHR' (reverse, pull-side handings) are never detected and are kept only when a client sets them. `null` on every other feature and where the arc could not be read. Round-trips unchanged on PUT. A value other than LH/RH/LHR/RHR is refused (422); on a feature that is not a single swing door it is dropped.
          - `relations` string[]: Ids of features this one is spatially related to — an undirected edge set, so if A lists B then B lists A. Untyped by design: filter the ids by the neighbour's `class` for a typed view (a room's walls are the related ids whose class is `wall`/`wall_centerline`; its wall surfaces, cut at each opening on the room's side, are those whose class is `wall_surface`; the piece across a door/window is class `wall_surface_with_opening`; both turn `sub_class` `wet wall` with a wet room).
          - `measurements` FeatureMeasurementsPublic: Real-world measurements the server derives from the geometry and the sheet's scale, always in SI units (m, m²); each field's unit is in its name. Read-only: ignored on a PUT. ``null`` means *not applicable or not measurable*, never a measured zero: a line has no area, a folder has no geometry, and a sheet without a usable scale has no measurements at all. They follow the GEOMETRY, not ``kind``: an object drawn as a polygon carries an ``area_m2``. Objects are counted, not measured, so do not sum them into a room total.
            - `area_m2` number, nullable: Polygon area, m².
            - `perimeter_m` number, nullable: Polygon boundary length, m (holes included).
            - `length_m` number, nullable: Line length, m.
            - `opening_width_m` number, nullable: Door/window clear width, m. Converted from `opening_width_units`.
            - `wall_thickness_m` number, nullable: Walls only: thickness face to face as drawn, m. Converted from `wall_thickness_units`. `null` on every other class and on a wall whose thickness was not measured.
    - `text` BlueprintTextPublic[]: The sheet's words. Read-only; ignored if sent on an update. Empty unless requested with `include_text`.
      - `id` string, required: Stable id for this word
      - `text` string, required: The word itself
      - `confidence` number, nullable: 0..1. The OCR score for a recognised word; 1.0 for text read out of the PDF's own digital layer.
      - `geometry` object, nullable: The word's box in blueprint coordinates, as GeoJSON. Follows the true (possibly rotated) glyph run, not an upright box.
      - `room_id` string, nullable: The room this word is printed in, if any.
      - `wall_id` string, nullable: The wall this word is printed on, if any.
    - `text_total` integer, nullable: Total words on the sheet, which may exceed len(text) because the page is capped — page with text_limit/text_offset until you have seen this many. None when text was not requested.
    - `identity` SheetIdentityPublic: What the sheet's title block says it is.
      - `sheet_number` string, nullable: The sheet number as printed in the title block, e.g. A-101. Not unique within a project.
      - `title` string, nullable: The sheet title as printed, e.g. FIRST FLOOR PLAN.
      - `discipline` string, nullable: Discipline letter of the US National CAD Standard, e.g. A (architectural), S (structural), M (mechanical).
      - `sheet_type` integer, nullable: Sheet-type digit of the US National CAD Standard, 0-9, e.g. 1 for plans.
      - `sheet_type_label` string, nullable: The sheet type's name, e.g. Plans.
      - `levels` string[]: Every building level the title names, e.g. ["L1", "L2"]; empty when it names none.
    - `rotation` integer: Degrees clockwise to turn the sheet for display: 0, 90, 180 or 270, relative to the tiles as served. A view setting: tiles, `url_width`/`url_height` and every `geometry` stay unturned, so apply it when you draw, to the image and the overlays alike. Set it with PUT /v1/blueprints/{blueprint_id}/rotation.
    - `auto_rotation` integer, nullable: Degrees clockwise (0, 90, 180, 270) Kamai turned the page at upload to bring it upright, on top of the PDF's own /Rotate. Already inside the tiles and every `geometry`: nothing to apply. Read-only. `null`: not decided (a sheet uploaded before the check existed).
    - `created` string, date-time, required: When the sheet was created (ISO 8601).
    - `updated` string, date-time, required: When the sheet record last changed (ISO 8601).
  - `message` string, required: Update confirmation message
  - `revision` string, nullable: The sheet's revision this copy was read at. Send it back as `base_revision` on a PUT that carries `geojson`: if the sheet changed in between, that save is refused with 409 `stale_sheet` instead of silently undoing the change. Opaque; compare for equality only.

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/kamai/apis/kamai-api.md) · [All operations](https://skmtc.dev/kamai/apis/kamai-api/llms.txt) · [OpenAPI document](https://skmtc.dev/kamai/apis/kamai-api/revisions/78f938546270?raw)
