quotes.linesFromTasks
Turn the flat rate tasks a worker picked into quote lines for quotes.create: shared tasks, or tasks per good, better, best option. Uses the member price when the customer has an active maintenance plan. Writes nothing; send the lines the worker approves to quotes.create.
| |
|---|
| Who | Agents can call this |
| REST | POST /v1/quotes/lines-from-tasks |
| MCP tool | quotes_linesFromTasks |
| Writes | no |
| Area | Shop |
When to use it
A flat rate task is a price book item with kind task: one price for the whole job, with an optional task_code, member_price_minor for customers on an active maintenance plan, est_minutes, warranty_note and parts (materials from the price book with a quantity, used for costing only; they do not take stock). Save tasks with pricebook.saveItem, or bring a book in with imports.historyPreview and imports.historyRun using kind flat_rate (presets jobber and housecall_pro; their column names are our best guess, so check the suggested mapping).
What to tell the owner
Tell them what you found in plain words. Don't read back raw fields.
| Field | Type | Required |
|---|
shop_id | string (uuid) | yes |
customer_id | string (uuid) | no |
tasks | array | no |
tasks[].item_id | string (uuid) | yes |
tasks[].quantity | number | no |
options | array | no |
options[].key | string | yes |
options[].label | string | yes |
options[].tasks | array | yes |
options[].tasks[].item_id | string (uuid) | yes |
options[].tasks[].quantity | number | no |
Example
POST https://doingwork.work/v1/quotes/lines-from-tasks
content-type: application/json
Idempotency-Key: 3f1c...
{
"shop_id": "00000000-0000-4000-8000-000000000000"
}
Output
| Field | Type | Always there |
|---|
member | boolean | yes |
plan | ['object', 'null'] | yes |
options | ['array', 'null'] | yes |
lines | array | yes |
lines[].description | string | yes |
lines[].quantity | number | yes |
lines[].unit_price_minor | integer | yes |
lines[].taxable | boolean | yes |
lines[].option_key | string | no |
details | array | yes |
details[].item_id | string (uuid) | yes |
details[].task_code | ['string', 'null'] | yes |
details[].option_key | ['string', 'null'] | yes |
details[].price_minor | integer | yes |
details[].member_price_minor | ['integer', 'null'] | yes |
details[].member_price_applied | boolean | yes |
details[].warranty_note | ['string', 'null'] | yes |
option_totals | ['object', 'null'] | yes |
{
"member": true,
"plan": "...",
"options": "...",
"lines": [
{
"description": "40 gallon gas heater, installed",
"quantity": "...",
"unit_price_minor": 50000,
"taxable": true
}
],
"details": [
{
"item_id": "00000000-0000-4000-8000-000000000000",
"task_code": "...",
"option_key": "...",
"price_minor": 50000,
"member_price_minor": "...",
"member_price_applied": true,
"warranty_note": "..."
}
],
"option_totals": "..."
}
Errors
| Code | Status | What to do |
|---|
invalid_input, invalid_token, rate_limited | | Can happen on any call. See errors. |