VAT-correct trade quotes with a branded PDF and one-tap customer accept, for UK trades' AI
Maintain this server? Claim it
Call this server's tools from your browser. Nothing to install.
Requests go through mcptry because browsers can't call most MCP servers directly. Header values are sent to the server for that request only and are never stored or logged.
Tool list from our last check. Connect live to refresh it.
Price a job after a site visit. Give the job, customer, labour (time, priced from the saved rate), materials (trade cost, marked up), other costs and optional extras; the server applies VAT correctly (registered or not, 20/5/0%, the construction domestic reverse charge for contractor customers), the deposit rule, validity, exclusions and a running quote number. Returns the totals, the trade-only margin view, warnings, a check_before_sending list of commonly forgotten items for that trade, and the links to the PDF and the customer's phone page (a DRAFT until finalise_quote). from_quote copies a past quote's lines for a new customer. save false returns the numbers without saving.
Short job name the customer sees, for example "Full rewire, 3 bedroom semi" or "Replace combi boiler".
Who the quote is for. type: homeowner, landlord, tenant, business (buying for itself) or contractor (a builder or main contractor buying your work). For business or contractor customers also give vat_registered, cis_registered and end_user, because they decide whether the construction domestic reverse charge applies.
The trade's secret key from setup_trade (starts qbk_).
Default true. false = preview the numbers only, nothing saved, no quote number used.
Anything else the customer should read.
Other costs charged as a set amount in pounds (ex VAT): skip hire, scaffolding, waste disposal, certification or notification fees, parking. qty multiplies the amount (for example scaffold per week).
Likely start, for example "w/c 7 December".
Which trade this job is, if the business does more than one. Drives the check_before_sending list.
Labour lines. Give days OR hours (time on the job, per person) and the server prices it from the trade's saved rate; or give a fixed price in pounds. rate: trade (default, the trade's own rate) or labourer (their mate or apprentice rate). people: how many on site for that time. rate_override: a one-off day or hour rate in pounds.
Override the trade's usual deposit rule for this quote only. Deposit rule. basis percent (with percent), fixed (with amount in pounds), materials (deposit equals the materials total), or none. no_deposit_under: no deposit on quotes below this total in pounds.
Two to four plain sentences describing the work as found on the visit, written for the customer. No jargon they would not understand.
Optional discount before VAT: percent OR amount (pounds), with a short reason the customer sees.
Time on site, for example "3 working days".
Materials. unit_cost is what the TRADE pays per unit in pounds; the server adds their markup. Set cost_includes_vat true if the price came from a receipt or shelf price including VAT (the server strips it for VAT registered trades). Give a saved code instead of description and unit_cost to use the price book. Prices used here are remembered for next time.
What is NOT included in this job, one short sentence each. Added to the trade's standard exclusions.
Start from this past quote. Fields you send replace that quote's fields; customer is required.
What the price assumes, for example "Clear access to the loft".
Job address, if different from the customer's address.
How many days the prices hold. Defaults to the trade's setting (usually 30).
Optional upgrades the customer can tick when accepting (for example an EV charger, a smart thermostat, extra sockets). price in pounds before VAT. Up to 6. Not included in the main total.
Default true: material prices used here go into the price book.
Default true.
This tool isn't marked read-only, so it may change something on the server or in an account you connected.
Pick your client. Values in capitals, like YOUR_TOKEN, are yours to fill in.
Run in a terminal
claude mcp add --transport http quote-builder https://quote-builder.nerolabs.workers.dev/mcp
Price a job after a site visit. Give the job, customer, labour (time, priced from the saved rate), materials (trade cost, marked up), other costs and optional extras; the server applies VAT correctly (registered or not, 20/5/0%, the construction domestic reverse charge for contractor customers), the deposit rule, validity, exclusions and a running quote number. Returns the totals, the trade-only margin view, warnings, a check_before_sending list of commonly forgotten items for that trade, and the links to the PDF and the customer's phone page (a DRAFT until finalise_quote). from_quote copies a past quote's lines for a new customer. save false returns the numbers without saving.
| Argument | Type | Description |
|---|---|---|
| save | boolean | Default true. false = preview the numbers only, nothing saved, no quote number used. |
| notes | string | Anything else the customer should read. |
| other | array | Other costs charged as a set amount in pounds (ex VAT): skip hire, scaffolding, waste disposal, certification or notification fees, parking. qty multiplies the amount (for example scaffold per week). |
| start | string | Likely start, for example "w/c 7 December". |
| title* | string | Short job name the customer sees, for example "Full rewire, 3 bedroom semi" or "Replace combi boiler". |
| trade | string | Which trade this job is, if the business does more than one. Drives the check_before_sending list. |
| labour | array | Labour lines. Give days OR hours (time on the job, per person) and the server prices it from the trade's saved rate; or give a fixed price in pounds. rate: trade (default, the trade's own rate) or labourer (their mate or apprentice rate). people: how many on site for that time. rate_override: a one-off day or hour rate in pounds. |
| deposit | object | Override the trade's usual deposit rule for this quote only. Deposit rule. basis percent (with percent), fixed (with amount in pounds), materials (deposit equals the materials total), or none. no_deposit_under: no deposit on quotes below this total in pounds. |
| summary | string | Two to four plain sentences describing the work as found on the visit, written for the customer. No jargon they would not understand. |
| customer* | object | Who the quote is for. type: homeowner, landlord, tenant, business (buying for itself) or contractor (a builder or main contractor buying your work). For business or contractor customers also give vat_registered, cis_registered and end_user, because they decide whether the construction domestic reverse charge applies. |
| discount | object | Optional discount before VAT: percent OR amount (pounds), with a short reason the customer sees. |
| duration | string | Time on site, for example "3 working days". |
| materials | array | Materials. unit_cost is what the TRADE pays per unit in pounds; the server adds their markup. Set cost_includes_vat true if the price came from a receipt or shelf price including VAT (the server strips it for VAT registered trades). Give a saved code instead of description and unit_cost to use the price book. Prices used here are remembered for next time. |
| trade_key* | string | The trade's secret key from setup_trade (starts qbk_). |
| exclusions | array | What is NOT included in this job, one short sentence each. Added to the trade's standard exclusions. |
| from_quote | string | Start from this past quote. Fields you send replace that quote's fields; customer is required. |
| assumptions | array | What the price assumes, for example "Clear access to the loft". |
| site_address | string | Job address, if different from the customer's address. |
| validity_days | number | How many days the prices hold. Defaults to the trade's setting (usually 30). |
| optional_extras | array | Optional upgrades the customer can tick when accepting (for example an EV charger, a smart thermostat, extra sockets). price in pounds before VAT. Up to 6. Not included in the main total. |
| remember_prices | boolean | Default true: material prices used here go into the price book. |
| include_standard_exclusions | boolean | Default true. |
{
"type": "object",
"required": [
"trade_key",
"title",
"customer"
],
"properties": {
"save": {
"type": "boolean",
"description": "Default true. false = preview the numbers only, nothing saved, no quote number used."
},
"notes": {
"type": "string",
"description": "Anything else the customer should read."
},
"other": {
"type": "array",
"items": {
"type": "object",
"required": [
"description",
"amount"
],
"properties": {
"qty": {
"type": "number"
},
"unit": {
"type": "string"
},
"amount": {
"type": "number"
},
"description": {
"type": "string"
},
"vat_category": {
"enum": [
"standard",
"reduced_5",
"zero_energy_saving",
"zero_new_build",
"zero_disabled",
"outside_scope"
],
"type": "string",
"description": "VAT treatment of this line if the trade is VAT registered. standard = 20% (almost all repair, maintenance and installation work). reduced_5 = 5% (home empty 2+ years, conversion into a different number of homes, grant-funded heating). zero_energy_saving = 0% until 31 March 2027 for installing insulation, heat pumps, solar panels, batteries or heating controls in a home (NOT gas or oil boilers). zero_new_build = building a new home. zero_disabled = adaptations for a disabled person (needs their signed declaration). outside_scope = a fee paid on the customer's behalf at cost. Default standard. Ignored if the trade is not VAT registered."
}
}
},
"description": "Other costs charged as a set amount in pounds (ex VAT): skip hire, scaffolding, waste disposal, certification or notification fees, parking. qty multiplies the amount (for example scaffold per week)."
},
"start": {
"type": "string",
"description": "Likely start, for example \"w/c 7 December\"."
},
"title": {
"type": "string",
"description": "Short job name the customer sees, for example \"Full rewire, 3 bedroom semi\" or \"Replace combi boiler\"."
},
"trade": {
"enum": [
"electrician",
"plumber_heating",
"builder",
"roofer",
"decorator"
],
"type": "string",
"description": "Which trade this job is, if the business does more than one. Drives the check_before_sending list."
},
"labour": {
"type": "array",
"items": {
"type": "object",
"required": [
"description"
],
"properties": {
"days": {
"type": "number"
},
"rate": {
"enum": [
"trade",
"labourer"
],
"type": "string"
},
"hours": {
"type": "number"
},
"price": {
"type": "number"
},
"people": {
"type": "number"
},
"description": {
"type": "string"
},
"vat_category": {
"enum": [
"standard",
"reduced_5",
"zero_energy_saving",
"zero_new_build",
"zero_disabled",
"outside_scope"
],
"type": "string",
"description": "VAT treatment of this line if the trade is VAT registered. standard = 20% (almost all repair, maintenance and installation work). reduced_5 = 5% (home empty 2+ years, conversion into a different number of homes, grant-funded heating). zero_energy_saving = 0% until 31 March 2027 for installing insulation, heat pumps, solar panels, batteries or heating controls in a home (NOT gas or oil boilers). zero_new_build = building a new home. zero_disabled = adaptations for a disabled person (needs their signed declaration). outside_scope = a fee paid on the customer's behalf at cost. Default standard. Ignored if the trade is not VAT registered."
},
"rate_override": {
"type": "number"
}
}
},
"description": "Labour lines. Give days OR hours (time on the job, per person) and the server prices it from the trade's saved rate; or give a fixed price in pounds. rate: trade (default, the trade's own rate) or labourer (their mate or apprentice rate). people: how many on site for that time. rate_override: a one-off day or hour rate in pounds."
},
"deposit": {
"type": "object",
"properties": {
"basis": {
"enum": [
"percent",
"fixed",
"materials",
"none"
],
"type": "string"
},
"amount": {
"type": "number"
},
"percent": {
"type": "number"
},
"no_deposit_under": {
"type": "number"
}
},
"description": "Override the trade's usual deposit rule for this quote only. Deposit rule. basis percent (with percent), fixed (with amount in pounds), materials (deposit equals the materials total), or none. no_deposit_under: no deposit on quotes below this total in pounds."
},
"summary": {
"type": "string",
"description": "Two to four plain sentences describing the work as found on the visit, written for the customer. No jargon they would not understand."
},
"customer": {
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string"
},
"type": {
"enum": [
"homeowner",
"landlord",
"tenant",
"business",
"contractor"
],
"type": "string"
},
"email": {
"type": "string"
},
"phone": {
"type": "string"
},
"address": {
"type": "string"
},
"company": {
"type": "string"
},
"end_user": {
"type": "boolean",
"description": "True if this business customer is the end user of the work (not selling it on)."
},
"postcode": {
"type": "string"
},
"cis_registered": {
"type": "boolean"
},
"vat_registered": {
"type": "boolean"
}
},
"description": "Who the quote is for. type: homeowner, landlord, tenant, business (buying for itself) or contractor (a builder or main contractor buying your work). For business or contractor customers also give vat_registered, cis_registered and end_user, because they decide whether the construction domestic reverse charge applies."
},
"discount": {
"type": "object",
"properties": {
"amount": {
"type": "number"
},
"reason": {
"type": "string"
},
"percent": {
"type": "number"
}
},
"description": "Optional discount before VAT: percent OR amount (pounds), with a short reason the customer sees."
},
"duration": {
"type": "string",
"description": "Time on site, for example \"3 working days\"."
},
"materials": {
"type": "array",
"items": {
"type": "object",
"properties": {
"qty": {
"type": "number"
},
"code": {
"type": "string"
},
"unit": {
"type": "string",
"description": "each, m, drum, tin, box, lot, m2..."
},
"unit_cost": {
"type": "number"
},
"description": {
"type": "string"
},
"vat_category": {
"enum": [
"standard",
"reduced_5",
"zero_energy_saving",
"zero_new_build",
"zero_disabled",
"outside_scope"
],
"type": "string",
"description": "VAT treatment of this line if the trade is VAT registered. standard = 20% (almost all repair, maintenance and installation work). reduced_5 = 5% (home empty 2+ years, conversion into a different number of homes, grant-funded heating). zero_energy_saving = 0% until 31 March 2027 for installing insulation, heat pumps, solar panels, batteries or heating controls in a home (NOT gas or oil boilers). zero_new_build = building a new home. zero_disabled = adaptations for a disabled person (needs their signed declaration). outside_scope = a fee paid on the customer's behalf at cost. Default standard. Ignored if the trade is not VAT registered."
},
"markup_percent": {
"type": "number"
},
"cost_includes_vat": {
"type": "boolean"
}
}
},
"description": "Materials. unit_cost is what the TRADE pays per unit in pounds; the server adds their markup. Set cost_includes_vat true if the price came from a receipt or shelf price including VAT (the server strips it for VAT registered trades). Give a saved code instead of description and unit_cost to use the price book. Prices used here are remembered for next time."
},
"trade_key": {
"type": "string",
"description": "The trade's secret key from setup_trade (starts qbk_)."
},
"exclusions": {
"type": "array",
"items": {
"type": "string"
},
"description": "What is NOT included in this job, one short sentence each. Added to the trade's standard exclusions."
},
"from_quote": {
"type": "string",
"description": "Start from this past quote. Fields you send replace that quote's fields; customer is required."
},
"assumptions": {
"type": "array",
"items": {
"type": "string"
},
"description": "What the price assumes, for example \"Clear access to the loft\"."
},
"site_address": {
"type": "string",
"description": "Job address, if different from the customer's address."
},
"validity_days": {
"type": "number",
"description": "How many days the prices hold. Defaults to the trade's setting (usually 30)."
},
"optional_extras": {
"type": "array",
"items": {
"type": "object",
"required": [
"description",
"price"
],
"properties": {
"price": {
"type": "number"
},
"description": {
"type": "string"
},
"vat_category": {
"enum": [
"standard",
"reduced_5",
"zero_energy_saving",
"zero_new_build",
"zero_disabled",
"outside_scope"
],
"type": "string",
"description": "VAT treatment of this line if the trade is VAT registered. standard = 20% (almost all repair, maintenance and installation work). reduced_5 = 5% (home empty 2+ years, conversion into a different number of homes, grant-funded heating). zero_energy_saving = 0% until 31 March 2027 for installing insulation, heat pumps, solar panels, batteries or heating controls in a home (NOT gas or oil boilers). zero_new_build = building a new home. zero_disabled = adaptations for a disabled person (needs their signed declaration). outside_scope = a fee paid on the customer's behalf at cost. Default standard. Ignored if the trade is not VAT registered."
}
}
},
"description": "Optional upgrades the customer can tick when accepting (for example an EV charger, a smart thermostat, extra sockets). price in pounds before VAT. Up to 6. Not included in the main total."
},
"remember_prices": {
"type": "boolean",
"description": "Default true: material prices used here go into the price book."
},
"include_standard_exclusions": {
"type": "boolean",
"description": "Default true."
}
}
}The quote in the exact argument shape of the Nero Work exchange's submit_quote tool (labour_minor, materials_minor, vat_minor in pence, validity_hours, exclusions, notes), checked with Nero Work's own rules. If the customer accepted with extras, they are included.
| Argument | Type | Description |
|---|---|---|
| quote* | string | Quote number, for example BLE-0007. |
| trade_key* | string | The trade's secret key from setup_trade (starts qbk_). |
{
"type": "object",
"required": [
"trade_key",
"quote"
],
"properties": {
"quote": {
"type": "string",
"description": "Quote number, for example BLE-0007."
},
"trade_key": {
"type": "string",
"description": "The trade's secret key from setup_trade (starts qbk_)."
}
}
}Lock a draft so the customer can answer it. Sets today's date and the valid-until date, and returns the customer link, the PDF link and a short ready-to-send message. Nothing is sent by this server: the trade sends the link by their own text, WhatsApp or email. Free allowance: 5 finalised quotes per calendar month (UK time) per trade, shown as free_allowance in the answer and in get_trade; past it the quote stays a saved draft and can be finalised from the 1st of next month. Drafts, revisions of quotes already sent, replies and exports never count.
| Argument | Type | Description |
|---|---|---|
| quote* | string | Quote number, for example BLE-0007. |
| trade_key* | string | The trade's secret key from setup_trade (starts qbk_). |
{
"type": "object",
"required": [
"trade_key",
"quote"
],
"properties": {
"quote": {
"type": "string",
"description": "Quote number, for example BLE-0007."
},
"trade_key": {
"type": "string",
"description": "The trade's secret key from setup_trade (starts qbk_)."
}
}
}One quote in full: lines, totals, VAT working with HMRC sources, margins (trade only), the customer's answer, history (drafted, sent, opened, accepted) and links.
| Argument | Type | Description |
|---|---|---|
| quote* | string | Quote number, for example BLE-0007. |
| trade_key* | string | The trade's secret key from setup_trade (starts qbk_). |
{
"type": "object",
"required": [
"trade_key",
"quote"
],
"properties": {
"quote": {
"type": "string",
"description": "Quote number, for example BLE-0007."
},
"trade_key": {
"type": "string",
"description": "The trade's secret key from setup_trade (starts qbk_)."
}
}
}The trade's saved settings, price book (most used first), quote stats (win rate, value won in the last 12 months) and, for a business that is not VAT registered, a warning when accepted work is nearing the £90,000 VAT registration threshold.
| Argument | Type | Description |
|---|---|---|
| trade_key* | string | The trade's secret key from setup_trade (starts qbk_). |
{
"type": "object",
"required": [
"trade_key"
],
"properties": {
"trade_key": {
"type": "string",
"description": "The trade's secret key from setup_trade (starts qbk_)."
}
}
}Recent quotes, newest first, with status (draft, sent, viewed, queried, accepted, declined, expired, withdrawn), total and whether there is news. Filter by status or search customer name, job title or number.
| Argument | Type | Description |
|---|---|---|
| limit | number | |
| search | string | |
| status | string | |
| trade_key* | string | The trade's secret key from setup_trade (starts qbk_). |
{
"type": "object",
"required": [
"trade_key"
],
"properties": {
"limit": {
"type": "number"
},
"search": {
"type": "string"
},
"status": {
"type": "string"
},
"trade_key": {
"type": "string",
"description": "The trade's secret key from setup_trade (starts qbk_)."
}
}
}What customers have done since the trade last checked: quotes opened, accepted (with the name they signed, extras ticked and final total), questions asked, declined. Marks them as seen unless mark_seen is false. Answers when the trade asks "any news on my quotes?".
| Argument | Type | Description |
|---|---|---|
| mark_seen | boolean | |
| trade_key* | string | The trade's secret key from setup_trade (starts qbk_). |
{
"type": "object",
"required": [
"trade_key"
],
"properties": {
"mark_seen": {
"type": "boolean"
},
"trade_key": {
"type": "string",
"description": "The trade's secret key from setup_trade (starts qbk_)."
}
}
}Answer a customer's question. The answer shows on their quote page under their question. Use revise_quote instead if the price or scope changes.
| Argument | Type | Description |
|---|---|---|
| quote* | string | Quote number, for example BLE-0007. |
| message* | string | |
| trade_key* | string | The trade's secret key from setup_trade (starts qbk_). |
{
"type": "object",
"required": [
"trade_key",
"quote",
"message"
],
"properties": {
"quote": {
"type": "string",
"description": "Quote number, for example BLE-0007."
},
"message": {
"type": "string"
},
"trade_key": {
"type": "string",
"description": "The trade's secret key from setup_trade (starts qbk_)."
}
}
}Change a quote. Send only the fields that change (a list you send, such as materials, replaces that whole list). A draft stays a draft. A quote the customer already has becomes the next revision on the same link, with fresh dates, and any earlier answer is cleared. Accepted quotes cannot change. status "withdrawn" pulls a quote. use_current_settings true re-prices with the trade's latest rates.
| Argument | Type | Description |
|---|---|---|
| notes | string | Anything else the customer should read. |
| other | array | Other costs charged as a set amount in pounds (ex VAT): skip hire, scaffolding, waste disposal, certification or notification fees, parking. qty multiplies the amount (for example scaffold per week). |
| quote* | string | Quote number, for example BLE-0007. |
| start | string | Likely start, for example "w/c 7 December". |
| title | string | Short job name the customer sees, for example "Full rewire, 3 bedroom semi" or "Replace combi boiler". |
| trade | string | Which trade this job is, if the business does more than one. Drives the check_before_sending list. |
| labour | array | Labour lines. Give days OR hours (time on the job, per person) and the server prices it from the trade's saved rate; or give a fixed price in pounds. rate: trade (default, the trade's own rate) or labourer (their mate or apprentice rate). people: how many on site for that time. rate_override: a one-off day or hour rate in pounds. |
Add or update materials in the trade's price book, so later quotes can use { code, qty } and the cost, unit and markup fill in. Materials used in quotes are also remembered automatically.
| Argument | Type | Description |
|---|---|---|
| trade_key* | string | The trade's secret key from setup_trade (starts qbk_). |
| price_items* | array | Materials the trade buys often, saved to their price book. Each: code (short id, optional), description, unit, unit_cost (pounds, what they pay), cost_includes_vat, markup_percent (optional, overrides the default). |
{
"type": "object",
"required": [
"trade_key",
"price_items"
],
"properties": {
"trade_key": {
"type": "string",
"description": "The trade's secret key from setup_trade (starts qbk_)."
},
"price_items": {
"type": "array",
"items": {
"type": "object",
"required": [
"description",
"unit_cost"
],
"properties": {
"code": {
"type": "string"
},
"unit": {
"type": "string"
},
"unit_cost": {
"type": "number"
},
"description": {
"type": "string"
},
"markup_percent": {
"type": "number"
},
"cost_includes_vat": {
"type": "boolean"
}
}
},
"description": "Materials the trade buys often, saved to their price book. Each: code (short id, optional), description, unit, unit_cost (pounds, what they pay), cost_includes_vat, markup_percent (optional, overrides the default)."
}
}
}Create a business, or update its saved settings (call with trade_key to update). Saves the rates and rules every quote uses: day and hour rates, labourer rate, materials markup, VAT registration and number, CIS, deposit rule, validity, payment terms, standard exclusions, brand colour, logo (https link or base64; PNG or JPEG for the PDF), quote number prefix, price book. On first call returns trade_key ONCE: it is shown only once and every other tool needs it. Also returns nero_trade_ref, the same identity the Nero Work exchange and Spark Pack use. Money in pounds.
| Argument | Type | Description |
|---|---|---|
| string | ||
| phone | string | |
| trades | array | Required on first setup. |
| address | string | |
| deposit | object | Deposit rule. basis percent (with percent), fixed (with amount in pounds), materials (deposit equals the materials total), or none. no_deposit_under: no deposit on quotes below this total in pounds. |
| website | string | |
| day_rate | number | The trade's own charge-out rate per day, pounds, before VAT. |
| logo_url | string | https link to the logo (PNG best, JPEG fine, SVG shows on the phone page only). Under 400 KB. |
We read every tool's name, description and inputs the way the model will, looking for instructions hidden from you. A clean result means no warning signs, not a guarantee. Scanned Nov 13, 2026.
| reason | string |
| status | string |
| deposit | object | Override the trade's usual deposit rule for this quote only. Deposit rule. basis percent (with percent), fixed (with amount in pounds), materials (deposit equals the materials total), or none. no_deposit_under: no deposit on quotes below this total in pounds. |
| summary | string | Two to four plain sentences describing the work as found on the visit, written for the customer. No jargon they would not understand. |
| customer | object | Who the quote is for. type: homeowner, landlord, tenant, business (buying for itself) or contractor (a builder or main contractor buying your work). For business or contractor customers also give vat_registered, cis_registered and end_user, because they decide whether the construction domestic reverse charge applies. |
| discount | object | Optional discount before VAT: percent OR amount (pounds), with a short reason the customer sees. |
| duration | string | Time on site, for example "3 working days". |
| materials | array | Materials. unit_cost is what the TRADE pays per unit in pounds; the server adds their markup. Set cost_includes_vat true if the price came from a receipt or shelf price including VAT (the server strips it for VAT registered trades). Give a saved code instead of description and unit_cost to use the price book. Prices used here are remembered for next time. |
| trade_key* | string | The trade's secret key from setup_trade (starts qbk_). |
| exclusions | array | What is NOT included in this job, one short sentence each. Added to the trade's standard exclusions. |
| assumptions | array | What the price assumes, for example "Clear access to the loft". |
| site_address | string | Job address, if different from the customer's address. |
| validity_days | number | How many days the prices hold. Defaults to the trade's setting (usually 30). |
| optional_extras | array | Optional upgrades the customer can tick when accepting (for example an EV charger, a smart thermostat, extra sockets). price in pounds before VAT. Up to 6. Not included in the main total. |
| remember_prices | boolean |
| use_current_settings | boolean |
| include_standard_exclusions | boolean | Default true. |
{
"type": "object",
"required": [
"trade_key",
"quote"
],
"properties": {
"notes": {
"type": "string",
"description": "Anything else the customer should read."
},
"other": {
"type": "array",
"items": {
"type": "object",
"required": [
"description",
"amount"
],
"properties": {
"qty": {
"type": "number"
},
"unit": {
"type": "string"
},
"amount": {
"type": "number"
},
"description": {
"type": "string"
},
"vat_category": {
"enum": [
"standard",
"reduced_5",
"zero_energy_saving",
"zero_new_build",
"zero_disabled",
"outside_scope"
],
"type": "string",
"description": "VAT treatment of this line if the trade is VAT registered. standard = 20% (almost all repair, maintenance and installation work). reduced_5 = 5% (home empty 2+ years, conversion into a different number of homes, grant-funded heating). zero_energy_saving = 0% until 31 March 2027 for installing insulation, heat pumps, solar panels, batteries or heating controls in a home (NOT gas or oil boilers). zero_new_build = building a new home. zero_disabled = adaptations for a disabled person (needs their signed declaration). outside_scope = a fee paid on the customer's behalf at cost. Default standard. Ignored if the trade is not VAT registered."
}
}
},
"description": "Other costs charged as a set amount in pounds (ex VAT): skip hire, scaffolding, waste disposal, certification or notification fees, parking. qty multiplies the amount (for example scaffold per week)."
},
"quote": {
"type": "string",
"description": "Quote number, for example BLE-0007."
},
"start": {
"type": "string",
"description": "Likely start, for example \"w/c 7 December\"."
},
"title": {
"type": "string",
"description": "Short job name the customer sees, for example \"Full rewire, 3 bedroom semi\" or \"Replace combi boiler\"."
},
"trade": {
"enum": [
"electrician",
"plumber_heating",
"builder",
"roofer",
"decorator"
],
"type": "string",
"description": "Which trade this job is, if the business does more than one. Drives the check_before_sending list."
},
"labour": {
"type": "array",
"items": {
"type": "object",
"required": [
"description"
],
"properties": {
"days": {
"type": "number"
},
"rate": {
"enum": [
"trade",
"labourer"
],
"type": "string"
},
"hours": {
"type": "number"
},
"price": {
"type": "number"
},
"people": {
"type": "number"
},
"description": {
"type": "string"
},
"vat_category": {
"enum": [
"standard",
"reduced_5",
"zero_energy_saving",
"zero_new_build",
"zero_disabled",
"outside_scope"
],
"type": "string",
"description": "VAT treatment of this line if the trade is VAT registered. standard = 20% (almost all repair, maintenance and installation work). reduced_5 = 5% (home empty 2+ years, conversion into a different number of homes, grant-funded heating). zero_energy_saving = 0% until 31 March 2027 for installing insulation, heat pumps, solar panels, batteries or heating controls in a home (NOT gas or oil boilers). zero_new_build = building a new home. zero_disabled = adaptations for a disabled person (needs their signed declaration). outside_scope = a fee paid on the customer's behalf at cost. Default standard. Ignored if the trade is not VAT registered."
},
"rate_override": {
"type": "number"
}
}
},
"description": "Labour lines. Give days OR hours (time on the job, per person) and the server prices it from the trade's saved rate; or give a fixed price in pounds. rate: trade (default, the trade's own rate) or labourer (their mate or apprentice rate). people: how many on site for that time. rate_override: a one-off day or hour rate in pounds."
},
"reason": {
"type": "string"
},
"status": {
"enum": [
"withdrawn"
],
"type": "string"
},
"deposit": {
"type": "object",
"properties": {
"basis": {
"enum": [
"percent",
"fixed",
"materials",
"none"
],
"type": "string"
},
"amount": {
"type": "number"
},
"percent": {
"type": "number"
},
"no_deposit_under": {
"type": "number"
}
},
"description": "Override the trade's usual deposit rule for this quote only. Deposit rule. basis percent (with percent), fixed (with amount in pounds), materials (deposit equals the materials total), or none. no_deposit_under: no deposit on quotes below this total in pounds."
},
"summary": {
"type": "string",
"description": "Two to four plain sentences describing the work as found on the visit, written for the customer. No jargon they would not understand."
},
"customer": {
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string"
},
"type": {
"enum": [
"homeowner",
"landlord",
"tenant",
"business",
"contractor"
],
"type": "string"
},
"email": {
"type": "string"
},
"phone": {
"type": "string"
},
"address": {
"type": "string"
},
"company": {
"type": "string"
},
"end_user": {
"type": "boolean",
"description": "True if this business customer is the end user of the work (not selling it on)."
},
"postcode": {
"type": "string"
},
"cis_registered": {
"type": "boolean"
},
"vat_registered": {
"type": "boolean"
}
},
"description": "Who the quote is for. type: homeowner, landlord, tenant, business (buying for itself) or contractor (a builder or main contractor buying your work). For business or contractor customers also give vat_registered, cis_registered and end_user, because they decide whether the construction domestic reverse charge applies."
},
"discount": {
"type": "object",
"properties": {
"amount": {
"type": "number"
},
"reason": {
"type": "string"
},
"percent": {
"type": "number"
}
},
"description": "Optional discount before VAT: percent OR amount (pounds), with a short reason the customer sees."
},
"duration": {
"type": "string",
"description": "Time on site, for example \"3 working days\"."
},
"materials": {
"type": "array",
"items": {
"type": "object",
"properties": {
"qty": {
"type": "number"
},
"code": {
"type": "string"
},
"unit": {
"type": "string",
"description": "each, m, drum, tin, box, lot, m2..."
},
"unit_cost": {
"type": "number"
},
"description": {
"type": "string"
},
"vat_category": {
"enum": [
"standard",
"reduced_5",
"zero_energy_saving",
"zero_new_build",
"zero_disabled",
"outside_scope"
],
"type": "string",
"description": "VAT treatment of this line if the trade is VAT registered. standard = 20% (almost all repair, maintenance and installation work). reduced_5 = 5% (home empty 2+ years, conversion into a different number of homes, grant-funded heating). zero_energy_saving = 0% until 31 March 2027 for installing insulation, heat pumps, solar panels, batteries or heating controls in a home (NOT gas or oil boilers). zero_new_build = building a new home. zero_disabled = adaptations for a disabled person (needs their signed declaration). outside_scope = a fee paid on the customer's behalf at cost. Default standard. Ignored if the trade is not VAT registered."
},
"markup_percent": {
"type": "number"
},
"cost_includes_vat": {
"type": "boolean"
}
}
},
"description": "Materials. unit_cost is what the TRADE pays per unit in pounds; the server adds their markup. Set cost_includes_vat true if the price came from a receipt or shelf price including VAT (the server strips it for VAT registered trades). Give a saved code instead of description and unit_cost to use the price book. Prices used here are remembered for next time."
},
"trade_key": {
"type": "string",
"description": "The trade's secret key from setup_trade (starts qbk_)."
},
"exclusions": {
"type": "array",
"items": {
"type": "string"
},
"description": "What is NOT included in this job, one short sentence each. Added to the trade's standard exclusions."
},
"assumptions": {
"type": "array",
"items": {
"type": "string"
},
"description": "What the price assumes, for example \"Clear access to the loft\"."
},
"site_address": {
"type": "string",
"description": "Job address, if different from the customer's address."
},
"validity_days": {
"type": "number",
"description": "How many days the prices hold. Defaults to the trade's setting (usually 30)."
},
"optional_extras": {
"type": "array",
"items": {
"type": "object",
"required": [
"description",
"price"
],
"properties": {
"price": {
"type": "number"
},
"description": {
"type": "string"
},
"vat_category": {
"enum": [
"standard",
"reduced_5",
"zero_energy_saving",
"zero_new_build",
"zero_disabled",
"outside_scope"
],
"type": "string",
"description": "VAT treatment of this line if the trade is VAT registered. standard = 20% (almost all repair, maintenance and installation work). reduced_5 = 5% (home empty 2+ years, conversion into a different number of homes, grant-funded heating). zero_energy_saving = 0% until 31 March 2027 for installing insulation, heat pumps, solar panels, batteries or heating controls in a home (NOT gas or oil boilers). zero_new_build = building a new home. zero_disabled = adaptations for a disabled person (needs their signed declaration). outside_scope = a fee paid on the customer's behalf at cost. Default standard. Ignored if the trade is not VAT registered."
}
}
},
"description": "Optional upgrades the customer can tick when accepting (for example an EV charger, a smart thermostat, extra sockets). price in pounds before VAT. Up to 6. Not included in the main total."
},
"remember_prices": {
"type": "boolean"
},
"use_current_settings": {
"type": "boolean"
},
"include_standard_exclusions": {
"type": "boolean",
"description": "Default true."
}
}
}| postcode | string |
| hour_rate | number | Per hour, pounds. If only one of day_rate and hour_rate is set the other is worked out from hours_per_day. |
| trade_key | string | Omit to create a new business. Give it to update an existing one (only the fields you send change). |
| vat_number | string |
| logo_base64 | string | The logo file as base64, instead of logo_url. |
| price_items | array | Materials the trade buys often, saved to their price book. Each: code (short id, optional), description, unit, unit_cost (pounds, what they pay), cost_includes_vat, markup_percent (optional, overrides the default). |
| brand_colour | string | Hex colour, for example #0B5FFF. If a logo is given and no colour, one is taken from the logo. |
| company_name | string | Registered company name if a limited company. |
| display_name | string | Business name customers see. Required on first setup. |
| licence_body | string | Scheme or registration body: niceic, napit, elecsa, stroma, gas_safe, oftec, hetas, fensa, certass, trustmark, nfrc, fmb, other. |
| quote_prefix | string | Letters before the quote number, for example BLE gives BLE-0001. Default from the business initials. |
| accent_colour | string |
| hours_per_day | number | Default 8. |
| payment_terms | string | Shown on every quote, for example "Deposit to book, balance on completion by bank transfer." |
| price_display | string | itemised (default) shows quantity and price per line; sections shows one price per section (labour, materials) with the lines listed. |
| validity_days | number | Default 30. |
| cis_registered | boolean |
| company_number | string |
| licence_number | string | Registration number with that body (Gas Safe number for gas engineers). |
| vat_registered | boolean | Required on first setup. If false, no VAT is ever added. |
| labourer_day_rate | number | Charge-out day rate for a mate, labourer or apprentice. |
| standard_exclusions | array | Things this business never includes unless stated, shown on every quote. |
| materials_markup_percent | number | Added to what materials cost the trade. Default 15. |
| use_suggested_exclusions | boolean | Adds a short set of common exclusions for the trade(s), for example plastering after chasing for electricians. |
{
"type": "object",
"properties": {
"email": {
"type": "string"
},
"phone": {
"type": "string"
},
"trades": {
"type": "array",
"items": {
"enum": [
"electrician",
"plumber_heating",
"builder",
"roofer",
"decorator"
],
"type": "string"
},
"description": "Required on first setup."
},
"address": {
"type": "string"
},
"deposit": {
"type": "object",
"properties": {
"basis": {
"enum": [
"percent",
"fixed",
"materials",
"none"
],
"type": "string"
},
"amount": {
"type": "number"
},
"percent": {
"type": "number"
},
"no_deposit_under": {
"type": "number"
}
},
"description": "Deposit rule. basis percent (with percent), fixed (with amount in pounds), materials (deposit equals the materials total), or none. no_deposit_under: no deposit on quotes below this total in pounds."
},
"website": {
"type": "string"
},
"day_rate": {
"type": "number",
"description": "The trade's own charge-out rate per day, pounds, before VAT."
},
"logo_url": {
"type": "string",
"description": "https link to the logo (PNG best, JPEG fine, SVG shows on the phone page only). Under 400 KB."
},
"postcode": {
"type": "string"
},
"hour_rate": {
"type": "number",
"description": "Per hour, pounds. If only one of day_rate and hour_rate is set the other is worked out from hours_per_day."
},
"trade_key": {
"type": "string",
"description": "Omit to create a new business. Give it to update an existing one (only the fields you send change)."
},
"vat_number": {
"type": "string"
},
"logo_base64": {
"type": "string",
"description": "The logo file as base64, instead of logo_url."
},
"price_items": {
"type": "array",
"items": {
"type": "object",
"required": [
"description",
"unit_cost"
],
"properties": {
"code": {
"type": "string"
},
"unit": {
"type": "string"
},
"unit_cost": {
"type": "number"
},
"description": {
"type": "string"
},
"markup_percent": {
"type": "number"
},
"cost_includes_vat": {
"type": "boolean"
}
}
},
"description": "Materials the trade buys often, saved to their price book. Each: code (short id, optional), description, unit, unit_cost (pounds, what they pay), cost_includes_vat, markup_percent (optional, overrides the default)."
},
"brand_colour": {
"type": "string",
"description": "Hex colour, for example #0B5FFF. If a logo is given and no colour, one is taken from the logo."
},
"company_name": {
"type": "string",
"description": "Registered company name if a limited company."
},
"display_name": {
"type": "string",
"description": "Business name customers see. Required on first setup."
},
"licence_body": {
"type": "string",
"description": "Scheme or registration body: niceic, napit, elecsa, stroma, gas_safe, oftec, hetas, fensa, certass, trustmark, nfrc, fmb, other."
},
"quote_prefix": {
"type": "string",
"description": "Letters before the quote number, for example BLE gives BLE-0001. Default from the business initials."
},
"accent_colour": {
"type": "string"
},
"hours_per_day": {
"type": "number",
"description": "Default 8."
},
"payment_terms": {
"type": "string",
"description": "Shown on every quote, for example \"Deposit to book, balance on completion by bank transfer.\""
},
"price_display": {
"enum": [
"itemised",
"sections"
],
"type": "string",
"description": "itemised (default) shows quantity and price per line; sections shows one price per section (labour, materials) with the lines listed."
},
"validity_days": {
"type": "number",
"description": "Default 30."
},
"cis_registered": {
"type": "boolean"
},
"company_number": {
"type": "string"
},
"licence_number": {
"type": "string",
"description": "Registration number with that body (Gas Safe number for gas engineers)."
},
"vat_registered": {
"type": "boolean",
"description": "Required on first setup. If false, no VAT is ever added."
},
"labourer_day_rate": {
"type": "number",
"description": "Charge-out day rate for a mate, labourer or apprentice."
},
"standard_exclusions": {
"type": "array",
"items": {
"type": "string"
},
"description": "Things this business never includes unless stated, shown on every quote."
},
"materials_markup_percent": {
"type": "number",
"description": "Added to what materials cost the trade. Default 15."
},
"use_suggested_exclusions": {
"type": "boolean",
"description": "Adds a short set of common exclusions for the trade(s), for example plastering after chasing for electricians."
}
}
}