Instant Roofer MCP
Tool reference
Every tool returns JSON (also as structuredContent matching its output schema). Failures return isError: true with { "error": "<code>", "message": "…" } as text and no structuredContent. Tools marked spends consume the Instant Measure allowance or place a paid order.
get_account — Get connected account
Scope: crm:read. Makes changes.
Describe the Instant Roofer account this connection acts as: the team member, the contractor, which permissions were granted, whether AI Tools is active (trialing, paying, or the free plan with limited results), configured per-minute, hourly and daily Instant Measure limits (not remaining usage), Human-Certified Measure Report pricing, and dashboard links for upgrading or managing assistants. Call this first when you need to know what the user can do or what an action will cost.
No parameters.
resolve_address — Resolve an address
Scope: crm:read. Makes changes.
Turn a typed US address into a verified address with coordinates and a Google place id. Use this before measure_roof or order_human_certified_report when you only have text, and show the user the resolved address if the input was ambiguous. Returns up to four alternative matches; pass one of their placeIds back to pick it instead. Only US addresses are supported: when the best worldwide match for the query is outside the US, the result carries a warning because the US match is probably a look-alike - show it to the user before using the address.
| Parameter | Type | Required | Description |
|---|---|---|---|
query | string | no | The address as the user typed it, e.g. "3334 Flickinger Rd, Westminster MD". |
placeId | string | no | A Google place id from a previous resolve_address result, to select a specific match. |
confirm_building_location — Confirm the building on a satellite map
Scope: measure:read. Makes changes. Can have irreversible effects.
Show which building an address resolves to before spending allowance or money on it. Google geocoding can resolve to the wrong building, so this creates a location confirmation and returns a satellite preview, a confidence assessment, and a confirmUrl where the user or a teammate can confirm or move the pin with no sign-in. Anyone with that link can view and confirm the location until it expires. Nothing is charged.
For measure_roof, have the user confirm the location on the map before passing its locationToken. For order_human_certified_report, the user may instead explicitly accept the preview and warning using acceptUnverifiedLocation: true. Pass notify only when the user requests delivery of the map link; it reaches the rep by push notification to the mobile app first, then text, then email. Users who let their assistant order Human-Certified reports without the map step get buildingConfirmationWaived: true instead and nobody is notified; order directly with the locationToken. Poll get_location_confirmation for the result.
| Parameter | Type | Required | Description |
|---|---|---|---|
address | string | no | Street address of the property (resolved with Google). |
latitude | number | no | Use with longitude when you already have a point on the roof. When no address is given, the street address for that point is looked up and used on the order. |
longitude | number | no | |
googlePlaceId | string | no | |
measurementId | string | no | Start from the building an existing Instant Measure used. |
customerJobId | string | no | Start from this customer job's address or confirmed building (from search_customers). |
leadId | string | no | Start from this lead's address or confirmed building (from search_leads). |
purpose | hcmr_order | measure | yes | What the confirmed location will be used for. Default: "hcmr_order". |
notify | object | no | Omit to show the map link in chat without contacting anyone. Supply a recipient only when the user explicitly requests or authorizes delivery of this map link to that person; an unattended automation or CRM call does not itself grant permission. A team member id is delivered as a push notification to their Instant Roofer mobile app when they are signed in on a device, otherwise as a text, otherwise as an email; a bare phone or email goes straight to that channel. The recipient can view and confirm the building without signing in. Skipped (buildingConfirmationWaived: true) when the user lets their assistant order Human-Certified reports without the map step. |
includePreviewImage | boolean | yes | Include the satellite preview image. Default: true. |
get_location_confirmation — Check a building confirmation
Scope: measure:read. Makes changes.
Check whether the user has confirmed (or declined) a building on the map for a locationToken from confirm_building_location or order_human_certified_report. Poll this after sending someone the confirmUrl or a notify push/text/email. Returns the confirmed coordinates and how far the pin moved from the geocode.
| Parameter | Type | Required | Description |
|---|---|---|---|
locationToken | string | yes | |
includePreviewImage | boolean | yes | Default: false. |
measure_roof — Run an AI Instant Measure (spends)
Scope: measure:run. Makes changes. Can have irreversible effects.
Measure a roof with Instant Roofer AI. Give an address (preferred) or latitude/longitude on the building. Returns square footage (aerial, measured, suggested with waste), squares, predominant pitch, complexity, facets, stories, confidence, and an outline image showing which building was measured.
Successful new measurements can deliver results to the company's configured webhooks. Attaching a result can replace a job's current measurement link.
This SPENDS the contractor's Instant Measure allowance. By default a successful measurement of the same property from the last 24 hours is returned instead of running again (reuseRecentWithinHours); only set it to 0 when the user explicitly wants a fresh run. Takes 10–90 seconds; progress notifications are sent while it runs.
The address is geocoded by Google, which occasionally picks the wrong building; the outline image identifies the measured building. Use render_instant_measure_images with the returned measurementId to display a gallery and provide image links; receiving image content alone does not confirm that the user can see it. If the user wants to pick the building first, call confirm_building_location and pass its locationToken here. Some users require that step: if the result is status "location_confirmation_required", have a person confirm the building (confirmUrl, or confirm_building_location with notify) and call again with the locationToken once it is confirmed.
| Parameter | Type | Required | Description |
|---|---|---|---|
address | string | no | Street address of the property. Resolved with Google before measuring. |
latitude | number | no | Use with longitude instead of address when you already have coordinates on the roof. |
longitude | number | no | |
googlePlaceId | string | no | Google place id from resolve_address, if you have one. |
locationToken | string | no | Token from confirm_building_location; measures the building the user confirmed (or previewed) there. |
customerJobId | string | no | Attach the finished measurement to this customer job (from search_customers). |
reuseRecentWithinHours | number | yes | Return an existing successful measurement of this property from within this many hours instead of measuring again. 0 forces a new measurement. Default: 24. |
includeOutlineImage | boolean | yes | Include the satellite image with the measured building outlined. Default: true. |
find_measurements — Find Instant Measures
Scope: measure:read. Makes changes.
Search the company's saved AI Instant Measures by address text, most recent first. Use it to check whether a property was already measured before spending allowance with measure_roof, or to find a measurement id for get_measurement / get_instant_measure_report_pdf. Include each returned confidence.display band beside its roof area or squares, including in lists; null means confidence was not provided. Do not infer confidence from the roof outline.
| Parameter | Type | Required | Description |
|---|---|---|---|
searchText | string | no | Address fragment, e.g. street name or ZIP. |
mineOnly | boolean | yes | Only measurements this team member requested. Default: false. |
limit | integer | yes | Default: 20. |
get_measurement — Get an Instant Measure result
Scope: measure:read. Makes changes.
Fetch a saved AI Instant Measure by id, including measurements, confidence, and (optionally) image content for analysis. Stored price estimates are omitted unless includeEstimates is requested for a cost-estimation task. To display roof outlines and facet diagrams to the user, call render_instant_measure_images with this measurementId. Results are redacted for accounts without an active AI Tools subscription.
| Parameter | Type | Required | Description |
|---|---|---|---|
measurementId | string | yes | |
includeImages | boolean | yes | Include the outline image and facet diagrams as images. Default: false. |
includeEstimates | boolean | yes | Include stored project price estimates, including any saved solar cost assumptions, only when the user asks about estimated costs. Leave false for roof measurements and images. Default: false. |
get_instant_measure_report_pdf — Get the Instant Measure Report PDF
Scope: measure:read. Makes changes. Can have irreversible effects.
Render (or re-render) the branded Instant Measure Report PDF for a saved measurement and return a download link valid for up to 15 minutes. Rendering replaces the stored PDF. Anyone holding the link can download it during that time. Freemium accounts get a redacted report.
| Parameter | Type | Required | Description |
|---|---|---|---|
measurementId | string | yes |
render_instant_measure_images — Show Instant Measure images
Scope: measure:read. Makes changes.
Use this when the user wants to see, display or compare saved Instant Measure satellite roof outlines and 2D/3D facet diagrams. Find measurement IDs with find_measurements first, or use IDs already returned by measure_roof/get_measurement. Opens an image gallery in supported clients and returns labelled image links as a fallback. This does not run a roof measurement, consume measurement allowance or order a report. Only images available under the connected account permissions are included. Creates temporary image copies and shareable links valid for 15 minutes; anyone holding a link can view that image until expiry. Receiving this result does not confirm that the user can see the gallery: if it is absent, provide the returned links. Never claim images are shown above solely because another tool returned image data.
| Parameter | Type | Required | Description |
|---|---|---|---|
measurementIds | array | yes | One to four saved Instant Measure IDs to show together; duplicate IDs are shown once. |
attach_measurement_to_job — Attach an Instant Measure to a customer job
Scope: measure:run. Makes changes. Can have irreversible effects.
Link a saved AI Instant Measure to a customer job so it shows up in that customer's workspace and can seed quotes. A job has one current measurement: attaching replaces it (the previous one is kept as history and reported as replacedMeasurementId). Pass customerJobId: null to detach the measurement from whichever job holds it; the job then falls back to its most recent earlier measurement, if any (restoredMeasurements).
| Parameter | Type | Required | Description |
|---|---|---|---|
measurementId | string | yes | |
customerJobId | any | yes | Customer job id from search_customers (primaryJob.id), or null to detach from its current job. |
order_human_certified_report — Order a Human-Certified Measure Report (spends)
Scope: hcmr:order. Makes changes. Can have irreversible effects.
Order a roof measurement report drawn and verified by a human. THIS COSTS MONEY: it uses one of the company's free report credits if any remain, otherwise it authorizes a hold on the card on file (typically $10), captured when the report completes. Reports take hours to complete; use get_human_certified_report to check status afterwards.
Two-step flow. 1) Call without confirm: the tool returns the price, a satellite preview of the building the address resolves to, a geocoding warning, and a locationToken. Show the user the price and the preview. Confirming the map does not approve payment. 2) Call again with confirm: true and that locationToken, plus acceptUnverifiedLocation: true if the user is happy with the pin as shown; or, if the user wants to check or move the pin, show confirmUrl in chat first (or, only when the user requests delivery to that rep, call confirm_building_location with notify) and pass the token once get_location_confirmation says "confirmed". If the company already has a report for this property, the tool reports the duplicate instead of ordering; pass confirmedDuplicateOrder: true only when the user explicitly wants a second report.
| Parameter | Type | Required | Description |
|---|---|---|---|
address | string | no | Street address of the property (resolved with Google). |
latitude | number | no | Use with longitude when you already have a point on the roof. When no address is given, the street address for that point is looked up and used on the order. |
longitude | number | no | |
googlePlaceId | string | no | |
measurementId | string | no | Start from the building an existing Instant Measure used. |
customerJobId | string | no | Start from this customer job's address or confirmed building (from search_customers). |
leadId | string | no | Start from this lead's address or confirmed building (from search_leads). |
locationToken | string | no | Token from the first call or from confirm_building_location. Carries the address and the (possibly user-corrected) pin. |
acceptUnverifiedLocation | boolean | yes | Order with the pin as previewed, without a map confirmation. Only after the user has seen the preview and the geocoding warning. Default: false. |
customerName | string | no | Homeowner name shown to the drawing team. |
confirm | boolean | yes | Set true only after the user agreed to use a credit or authorize the payment. Default: false. |
confirmedDuplicateOrder | boolean | yes | Order even though a report for this property already exists. Default: false. |
includePreviewImage | boolean | yes | Include the satellite preview image in confirmation responses. Default: true. |
get_human_certified_report — Get a Human-Certified Measure Report
Scope: hcmr:read. Makes changes.
Fetch the status and results of a Human-Certified Measure Report by id. When complete, includes the download URLs (PDF, CSV, HTML, XML) and the parsed measurements: squares, roof area, flat roof area (1/12 and flatter, excluded from the squares), drip edge, and ridge, hip, valley, rake, eave, sidewall and headwall lengths in feet, plus each facet's area, pitch and slope direction. Read measurementsNote before quoting the numbers. Do not poll more often than every few minutes while pending.
| Parameter | Type | Required | Description |
|---|---|---|---|
reportId | string | yes |
list_human_certified_reports — List Human-Certified Measure Reports
Scope: hcmr:read. Makes changes.
List the company's Human-Certified Measure Report orders, most recent first, optionally filtered by status or address text. Use get_human_certified_report for the selected report's measurements and download links.
| Parameter | Type | Required | Description |
|---|---|---|---|
status | all | pending | completed | failed | yes | Default: "all". |
searchText | string | no | Address or customer name fragment. |
mineOnly | boolean | yes | Only reports this team member ordered. Default: false. |
limit | integer | yes | Default: 20. |
attach_human_report_to_job — Attach a Human-Certified report to a customer job
Scope: hcmr:order. Makes changes. Can have irreversible effects.
Attach a Human-Certified Measure Report to a customer job, replacing its previous report link and updating the job status and stage. Copies available report files to shareable company-storage URLs and can refresh the stored HTML report on repeat calls. Anyone holding a public report URL can access that file. The previous report record is retained.
| Parameter | Type | Required | Description |
|---|---|---|---|
reportId | string | yes | |
customerJobId | string | yes | Customer job id from search_customers (primaryJob.id). |
list_quotes — List quotes
Scope: quotes:read. Makes changes.
List quotes this team member created or is assigned to, with status, totals, timestamps, and the customer or lead they belong to, most recently updated first. Company administrators can see all company quotes. Filter by status, customer, lead, or free text. Each row is one option; options of the same good/better/best group share a quoteGroupId and show their customer-facing displayRef (0042-01, 0042-02, ...). The status filter matches the quote's current status only: a quote that was accepted and later voided is "voided" (its acceptedAt timestamp is kept for history).
| Parameter | Type | Required | Description |
|---|---|---|---|
status | all | draft | sent | viewed | accepted | declined | expired | converted | voided | yes | Default: "all". |
customerId | string | no | |
leadId | string | no | |
searchText | string | no | Customer name, address, or quote title fragment. |
limit | integer | yes | Default: 25. |
get_quote — Get a quote
Scope: quotes:read. Makes changes.
Fetch one visible quote option in full: line items (with lineItemId for edits), totals, applied tax rate ids, financing plan, status timestamps, the customer message, internal notes, and its sibling options in the same group. Each line item reports the base unitPriceUsd, markupPct, the customer-facing effectiveUnitPriceUsd, and lineSubtotalUsd (quantity x unitPriceUsd x (1 + markupPct / 100)); lines with includedInQuote=false are hidden from the customer but still count toward totals. Use edit_quote_line_items and update_quote to change it, get_quote_layout for its pages and photos, preview_quote_pdf to see it, and get_quote_public_link for the customer-facing link and PDF.
| Parameter | Type | Required | Description |
|---|---|---|---|
quoteId | string | yes |
get_quote_public_link — Get a quote's customer link and PDF
Scope: quotes:read. Makes changes. Can have irreversible effects.
Use when the connected roofing contractor requests a customer-facing link or PDF for an existing quote. Creates or refreshes shareable access to that quote and renders its PDF on demand; this can replace the stored PDF. Anyone holding the customer link can open the quote until expiresAt. The contractor can share the returned link with the homeowner, who can separately review and sign the quote and, when online payments are enabled, choose to pay through the contractor's external checkout. This tool does not create a quote, change its commercial terms, send a message, accept the quote, start checkout, collect payment credentials, or charge anyone. Only visible quotes may be shared; grouped quotes require access to every option. Voided quotes have no customer link.
| Parameter | Type | Required | Description |
|---|---|---|---|
quoteId | string | yes |
create_quote — Create a quote
Scope: quotes:write. Makes changes.
Create a new quote for a customer or lead as a group of options (Good / Better / Best by default, from the company's default option names; pass one name for a single option). Each option starts with the company's "always added" catalog items, default tax rates, default financing plan and default template. Pass fromMeasurementId to seed every option with the roofing lines the dashboard import produces from that saved AI Instant Measure (price per square from the option's tier material, linear-foot components, low-slope roofing) using the company import settings; roofMaterialKeys picks the material per option. Returns every option in full with lineItemIds for edit_quote_line_items. Nothing is sent to the customer.
| Parameter | Type | Required | Description |
|---|---|---|---|
customerId | string | no | Customer id from search_customers. |
leadId | string | no | Lead id from search_leads. |
title | string | no | Quote title shown on the group, e.g. the job address or scope. |
optionNames | array | no | Option names in order; defaults to the company's default option names (usually Good, Better, Best). |
fromMeasurementId | string | no | Saved AI Instant Measure id to seed roofing line items from. |
roofMaterialKeys | array | no | Catalog keys (get_product_catalog) of the roofing material for each option, in option order; omitted entries use the company's tier default. |
update_quote — Update a quote option
Scope: quotes:write. Makes changes.
Change one quote option's title, dates, option name, enabled state, customer message, internal notes, applied tax rates, financing plan, template or assignment. Only the fields passed change; line items are kept as they are (use edit_quote_line_items for those). Refused once any option in the group has been accepted by the customer. Returns the option in full with recomputed totals.
| Parameter | Type | Required | Description |
|---|---|---|---|
quoteId | string | yes | |
title | string | no | |
issueDate | string | no | |
expirationDate | string | no | When the customer link stops working; defaults to the company quote lifetime. |
optionName | string | no | |
isOptionEnabled | boolean | no | Disabled options stay in the group but are not offered to the customer. |
messageToCustomer | string | no | Shown on the customer page; empty string clears it. |
internalNotes | string | no | Team-only notes; empty string clears them. |
appliedTaxRateIds | array | no | Tax rate ids from get_quote_settings; replaces the current set. |
financingPlanId | any | no | Financing plan id from get_quote_settings; null removes financing. |
quoteTemplateId | string | no | Quote template id from list_quote_templates. |
assignedToUserId | any | no | Team member to assign (admins only); null unassigns. |
edit_quote_line_items — Edit quote line items
Scope: quotes:write. Makes changes.
Add, change, remove and reorder the line items of one quote option in a single save. Prices are dollars; markupPct is a percentage; lineSubtotal = quantity x unitPrice x (1 + markupPct / 100). New lines may copy a catalog item (catalogItemId) and override any of its fields. Discount lines use sku DISCOUNT with a negative unitPriceUsd and are not taxable. Returns the option in full with recomputed totals; report those totals rather than computing your own. Refused once any option in the group has been accepted.
| Parameter | Type | Required | Description |
|---|---|---|---|
quoteId | string | yes | |
add | array | no | |
update | array | no | |
remove | array | no | lineItemIds to delete. |
reorder | array | no | Every remaining lineItemId in the desired order (new lines are identified by their position in add[] appended at the end unless they carry position). |
add_quote_option — Add an option to a quote
Scope: quotes:write. Makes changes.
Add another option (e.g. a fourth tier or an alternative material) to an existing quote group. Start it blank with the company defaults, copy the lines of another option in the group (copyFromQuoteId), or apply a saved option template (optionTemplateId from list_quote_options_templates). The new option inherits the group's customer or lead and template. Refused once any option in the group has been accepted.
| Parameter | Type | Required | Description |
|---|---|---|---|
quoteId | string | yes | Any option in the target group. |
optionName | string | no | |
copyFromQuoteId | string | no | Copy line items, taxes, financing and discount from this option in the same group. |
optionTemplateId | string | no | Apply a saved option template instead. |
copy_quote — Copy a quote
Scope: quotes:write. Makes changes.
Duplicate a quote group (every enabled option with its lines, taxes, financing, notes and page photos) as new drafts for a customer or lead, with fresh quote numbers and the company's default expiration. Use it to reuse a past quote for a similar job. Nothing is sent.
| Parameter | Type | Required | Description |
|---|---|---|---|
quoteId | string | yes | Any option of the group to copy. |
customerId | string | no | Customer id from search_customers. |
leadId | string | no | Lead id from search_leads. |
title | string | no |
set_quote_status — Change a quote's status
Scope: quotes:write. Makes changes. Can have irreversible effects.
Mark one quote option accepted (signed in person; only from sent or viewed), declined, expired or voided. Accepting locks every option in the group against edits; voiding the accepted option unlocks it. accepted and voided are two-step: call without confirm to see what will change, then with confirm: true. Voiding does not cancel payment links or refund anything. converted cannot be set here.
| Parameter | Type | Required | Description |
|---|---|---|---|
quoteId | string | yes | |
status | accepted | declined | expired | voided | yes | |
note | string | no | Recorded in the quote's activity log. |
confirm | boolean | yes | Required for accepted and voided; set true only after the user agreed. Default: false. |
attach_quote_to_record — Attach a quote to a customer or lead
Scope: quotes:write. Makes changes.
Point a quote (and every option in its group) at a customer or lead, or detach it (kind none). The record supplies the name, address and email used on the customer page and in the quote email. Refused once any option in the group has been accepted.
| Parameter | Type | Required | Description |
|---|---|---|---|
quoteId | string | yes | |
kind | customer | lead | none | yes | |
targetId | string | no | Customer or lead id; omit for kind none. |
delete_quote — Delete a quote option
Scope: quotes:write. Makes changes. Can have irreversible effects.
Permanently delete one quote option that was created by mistake. Two-step: call without confirm to see what would be deleted, then with confirm: true. Refused for accepted quotes, locked groups and quotes with payment activity (void those instead). Deleting the last option removes the group.
| Parameter | Type | Required | Description |
|---|---|---|---|
quoteId | string | yes | |
confirm | boolean | yes | Set true only after the user confirmed the deletion. Default: false. |
get_quote_layout — Get a quote's pages, photos and text
Scope: quotes:read. Makes changes.
Describe how one quote will be presented: the assigned template's pages (with visibility and which option each pricing page shows), every photo box (nodeId, label, capacity, current photos, and which box is the featured full-width one), every editable text or rich-text element with the template text and any per-quote override, and attached pages. Use the nodeIds and pageIds with edit_quote_layout. Photos, text and page settings are shared by all options in the group.
| Parameter | Type | Required | Description |
|---|---|---|---|
quoteId | string | yes |
edit_quote_layout — Edit a quote's photos, text and pages
Scope: quotes:write. Makes changes.
Change what the quote pages show, for every option in the group at once: place Project Media photos into a photo box (setPhotos, by mediaAssetId from list_project_media; photos must belong to the quote's customer or lead or the company library), clear a box, override editable template text (setText) or a rich-text block (setRichText, HTML or plain paragraphs), and show or hide template or attached pages (setPageVisibility). Get the nodeIds and pageIds from get_quote_layout. Refused once any option in the group has been accepted. Call preview_quote_pdf afterwards to see the result; the stored PDF is re-rendered on the next preview, link or send.
| Parameter | Type | Required | Description |
|---|---|---|---|
quoteId | string | yes | |
setPhotos | array | no | |
clearPhotos | array | no | Photo box nodeIds to empty. |
setText | array | no | |
setRichText | array | no | |
setPageVisibility | array | no |
preview_quote_pdf — Preview a quote PDF
Scope: quotes:read. Makes changes.
Render the quote exactly as the customer PDF (every offered option, photos, text and page settings) and return the PDF link plus an image of each page, shown in a page viewer in supported clients. Rendering takes a few seconds and is skipped when nothing changed since the last preview; pass force: true to re-render anyway. Pages imported from other PDFs appear in the PDF but have no page image. This does not create or refresh the customer link and sends nothing.
| Parameter | Type | Required | Description |
|---|---|---|---|
quoteId | string | yes | |
force | boolean | yes | Re-render even if the stored preview is current. Default: false. |
list_quote_templates — List quote templates
Scope: quotes:read. Makes changes.
List the quote templates this company can use: its own templates and the published platform (global) templates, with page counts and which one is the company default. Use get_quote_template to see a template's pages and elements, copy_quote_template to make an editable company copy of a global one, and update_quote (quoteTemplateId) or set_default_quote_template to use one.
No parameters.
get_quote_template — Get a quote template
Scope: quotes:read. Makes changes.
Describe a quote template page by page: every element with its nodeId and type (text with its current text and merge-field binding, rich-text blocks, images, photo boxes with capacity and layout, shapes), which pages are pricing pages, and how many company quotes currently render through it. Use the nodeIds with edit_quote_template_content. Element positions and styling are not included; those are edited in the dashboard designer.
| Parameter | Type | Required | Description |
|---|---|---|---|
templateId | string | yes |
copy_quote_template — Copy a quote template
Scope: quotes:settings. Makes changes.
Make an editable company copy of a quote template (typically a platform template). Page and element ids are preserved so quotes switched to the copy keep their photos and text overrides. Company administrators only. Nothing else changes until the copy is assigned to quotes or made the default.
| Parameter | Type | Required | Description |
|---|---|---|---|
templateId | string | yes | |
name | string | no | Name for the copy; defaults to "<source name> (copy)". |
edit_quote_template_content — Edit a quote template's content
Scope: quotes:settings. Makes changes.
Change the content of a company quote template without moving or restyling anything: set the text of text elements (setText; merge-field elements cannot be set), the HTML or plain paragraphs of rich-text blocks (setRichText), the picture of image elements (setImage from a Project Media mediaAssetId or an Instant Roofer-hosted image URL), photo-box settings (setPhotoBox: label, maxImages 1-12, layoutMode, autoFillKeywords), and page names (renamePage). Company administrators only. The change applies to every quote using the template the next time its PDF renders, so check quotesUsingTemplate in the result. Platform templates must be copied first (copy_quote_template).
| Parameter | Type | Required | Description |
|---|---|---|---|
templateId | string | yes | |
setText | array | no | |
setRichText | array | no | |
setImage | array | no | |
setPhotoBox | array | no | |
renamePage | array | no |
set_default_quote_template — Set the default quote template
Scope: quotes:settings. Makes changes.
Make a template the one new quotes use (existing quotes keep their assigned template). Company administrators only.
| Parameter | Type | Required | Description |
|---|---|---|---|
templateId | string | yes |
send_quote — Send a quote to the customer
Scope: quotes:send. Makes changes. Can have irreversible effects.
Email the customer or lead on the quote a link to review, sign and, when online payments are enabled, pay for the quoted work. One email with the link is sent (no PDF attachment, no text message); every offered option in the group is included. Two steps: call without confirm to validate the quote and see the recipients (to defaults to the record's email), subject, expiry and whether this is a revision; show them to the user; then call again with confirm: true and the same recipients only after they explicitly agree. Marks the quote sent. Refused for accepted, declined, expired, converted or voided quotes, for locked groups, and until a template, an attached record and at least one priced option exist.
| Parameter | Type | Required | Description |
|---|---|---|---|
quoteId | string | yes | |
to | string | no | Recipient email(s); defaults to the customer or lead on the quote. |
cc | string | no | One or more email addresses separated by commas or spaces. |
bcc | string | no | One or more email addresses separated by commas or spaces. |
note | string | no | Personal note included in the email. |
confirm | boolean | yes | Set true only after the user approved sending to the recipients shown. Default: false. |
get_quote_settings — Get quote settings
Scope: quotes:read. Makes changes.
The quote settings this team member quotes with: company defaults (markup, option names, quote lifetime, default template, default tax rates and financing plan, payment terms), the catalog items available for line items, tax rates and financing plans (company-wide plus this member's personal rows; personal rows override company rows with the same name or item id). Use the ids with edit_quote_line_items, update_quote and the upsert/archive tools.
| Parameter | Type | Required | Description |
|---|---|---|---|
includeArchived | boolean | yes | Also list archived catalog items, tax rates and financing plans. Default: false. |
upsert_quote_catalog_item — Create or update a quote catalog item
Scope: quotes:settings. Makes changes.
Create a quote catalog item (omit catalogItemId) or change one (pass catalogItemId; only the fields passed change). Catalog items are the reusable line items with default price, markup, unit and taxability; alwaysAdded items are seeded onto every new quote. Company-wide items need the Admin privilege; other team members get personal items. Changing an item does not alter existing quotes.
| Parameter | Type | Required | Description |
|---|---|---|---|
catalogItemId | string | no | |
scope | contractor | user | no | contractor = company-wide (Admin privilege required); user = this team member's personal row. Defaults to contractor for admins, user otherwise. |
sku | string | no | Item id/code shown on quotes; unique among active items of the same scope. |
description | string | no | |
defaultQuantity | number | no | |
unit | SQ | LF | EA | BX | HR | no | |
defaultUnitPriceUsd | number | no | |
defaultMarkupPct | number | no | |
taxable | boolean | no | |
alwaysAdded | boolean | no | Seed this item onto every new quote (the dashboard's "Always" switch). |
category | string | no |
archive_quote_catalog_item — Archive or restore a quote catalog item
Scope: quotes:settings. Makes changes.
Archive a catalog item so it stops being offered for new lines (restore: true brings it back). Archiving never deletes it or changes existing quotes. Company-wide items need the Admin privilege.
| Parameter | Type | Required | Description |
|---|---|---|---|
catalogItemId | string | yes | |
restore | boolean | yes | Default: false. |
upsert_quote_tax_rate — Create or update a tax rate
Scope: quotes:settings. Makes changes.
Create a tax rate (omit taxRateId) or change one (pass taxRateId; only the fields passed change). Default rates are preselected on new quotes, and company default rates are also charged at Orders Online and Online Scheduler checkout, so creating or changing a company default rate is two-step: call without confirm to see the warning, then with confirm: true. Company-wide rates need the Admin privilege. Existing quotes keep their rate until they are saved again.
| Parameter | Type | Required | Description |
|---|---|---|---|
taxRateId | string | no | |
scope | contractor | user | no | contractor = company-wide (Admin privilege required); user = this team member's personal row. Defaults to contractor for admins, user otherwise. |
name | string | no | |
ratePct | number | no | Percentage, e.g. 8.6. |
isDefault | boolean | no | |
confirm | boolean | yes | Default: false. |
archive_quote_tax_rate — Archive or restore a tax rate
Scope: quotes:settings. Makes changes. Can have irreversible effects.
Archive a tax rate so new quotes stop offering it (restore: true brings it back). Archiving a company default rate also removes it from Orders Online and Online Scheduler checkout, so that is two-step with confirm. Quotes already using the rate drop it the next time they are saved. Company-wide rates need the Admin privilege.
| Parameter | Type | Required | Description |
|---|---|---|---|
taxRateId | string | yes | |
restore | boolean | yes | Default: false. |
confirm | boolean | yes | Default: false. |
upsert_quote_financing_plan — Create or update a financing plan
Scope: quotes:settings. Makes changes.
Create a financing plan (omit financingPlanId) or change one (pass financingPlanId; only the fields passed change). A plan is an APR, a term in months, optional promotional (deferred-interest) months and a dealer fee; the default plan is applied to new quotes and shown as a monthly payment on the customer page. Company-wide plans need the Admin privilege. Existing quotes keep their snapshot until saved again.
| Parameter | Type | Required | Description |
|---|---|---|---|
financingPlanId | string | no | |
scope | contractor | user | no | contractor = company-wide (Admin privilege required); user = this team member's personal row. Defaults to contractor for admins, user otherwise. |
name | string | no | |
aprPct | number | no | |
termMonths | integer | no | |
promotionalMonths | integer | no | |
dealerFeePct | number | no | |
isDefault | boolean | no |
archive_quote_financing_plan — Archive or restore a financing plan
Scope: quotes:settings. Makes changes.
Archive a financing plan so new quotes stop offering it (restore: true brings it back). Quotes using it drop the financing the next time they are saved. Company-wide plans need the Admin privilege.
| Parameter | Type | Required | Description |
|---|---|---|---|
financingPlanId | string | yes | |
restore | boolean | yes | Default: false. |
update_quote_company_settings — Update company quote defaults
Scope: quotes:settings. Makes changes.
Change the company-wide quote defaults: default markup percentage, default option names (e.g. Good, Better, Best), how many days quotes stay valid (1-180), the default template, and the default payment terms (full payment, deposit, or a custom schedule) that new quotes start with. Only the fields passed change. Company administrators only. Accepted payment methods and measurement import settings are managed in the dashboard.
| Parameter | Type | Required | Description |
|---|---|---|---|
defaultMarkupPct | number | no | |
defaultOptionNames | array | no | |
defaultQuoteLifetimeDays | integer | no | |
defaultQuoteTemplateId | any | no | null clears the company default so the platform default applies. |
defaultPaymentRequirement | any | no | null clears it so new quotes require full payment. |
list_quote_option_templates — List saved quote option templates
Scope: quotes:read. Makes changes.
List the company's saved option templates: reusable sets of line items, taxes, financing and discount that add_quote_option can apply as a new option. Save one from an existing option with save_quote_option_template.
No parameters.
save_quote_option_template — Save a quote option as a template
Scope: quotes:settings. Makes changes.
Save one quote option's line items, applied tax rates, financing plan and discount as a company-wide option template that add_quote_option can apply to future quotes. The source quote is not changed.
| Parameter | Type | Required | Description |
|---|---|---|---|
quoteId | string | yes | The option to snapshot. |
name | string | yes | |
description | string | no |
get_product_catalog — Get products and services pricing
Scope: products:manage. Makes changes.
List the company's homeowner-facing product catalog: roofing materials, solar, permanent lighting, gutters, batteries, services and subscriptions, with prices in natural units (per square, per watt, per linear foot, each; gutters priced from the roof take-off also list their prices per downspout, elbow, end cap and miter), descriptions, selling points, photos, and which channels offer each product (Website Calculator, Orders Online, quotes with their tier, lead distribution). Standard materials the company has not priced are listed with isOffered: false. Use the product key with update_product, add_product and remove_product, and with create_quote roofMaterialKeys.
| Parameter | Type | Required | Description |
|---|---|---|---|
includeUnoffered | boolean | yes | Also list standard materials the company has not added. Default: false. |
update_product — Update a product or service
Scope: products:manage. Makes changes.
Change one product in the homeowner-facing catalog: prices (per square, per watt, per linear foot, each; for gutters priced from the roof take-off, also the prices per downspout, per foot of downspout, per elbow, per end cap and per inside and outside miter), description, selling points, photo, unit or billing period (custom products only), the quote tier, and whether it is offered in the Website Calculator, Orders Online or quote imports. Only the price fields of the product's own kind are read. Two-step: call without confirm to get the before/after diff, the calculator lists that would change and warnings; then call again with confirm: true. Changes are live to homeowners as soon as they are saved. Company Admin privilege required. Lead distribution, financing terms and Orders Online payment collection are not editable here.
| Parameter | Type | Required | Description |
|---|---|---|---|
key | string | yes | Product key from get_product_catalog. |
label | string | no | Display name (custom products only). |
description | string | no | Customer-facing description (custom products only). |
features | array | no | Up to three short selling points (custom products only). |
mediaAssetId | string | no | Project Media photo to use as the product photo (custom products only). |
imageUrl | string | no | An image URL already hosted by Instant Roofer (custom products only). |
pricing | object | no | |
availableInQuoting | boolean | no | Offer this roofing material when quotes import a measurement. |
quoteTier | any | no | The quote option this material is the default for; null clears it. |
promotedInHouse | boolean | no | Offer it in the Website Calculator (measured products only). |
orderableOnline | boolean | no | Sell it through Orders Online. |
unit | SQ | LF | EA | BX | HR | no | Fixed-price products only. |
billingPeriod | monthly | quarterly | yearly | no | Subscriptions only. |
calculatorSortOrder | any | no | |
onlineSortOrder | any | no | |
confirm | boolean | yes | Set true only after the user reviewed the diff and warnings from the first call and agreed. Default: false. |
add_product — Add a product or service
Scope: products:manage. Makes changes.
Add a custom product to the homeowner-facing catalog: a measured product priced from the roof measurement (category material priced per square, solarPanels per watt, permanentLighting per linear foot of roofline, or gutters priced from the roof's gutter take-off: pricePerLinearFootUsd per foot of gutter plus optional prices per downspout, per foot of downspout, per elbow, per end cap and per miter), a fixed-price product or service (gutters sold each or by the box, battery, service or other, priced each with a unit), or a subscription (priced per billing period). Gutters priced by the linear foot belong to pricingModel measured: only those are priced from the take-off and can be offered in the Website Calculator. Optionally offer the product in the Website Calculator, Orders Online or quote imports right away. Two-step with confirm; the product is visible to homeowners on the selected channels as soon as it is saved. Company Admin privilege required. To price a standard material the company has not added yet, use update_product with its key instead.
| Parameter | Type | Required | Description |
|---|---|---|---|
pricingModel | measured | fixed | recurring | yes | |
category | material | solarPanels | permanentLighting | gutters | battery | service | other | yes | |
label | string | yes | |
description | string | no | Customer-facing description (custom products only). |
features | array | no | Up to three short selling points (custom products only). |
mediaAssetId | string | no | Project Media photo to use as the product photo (custom products only). |
imageUrl | string | no | An image URL already hosted by Instant Roofer (custom products only). |
pricing | object | yes | |
availableInQuoting | boolean | no | Offer this roofing material when quotes import a measurement. |
quoteTier | any | no | The quote option this material is the default for; null clears it. |
promotedInHouse | boolean | no | Offer it in the Website Calculator (measured products only). |
orderableOnline | boolean | no | Sell it through Orders Online. |
unit | SQ | LF | EA | BX | HR | no | Fixed-price products; defaults by category (gutters LF, otherwise EA). Fixed-price gutters sold by the LF are sized from the eave length at one price; to price downspouts and fittings too, add the gutters as pricingModel measured instead. |
billingPeriod | monthly | quarterly | yearly | no | Subscriptions; defaults to monthly. |
confirm | boolean | yes | Set true only after the user reviewed the diff and warnings from the first call and agreed. Default: false. |
remove_product — Remove a product or service
Scope: products:manage. Makes changes. Can have irreversible effects.
Take a product off every channel: a custom product is deleted from the catalog; a standard material is reset to "not added" (its platform definition stays available). Two-step with confirm. Removing a subscription product does not cancel subscriptions homeowners already started, and quotes that already reference the product keep their line items. Company Admin privilege required.
| Parameter | Type | Required | Description |
|---|---|---|---|
key | string | yes | |
confirm | boolean | yes | Set true only after the user reviewed the diff and warnings from the first call and agreed. Default: false. |
list_project_media — List project media
Scope: media:read. Makes changes.
Browse photos and documents in Project Media. With entityType + entityId, lists the media attached to that lead, customer, or the contractor library (returned as a flat list). Without an entity, returns the company-wide feed of recent media the team member may see. Use searchText and tags to narrow; results include thumbnail and preview URLs. To show the photos to the user, pass the selected items to render_project_media. Use get_media_asset for a selected file's AI analysis and original download link.
| Parameter | Type | Required | Description |
|---|---|---|---|
entityType | lead | customer | contractor | no | |
entityId | string | no | Lead id, customer id, or the contractor id for the company library. |
searchText | string | no | Words to find in the filename, AI caption and summary, tags, document text, or the capture address. Every word must match, so prefer a few distinctive tokens ("789 Palm") over a full string with abbreviations that may differ ("Palm Lane" will not match "Palm Ln"). |
tags | array | no | |
folderId | string | no | Only media in this folder (entity listings only). |
cursor | string | no | Opaque nextCursor from a previous page. Pass it back unchanged. |
limit | integer | yes | Default: 30. |
list_media_folders — List project media folders
Scope: media:read. Makes changes.
List the folders that organise a lead's, customer's, or the company library's project media.
| Parameter | Type | Required | Description |
|---|---|---|---|
entityType | lead | customer | contractor | yes | |
entityId | string | yes |
get_media_asset — Get a project media asset
Scope: media:read. Makes changes.
Fetch one photo or document with its AI caption, detailed summary, tags, scene and photo type, quality flags, contractor note text, and file URLs. Device and EXIF details are not returned. Capture coordinates are omitted unless includeLocationMetadata is explicitly requested for a task that needs them. aiAnalysis.status is one of: ready (the AI fields above are present), skipped (this asset type is never analysed, e.g. field-pitch captures; read pitchCapture instead), pending, failed, or unavailable; aiAnalysis.note explains every non-ready state. Image previews are independent of AI status. Set includeImage to receive the preview for your own analysis; this does not confirm a visible user attachment, and most clients do not display it. To show the photo to the user, call render_project_media with this asset. If that gallery is unavailable, provide the labelled previewUrl or originalUrl actually returned for this asset. Never substitute web, stock, or another project image, or invent a URL.
| Parameter | Type | Required | Description |
|---|---|---|---|
entityType | lead | customer | contractor | yes | |
entityId | string | yes | |
mediaAssetId | string | yes | |
includeImage | boolean | yes | Return the preview image as image content for your analysis (photos only, up to ~1.5 MB). Not a user-visible display; use render_project_media for that. Default: false. |
includeLocationMetadata | boolean | yes | Include stored photo and field-pitch capture coordinates only when the user asks where the capture was made or needs them for a location task. Leave false for viewing, analysis, notes and pitch summaries. Default: false. |
render_project_media — Show project media
Scope: media:read. Makes changes.
Use this when the user wants to see project photos or documents. Pass the entityType, entityId and mediaAssetId of each item (from list_project_media or get_media_asset); up to 12 are shown together. Opens a thumbnail gallery with enlarge and preview links in supported clients, and returns the same thumbnail and preview URLs in the result as a fallback for clients without a gallery. Only media the connected team member may view is included; the gallery never carries full-resolution originals, which remain available per asset through get_media_asset. This does not run AI analysis, upload, move or delete anything. Receiving this result does not confirm that the user can see the gallery: if it is absent, provide the returned previewUrl links. Never claim images are shown merely because get_media_asset includeImage returned image data.
| Parameter | Type | Required | Description |
|---|---|---|---|
assets | array | yes | One to twelve media items to show together; duplicates are shown once. Items may come from different leads or customers. |
title | string | no | Optional gallery heading, such as the job address or folder name the photos belong to. |
search_customers — Search customers
Scope: crm:read. Makes changes.
Find customers in the company CRM by name, phone, email, or address. Returns each customer's id and their primary job (customerJobId, address, stage, measurement/report status) so measurements, reports, quotes, and media can be attached to the right job. Phone and email are omitted unless includeContactDetails is explicitly requested for a task that needs them.
| Parameter | Type | Required | Description |
|---|---|---|---|
searchText | string | no | Name, phone, email, or address fragment. Omit to list recent customers. |
includeArchived | boolean | yes | Default: false. |
includeContactDetails | boolean | yes | Include phone and email only when the user asks for contact information or a task requires it. Leave false for ordinary record lookup; searching by phone or email does not require returning them. Default: false. |
limit | integer | yes | Default: 20. |
search_leads — Search leads
Scope: crm:read. Makes changes.
Find leads in the company CRM by name, phone, email, or address. Sales members only see leads assigned to them. Returns lead ids, property addresses, product/source, lifecycle status, and the assigned sales member. Phone and email are omitted unless includeContactDetails is explicitly requested for a task that needs them.
| Parameter | Type | Required | Description |
|---|---|---|---|
searchText | string | no | Name, phone, email, or address fragment. Omit to list recent leads. |
status | active | inactive | all | yes | Default: "active". |
includeContactDetails | boolean | yes | Include phone and email only when the user asks for contact information or a task requires it. Leave false for ordinary record lookup; searching by phone or email does not require returning them. Default: false. |
limit | integer | yes | Default: 20. |
list_webhooks — List CRM webhooks
Scope: webhooks:manage. Makes changes.
List the company's outbound webhooks that send new leads and Instant Measure results to a CRM or other system. Returns ids, destination origins (paths and parameters hidden), enabled states, events, header names, body mappings and configuration warnings. Authentication headers and all fixed custom values are hidden. Requires the company Admin privilege.
No parameters.
get_webhook — Get a CRM webhook
Scope: webhooks:manage. Makes changes.
Inspect one company webhook with configuration warnings and example request shapes for its events, using fake data. Authentication values, fixed custom values and destination paths/parameters are hidden. Optionally includes a redacted Markdown integration brief for building the receiving endpoint. Exact destination and existing credentials are available only in the authenticated dashboard.
| Parameter | Type | Required | Description |
|---|---|---|---|
webhookId | string | yes | Webhook id from list_webhooks or create_webhook. |
includeExampleRequests | boolean | yes | Default: true. |
includeIntegrationBrief | boolean | yes | Include the long Markdown brief (delivery rules, field reference, receiver checklist). Default: false. |
get_webhook_field_reference — Webhook field reference
Scope: webhooks:manage. Makes changes.
Every field a webhook body parameter can map, with type, description, and whether each selected event populates it always, sometimes (with the condition) or never. Call this before create_webhook or update_webhook to choose body-parameter mappings the destination CRM needs. Also lists the events and the special "custom" and "selected_preset_field_summary" fields.
| Parameter | Type | Required | Description |
|---|---|---|---|
productSourceCombos | array | no | Limit the reference to the fields at least one of these events can populate. Omit for every field and every event. |
create_webhook — Create a CRM webhook
Scope: webhooks:manage. Makes changes. Can have irreversible effects.
Create an outbound webhook that POSTs new leads and/or Instant Measure results to a public HTTPS destination without URL username/password. Defaults to disabled; active: true immediately enables future deliveries, including homeowner contact details for lead events. Test each event before enabling after user agreement. Authentication is necessary for the receiver to verify deliveries: use a freshly generated 32+ character webhook secret and have the owner store it securely at the destination; never request existing credentials in chat. Existing credentials can be configured in the authenticated dashboard. Map id for de-duplication and product for multiple events; use get_webhook_field_reference to select fields. Results hide authentication, fixed custom values and URL paths/parameters.
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | yes | Display name shown in the dashboard, e.g. "JobNimbus leads". |
uri | string | yes | Public HTTPS destination with no URL username/password. Prefer a newly generated authentication header over secrets in the URL. Results hide the path and parameters; omit uri on update to retain the stored destination. |
productSourceCombos | array | yes | Events that trigger this webhook. Instant Measure events carry no homeowner data, so prefer a separate webhook for estimate_manual. |
format | json | form | yes | "json" sends a JSON object with Content-Type application/json; "form" sends application/x-www-form-urlencoded (all values strings, no automatic Content-Type header). Default: "json". |
headers | array | yes | Custom request headers, typically one authentication header. Default: []. |
bodyParams | array | yes | Body keys and where each value comes from. Only mapped keys are sent; always include the id field and, with several events, the product field. Default: []. |
active | boolean | yes | Defaults to false. Inspect with test_webhook mode "preview"; a real test send and enabling automatic deliveries each require explicit user authorization. Default: false. |
update_webhook — Update a CRM webhook
Scope: webhooks:manage. Makes changes. Can have irreversible effects.
Change a company webhook's configuration or enabled state. Omitted fields retain their stored values; headers and bodyParams replace the whole list when supplied. Omit an existing header or custom parameter's value to retain it by key. Use newly generated webhook secrets for rotation; configure existing credentials securely in the dashboard, never request them in chat. URLs must use public HTTPS with no username/password; omit uri to keep the stored destination, since results hide its path/parameters. active: true starts real deliveries including homeowner contact details for lead events: obtain user agreement and test first. active: false alone can pause a legacy insecure destination without losing configuration.
| Parameter | Type | Required | Description |
|---|---|---|---|
webhookId | string | yes | Webhook id from list_webhooks or create_webhook. |
name | string | no | Display name shown in the dashboard, e.g. "JobNimbus leads". |
uri | string | no | Public HTTPS destination with no URL username/password. Prefer a newly generated authentication header over secrets in the URL. Results hide the path and parameters; omit uri on update to retain the stored destination. |
productSourceCombos | array | no | Events that trigger this webhook. Instant Measure events carry no homeowner data, so prefer a separate webhook for estimate_manual. |
format | json | form | no | "json" sends a JSON object with Content-Type application/json; "form" sends application/x-www-form-urlencoded (all values strings, no automatic Content-Type header). |
headers | array | no | Replaces the whole header list when given. Omit a header's value to keep its stored value. |
bodyParams | array | no | Replaces the whole body-parameter list when given. Omit a custom param's value to keep its stored value. |
active | boolean | no | true starts real deliveries to the URL. Confirm with the user and test first. |
delete_webhook — Delete a CRM webhook
Scope: webhooks:manage. Makes changes. Can have irreversible effects.
Permanently remove a webhook. Deliveries to its URL stop immediately and the configuration (including any secret header) cannot be recovered. Confirm with the user first; to pause instead, use update_webhook with active: false.
| Parameter | Type | Required | Description |
|---|---|---|---|
webhookId | string | yes | Webhook id from list_webhooks or create_webhook. |
test_webhook — Test a CRM webhook
Scope: webhooks:manage. Makes changes. Can have irreversible effects.
Preview one webhook request with fake event data without contacting the destination; this is the default. Use mode "send" only after the user explicitly authorizes a real test for this webhook and event. Sending performs one real POST using stored authentication and custom values and can trigger receiver workflows, even for a disabled webhook. A request to inspect configuration is not permission to send. Send mode requires public HTTPS without URL username/password and adds X-Instant-Roofer-Webhook-Test: true. Returns a redacted request shape and, for sends, status code, safe content-type/retry-after headers, timing and failure guidance; response bodies, reason phrases, credentials and URL paths/parameters are omitted. Sends are rate limited per company. Repeating a send can repeat receiver side effects; do not automatically retry.
| Parameter | Type | Required | Description |
|---|---|---|---|
webhookId | string | yes | Webhook id from list_webhooks or create_webhook. |
productSourceCombo | estimate_subscription | estimate_embed | estimate_manual | contact_embed | repair_embed | yes | Event to simulate; must be one of the webhook's selected events. |
mode | preview | send | yes | Defaults to "preview": build the request without contacting the destination. Set "send" only after the user explicitly authorizes one real POST for this webhook and event, including when the webhook is disabled. Default: "preview". |