Field24 logo
Field24 MCP server

Tool reference

The 15 tools the Field24 MCP server gives your AI client. The client picks them; you just ask in plain words. This page is generated from the server itself, so it always matches what a client sees.

Open in ChatGPT
ToolWhat it doesEffect
get_profileGet the signed-in Field24 user's profile: their stable account id, name, email and a short nickname to greet them by.Reads only
get_usageGet the signed-in user's Field24 spend for the current billing month (totalUsage) against their included allowance (includedUsageUsd), plus their remaining prepaid credit (currentBalanceUsd) and whether extra usage beyond the allowance is enabled.Reads only
list_projectsList every project (job) on the signed-in contractor's Field24 account, with a count of the files in each.Reads only
create_projectFirst step for any construction estimate, takeoff, bid or proposal request.Can change data
update_projectRename a project, change its client or status, or archive it (archived: true) and restore it (archived: false).Can overwrite or delete data
list_project_filesList the files in one of the user's projects — drawings, site photos, receipts and generated documents — with their type and format.Can change data
add_project_filesAdd files the user attached in this conversation (plans, drawings, photos, documents) to one of their Field24 projects, so they sync into the user's Field24 workspace.Can change data
get_project_upload_urlsUse this when the user's plans, drawings or photos are files on their computer (you have a local path, not a ChatGPT-hosted download URL).Can change data
get_projectGet one of the user's projects with its files.Can change data
list_price_bookList the signed-in contractor's price book — their own saved labor and material unit prices, newest first.Reads only
save_price_book_itemAdd a rate to the user's price book, or update the existing row when the same type + item is already saved (case-insensitive) — re-saving an item the user already has edits it rather than creating a duplicate.Can overwrite or delete data
update_price_book_itemEdit one price book row by its id (from list_price_book).Can overwrite or delete data
delete_price_book_itemPermanently remove one price book row by its id.Can overwrite or delete data
field24_agentRuns Field24's estimating agents in the user's own Field24 workspace for a construction estimate, quantity takeoff, bid, pricing or proposal, from the project's plans, drawings, photos or written scope.Can overwrite or delete data
update_takeoffEdit a Field24 takeoff record directly: change, add or remove rows by row id.Can overwrite or delete data

Account

get_profile

Get the signed-in Field24 user's profile: their stable account id, name, email and a short nickname to greet them by.

Reads only.

Input and output

Input

No fields.

Output

FieldTypeRequiredDescription
idstringyes
namestring or nullyes
emailstring or nullyes
nicknamestring or nullyes

get_usage

Get the signed-in user's Field24 spend for the current billing month (totalUsage) against their included allowance (includedUsageUsd), plus their remaining prepaid credit (currentBalanceUsd) and whether extra usage beyond the allowance is enabled. All amounts are USD.

Reads only.

Input and output

Input

No fields.

Output

FieldTypeRequiredDescription
totalUsagenumberyes
includedUsageUsdnumberyes
extraUsagebooleanyes
currentBalanceUsdnumberyes

Projects and files

list_projects

List every project (job) on the signed-in contractor's Field24 account, with a count of the files in each. Archived projects are included and carry a non-null archivedAt. Use this to resolve a project the user names in conversation to its projectId.

Reads only.

Input and output

Input

No fields.

Output

FieldTypeRequiredDescription
projectsarray of anyyes

create_project

First step for any construction estimate, takeoff, bid or proposal request. Create a Field24 project for a job the user wants estimated. Call this first, once per job, before adding files or starting an estimate. Derive a short human name from the address or the work.

Can change data.

Input and output

Input

FieldTypeRequiredDescription
namestring, min length 1, max length 200yes
clientstring, min length 1, max length 200no
{
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 200
    },
    "client": {
      "type": "string",
      "minLength": 1,
      "maxLength": 200
    }
  },
  "required": [
    "name"
  ]
}

Output

FieldTypeRequiredDescription
projectIdstring, format uuidyes
createdBystringyes
projectNamestringyes
clientstring or nullyes
projectTagstringyes
statusany or nullyes
archivedAtstring or nullyes
createdAtstringyes
updatedAtstringyes
uploadUrlstring, format uriyesField24 page where the signed-in user can add files to their projects by hand.

update_project

Rename a project, change its client or status, or archive it (archived: true) and restore it (archived: false). Archiving is reversible and never deletes files or history.

