An infrastructure contractor carrying 12 active projects, with pay applications stacking against a controller who reconciled retainage in Excel every cycle. We rebuilt the pay-app desk as a pipeline: LlamaParse on the G702 and G703, Sage 300 CRE and Procore as the systems of record, a cycle the accounting team runs without us.
| App # | Subcontractor | Contract | This period | Retainage | Status |
|---|---|---|---|---|---|
| PA-0742 | Ironbridge Steel | $2,840,000 | $184,200 | $18,420 | posted |
| PA-0743 | Wasatch Concrete | $1,675,000 | $142,800 | $14,280 | posted |
| PA-0744 | Cascade Mechanical | $3,210,000 | $268,540 | $26,854 | waiver |
| PA-0745 | Summit Electric | $1,920,000 | $96,300 | $9,630 | posted |
| PA-0746 | Beacon Glazing | $845,000 | $72,150 | $7,215 | posted |
| PA-0747 | Redrock Earthworks | $2,180,000 | $215,600 | $10,780 | variance |
| PA-0748 | Pioneer Plumbing | $1,340,000 | $118,900 | $11,890 | posted |
| PA-0749 | Highline Drywall | $612,000 | $48,400 | $4,840 | waiver |
At a glance
One controller, 12 projects, the schedule of values as the source of truth. Everything else was implementation detail.
The engagement
The stack
ISO 27001 · ISO 9001 · DPA and NDA signed at kickoff.
Before, the pay-app desk
The desk worked. It worked the way desks work when the SoV lives in Excel, retainage is done by hand, and the owner reviews on a 10-day clock. These were the three patterns we found in discovery.
Subs sent G702 and G703 on the first of the month. The controller checked pieces by hand against the SoV, assembled the consolidated pay app, and walked it to the owner. Owner counsel and owner PM reviewed for another week. Draws hit 35 days from sub submission on a clean cycle.
Pre-build baseline: 10 business days median, 14 days on exception cycles, across the prior fiscal year.
Retainage rules varied by sub: 10% through 50% complete, 5% after, held back on stored materials. The controller kept a rolling workbook per project, manually updated from the G703. When the percent complete changed, the retainage math was reworked by hand.
Pre-build baseline: retainage discrepancies on approximately 8% of pay apps, caught at closeout.
When a sub added a change order mid-project, the G703 carried the new line but the SoV sometimes did not. The controller noticed at closeout, chased the change order paperwork, and reissued. Mid-cycle, the math looked fine; at closeout, it did not.
Pre-build baseline: approximately 14% of projects had a G703-to-SoV line mismatch at final reconciliation.
What we built
The pipeline follows the same five stages we run on every construction engagement. The details below are the ones we actually implemented for this contractor, not a generic template.
Sub email polled on a 15-minute cadence. Procore uploads captured via webhook. Owner portal polled nightly. All normalised to a single pay-app ID per project per cycle.
Document type tagged on ingest. Stamped G702 routed to LandingAI, typed G703 tables routed to AWS Textract, SoV reference pulled from Sage 300 CRE. Below 0.90 confidence, the document holds for AP tagging.
G702 totals, G703 line items with percent complete and stored materials, retainage by line. LlamaParse primary, AWS Textract for the G703 tables, both anchored to the SoV line codes.
G703 lines matched to the SoV. Retainage calculated per sub contract, including the 50% step-down and stored-materials holdback. Below 0.90 confidence, the pay app holds for controller review.
Clean pay apps posted to Sage 300 CRE (AP invoice with job cost dimensions) and Procore (pay-app module). Owner package assembled with source documents attached. Exceptions routed to the controller with the flag in plain English.
After, the numbers the desk signs off
Same controller, same subs, same owners, same AIA forms. The pipeline reconciled the G703 against the SoV and applied the retainage rule per contract. What changed was the cycle, not the accounting team.
The controller still owns the change-order call. She still signs off every pay app before it leaves for the owner. The difference is that on a clean cycle, the G703 reconciles and posts to Sage 300 CRE with retainage calculated per contract. On a bad cycle, she sees one flagged line instead of a workbook.
From the desk
Retainage used to live in a workbook on my desktop. Now it sits inside the approval path, per contract, every cycle.
ControllerInfrastructure contractor, Salt Lake City
Handover
The engagement ends at a clean handover. The accounting team runs the pipeline; Hexaa stays on call for a fixed retention period, then steps back.
Related cases
Each links to a named client, a named document, and the system the clean data lands in. We publish only what the client signed off to publish.
Submittal log reconciliation against the prime contract spec. 1,200 submittals per project, Procore as the system of record.
→Construction · 2026Multi-entity contractor · three-way match on Sage IntacctRetainage-aware three-way match across four entities. 98% auto-match rate, Sage Intacct as the system of record.
→Construction · 2025Regional contractor · COI tracking and renewalAcord 25 certificates read, matched to subs, renewed 45 days before lapse. Zero lapsed COIs since go-live.
→Free 30-minute call
You'll leave with a clear next step.
The G702 carries a total, the G703 continuation sheet carries the line-item math, the SoV carries the contract amounts and the retainage rule. The pipeline compares all three at the line level, applies the retainage rule per contract, and holds the pay app until the totals agree.