Skip to content
TruTecDevelopers
Get an API key

Editing takeoff shapes

List the shapes on a saved aerial takeoff and add, remove, reclassify, retype or rephase them, saved the same way the takeoff editor saves.

View as Markdown

A saved aerial takeoff is made of shapes: drawn areas, counted items (arrows, symbols, wheel stops, bollards), drawn lines (striping and curbs), painted shapes (crosswalks, hatching, stop bars) and custom item shapes. These endpoints let an integration or an AI assistant change those shapes the way a person does in the takeoff editor, and save the takeoff the way the editor saves it: the takeoff's counts, footage and areas follow, the change is kept in the takeoff's history, and estimates linked to the takeoff re-pull their quantities.

Typical flow:

  1. GET /v1/measurements/{measurement_id}/shapes for the shapes, their ids and the takeoff's rev.
  2. POST /v1/measurements/{measurement_id}/edits with that rev as base_rev and a list of operations.
  3. GET /v1/measurements/{measurement_id}/items for the new quantities (see Takeoffs).

Only aerial takeoffs can be edited here. Plan-sheet and landscape takeoffs return 422.

Note

Coordinates are [lat, lng], the order TruTec stores takeoffs in (the same as geometry in GET /v1/measurements/{id}). If your data is in GeoJSON order, send "coordinate_order": "lng_lat" with your edits. A new shape several kilometers from the takeoff's other shapes is refused, which catches swapped coordinates.

What the API edits#

Shape Add Remove Reclassify Type Phase Surface
Areas (main, concrete, sidewalk, driveway, carport) Yes Yes Yes Yes
Cut-outs (hole areas) Yes Yes
Counts: arrows, abc (symbols), wheel_stop, bollard Yes Yes To another count category Yes Yes
Lines: lines_white, lines_yellow, lines_double_yellow, red_line, misc_lines, curb, curb_red, curb_yellow, curb_green, curb_blue Yes Yes To another line category Yes Yes
Custom item shapes (points, lines, polygons) Yes Yes To another item of the same kind Phase-split area items

These stay in the takeoff editor, because the editor works out their numbers from the whole layout. An operation that touches one returns 422 Edit in the takeoff editor with the reason:

  • stalls, handicap, truck and parallel stalls (their striping footage comes from the stall layout), speed bumps, center lines and skip lane lines;
  • painted crosswalks, hatching, stop bars and detected stripes;
  • a category whose quantity someone typed over the measured one on this takeoff;
  • an area or custom shape that carries a service, type, catalog item or work area (an area's phase can still change), and a cut-out inside one;
  • custom items that count toward the takeoff's total area, and measuring-tape rulers.

The shapes listing marks each shape's allowed edits in actions, with a note when there are none.

List a takeoff's shapes#

GET /v1/measurements/{measurement_id}/shapes

Permission: Read measurements

Name Type Description
kind string Only area, count, line, painted_shape or custom shapes.
category string Only one category (for example arrows) or custom item name.
include_coordinates boolean Default true. false leaves coordinates out for a lighter list.
limit, offset integer Paging. limit defaults to 100, max 500.
curl "https://trutec.ai/api/v1/measurements/90311/shapes?kind=count" \
  -H "X-API-Key: sk_your_api_key_here"
{
  "data": [
    {
      "id": "trutec:counter_marker:arrows:0b6d2f7e-8f1c-4d61-b0a4-61c3f0d2e9b4",
      "kind": "count",
      "category": "arrows",
      "label": "Arrows",
      "geometry": "point",
      "phase": "Phase 1",
      "quantity": 1,
      "unit": "EA",
      "coordinates": [30.4006, -97.7203],
      "actions": ["remove", "reclassify", "set_spec", "set_phase"]
    }
  ],
  "pagination": {"total": 1, "limit": 100, "offset": 0},
  "measurement": {"id": 90311, "name": "Lakeside Plaza main lot", "job_id": 4812, "area": 18250.5,
                  "rev": "g1-3f9a0c27b1d84e65", "coordinate_order": "lat_lng"},
  "options": {
    "count_categories": ["arrows", "abc", "wheel_stop", "bollard"],
    "line_categories": ["lines_white", "lines_yellow", "lines_double_yellow", "red_line", "misc_lines",
                        "curb", "curb_red", "curb_yellow", "curb_green", "curb_blue"],
    "surfaces": ["main", "concrete", "sidewalk", "driveway", "carport", "hole"],
    "custom_items": [{"name": "Asphalt patching", "type": "polygon", "on_takeoff": false}],
    "types": {"lines_yellow": ["4\" Yellow"]},
    "phases": ["Phase 1"]
  }
}
Field Description
id The shape's stable id. Use it in edits. A shape added through the API or the editor keeps its id.
kind area, count, line, painted_shape or custom.
surface Areas: main, concrete, sidewalk, driveway, carport, or hole for a cut-out.
category, label Counts, lines and painted shapes.
item Custom shapes: the custom item's name.
geometry point, line or polygon.
phase, spec The shape's phase and type (sub-type), when it has them.
service_labels, service_id, item_key, item_name, work_area What an area or custom shape is assigned to, when it is.
quantity, unit Square feet for areas and polygons, linear feet for lines (painted footage for dashed lines), 1 EA for points.
coordinates [lat, lng] for a point, a list of points for a line, a list of rings for a polygon (the first ring is the outline, the rest are holes).
actions The edits the API takes on this shape.
measurement.rev The takeoff's revision. Send it as base_rev. It changes whenever anyone saves the takeoff. GET /v1/measurements/{id} returns it too.
options What an edit may name: categories, types per category (they come from the services that price the item), custom items on the takeoff or in the workspace, and the takeoff's phases.

Edit a takeoff's shapes#

POST /v1/measurements/{measurement_id}/edits

Permission: Write measurements. Operations that remove a shape also need Delete records.

Name Type Required Description
base_rev string Yes measurement.rev from the shapes listing, or rev from your last edit.
operations array Yes 1 to 200 operations, applied in order.
coordinate_order string No lat_lng (default) or lng_lat.
confirm_remove_all_areas boolean No Needed to remove every drawn area from a takeoff that keeps other shapes.

All operations save together: if one is refused, nothing is saved and the error names it with operation_index.

op Fields What it does
add_area coordinates (a ring, or a list of rings), surface (default main), phase Draws an area. surface: "hole" cuts an area out; a cut-out takes the phase of the area it cuts.
add_count category, coordinates ([lat, lng]), spec, phase Adds a counted item.
add_line category, coordinates (2 or more points), spec, phase Draws a line.
add_custom_shape item, coordinates, item_type, color, phase Adds a shape to a custom item: a point, line or polygon, matching the item. item can be on the takeoff already or one of the workspace's custom items; for a new item name send item_type (point, line or polygon). phase only for items split by phase.
remove id Removes the shape.
reclassify id, then category (+ optional spec) for a count or line, or item for a custom shape Moves the shape to another category or custom item. Its old type is dropped.
set_spec id, spec (or null) Sets or clears a count's or line's type.
set_phase id, phase Moves an area, count or line (or a phase-split custom area) to a phase.
set_surface id, surface Changes an area to main, concrete, sidewalk, driveway or carport.

A count or line added without phase takes the phase of the area it sits in, as in the editor. A spec must be one of the category's types in options.types: types come from the services that price the item, and the API never invents one. A line whose type has a dash pattern in the catalog counts its painted footage, as in the editor.

curl -X POST https://trutec.ai/api/v1/measurements/90311/edits \
  -H "X-API-Key: sk_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "base_rev": "g1-3f9a0c27b1d84e65",
    "operations": [
      {"op": "add_count", "category": "arrows", "coordinates": [30.4006, -97.7203]},
      {"op": "add_line", "category": "lines_yellow", "coordinates": [[30.4010, -97.7208], [30.4010, -97.7198]]},
      {"op": "reclassify", "id": "trutec:counter_line:lines_white:7c1e0f3a-2b44-4c8e-9d71-5a0f6e2b8c13", "category": "lines_yellow"},
      {"op": "remove", "id": "trutec:counter_marker:abc:3e5d9b20-7a61-4f0c-8b2e-91d4c6a7f058"}
    ]
  }'

