Private preview of the new site. Not live.

materials.list

Materials recorded on a job (or one visit), with the price and cost totals of those still counted. Prices show only with see_prices, costs only with see_costs; lines with no price or cost set are counted in unpriced_count and uncosted_count.

WhoAgents can call this
RESTGET /v1/materials
MCP toolmaterials_list
Writesno
AreaField work (checklists, forms, time, notes, change orders, subcontractors)

When to use it

Record what went into a job: materials.add from the price book (pricebook_item_id; its name, unit, price, cost and taxable are copied as they are today) or typed in, optionally on one visit. Afterwards only the quantity, visit and notes change (materials.update); for anything else remove it (materials.remove keeps it in history with who and why) and add it again.

What to tell the owner

Tell them what you found in plain words. Don't read back raw fields.

Input

FieldTypeRequired
job_idstring (uuid)yes
visit_idstring (uuid)no
include_removedbooleanno

Example

GET https://doingwork.work/v1/materials?job_id=00000000-0000-4000-8000-000000000000

Output

FieldTypeAlways there
job_idstring (uuid)yes
itemsarrayyes
items[].material_idstring (uuid)yes
items[].shop_idstring (uuid)yes
items[].job_idstring (uuid)yes
items[].visit_id['string', 'null', ' ', '(', 'u', 'u', 'i', 'd', ')']yes
items[].pricebook_item_id['string', 'null', ' ', '(', 'u', 'u', 'i', 'd', ')']yes
items[].namestringyes
items[].unitstringyes
items[].quantitynumberyes
items[].unit_price_minor['integer', 'null']yes
items[].unit_cost_minor['integer', 'null']yes
items[].price_minor['integer', 'null']yes
items[].cost_minor['integer', 'null']yes
items[].taxablebooleanyes
items[].notes['string', 'null']yes
items[].entered_bystring (uuid)yes
items[].entered_by_name['string', 'null']yes
items[].created_atstring (date-time)yes
items[].updated_atstring (date-time)yes
items[].removed_at['string', 'null', ' ', '(', 'd', 'a', 't', 'e', '-', 't', 'i', 'm', 'e', ')']yes
items[].removed_by['string', 'null', ' ', '(', 'u', 'u', 'i', 'd', ')']yes
items[].remove_reason['string', 'null']yes
price_total_minor['integer', 'null']yes
cost_total_minor['integer', 'null']yes
unpriced_countintegeryes
uncosted_countintegeryes
{
  "job_id": "00000000-0000-4000-8000-000000000000",
  "items": [
    {
      "material_id": "00000000-0000-4000-8000-000000000000",
      "shop_id": "00000000-0000-4000-8000-000000000000",
      "job_id": "00000000-0000-4000-8000-000000000000",
      "visit_id": "00000000-0000-4000-8000-000000000000",
      "pricebook_item_id": "00000000-0000-4000-8000-000000000000",
      "name": "Ruiz Plumbing",
      "unit": "...",
      "quantity": "...",
      "unit_price_minor": "...",
      "unit_cost_minor": "...",
      "price_minor": "...",
      "cost_minor": "...",
      "taxable": true,
      "notes": "...",
      "entered_by": "00000000-0000-4000-8000-000000000000",
      "entered_by_name": "...",
      "created_at": "...",
      "updated_at": "...",
      "removed_at": "...",
      "removed_by": "00000000-0000-4000-8000-000000000000",
      "remove_reason": "..."
    }
  ],
  "price_total_minor": "...",
  "cost_total_minor": "...",
  "unpriced_count": 1,
  "uncosted_count": 1
}

Errors

CodeStatusWhat to do
invalid_input, invalid_token, rate_limitedCan happen on any call. See errors.