Can overwrite or delete data.

Input and output

Input

FieldTypeRequiredDescription
projectIdstring, format uuidyes
namestring, min length 1, max length 200no
clientstring or nullno
statusanyno
archivedbooleanno
{
  "type": "object",
  "properties": {
    "projectId": {
      "type": "string",
      "format": "uuid",
      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)
quot; }, "name": { "type": "string", "minLength": 1, "maxLength": 200 }, "client": { "anyOf": [ { "type": "string", "minLength": 1, "maxLength": 200 }, { "type": "null" } ] }, "status": { "allOf": [ { "$ref": "#/definitions/ProjectStatus" } ] }, "archived": { "type": "boolean" } }, "required": [ "projectId" ], "definitions": { "ProjectStatus": { "type": "string", "enum": [ "estimating", "proposal_sent", "won", "lost" ] } } }

Output

FieldTypeRequiredDescription
projectIdstring, format uuidyes
createdBystringyes
projectNamestringyes
clientstring or nullyes
projectTagstringyes
statusany or nullyes
archivedAtstring or nullyes
createdAtstringyes
updatedAtstringyes

list_project_files

List the files in one of the user's projects — drawings, site photos, receipts and generated documents — with their type and format. Use it to tell the user what a job already has on file. Returns metadata only, never file contents or download links.

Can change data.

Input and output

Input

FieldTypeRequiredDescription
projectIdstring, format uuidyes
{
  "type": "object",
  "properties": {
    "projectId": {
      "type": "string",
      "format": "uuid",
      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)
quot; } }, "required": [ "projectId" ] }

Output

FieldTypeRequiredDescription
filesarray of anyyes

add_project_files

Add files the user attached in this conversation (plans, drawings, photos, documents) to one of their Field24 projects, so they sync into the user's Field24 workspace. Use this to hand the user's attached plans, drawings and photos to Field24 instead of analysing them yourself. Pass every attached file in files — at most 20 per call. Each file is reported separately; a file that fails does not stop the others. Use this only when the file is attached in the chat and you were given a download URL for it. If you only have a local file path, use get_project_upload_urls instead. Only PDFs, images (PNG, JPEG, WebP, HEIC, GIF, TIFF), office documents (DOC, DOCX, XLS, XLSX, CSV, TXT, MD) and ZIP archives are accepted.

Can change data.

Input and output

Input

FieldTypeRequiredDescription
projectIdstring, format uuidyes
filesarray of objectno
files[].download_urlstring, min length 1, max length 4096yes
files[].file_idstring, min length 1, max length 500yes
files[].mime_typestring, max length 200no
files[].file_namestring, max length 500no
{
  "type": "object",
  "properties": {
    "projectId": {
      "type": "string",
      "format": "uuid",
      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)
quot; }, "files": { "type": "array", "items": { "type": "object", "properties": { "download_url": { "type": "string", "minLength": 1, "maxLength": 4096 }, "file_id": { "type": "string", "minLength": 1, "maxLength": 500 }, "mime_type": { "type": "string", "maxLength": 200 }, "file_name": { "type": "string", "maxLength": 500 } }, "required": [ "download_url", "file_id" ] } } }, "required": [ "projectId" ] }

Output

FieldTypeRequiredDescription
filesarray of objectyes
files[].oktrueyes
files[].fileIdstringno
files[].namestringyes
files[].bytesinteger, min 0no
files[].errorstringno

get_project_upload_urls

Use this when the user's plans, drawings or photos are files on their computer (you have a local path, not a ChatGPT-hosted download URL). Give each file's name and exact size in bytes. Upload each file with an HTTP PUT to its upload_url using exactly the returned headers, e.g. curl -sS -X PUT -H 'content-type: application/pdf' --data-binary @'/path/to/plans.pdf' '<upload_url>'. Then call get_project: uploaded files appear on the project automatically. Only PDFs, images, office documents and ZIP archives up to 300 MB are accepted. Do not open the URL in a browser.

Can change data.

Input and output

Input

FieldTypeRequiredDescription
projectIdstring, format uuidyes
filesarray of object, min items 1, max items 20yes
files[].file_namestring, min length 1, max length 500yes
files[].size_bytesintegeryes
files[].mime_typestring, max length 200no
{
  "type": "object",
  "properties": {
    "projectId": {
      "type": "string",
      "format": "uuid",
      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)
quot; }, "files": { "minItems": 1, "maxItems": 20, "type": "array", "items": { "type": "object", "properties": { "file_name": { "type": "string", "minLength": 1, "maxLength": 500 }, "size_bytes": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 }, "mime_type": { "type": "string", "maxLength": 200 } }, "required": [ "file_name", "size_bytes" ] } } }, "required": [ "projectId", "files" ] }

