Skip to content
TruTecDevelopers
Get an API key

Saving & managing takeoffs

Save a detection onto a job as a takeoff, rename or delete takeoffs, and read every quantity a takeoff provides, by item and by service.

View as Markdown

A takeoff (a saved measurement) is what a job's estimate pulls quantities from. Takeoffs you draw in TruTec are already saved. A detection you run through the API (Measure a site) is not: it returns quantities and geometry but attaches nothing to a job. Save it onto a job to make it a takeoff: it then shows on the job, opens in the aerial takeoff editor where your team can adjust it, and feeds estimates.

Typical flow:

  1. POST /v1/detect/address (or /v1/detect/full) with "async": true. Keep the returned id.
  2. Poll GET /v1/detect/status/{id} until status is completed.
  3. POST /v1/jobs/{job_id}/measurements with {"detection_id": "<id>"}.
  4. GET /v1/measurements/{measurement_id}/items for the quantities.

Reading saved takeoffs is covered in Saved measurements & imagery. To add, remove or reclassify an aerial takeoff's areas, counts, lines and custom item shapes, see Editing takeoff shapes. Plan-sheet takeoffs can be built and edited end to end through the API, see Blueprint takeoffs.

Note

Partner keys add firm_id to name the workspace: in the query string, or in the JSON body on writes. See Partner API.

Save a detection onto a job#

POST /v1/jobs/{job_id}/measurements

Permission: Write measurements

Name Type Required Description
detection_id string One of the two The id of an async detection run by this workspace. It must be completed.
detection object One of the two The JSON body a synchronous detect call returned. It must be the json format, not GeoJSON or KMZ.
name string No Up to 200 characters. Default "<job name> Aerial Takeoff".
curl -X POST https://trutec.ai/api/v1/jobs/4812/measurements \
  -H "X-API-Key: sk_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"detection_id": "6b0f2a51-8c1e-4d7a-9f3e-2a7c4b9d1e60", "name": "Lakeside Plaza main lot"}'

Returns 201:

{
  "data": {
    "id": 90311,
    "name": "Lakeside Plaza main lot",
    "type": "parking",
    "job_id": 4812,
    "area": 18250.5,
    "imagery_source": "google",
    "created_at": "2026-10-12T15:04:11Z",
    "updated_at": "2026-10-12T15:04:11Z"
  }
}

The takeoff is recorded on the job's timeline as the person who created the API key. imagery_source is google, or nearmap:<survey id> when the detection ran on a Nearmap survey, so map exports and imagery downloads use the same imagery.

If the detection ran with add-on models, its curbs, wheel stops, speed bumps, bollards and parallel stalls are saved as the takeoff's curb, wheel stop, speed bump, bollard and parallel stall items, so they show in the takeoff editor. Curb linear feet and curb count are in the takeoff's quantities right away; the other items' counts, and parallel stall striping footage, are worked out by the editor and fill in the first time someone saves the takeoff there. Add-ons whose status is failed add nothing. Landscape results are not saved into the takeoff.

Saving does not run or bill another detection. Each save makes a new takeoff, so save a detection once. If your team later runs detection again on this takeoff inside the TruTec editor, that run is billed like any new detection.

Status error
400 Send detection_id or detection (neither or both sent), name must be 200 characters or less, Unknown fields
403 API key lacks measurement write permission
404 Job not found, Detection not found (unknown id, or another workspace's run)
409 Detection still running. Poll GET /v1/detect/status/{id} and save it when it is completed.
422 Detection failed, GeoJSON results cannot be saved, Not a detection result

Get takeoff quantities#

GET /v1/measurements/{measurement_id}/items

Permission: Read measurements

Every quantity an estimate can pull from the takeoff: the same list the estimate's quantity picker shows. It covers total area, area by spec, concrete and sidewalk area, stall and marking counts and their striping footage, spec splits (for example van-accessible handicap stalls), custom items, and blueprint layers. Works for any saved takeoff, aerial or blueprint.

services lists services the takeoff's Services tab mapped measured items to, with the summed quantity in the unit the takeoff measured. It is empty when nothing was mapped.

curl https://trutec.ai/api/v1/measurements/90311/items \
  -H "X-API-Key: sk_your_api_key_here"
{
  "data": {
    "measurement_id": 90311,
    "name": "Lakeside Plaza main lot",
    "job_id": 4812,
    "items": [
      {"key": "total_area_sf", "label": "Total area", "quantity": 18250.5, "unit": "SF"},
      {"key": "stalls", "label": "Parking stalls", "quantity": 142, "unit": "EA"},
      {"key": "stalls_lf", "label": "Parking stalls", "quantity": 2556.0, "unit": "LF"},
      {"key": "item_spec:handicap:Van accessible", "label": "Handicap — Van accessible", "quantity": 2, "unit": "EA", "kind": "spec"}
    ],
    "services": [
      {"service_id": 318, "service_name": "4\" Restripe", "item_keys": ["stalls", "crosswalks"], "quantity": 2980.0, "unit": "LF"}
    ]
  }
}
Field Description
items[].key Stable key for the quantity on this takeoff.
items[].label What the estimate picker calls it.
items[].quantity, items[].unit Value and unit: SF, LF, EA, CY, TON.
items[].kind spec for a spec or size split, custom for a custom item. Absent for standard quantities.
services[].service_id, service_name The catalog service.
services[].item_keys Measured items mapped to it.
services[].quantity, unit The summed quantity, or null when nothing mapped was measured.

Only quantities above zero are listed. 422 Could not read quantities means the takeoff's saved data could not be read; open it in TruTec and save it again.

Rename a takeoff#

PATCH /v1/measurements/{measurement_id}

Permission: Write measurements

Name Type Required Description
name string Yes Up to 200 characters.
curl -X PATCH https://trutec.ai/api/v1/measurements/90311 \
  -H "X-API-Key: sk_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"name": "Main lot"}'

Returns 200 with the takeoff in the same shape as the save response. Errors: 400 name is required, 400 name must be 200 characters or less, 400 Unknown fields (only name can change here).

Delete a takeoff#

DELETE /v1/measurements/{measurement_id}

Permission: Write measurements and Delete records

Deletes the takeoff the way the editor's Delete does: it is logged on the job, and its stored plan sheets and drone photos are cleaned up. Estimates that already pulled quantities from it keep their numbers. Returns 204. This cannot be undone.

curl -X DELETE https://trutec.ai/api/v1/measurements/90311 \
  -H "X-API-Key: sk_your_api_key_here"