Returns 200:

{
  "data": {
    "measurement_id": 90311,
    "rev": "g1-8c41d2e05f7a93b6",
    "area": 18250.5,
    "results": [
      {"index": 0, "op": "add_count", "id": "trutec:counter_marker:arrows:a1f3c2d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d", "quantity": 1, "unit": "EA"},
      {"index": 1, "op": "add_line", "id": "trutec:counter_line:lines_yellow:b2e4d3c5-6f7a-4b8c-9d0e-1f2a3b4c5d6e", "quantity": 31.62, "unit": "LF"},
      {"index": 2, "op": "reclassify", "id": "trutec:counter_line:lines_white:7c1e0f3a-2b44-4c8e-9d71-5a0f6e2b8c13", "category": "lines_yellow"},
      {"index": 3, "op": "remove", "id": "trutec:counter_marker:abc:3e5d9b20-7a61-4f0c-8b2e-91d4c6a7f058"}
    ]
  }
}

rev is the takeoff's new revision: send it as base_rev for your next edit. area is the takeoff's total area in square feet. New shapes' ids are in results.

The save is recorded as the person who created the API key, in the takeoff's revision history like any editor save, and estimates linked to the takeoff re-pull their quantities. Nothing is sent to anyone.

Status error
400 base_rev is required, operations is required, Invalid operation (with operation_index), Shape is far from the takeoff, Unknown category, Wrong shape for item, item_type is required, Unknown fields
403 API key lacks measurement write permission, API key lacks delete permission (a remove without Delete records), Key owner unavailable (the key's creator left the workspace)
404 Measurement not found, Shape not found (with operation_index: list the shapes again)
409 stale_measurement: someone saved the takeoff since base_rev. The body has current_rev; list the shapes again and resend. Takeoff locked for review. would_remove_all_areas: resend with confirm_remove_all_areas if that is what you mean.
422 Edit in the takeoff editor (see above), Unknown type, Takeoff would be empty (delete the takeoff instead), Not an aerial takeoff, Takeoff needs the editor first

Note

The first edit of a takeoff that was saved from a detection through the API stores it in the editor's own format, as opening and saving it in the editor does. Its measured quantities (total area, counts, footage, custom items) carry over; a few raw detection values in its quantity list are replaced by the editor's equivalents.