Output

FieldTypeRequiredDescription
uploadsarray of objectyes
uploads[].oktrueyes
uploads[].file_namestringyes
uploads[].upload_urlstringno
uploads[].method"PUT"no
uploads[].headersobjectno
uploads[].headers.content-typestringyes
uploads[].headers.content-lengthstringyes
uploads[].expires_in_secondsintegerno
uploads[].errorstringno

get_project

Get one of the user's projects with its files. Files uploaded through get_project_upload_urls are recorded here automatically; any upload that was not a valid file is listed under pending with a note.

Can change data.

Input and output

Input

FieldTypeRequiredDescription
projectIdstring, format uuidyes
{
  "type": "object",
  "properties": {
    "projectId": {
      "type": "string",
      "format": "uuid",
      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)
quot; } }, "required": [ "projectId" ] }

Output

FieldTypeRequiredDescription
projectIdstringyes
tagstringyes
namestringyes
clientstring or nullyes
uploadUrlstringyes
filesarray of objectyes
files[].fileIdstringyes
files[].namestringyes
files[].bytesinteger or nullyes
files[].typestringyes
pendingarray of objectno
pending[].namestringyes
pending[].notestringyes

Price book

list_price_book

List the signed-in contractor's price book — their own saved labor and material unit prices, newest first. Call this BEFORE quoting any number, so the estimate uses the user's real rates instead of generic averages. Use q to search item names and notes, and type to fetch only labor or only material rows.

Reads only.

Input and output

Input

FieldTypeRequiredDescription
qstring, min length 1, max length 200no
type"material" or "labor"noWhich bucket the price falls in. "labor" is costed from an hourly rate; everything else is priced as a material. Accepts any casing, and "labour" folds into "labor".
activeOnlybooleanno
limitinteger, min 1, max 1000no
{
  "type": "object",
  "properties": {
    "q": {
      "type": "string",
      "minLength": 1,
      "maxLength": 200
    },
    "type": {
      "type": "string",
      "enum": [
        "material",
        "labor"
      ],
      "description": "Which bucket the price falls in. \"labor\" is costed from an hourly rate; everything else is priced as a material. Accepts any casing, and \"labour\" folds into \"labor\"."
    },
    "activeOnly": {
      "type": "boolean"
    },
    "limit": {
      "type": "integer",
      "minimum": 1,
      "maximum": 1000
    }
  }
}

Output

FieldTypeRequiredDescription
itemsarray of anyyes

save_price_book_item

Add a rate to the user's price book, or update the existing row when the same type + item is already saved (case-insensitive) — re-saving an item the user already has edits it rather than creating a duplicate. type is "material" or "labor". unit is free text and is stored uppercased (e.g. SQFT, LF, HR, EA). created in the result says whether a new row was made. Always confirm the number with the user before saving it.

Can overwrite or delete data.

Input and output

Input

FieldTypeRequiredDescription
type"material" or "labor"yesWhich bucket the price falls in. "labor" is costed from an hourly rate; everything else is priced as a material. Accepts any casing, and "labour" folds into "labor".
itemstring, min length 1, max length 200yes
unitstring, min length 1, max length 20yes
unitPricenumber, min 0, max 99999999.99yes
currency"USD" or "CAD"noCurrency the unit price is quoted in. Accepts any casing.
notesstring or nullno
markupPctnumber or nullno
isActivebooleanno
{
  "type": "object",
  "properties": {
    "type": {
      "type": "string",
      "enum": [
        "material",
        "labor"
      ],
      "description": "Which bucket the price falls in. \"labor\" is costed from an hourly rate; everything else is priced as a material. Accepts any casing, and \"labour\" folds into \"labor\"."
    },
    "item": {
      "type": "string",
      "minLength": 1,
      "maxLength": 200
    },
    "unit": {
      "type": "string",
      "minLength": 1,
      "maxLength": 20
    },
    "unitPrice": {
      "type": "number",
      "minimum": 0,
      "maximum": 99999999.99
    },
    "currency": {
      "type": "string",
      "enum": [
        "USD",
        "CAD"
      ],
      "description": "Currency the unit price is quoted in. Accepts any casing."
    },
    "notes": {
      "anyOf": [
        {
          "type": "string",
          "maxLength": 2000
        },
        {
          "type": "null"
        }
      ]
    },
    "markupPct": {
      "anyOf": [
        {
          "type": "number",
          "minimum": 0,
          "maximum": 999.99
        },
        {
          "type": "null"
        }
      ]
    },
    "isActive": {
      "type": "boolean"
    }
  },
  "required": [
    "type",
    "item",
    "unit",
    "unitPrice"
  ]
}

