
Implementation Guide: Auto-generate progress invoices based on project milestone completion
Step-by-step implementation guide for deploying AI to auto-generate progress invoices based on project milestone completion for Construction & Contractors clients.
Hardware Procurement
Field Tablet for Milestone Sign-Off
iPad 10th Generation (A2696) - 64GB Wi-Fi + Cellular
$449 per unit MSP cost / $529 suggested resale (includes MDM enrollment and protective case)
Enables field superintendents and project managers to mark milestones complete on-site using the PM platform's mobile app (Procore, Buildertrend, or Knowify). Cellular connectivity ensures milestone updates push to the automation engine even at remote job sites without Wi-Fi.
Rugged Tablet Case
$70 per unit MSP cost / $90 suggested resale
Protects field tablets from drops, dust, and moisture typical on construction job sites. Includes integrated stand for use during milestone review meetings.
Document Scanner for Lien Waivers
$395 MSP cost / $475 suggested resale
Digitizes signed lien waivers, change orders, and AIA pay application backup documentation. Scanned documents are auto-uploaded to the project folder in the PM platform or cloud storage, where they are attached to the corresponding invoice by the automation workflow.
Office Workstation for Invoice Review/Approval
Office Workstation for Invoice Review/Approval
$899 MSP cost / $1,049 suggested resale
Dedicated workstation for the office manager or bookkeeper to review auto-generated draft invoices, approve them, and manage the billing queue in the accounting platform. Dual-monitor setup recommended for side-by-side SOV and invoice comparison.
Secondary Monitor
$199 MSP cost / $249 suggested resale
Second display for the invoice review workstation, allowing the bookkeeper to view the PM platform's milestone/SOV data alongside the accounting platform's invoice draft simultaneously.
Software Procurement
Knowify Advanced
$349/month (estimated mid-tier; confirm with Knowify sales for exact current pricing)
Primary construction project management platform for specialty and trade contractors. Provides milestone tracking, Schedule of Values management, AIA billing, change order tracking, and native QuickBooks Online bi-directional sync. The milestone completion events in Knowify serve as the trigger source for the entire automation.
QuickBooks Online Advanced
$275/month (effective July 2025 pricing). MSP procures via QuickBooks Solution Provider Program or ProAdvisor discount at ~30% off ($192.50/month MSP cost).
Primary accounting and invoicing platform. Receives auto-generated draft invoices from the automation workflow. Handles accounts receivable, job costing, retainage tracking, payment processing, and financial reporting. Advanced tier required for API access, custom fields, and workflow approvals.
Make (formerly Integromat) - Pro Plan
$16/month
Core automation and integration middleware. Orchestrates the milestone-to-invoice workflow: listens for milestone completion events via webhooks or polling, executes retainage calculations, maps SOV line items to invoice line items, creates draft invoices in QBO, attaches lien waiver documents, and sends notification emails. Make is preferred over Zapier for this project due to superior branching logic, data transformation capabilities, and lower per-operation cost.
License type: SaaS - monthly subscription (usage-based operations). Most mid-size contractors will use 2,000–5,000 operations/month.
PayAppPro
$7.99–$19.99 per pay application package, or ~$49/month subscription for unlimited (contact vendor for current plans)
Generates AIA G702 (Application and Certificate for Payment) and G703 (Continuation Sheet) compliant PDF documents from invoice data. Required when the client's general contractor or project owner mandates AIA-format pay applications. Integrates with QuickBooks estimates and progress invoicing.
Microsoft 365 Business Standard
$12.50/user/month (MSP cost via CSP ~$10.50/user/month)
Provides Exchange Online email for invoice delivery and notifications, SharePoint/OneDrive for document storage (lien waivers, signed pay apps, backup documentation), and Microsoft Teams for internal approval notifications. Azure AD provides SSO and MFA across all platforms.
Jamf Now (or Microsoft Intune)
Jamf Now: $4/device/month (Plus tier). If client is already on M365 Business Premium, Intune is included.
Mobile Device Management for the field iPads. Enforces passcode policies, remote wipe capability, app deployment (PM platform mobile app), and ensures tablets are compliant with company security policies before accessing project and financial data.
ScanSnap Home
$0 (bundled with scanner)
Scanner management software that enables one-touch scanning profiles. Configure profiles for 'Lien Waiver', 'Change Order', and 'Pay Application Backup' that automatically OCR, name, and route scanned documents to the correct project folder in SharePoint/OneDrive.
Prerequisites
- Active QuickBooks Online Advanced subscription with API access enabled (Settings > Account and Settings > Advanced > verify API/OAuth enabled). The client must have a QBO company file with their Chart of Accounts, Items/Services list, and Customer list already configured.
- Active construction project management platform subscription (Knowify, Buildertrend, or Procore) with at least 2–3 active projects that have a defined Schedule of Values (SOV) with milestones or phases.
- Client must have a documented billing process: What triggers an invoice today? Who approves it? What format (standard invoice vs. AIA G702/G703)? What retainage percentage is used per contract? Gather this in the discovery phase.
- Microsoft 365 Business Standard (or equivalent email/identity platform) deployed with MFA enabled for all users who will access the PM platform, accounting platform, or automation dashboards.
- Stable internet connectivity at the main office (minimum 25 Mbps down / 10 Mbps up). Cellular data plans on field tablets (minimum 5GB/month per device).
- Admin credentials for both the PM platform and QBO (or delegated API access via OAuth). The MSP will need these during automation configuration and must document them in the client's password manager.
- At least one completed or near-completed project with known milestone values that can serve as the test case during implementation. The bookkeeper should have the corresponding manual invoices for validation comparison.
- List of all active contracts with retainage terms (percentage, cap, release conditions) and any state-specific retainage laws that apply (e.g., 5% cap in Nevada, 10% until 50% completion in North Dakota).
- If AIA billing is required: Copies of recent G702/G703 forms the client has submitted, so the automation output can be matched to the expected format.
- Designated client-side project champion — typically the office manager or head bookkeeper — who will be available for 2–4 hours per week during the implementation for requirements validation, testing, and training.
Installation Steps
Step 1: Discovery & Current-State Workflow Mapping
Conduct a 2–3 hour on-site or video discovery session with the client's bookkeeper, project manager, and owner. Map the current invoicing workflow end-to-end: How are milestones currently tracked? Who determines when a milestone is complete? How is the invoice amount calculated (fixed milestone amount vs. percentage of completion vs. cost-to-cost)? What is the approval chain? How are invoices delivered (email, mail, portal)? What format (standard invoice vs. AIA pay app)? What retainage terms apply per contract? Document everything in a workflow diagram.
Use a structured discovery questionnaire. Key questions: (1) How many active projects at any given time? (2) Average number of milestones per project? (3) How many invoices per month? (4) Do different project owners require different invoice formats? (5) What is the current average time from milestone completion to invoice sent? (6) What are the biggest pain points? This discovery output becomes the automation requirements document.
Step 2: Configure Construction PM Platform - Knowify Setup
If the client is not yet on a PM platform, provision Knowify Advanced. If already on Buildertrend or Procore, skip to the relevant variant of this step.
If the client already uses Knowify, audit the existing SOV structure to ensure milestones are granular enough for billing. Each billable milestone must be a discrete line item in the SOV. If the SOV is too coarse (e.g., 'Framing - $150,000' with no sub-milestones), work with the PM to break it down into billable phases (e.g., 'First Floor Framing - $60,000', 'Second Floor Framing - $55,000', 'Roof Framing - $35,000').
Step 3: Configure QuickBooks Online Advanced for Construction Billing
Ensure QBO Advanced is properly configured for construction progress invoicing:
Progress Invoicing in QBO works by creating an Estimate first, then invoicing against it in increments. The automation will create the Estimate (representing the full contract SOV) and then create Invoice records against it as milestones complete. Verify that the client's QBO subscription is Advanced ($275/mo as of July 2025) — the Plus plan supports progress invoicing but lacks custom fields and advanced API features we need.
Step 4: Provision and Configure Make.com Automation Account
Create a Make.com account for the client (or under the MSP's team account if managing centrally). Set up the organization, team, and initial scenario structure: (1) Create organization named '[ClientName]-Automation', (2) Create a team for the client, (3) Create a folder structure: 'Invoice Automation', 'Notifications', 'Document Management', (4) Install required app connections: QuickBooks Online (via OAuth 2.0), Knowify (via API key or webhook), Email (SMTP or Microsoft 365), SharePoint/OneDrive (via OAuth).
Make.com is preferred over Zapier for this implementation because: (1) Make supports complex branching and conditional logic needed for retainage calculations that vary by contract, (2) Make's router module allows a single trigger to produce multiple outputs (invoice + lien waiver + notification), (3) Make's pricing is per-operation rather than per-task, making it 3–5x more cost-effective for multi-step workflows. If the client has strong preference for Microsoft ecosystem, Power Automate is a viable alternative (see Alternatives section).
Step 5: Build Core Automation Scenario - Milestone Trigger Configuration
Create the primary Make.com scenario that watches for milestone completion events. The trigger mechanism depends on the PM platform: For Knowify, use a polling trigger via Knowify API or a custom webhook. For Buildertrend or Procore, use their native webhook capabilities. Configure the trigger to fire when a milestone/phase status changes to 'Complete' or when percentage-of-completion reaches a billing threshold.
Make.com Scenario: 'Milestone-to-Invoice Generator' — Module 1: Webhook Trigger (Custom Webhook). Webhook Payload Expected Structure:
{
"event": "milestone.completed",
"project_id": "PRJ-2025-042",
"project_name": "Riverside Office Renovation",
"milestone_id": "MS-007",
"milestone_name": "Electrical Rough-In Complete",
"milestone_amount": 45000.00,
"contract_total": 380000.00,
"completed_to_date": 185000.00,
"retainage_pct": 10,
"customer_name": "Riverside Development LLC",
"customer_email": "ap@riversidedev.com",
"completed_by": "John Smith",
"completed_date": "2025-07-15T14:30:00Z",
"sov_line_items": [
{
"line_id": "SOV-007",
"description": "Division 26 - Electrical Rough-In",
"scheduled_value": 45000.00,
"previous_billed": 0,
"this_period": 45000.00,
"retainage": 4500.00
}
]
}If Knowify does not support native webhooks (check current API docs), implement a polling approach: use Make's Schedule module to check the Knowify API every 15 minutes for milestones whose status changed to 'Complete' since the last poll. Store the last-checked timestamp in a Make data store. For Procore, use the Webhooks API (POST /rest/v1.0/webhooks) to register the Make webhook URL with trigger event 'budget_line_items.update' or 'schedule.tasks.update'. For Buildertrend, check for API/webhook availability or use Zapier as an intermediary trigger that calls the Make webhook.
POST /rest/v1.0/webhooksStep 6: Build Invoice Calculation & Retainage Logic Module
Add data transformation modules to the Make scenario that calculate the invoice amounts including retainage deductions. This is the core business logic: (1) For each SOV line item in the milestone, calculate: This Period Amount = milestone_amount, Retainage This Period = milestone_amount × retainage_pct, Net Billable This Period = milestone_amount - retainage, (2) Calculate running totals: Total Completed to Date, Total Retainage to Date, Total Previously Billed, (3) Handle edge cases: milestone amounts that differ from SOV scheduled values (change orders), final milestone where retainage is released, stored materials billing.
# Module 3: Set Variable - Calculate Line Item Values
# - scheduled_value: {{iterator.scheduled_value}}
# - previous_billed: {{iterator.previous_billed}}
# - this_period: {{iterator.this_period}}
# - retainage_pct: {{webhook.retainage_pct}} / 100
# - retainage_amount: {{iterator.this_period}} * ({{webhook.retainage_pct}} / 100)
# - net_billable: {{iterator.this_period}} - ({{iterator.this_period}} * ({{webhook.retainage_pct}} / 100))
# - completed_to_date: {{iterator.previous_billed}} + {{iterator.this_period}}
# - pct_complete: ({{iterator.previous_billed}} + {{iterator.this_period}}) / {{iterator.scheduled_value}} * 100
# Module 4: Router (Conditional Paths)
# Path A: Standard milestone (retainage_pct > 0 AND milestone is not final)
# -> Continue to invoice creation with retainage deduction
# Path B: Final milestone (milestone triggers retainage release)
# -> Create invoice for milestone amount PLUS accumulated retainage
# Path C: Stored materials only (no milestone completion, just material delivery)
# -> Create invoice for stored materials value only
# Module 5: Aggregator
# - Aggregates all line items back into a single invoice payload
# - Sums: total_this_period, total_retainage, total_net_billableRetainage logic is critical and must be configurable per contract. Some contracts use 10% retainage until 50% complete, then 5% thereafter (common in North Dakota and other states). Store retainage rules in a Make data store keyed by project_id so each project can have its own retainage schedule. The final milestone path must include logic to release all accumulated retainage — verify with the client whether retainage release requires a separate invoice or is included in the final progress invoice.
Step 7: Build QuickBooks Online Invoice Creation Module
Configure the Make scenario to create a draft invoice in QuickBooks Online using the calculated values from the previous module. The invoice is created as a Draft (not sent) so the bookkeeper can review before sending. Map the aggregated line items to QBO invoice line items, populate custom fields, and set the correct customer, terms, and due date.
# creates invoice with mapped line items, customer reference, and custom
# fields
POST https://quickbooks.api.intuit.com/v3/company/{companyId}/invoice
Content-Type: application/json
Authorization: Bearer {access_token}
Body: {
"Line": [...mapped line items...],
"CustomerRef": {"value": "{qbo_customer_id}"},
"TxnDate": "2025-07-15",
"DueDate": "2025-08-14",
"DocNumber": "PI-PRJ2025042-007",
"CustomField": [...],
"PrivateNote": "Auto-generated..."
}QBO creates invoices in 'Unsent' status by default, which acts as our 'Draft' state. The bookkeeper will see these in the Invoice list with status 'Unsent' and can review, edit if needed, then send. Important: QBO's progress invoicing feature works against Estimates. If the client wants to use QBO's native progress invoicing (billing against an Estimate), the automation must first create or reference the Estimate for the full contract, then create partial invoices against it. This is more complex but provides better tracking in QBO. Alternatively, create standalone invoices with project tracking via custom fields — simpler to automate but less integrated with QBO's built-in progress invoicing reports.
Step 8: Build Notification & Approval Workflow Module
Add modules to the Make scenario that notify the appropriate people when a draft invoice is generated and route it for approval: (1) Send email to the bookkeeper/office manager with invoice summary and a direct link to the draft invoice in QBO, (2) Send a Microsoft Teams message to the #billing channel with invoice details, (3) If the invoice amount exceeds a configurable threshold (e.g., $25,000), send an additional approval request to the company owner/CFO via email with approve/reject links, (4) Log the invoice generation event to a tracking spreadsheet or data store for audit purposes.
# To, CC, Subject, and HTML Body fields
To: {{bookkeeper_email}}
CC: {{pm_email}}
Subject: '[Action Required] Draft Invoice Generated - {{webhook.project_name}} - {{webhook.milestone_name}}'
Body (HTML):
<h2>Progress Invoice Ready for Review</h2>
<table>
<tr><td><b>Project:</b></td><td>{{webhook.project_name}}</td></tr>
<tr><td><b>Milestone:</b></td><td>{{webhook.milestone_name}}</td></tr>
<tr><td><b>Gross Amount:</b></td><td>${{total_this_period}}</td></tr>
<tr><td><b>Retainage ({{webhook.retainage_pct}}%):</b></td><td>${{total_retainage}}</td></tr>
<tr><td><b>Net Invoice Amount:</b></td><td>${{total_net_billable}}</td></tr>
<tr><td><b>Completed By:</b></td><td>{{webhook.completed_by}}</td></tr>
<tr><td><b>Completed Date:</b></td><td>{{webhook.completed_date}}</td></tr>
</table>
<p><a href='https://app.qbo.intuit.com/app/invoice/{{qbo_invoice_id}}'>Review Invoice in QuickBooks</a></p>
<p><i>This invoice was auto-generated. Please review all line items and amounts before sending to the customer.</i></p># Post message to #billing-notifications channel
Channel: #billing-notifications
Message: 'New draft invoice: {{webhook.project_name}} - {{webhook.milestone_name}} - ${{total_net_billable}}'# Audit log row structure
Row: [timestamp, project_id, milestone_id, gross_amount, retainage, net_amount, qbo_invoice_id, status='draft']The approval threshold should be configurable — store it in a Make data store variable. Some clients may want all invoices auto-sent without approval (rare in construction but possible for small recurring service work). Others may want two-tier approval (PM approves scope accuracy, then bookkeeper approves financial accuracy). Design the notification flow to be adjustable without rebuilding the scenario. Consider adding a 48-hour reminder: if the draft invoice hasn't been sent within 48 hours, send a follow-up reminder email to the bookkeeper.
Step 9: Build Lien Waiver Document Generation Module
Add a module that generates a conditional lien waiver document to accompany each progress invoice. In many states, general contractors require subcontractors to submit a conditional lien waiver with every pay application. The automation generates a pre-filled waiver from a template and attaches it to the invoice notification email and/or uploads it to the project document folder.
Option A: Use Make's Document Generator (Google Docs Template)
Option B: Use WebMerge/Formstack Documents for PDF Generation
POST to Formstack Documents API with merge fieldsTwelve states require specific statutory lien waiver forms — Arizona, California, Georgia, Florida, Michigan, Mississippi, Missouri, Nevada, Texas, Utah, Wisconsin, and Wyoming. Mississippi and Wyoming require notarization. During discovery, identify which states the client operates in and obtain the correct statutory forms. Create separate templates for each required state form. Store the state-to-template mapping in a Make data store. If the client operates in a state without statutory forms, a standard conditional lien waiver template is sufficient.
Step 10: Configure AIA G702/G703 Pay Application Generation (If Required)
If the client's contracts require AIA-format pay applications (common for commercial GC/owner billing), integrate PayAppPro or configure the PM platform's native AIA billing feature. This step maps the automation's invoice data to the G702 (Application and Certificate for Payment) and G703 (Continuation Sheet) format.
Option A: PayAppPro Integration
Option B: Knowify Native AIA Billing
Option C: Custom PDF Generation via Make + Google Docs
Key G702 Fields to Map
- Application No., Application Date, Period To
- Contract For, Project Name, Owner, Architect
- Original Contract Sum, Net Change by Change Orders
- Contract Sum to Date, Total Completed & Stored to Date
- Retainage (a% of Completed Work, b% of Stored Material)
- Total Earned Less Retainage
- Less Previous Certificates for Payment
- Current Payment Due
G703 Continuation Sheet: One Row Per SOV Line Item
- Item No.
- Description of Work
- Scheduled Value
- Work Completed (Previous, This Period)
- Materials Stored
- Total Completed & Stored
- % Complete
- Balance to Finish
- Retainage
AIA G702/G703 forms are copyrighted by the American Institute of Architects. If using custom PDF generation (Option C), be aware that reproducing the exact AIA form layout may require an AIA license. PayAppPro and Knowify have licensed the forms. For clients who only occasionally need AIA format, PayAppPro's per-package pricing ($7.99) is most cost-effective. For clients who bill every project in AIA format, Knowify's built-in AIA billing is the better path. Confirm with the client which projects require AIA format vs. standard invoicing.
Step 11: Deploy Field Tablets and Configure Mobile Access
Provision the iPads for field staff, enroll them in MDM, install the PM platform's mobile app, and configure the milestone sign-off workflow:
iPads are recommended over Android tablets for this deployment due to better enterprise MDM support, longer OS update lifecycle, and superior construction app availability. If the client already has Android devices, Samsung Galaxy Tab A9+ with Samsung Knox MDM is an acceptable alternative. Configure the tablets with a shared Apple ID managed by the MSP for app purchases, or use Apple Business Manager for volume app licensing. Each user should have their own PM platform login.
Step 12: Configure Document Scanner and Scan Profiles
Set up the Fujitsu ScanSnap iX1600 at the client's office with pre-configured scan profiles for construction document types. Each profile automatically names, OCRs, and routes the scanned document to the correct SharePoint folder.
- Profile 1: 'Lien Waiver' — Scan settings: Color, 300dpi, Auto-detect size | File format: Searchable PDF | Naming: 'LienWaiver_[DateStamp]_[Counter]' | Save to: OneDrive/SharePoint > Projects > _Lien Waivers (Inbox)
- Profile 2: 'Signed Pay Application' — Scan settings: Color, 300dpi, Letter size | File format: Searchable PDF | Naming: 'PayApp_[DateStamp]_[Counter]' | Save to: OneDrive/SharePoint > Projects > _Pay Applications (Inbox)
- Profile 3: 'Change Order' — Scan settings: Color, 300dpi, Auto-detect size | File format: Searchable PDF | Naming: 'ChangeOrder_[DateStamp]_[Counter]' | Save to: OneDrive/SharePoint > Projects > _Change Orders (Inbox)
The ScanSnap iX1600 supports up to 30 custom profiles selectable via its touchscreen. Create a laminated quick-reference card showing which profile to select for each document type and place it next to the scanner. The scanned documents in the SharePoint inbox folders can optionally trigger a secondary Make scenario that files them into the correct project subfolder based on OCR content or manual tagging.
Step 13: End-to-End Integration Testing
Conduct comprehensive testing of the full automation pipeline using a real project's data. This is the most critical step — run the automation against known historical invoices and compare output to the manually-created originals. Test at least 3 scenarios: (1) standard milestone completion with retainage, (2) final milestone with retainage release, (3) milestone with a change order affecting the SOV.
Test Scenario 1: Standard Milestone with 10% Retainage
- Input: Milestone 'Foundation Complete' on Project 'Riverside Renovation'
- SOV Line: 'Division 3 - Concrete', Scheduled Value: $75,000
- Previous Billed: $0
- This Period: $75,000
- Retainage: 10%
Expected Output — Scenario 1
- QBO Draft Invoice: $67,500 ($75,000 - $7,500 retainage)
- Retainage line item: -$7,500
- Email notification sent to bookkeeper
- Conditional lien waiver PDF generated
Test Scenario 2: Final Milestone with Retainage Release
- Input: Milestone 'Final Punch List Complete' on Project 'Oak Street Build'
- Final milestone flag: true
- This Period: $15,000
- Accumulated Retainage to Release: $38,000
Expected Output — Scenario 2
- QBO Draft Invoice: $53,000 ($15,000 + $38,000 retainage release)
- Retainage release line item: +$38,000
Test Scenario 3: Milestone with Change Order
- Input: Milestone 'Electrical Rough-In' with approved CO #3
- Original SOV: $45,000
- CO #3 adds: $8,500
- Revised SOV: $53,500
Expected Output — Scenario 3
- Invoice reflects revised amount: $53,500 less retainage
- CO reference noted in invoice description
Validation Checklist
Run these tests on a QBO Sandbox environment first if possible (available via QBO Developer Portal). If not, create the test invoices in QBO Production and immediately void/delete them after validation. Have the client's bookkeeper sit alongside during testing to validate that the output matches their expectations and manual process. Document any discrepancies and adjust the automation logic before go-live. Keep a test log spreadsheet with expected vs. actual results for each test case.
Step 14: Go-Live Cutover and Parallel Run
Deploy the automation in production with a 2-week parallel run period where both the manual process and automated process operate simultaneously. During this period, the bookkeeper creates invoices manually as usual AND the automation generates draft invoices. Compare outputs daily to catch any discrepancies before fully transitioning to automated invoicing.
Go-Live Checklist
Parallel Run Procedure (2 weeks)
The parallel run is essential for building client confidence and catching edge cases. Common issues that surface during parallel run: (1) milestone names don't exactly match SOV descriptions (fuzzy matching needed), (2) change orders were approved but not yet reflected in the PM platform's SOV, (3) tax calculations differ between manual and automated methods, (4) retainage terms changed mid-project and weren't updated in the data store. Budget 4–8 hours of MSP time during the parallel run for adjustments.
Custom AI Components
Milestone-to-Invoice Automation Workflow
Type: workflow
The primary Make.com scenario that orchestrates the entire milestone completion to draft invoice generation pipeline. This is a multi-module, branching workflow that handles webhook reception, data transformation, retainage calculation, QBO invoice creation, lien waiver generation, and notification distribution. It is the core deliverable of this project.
Implementation:
SCENARIO ARCHITECTURE
Module 1: Custom Webhook (Trigger)
- Type: webhooks/CustomWebHook
- Name: 'knowify-milestone-complete'
- Webhook URL: [auto-generated by Make]
Data Structure Definition:
{
"event": "string",
"project_id": "string",
"project_name": "string",
"milestone_id": "string",
"milestone_name": "string",
"milestone_amount": "number",
"contract_total": "number",
"completed_to_date": "number",
"retainage_pct": "number",
"customer_name": "string",
"customer_email": "string",
"customer_qbo_id": "string",
"completed_by": "string",
"completed_date": "string",
"is_final_milestone": "boolean",
"accumulated_retainage": "number",
"state_code": "string",
"contract_number": "string",
"sov_line_items": [
{
"line_id": "string",
"description": "string",
"scheduled_value": "number",
"previous_billed": "number",
"this_period": "number",
"stored_materials": "number"
}
]
}Module 2: Data Store Lookup - Retainage Rules
- Type: datastore/GetRecord
- Data Store: 'project-retainage-rules'
- Key: {{1.project_id}}
- Returns: retainage_pct, retainage_cap_pct_complete, retainage_after_cap, retainage_release_trigger
- Fallback: Use {{1.retainage_pct}} from webhook if no override exists
Module 3: Set Variable - Calculate Retainage
- Type: tools/SetVariable
Variables:
effective_retainage_pct:
IF({{1.completed_to_date}} / {{1.contract_total}} * 100 >= {{2.retainage_cap_pct_complete}},
{{2.retainage_after_cap}},
{{2.retainage_pct}})
is_final: {{1.is_final_milestone}}Module 4: Iterator - SOV Line Items
- Type: flow/Iterator
- Source Array: {{1.sov_line_items}}
Module 5: Set Variable - Per Line Calculations
- Type: tools/SetVariable
For each SOV line item:
gross_this_period: {{4.this_period}} + {{4.stored_materials}}
retainage_this_period: ({{4.this_period}} * {{3.effective_retainage_pct}} / 100)
net_this_period: {{4.this_period}} + {{4.stored_materials}} - ({{4.this_period}} * {{3.effective_retainage_pct}} / 100)
total_completed: {{4.previous_billed}} + {{4.this_period}} + {{4.stored_materials}}
pct_complete: ROUND(({{4.previous_billed}} + {{4.this_period}}) / {{4.scheduled_value}} * 100, 1)
balance_to_finish: {{4.scheduled_value}} - {{4.previous_billed}} - {{4.this_period}}Module 6: Array Aggregator
- Type: flow/ArrayAggregator
- Source Module: Module 5
- Aggregated Fields: All calculated line item values
Also calculate totals:
total_gross: SUM(gross_this_period)
total_retainage: SUM(retainage_this_period)
total_net: SUM(net_this_period)Module 7: Router (3 paths)
- Type: flow/Router
Path A: Standard Progress Invoice (is_final = false)
Module 8A: QBO - Create Invoice
- Type: quickbooks/CreateInvoice
- Connection: [QBO OAuth Connection]
- CustomerRef: {{1.customer_qbo_id}}
- TxnDate: {{formatDate(1.completed_date, 'YYYY-MM-DD')}}
- DueDate: {{addDays(formatDate(1.completed_date, 'YYYY-MM-DD'), 30)}}
- DocNumber: CONCAT('PI-', {{1.project_id}}, '-', {{formatDate(now, 'YYYYMM')}})
Line Items — for each aggregated line item:
{
"DetailType": "SalesItemLineDetail",
"Amount": {{line.net_this_period}},
"Description": CONCAT({{line.description}}, ' | Period: ', {{formatDate(1.completed_date, 'MMM YYYY')}}, ' | ', {{line.pct_complete}}, '% Complete'),
"SalesItemLineDetail": {
"ItemRef": {"value": "[mapped_qbo_item_id]"},
"Qty": 1,
"UnitPrice": {{line.net_this_period}}
}
}Plus retainage tracking line:
{
"DetailType": "SalesItemLineDetail",
"Amount": -{{6.total_retainage}},
"Description": CONCAT('Retainage Withheld (', {{3.effective_retainage_pct}}, '%)'),
"SalesItemLineDetail": {
"ItemRef": {"value": "[retainage_item_id]"},
"Qty": 1,
"UnitPrice": -{{6.total_retainage}}
}
}Custom fields and private note:
"CustomField": [
{"Name": "Project Name", "StringValue": {{1.project_name}}},
{"Name": "Milestone ID", "StringValue": {{1.milestone_id}}},
{"Name": "Contract Number", "StringValue": {{1.contract_number}}}
]
"PrivateNote": CONCAT('Auto-generated from milestone: ', {{1.milestone_name}}, '. Gross: $', {{6.total_gross}}, ', Retainage: $', {{6.total_retainage}}, ', Net: $', {{6.total_net}})Path B: Final Invoice with Retainage Release (is_final = true)
Module 8B: QBO - Create Invoice (Final + Retainage) — Same as 8A except add the following additional line item for retainage release, and update PrivateNote accordingly:
{
"DetailType": "SalesItemLineDetail",
"Amount": {{1.accumulated_retainage}},
"Description": "Retainage Release - All Prior Periods",
"SalesItemLineDetail": {
"ItemRef": {"value": "[retainage_release_item_id]"},
"Qty": 1,
"UnitPrice": {{1.accumulated_retainage}}
}
}
"PrivateNote": CONCAT('FINAL INVOICE with retainage release. ', ...)Path C: Continue to shared post-invoice modules
Module 9: Data Store - Log Invoice
- Type: datastore/AddRecord
- Data Store: 'invoice-audit-log'
{
"timestamp": {{now}},
"project_id": {{1.project_id}},
"milestone_id": {{1.milestone_id}},
"milestone_name": {{1.milestone_name}},
"gross_amount": {{6.total_gross}},
"retainage_amount": {{6.total_retainage}},
"net_invoice_amount": {{6.total_net}},
"qbo_invoice_id": {{8.id}},
"qbo_doc_number": {{8.DocNumber}},
"status": "draft",
"is_final": {{3.is_final}}
}Module 10: Email Notification
- Type: microsoft365/SendEmail
- To: [bookkeeper_email from data store]
- CC: [pm_email from webhook or data store]
- Subject: CONCAT('[Review] Draft Invoice ', {{8.DocNumber}}, ' - ', {{1.project_name}})
- HTML Body: (see Step 8 commands for template)
Error Handling
- Each module has a Break error handler that logs the error to the 'invoice-error-log' data store, sends an alert email to the MSP monitoring address, and sends an alert email to the bookkeeper with details
- Retry policy: 3 retries with exponential backoff for API timeouts
Data Stores Required
PM Platform Webhook Relay
Type: integration A lightweight middleware component that bridges the construction PM platform's event system with the Make.com webhook. For platforms like Knowify that may not have native webhook support, this relay polls the PM platform's API on a schedule and translates status changes into webhook calls to the main automation scenario. For platforms like Procore that have native webhooks, this component configures and manages the webhook subscription.
Implementation:
Option A: Polling Relay for Knowify (Make.com Scenario)
- Scenario Name: 'PM Platform Poller'
- Schedule: Every 15 minutes
Module 1: Data Store - Get Last Poll Timestamp
- Type: datastore/GetRecord
- Data Store: 'config'
- Key: 'last_poll_timestamp'
- Returns: {{timestamp_value}}
Module 2: HTTP Request - Knowify API
- Type: http/MakeRequest
- URL: https://api.knowify.com/v1/projects/milestones (Note: Verify exact Knowify API endpoint - may need to use /projects/{id}/tasks or /projects/{id}/schedule depending on API version)
- Method: GET
- Headers: - Authorization: Bearer {{knowify_api_key}} - Content-Type: application/json
- Query Parameters: - updated_since: {{1.timestamp_value}} - status: completed
Module 3: Iterator
- Source: {{2.data.milestones}} (or equivalent response array)
- Filter: Only milestones where status_changed_to = 'completed' AND milestone_id NOT IN [already_processed_ids from data store]
Module 4: HTTP Request - Call Main Webhook
- Type: http/MakeRequest
- URL: [Make.com webhook URL from main scenario]
- Method: POST
Body (JSON): Transform Knowify milestone data to webhook payload format:
# map Make.com module 3 fields to these keys
{
"event": "milestone.completed",
"project_id": "{{3.project_id}}",
"project_name": "{{3.project_name}}",
"milestone_id": "{{3.milestone_id}}",
"milestone_name": "{{3.milestone_name}}",
"milestone_amount": {{3.amount}},
"contract_total": {{3.contract_total}},
"completed_to_date": {{3.billed_to_date + 3.amount}},
"retainage_pct": {{3.retainage_percentage}},
"customer_name": "{{3.client_name}}",
"customer_email": "{{3.client_email}}",
"customer_qbo_id": "[lookup from qbo-customer-map data store]",
"completed_by": "{{3.completed_by_user}}",
"completed_date": "{{3.completion_date}}",
"is_final_milestone": {{3.is_final}},
"accumulated_retainage": {{3.total_retainage_held}},
"state_code": "{{3.project_state}}",
"contract_number": "{{3.contract_number}}",
"sov_line_items": {{3.schedule_of_values_items}}
}Module 5: Data Store - Update Last Poll Timestamp
- Type: datastore/UpdateRecord
- Data Store: 'config'
- Key: 'last_poll_timestamp'
- Value: {{now}}
Module 6: Data Store - Record Processed Milestone
- Type: datastore/AddRecord
- Data Store: 'processed-milestones'
- Record: {milestone_id: {{3.milestone_id}}, processed_at: {{now}}}
Option B: Procore Native Webhook Configuration
Use Procore's REST API to register webhook subscriptions directly.
curl -X POST 'https://api.procore.com/rest/v1.0/companies/{company_id}/webhooks/hooks' \
-H 'Authorization: Bearer {procore_access_token}' \
-H 'Content-Type: application/json' \
-d '{
"hook": {
"api_version": "v2",
"destination_url": "{make_webhook_url}",
"namespace": "company"
}
}'curl -X POST 'https://api.procore.com/rest/v1.0/companies/{company_id}/webhooks/hooks/{hook_id}/triggers' \
-H 'Authorization: Bearer {procore_access_token}' \
-H 'Content-Type: application/json' \
-d '{
"trigger": {
"resource_name": "Schedule Tasks",
"event_type": "update"
}
}'The Make.com main scenario's webhook module will need a filter to only process events where the task status changed to 'completed' and the task is tagged as a 'billing milestone' in Procore.
Retainage Calculation Engine
Type: skill A configurable retainage calculation module that supports multiple retainage schemes used across different states and contract types. This component is called by the main workflow for every invoice line item and returns the correct retainage amount based on the project's rules, the current completion percentage, and applicable state law.
Implementation:
Make.com Custom JavaScript Module (Module type: tools/Custom)
// Make.com Custom JavaScript Module
// Retainage Calculation Engine
// Input variables from previous modules:
// scheduled_value: Total scheduled value of the line item
// previous_billed: Amount previously billed for this line item
// this_period: Amount being billed this period
// stored_materials: Materials presently stored (not yet installed)
// project_pct_complete: Overall project completion percentage
// retainage_rules: Object from data store lookup
// {
// base_pct: 10, // Base retainage percentage
// cap_at_project_pct: 50, // Reduce retainage after project is X% complete
// reduced_pct: 5, // Reduced retainage percentage after cap
// max_retainage_amount: null, // Optional dollar cap on total retainage
// materials_retainage_pct: 0, // Retainage on stored materials (often 0%)
// release_at_substantial: true, // Release retainage at substantial completion
// state_code: 'NV' // State for regulatory compliance
// }
// is_final_milestone: boolean
// accumulated_retainage: Total retainage held to date across all prior periods
const STATE_RETAINAGE_CAPS = {
'NV': { max_pct: 5, notes: 'Nevada caps retainage at 5%' },
'ND': { max_pct: 10, reduce_at_50_pct: true, notes: 'ND: 10% until 50% complete, then 0%' },
'CO': { max_pct: 5, notes: 'Colorado: typically 5% max' },
'CA': { max_pct: 5, notes: 'California: 5% on public works' },
'TX': { max_pct: 10, notes: 'Texas: 10% standard' },
'FL': { max_pct: 10, notes: 'Florida: 10% standard, 5% after 50%' },
// Add additional states as needed per client requirements
};
function calculateRetainage(input) {
const rules = input.retainage_rules;
const stateRules = STATE_RETAINAGE_CAPS[rules.state_code] || {};
// Start with base retainage percentage from contract
let effectivePct = rules.base_pct;
// Apply project completion reduction if applicable
if (rules.cap_at_project_pct && input.project_pct_complete >= rules.cap_at_project_pct) {
effectivePct = rules.reduced_pct || 0;
}
// Apply state-specific caps (state law overrides contract if lower)
if (stateRules.max_pct && effectivePct > stateRules.max_pct) {
effectivePct = stateRules.max_pct;
}
// North Dakota special rule: no retainage after 50% complete
if (rules.state_code === 'ND' && input.project_pct_complete >= 50) {
effectivePct = 0;
}
// Calculate retainage on work performed
const workRetainage = input.this_period * (effectivePct / 100);
// Calculate retainage on stored materials (often 0%)
const materialsRetainagePct = rules.materials_retainage_pct || 0;
const materialsRetainage = input.stored_materials * (materialsRetainagePct / 100);
const totalRetainage = workRetainage + materialsRetainage;
// Apply dollar cap if specified
let cappedRetainage = totalRetainage;
if (rules.max_retainage_amount) {
const remainingCap = rules.max_retainage_amount - input.accumulated_retainage;
cappedRetainage = Math.min(totalRetainage, Math.max(0, remainingCap));
}
// Final milestone: release all accumulated retainage
let retainageRelease = 0;
if (input.is_final_milestone) {
retainageRelease = input.accumulated_retainage;
}
return {
effective_retainage_pct: effectivePct,
retainage_on_work: workRetainage,
retainage_on_materials: materialsRetainage,
total_retainage_this_period: cappedRetainage,
retainage_release: retainageRelease,
net_billable: (input.this_period + input.stored_materials) - cappedRetainage + retainageRelease,
gross_billable: input.this_period + input.stored_materials,
new_accumulated_retainage: input.accumulated_retainage + cappedRetainage - retainageRelease,
state_compliance_note: stateRules.notes || 'No state-specific retainage cap applied',
calculation_details: `Base: ${rules.base_pct}%, Effective: ${effectivePct}%, State: ${rules.state_code}, Project Complete: ${input.project_pct_complete}%`
};
}
// Execute
const result = calculateRetainage({
scheduled_value: scheduled_value,
previous_billed: previous_billed,
this_period: this_period,
stored_materials: stored_materials,
project_pct_complete: project_pct_complete,
retainage_rules: retainage_rules,
is_final_milestone: is_final_milestone,
accumulated_retainage: accumulated_retainage
});
return result;Data Store Schema: 'project-retainage-rules'
- Key: project_id (string)
- base_pct (number): Default retainage percentage for this contract
- cap_at_project_pct (number): Project completion % at which retainage reduces
- reduced_pct (number): Retainage % after the cap threshold
- max_retainage_amount (number, nullable): Dollar cap on total retainage
- materials_retainage_pct (number): Retainage % on stored materials
- release_at_substantial (boolean): Whether to release at substantial completion
- state_code (string): Two-letter state code for regulatory compliance
Setup Instructions
Lien Waiver Document Generator
Type: skill Generates state-appropriate conditional lien waiver PDF documents pre-filled with invoice data. Uses Google Docs templates with merge fields, with different templates for states that require statutory forms (AZ, CA, FL, GA, MI, MO, MS, NV, TX, UT, WI, WY) versus generic conditional waivers for other states.
Implementation
Setup: Google Docs Templates
Template 1: Generic Conditional Waiver (Non-Statutory States)
Create a Google Doc with the following content and merge fields:
CONDITIONAL WAIVER AND RELEASE ON PROGRESS PAYMENT
Project: {{project_name}}
Job Location: {{project_address}}
Owner: {{owner_name}}
Through Date: {{billing_period_end}}
On receipt of payment in the sum of ${{invoice_amount}}, the undersigned waives and releases any mechanic's lien, stop payment notice, or bond right claims for labor, services, equipment, or material furnished to the above-referenced project through the date shown above.
This waiver and release is CONDITIONED on receipt of payment. If the maker of the payment fails to issue a check, or if the check is dishonored, this waiver and release shall be null and void.
Claimant: {{contractor_name}}
Claimant Address: {{contractor_address}}
Date: {{current_date}}
Signature: _________________________
Title: _________________________Template 2: California Statutory Form (Civil Code § 8132)
Use exact statutory language from California Civil Code Section 8132.
Template 3: Texas Statutory Form
Use exact statutory language from Texas Property Code Chapter 53.
Template 4: Florida Statutory Form
Use Florida Statute § 713.20 language.
Additional templates required for: AZ (A.R.S. § 33-1008), GA, MI, MO, MS, NV, UT, WI, WY.
Make.com Sub-Scenario: 'Generate Lien Waiver'
Module 1: Data Store Lookup — State Template Map
- Data Store: 'lien-waiver-templates'
- Key: {{state_code}}
- Returns: google_doc_template_id, requires_notarization (boolean)
Module 2: Google Docs — Create Document from Template
# Google Docs CreateDocumentFromTemplate
Type: googledocs/CreateDocumentFromTemplate
Template Document ID: {{1.google_doc_template_id}}
New Document Title: CONCAT('Conditional_Lien_Waiver_', {{project_id}}, '_', {{milestone_id}}, '_', {{formatDate(now, 'YYYY-MM-DD')}})
Save to Folder: [Google Drive folder ID for staging]
Merge Fields:
project_name: {{project_name}}
project_address: {{project_address}}
owner_name: {{owner_name}}
billing_period_end: {{formatDate(completed_date, 'MMMM DD, YYYY')}}
invoice_amount: {{formatNumber(net_invoice_amount, 2)}}
contractor_name: {{contractor_name}}
contractor_address: {{contractor_address}}
current_date: {{formatDate(now, 'MMMM DD, YYYY')}}Module 3: Google Drive — Download File as PDF
Type: googledrive/DownloadFile
File ID: {{2.documentId}}
Format: PDFModule 4: SharePoint — Upload PDF
Type: microsoft365/UploadFile
Site: [Client SharePoint site]
Path: /Projects/{{project_id}}/Lien Waivers/
Filename: {{2.title}}.pdf
Content: {{3.data}}Module 5: Return PDF Data
Return the PDF binary data and SharePoint URL for attachment to the notification email in the parent scenario.
Data Store Schema: 'lien-waiver-templates'
- Key: state_code (string, 2-letter)
- google_doc_template_id (string): Google Doc ID for that state's form
- form_type (string): 'statutory' or 'generic'
- requires_notarization (boolean): true for MS, WY
- notes (string): Any state-specific instructions
Populate the data store for each state where the client operates. Default fallback to the generic template if state_code is not found in the data store.
Invoice Audit & Reconciliation Dashboard
Type: workflow
A secondary Make.com scenario that runs weekly (or on-demand) to reconcile the automation's invoice log against QBO's actual invoice data. Detects discrepancies, identifies draft invoices that haven't been sent within the expected timeframe, and generates a summary report for the bookkeeper and MSP.
Implementation:
## Module 1: Scheduler
- Type: flow/Scheduler
- Run: Weekly, Monday 08:00
## Module 2: Data Store - Get All Records from Last 7 Days
- Type: datastore/SearchRecords
- Data Store: 'invoice-audit-log'
- Filter: timestamp >= {{addDays(now, -7)}}
- Returns: Array of all logged invoices from past week
## Module 3: Iterator - For Each Logged Invoice
- Type: flow/Iterator
- Source: {{2.records}}
## Module 4: QBO - Get Invoice by ID
- Type: quickbooks/GetInvoice
- Invoice ID: {{3.qbo_invoice_id}}
- Returns: QBO invoice record with current status, amount, etc.
## Module 5: Set Variable - Compare & Flag Issues
- Type: tools/SetVariable
- Variables:
- amount_match: {{3.net_invoice_amount}} == {{4.TotalAmt}} ? 'OK' : 'MISMATCH'
- status: {{4.EmailStatus}} (Sent, NotSent, etc.)
- days_since_created: dateDiff({{3.timestamp}}, now, 'days')
- is_stale: {{days_since_created}} > 2 AND {{status}} == 'NotSent' ? true : false
- flag: IF(amount_match != 'OK', 'AMOUNT_MISMATCH',
IF(is_stale, 'STALE_DRAFT', 'OK'))
## Module 6: Filter - Only Flagged Items
- Condition: {{5.flag}} != 'OK'
## Module 7: Array Aggregator
- Collect all flagged items into a summary array
## Module 8: Email - Send Reconciliation Report
- Type: microsoft365/SendEmail
- To: [bookkeeper_email], [msp_monitoring_email]
- Subject: CONCAT('Weekly Invoice Reconciliation Report - ', formatDate(now, 'MMM DD, YYYY'))
- Body (HTML):
<h2>Invoice Automation - Weekly Reconciliation</h2>
<p>Period: {{formatDate(addDays(now, -7), 'MMM DD')}} - {{formatDate(now, 'MMM DD, YYYY')}}</p>
<p>Total Invoices Generated: {{length(2.records)}}</p>
<p>Issues Found: {{length(7.array)}}</p>
IF issues found:
<table border='1'>
<tr><th>Invoice #</th><th>Project</th><th>Issue</th><th>Expected</th><th>Actual</th></tr>
FOR EACH flagged item:
<tr>
<td>{{item.qbo_doc_number}}</td>
<td>{{item.project_name}}</td>
<td>{{item.flag}}</td>
<td>${{item.expected_amount}}</td>
<td>${{item.actual_amount}}</td>
</tr>
</table>
IF no issues: <p style='color:green'>✓ All invoices reconciled successfully.</p>
## Module 9: Data Store - Update Reconciliation Log
- Record reconciliation run timestamp and resultsError Handling: If QBO API returns 404 for an invoice (deleted), flag as 'INVOICE_DELETED'. If QBO API is unreachable, retry 3x then send alert email to MSP.
Testing & Validation
Client Handoff
The client handoff should be structured as a half-day (4-hour) session with two audiences: office staff (bookkeeper, office manager, owner) and field staff (project managers, superintendents). Cover the following topics:
For Office Staff (2.5 hours)
For Field Staff (1.5 hours)
Documentation to Leave Behind
- Quick Reference Card (laminated, for each desk/tablet): Step-by-step for marking milestones complete and reviewing draft invoices
- Full Process Documentation (PDF + SharePoint): Detailed guide with screenshots for every step
- Retainage Rules Reference: Table showing each active project's retainage terms and the state law that applies
- Error Handling Playbook: What to do for each type of automation failure
- Contact Card: MSP helpdesk phone, email, portal URL, and SLA response times
- Make.com Admin Guide: How to access the automation dashboard, view execution logs, and pause/resume scenarios (for the designated client admin only)
Success Criteria to Review Together
Maintenance
Ongoing MSP Responsibilities:
Weekly (30 minutes):
- Review Make.com scenario execution logs for errors or warnings
- Check the invoice-error-log data store for any new entries
- Review the automated weekly reconciliation report
- Verify webhook connectivity (check last successful trigger timestamp)
Monthly (1-2 hours):
- Review Make.com operations usage against plan limits (Pro plan: 10,000 ops)
- Verify QBO OAuth token is still valid (tokens expire; refresh tokens are used automatically but can fail)
- Review and rotate any API keys if security policy requires it
- Check for PM platform or QBO updates that may affect API compatibility
- Add retainage rules for any new projects started during the month
- Review client's invoice accuracy metrics and address any recurring issues
Quarterly (2-4 hours):
- Comprehensive system health review with the client bookkeeper
- Update state retainage rules if any legislative changes occurred
- Update lien waiver templates if state forms have been revised
- Review and optimize Make.com scenarios for performance (check execution times, consolidate modules if possible)
- Assess whether additional automation opportunities exist (e.g., automated payment reminders, AR aging alerts)
- Update documentation with any process changes
Annually:
- Full platform version review — check for major updates to Knowify/Buildertrend/Procore, QBO, and Make.com
- Renew software subscriptions and renegotiate pricing if possible
- Re-validate AIA form compliance (AIA periodically updates form versions)
- Review field tablet hardware — replace batteries or devices if degraded
- Re-train any new staff members
SLA Considerations:
- Target 4-hour response time for automation failures during business hours (invoice generation is time-sensitive due to Prompt Payment Act deadlines)
- Target 1-business-day resolution for non-critical issues (formatting, notification delivery)
- Target same-business-day resolution for critical issues (invoices not generating, wrong amounts)
- Provide after-hours emergency contact for month-end billing periods (contractors often do heavy billing on the last 2-3 days of the month)
Escalation Path:
Monitoring Alerts (configure in Make.com):
- Scenario execution failure → immediate email to MSP monitoring inbox
- Scenario execution time > 5 minutes → warning alert
- Operations usage > 80% of monthly limit → alert to MSP for plan upgrade consideration
- No scenario executions for 5+ business days → alert (may indicate webhook disconnection or no milestones being completed, which should be verified with client)
Alternatives
Zapier-Based Implementation (Instead of Make.com)
Replace Make.com with Zapier as the automation middleware. Zapier has pre-built connectors for Procore, QuickBooks Online, and many construction platforms. The workflow is built using Zapier's Zap editor with multi-step Zaps, Paths for conditional logic, and Formatter actions for calculations.
Microsoft Power Automate Implementation
Use Microsoft Power Automate as the middleware instead of Make.com. This is ideal when the client is already invested in the Microsoft 365 ecosystem (SharePoint, Teams, Outlook). Power Automate's premium connectors include QuickBooks Online and can connect to Procore/Knowify via custom HTTP connectors.
Native PM Platform Billing (No Middleware)
Skip the external automation layer entirely and use the construction PM platform's built-in billing features. Knowify, Buildertrend, and Procore all have native progress invoicing and QBO sync capabilities. The workflow becomes: PM marks milestone complete → uses the platform's billing module to generate the invoice → native sync pushes to QBO.
Procore + Sage Intacct Enterprise Stack
For large general contractors ($20M+ annual revenue), replace the Knowify/QBO stack with Procore for project management and Sage Intacct Construction for accounting. Both platforms have native integration capabilities and enterprise-grade features for multi-entity, multi-project progress billing.
Custom API Integration (Node.js/Python)
Instead of using a no-code/low-code middleware like Make.com, build a custom integration application using Node.js or Python that directly interfaces with the PM platform API and QBO API. Host on a small cloud VM (AWS EC2 or Azure VM) or serverless functions (AWS Lambda / Azure Functions).
Want early access to the full toolkit?