Output

FieldTypeRequiredDescription
idstring, format uuidyes
type"material" or "labor"yesWhich bucket the price falls in. "labor" is costed from an hourly rate; everything else is priced as a material. Accepts any casing, and "labour" folds into "labor".
itemstringyes
unitstringyes
unitPricenumberyes
currencystringyes
notesstring or nullyes
markupPctnumber or nullyes
isActivebooleanyes
createdAtstringyes
updatedAtstringyes
createdbooleanyes

update_price_book_item

Edit one price book row by its id (from list_price_book). Send only the fields that change; at least one is required. Use this for a targeted edit such as bumping a unit price — use save_price_book_item when the user is adding a rate.

Can overwrite or delete data.

Input and output

Input

FieldTypeRequiredDescription
idstring, format uuidyes
type"material" or "labor"noWhich bucket the price falls in. "labor" is costed from an hourly rate; everything else is priced as a material. Accepts any casing, and "labour" folds into "labor".
itemstring, min length 1, max length 200no
unitstring, min length 1, max length 20no
unitPricenumber, min 0, max 99999999.99no
currency"USD" or "CAD"noCurrency the unit price is quoted in. Accepts any casing.
notesstring or nullno
markupPctnumber or nullno
isActivebooleanno
{
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid",
      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)
quot; }, "type": { "type": "string", "enum": [ "material", "labor" ], "description": "Which bucket the price falls in. \"labor\" is costed from an hourly rate; everything else is priced as a material. Accepts any casing, and \"labour\" folds into \"labor\"." }, "item": { "type": "string", "minLength": 1, "maxLength": 200 }, "unit": { "type": "string", "minLength": 1, "maxLength": 20 }, "unitPrice": { "type": "number", "minimum": 0, "maximum": 99999999.99 }, "currency": { "type": "string", "enum": [ "USD", "CAD" ], "description": "Currency the unit price is quoted in. Accepts any casing." }, "notes": { "anyOf": [ { "type": "string", "maxLength": 2000 }, { "type": "null" } ] }, "markupPct": { "anyOf": [ { "type": "number", "minimum": 0, "maximum": 999.99 }, { "type": "null" } ] }, "isActive": { "type": "boolean" } }, "required": [ "id" ] }

Output

FieldTypeRequiredDescription
idstring, format uuidyes
type"material" or "labor"yesWhich bucket the price falls in. "labor" is costed from an hourly rate; everything else is priced as a material. Accepts any casing, and "labour" folds into "labor".
itemstringyes
unitstringyes
unitPricenumberyes
currencystringyes
notesstring or nullyes
markupPctnumber or nullyes
isActivebooleanyes
createdAtstringyes
updatedAtstringyes

delete_price_book_item

Permanently remove one price book row by its id. Destructive — always confirm with the user first, and prefer setting isActive: false with update_price_book_item when they only want to stop using a rate.

Can overwrite or delete data.

Input and output

Input

FieldTypeRequiredDescription
idstring, format uuidyes
{
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid",
      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)
quot; } }, "required": [ "id" ] }

Output

FieldTypeRequiredDescription
idstringyes
deletedtrueyes

Estimating agents

field24_agent

Runs Field24's estimating agents in the user's own Field24 workspace for a construction estimate, quantity takeoff, bid, pricing or proposal, from the project's plans, drawings, photos or written scope. type: takeoff (scope of work and measured quantities from the project's plans, photos or written scope, 15 to 30 minutes), takeoff_review (Field24's reviewer checks a finished takeoff against the plans and returns findings, about 10 minutes), pricing (prices a takeoff from the user's rates and local store prices, up to 15 minutes), pricing_review (Field24's reviewer checks the priced takeoff and returns findings, about 5 minutes), proposal (a branded PDF, optional: you may write the proposal yourself from the priced takeoff instead). action: create starts the agent and returns a sessionId at once; status reads it; follow-up sends the user's answers or corrections to the same agent; abort stops it. Never wait in a turn: after create or follow-up, tell the user and call status when they return or ask. When a takeoff completes, start a takeoff_review instead of reviewing it yourself; when pricing completes, start a pricing_review. Show the user every assumption, question and finding from the replies. Apply accepted findings and corrections with action follow-up on the takeoff or pricing session, never by re-estimating yourself. Never present a quantity or price Field24 did not return.

Can overwrite or delete data.

Input and output

Input

FieldTypeRequiredDescription
type"takeoff" or "takeoff_review" or "pricing" or "pricing_review" or "proposal"yesWhich agent: takeoff, takeoff_review, pricing, pricing_review or proposal.
action"create" or "status" or "follow-up" or "abort"yescreate starts the agent; status reads it; follow-up sends the user's answers or corrections; abort stops it.
projectIdstring, format uuidnotype takeoff + action create only (required there): the project whose plans, photos or written scope to take off.
scopestring, min length 3, max length 2000notype takeoff + action create only (required there): the scope of work the user locked, verbatim.
takeoffIdstring, format uuidnotypes takeoff_review, pricing, pricing_review and proposal + action create only (required there): the takeoff to review, price or build the proposal from.
rowIdsarray of string, min items 1notype pricing + action create only (optional): re-price only these rows, e.g. unpricedRowIds. Omit to price the whole takeoff.
templatestring, min length 1, max length 100notype proposal + action create only (optional): a proposal template tag the user saved in Field24.
sessionIdstring, min length 1, max length 256noactions status, follow-up and abort (required there): the sessionId that create returned for this same type.
messagestring, min length 1, max length 4000noaction follow-up only (required there): the user's answers or corrections, in their words.
{
  "type": "object",
  "properties": {
    "type": {
      "type": "string",
      "enum": [
        "takeoff",
        "takeoff_review",
        "pricing",
        "pricing_review",
        "proposal"
      ],
      "description": "Which agent: takeoff, takeoff_review, pricing, pricing_review or proposal."
    },
    "action": {
      "type": "string",
      "enum": [
        "create",
        "status",
        "follow-up",
        "abort"
      ],
      "description": "create starts the agent; status reads it; follow-up sends the user's answers or corrections; abort stops it."
    },
    "projectId": {
      "description": "type takeoff + action create only (required there): the project whose plans, photos or written scope to take off.",
      "type": "string",
      "format": "uuid",
      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)
quot; }, "scope": { "description": "type takeoff + action create only (required there): the scope of work the user locked, verbatim.", "type": "string", "minLength": 3, "maxLength": 2000 }, "takeoffId": { "description": "types takeoff_review, pricing, pricing_review and proposal + action create only (required there): the takeoff to review, price or build the proposal from.", "type": "string", "format": "uuid", "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)
quot; }, "rowIds": { "description": "type pricing + action create only (optional): re-price only these rows, e.g. unpricedRowIds. Omit to price the whole takeoff.", "minItems": 1, "type": "array", "items": { "type": "string", "pattern": "^t\\d+
quot; } }, "template": { "description": "type proposal + action create only (optional): a proposal template tag the user saved in Field24.", "type": "string", "minLength": 1, "maxLength": 100 }, "sessionId": { "description": "actions status, follow-up and abort (required there): the sessionId that create returned for this same type.", "type": "string", "minLength": 1, "maxLength": 256 }, "message": { "description": "action follow-up only (required there): the user's answers or corrections, in their words.", "type": "string", "minLength": 1, "maxLength": 4000 } }, "required": [ "type", "action" ] }

Output

FieldTypeRequiredDescription
sessionIdstringyesThe agent session. Keep it: status, follow-up and abort take it.
status"running" or "completed" or "failed" or "aborted"yesrunning: check again after pollAfterSeconds. completed: the result fields for the type are present. failed: see error. aborted: stopped by abort.
expectedMinutesintegernocreate and follow-up only: how long the run usually takes.
pollAfterSecondsintegernocreate, follow-up and status running: wait at least this long before checking status.
startedAtstringnostatus running only: when the session started (ISO 8601).
replystringnostatus completed only: the agent's final message, with its assumptions and questions — for takeoff_review and pricing_review, the numbered findings. Show them to the user.
takeoffIdstringnostatus completed only: the takeoff the agent wrote or worked on.
reviewUrlstringnotakeoff, takeoff_review, pricing and pricing_review completed only: the Field24 page where the user can review and edit rows by hand.
summaryobjectnotakeoff completed only: leaf row count, division count and rows with no quantity.
summary.rowsintegeryes
summary.divisionsintegeryes
summary.rowsWithoutQtyintegeryes
itemsarray of objectnotakeoff and pricing completed only: the takeoff as it stands now; pricing adds the prices.
items[].idstringnoStable row id (t1, t2, …) — use it in rowIds.
items[].divstringyesCSI division.
items[].itemstringyes
items[].descriptionstringyes
items[].qtynumber or nullyesMeasured quantity; null = the agent could not settle one.
items[].unitstringyes
items[].confidence"HIGH" or "MEDIUM" or "LOW"yes
items[].sourcesarray of objectyes
items[].sources[].documentstringyes
items[].sources[].pagesarray of integeryes
items[].unitCostnumbernopricing only.
items[].extCostnumbernopricing only: bare cost, quantity × unit cost, no waste or markup.
items[].suggestedCostnumbernopricing only: client-facing price for the row, waste, contingency and margin included.
items[].costType"material" or "labor"no
items[].wastePctnumberno
items[].childrenarray of objectnoAn assembly's component rows; the parent carries no money of its own.
items[].children[].idstringnoStable row id (t1, t2, …) — use it in rowIds.
items[].children[].divstringyesCSI division.
items[].children[].itemstringyes
items[].children[].descriptionstringyes
items[].children[].qtynumber or nullyesMeasured quantity; null = the agent could not settle one.
items[].children[].unitstringyes
items[].children[].confidence"HIGH" or "MEDIUM" or "LOW"yes
items[].children[].sourcesarray of objectyes
items[].children[].unitCostnumbernopricing only.
items[].children[].extCostnumbernopricing only: bare cost, quantity × unit cost, no waste or markup.
items[].children[].suggestedCostnumbernopricing only: client-facing price for the row, waste, contingency and margin included.
items[].children[].costType"material" or "labor"no
items[].children[].wastePctnumberno
costnumbernopricing completed only: bare cost, Σ leaf quantity × unit cost.
suggestedTotalnumbernopricing completed only: the client-facing total — waste, contingency and margin included.
currency"USD" or "CAD" or nullnopricing completed only.
storeLocationstring or nullnopricing completed only: the store material prices came from.
opPctnumber or nullnopricing completed only: overhead and profit percent applied.
contingencyPctnumber or nullnopricing completed only.
exclusionsarray of anynopricing completed only.
unpricedRowIdsarray of stringnopricing completed only: rows with a quantity and no price. Never present a total while this is not empty.
filesarray of objectnoproposal completed only: the proposal PDFs. The links expire; call status again for fresh ones.
files[].namestringyes
files[].urlstring or nullyesShort-lived download link; null when it could not be made.
files[].notestringno
errorobjectnostatus failed only: what went wrong; when retryable, offer to start it again.
error.codestring, min length 1yes
error.messagestringyes
error.retryablebooleanyes

Takeoff edits

update_takeoff

Edit a Field24 takeoff record directly: change, add or remove rows by row id. Use this ONLY for a change the user states explicitly with its value (for example 'change the drywall to 500 SF' or 'remove the vanity'). Anything that needs measuring, re-reading the plans, or judgement — including every reviewer finding — goes to the estimator with field24_agent action follow-up instead. Read the current rows first (field24_agent takeoff status) and copy row ids exactly. After a quantity change on a priced row, re-run pricing for that row.

Can overwrite or delete data.

Input and output

Input

FieldTypeRequiredDescription
takeoffIdstring, format uuidyesThe takeoff to edit.
itemsarray of object, min items 1, max items 100noRows to change (by id) or add (no id). Send only the fields the user changed on an existing row.
items[].idstring, pattern ^t\d+$noThe row's id from field24_agent takeoff status (t1, t2, …), copied exactly. Required to change a row; omit ONLY to add a new row.
items[].divstring, min length 1, max length 20noCSI division, e.g. 09. Required for a new row.
items[].itemstring, min length 1, max length 200noRow name. Required for a new row.
items[].descriptionstring, max length 2000noRequired for a new row.
items[].qtynumber, min 0noThe quantity the user stated. Required for a new row.
items[].unitstring, min length 1, max length 20noSF, LF, EA, … Required for a new row.
items[].unitCostnumber, min 0noOptional: the unit cost the user stated.
items[].childrenarray of object, min items 1noOnly when editing an assembly's child SET: the full list of its children (a child left out is removed). Every existing child carries its id. To change one child, send that child by its own id instead.
items[].children[].idstring, pattern ^t\d+$noThe row's id from field24_agent takeoff status (t1, t2, …), copied exactly. Required to change a row; omit ONLY to add a new row.
items[].children[].divstring, min length 1, max length 20noCSI division, e.g. 09. Required for a new row.
items[].children[].itemstring, min length 1, max length 200noRow name. Required for a new row.
items[].children[].descriptionstring, max length 2000noRequired for a new row.
items[].children[].qtynumber, min 0noThe quantity the user stated. Required for a new row.
items[].children[].unitstring, min length 1, max length 20noSF, LF, EA, … Required for a new row.
items[].children[].unitCostnumber, min 0noOptional: the unit cost the user stated.
removearray of object, min items 1, max items 100noRows to remove, by id.
remove[].idstring, pattern ^t\d+$yes
{
  "type": "object",
  "properties": {
    "takeoffId": {
      "type": "string",
      "format": "uuid",
      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)
quot;, "description": "The takeoff to edit." }, "items": { "description": "Rows to change (by id) or add (no id). Send only the fields the user changed on an existing row.", "minItems": 1, "maxItems": 100, "type": "array", "items": { "type": "object", "properties": { "id": { "description": "The row's id from field24_agent takeoff status (t1, t2, …), copied exactly. Required to change a row; omit ONLY to add a new row.", "type": "string", "pattern": "^t\\d+
quot; }, "div": { "description": "CSI division, e.g. 09. Required for a new row.", "type": "string", "minLength": 1, "maxLength": 20 }, "item": { "description": "Row name. Required for a new row.", "type": "string", "minLength": 1, "maxLength": 200 }, "description": { "description": "Required for a new row.", "type": "string", "maxLength": 2000 }, "qty": { "description": "The quantity the user stated. Required for a new row.", "type": "number", "minimum": 0 }, "unit": { "description": "SF, LF, EA, … Required for a new row.", "type": "string", "minLength": 1, "maxLength": 20 }, "unitCost": { "description": "Optional: the unit cost the user stated.", "type": "number", "minimum": 0 }, "children": { "description": "Only when editing an assembly's child SET: the full list of its children (a child left out is removed). Every existing child carries its id. To change one child, send that child by its own id instead.", "minItems": 1, "type": "array", "items": { "type": "object", "properties": { "id": { "description": "The row's id from field24_agent takeoff status (t1, t2, …), copied exactly. Required to change a row; omit ONLY to add a new row.", "type": "string", "pattern": "^t\\d+
quot; }, "div": { "description": "CSI division, e.g. 09. Required for a new row.", "type": "string", "minLength": 1, "maxLength": 20 }, "item": { "description": "Row name. Required for a new row.", "type": "string", "minLength": 1, "maxLength": 200 }, "description": { "description": "Required for a new row.", "type": "string", "maxLength": 2000 }, "qty": { "description": "The quantity the user stated. Required for a new row.", "type": "number", "minimum": 0 }, "unit": { "description": "SF, LF, EA, … Required for a new row.", "type": "string", "minLength": 1, "maxLength": 20 }, "unitCost": { "description": "Optional: the unit cost the user stated.", "type": "number", "minimum": 0 } } } } } } }, "remove": { "description": "Rows to remove, by id.", "minItems": 1, "maxItems": 100, "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "pattern": "^t\\d+
quot; } }, "required": [ "id" ] } } }, "required": [ "takeoffId" ] }

Output

FieldTypeRequiredDescription
takeoffIdstringyes
reviewUrlstringyesThe Field24 page where the user can see and edit the takeoff.
changedarray of stringyesRow ids whose fields changed.
addedarray of stringyesIds of the rows this edit added.
removedarray of stringyesIds of the rows this edit removed.
summaryobjectyesThe takeoff after the edit: leaf rows, divisions and rows with no quantity.
summary.rowsintegeryes
summary.divisionsintegeryes
summary.rowsWithoutQtyintegeryes