A pursuit platform that scores public work before the team spends money chasing it
We built a pursuit platform for a client's construction team. It pulls public opportunities from federal sources, scores each one against what the firm actually builds, and tracks who else is bidding.
Public-sector construction work is posted in public, but that does not make it easy to find. Opportunities are spread across federal systems, each with its own search, its own data shapes, and its own rate limits. A construction team that wants this work either pays someone to watch the feeds or loses hours a week scrolling notices that mostly do not fit.
The business development team at a commercial real estate developer's construction arm asked for five things: pull opportunities from the federal sources, match them against what the firm actually builds, give each one a bid or no-bid call with the compliance details, show who has won similar work before, and run it all as a pipeline with alerts.
What we built
A Next.js app on Supabase and Vercel, with a full mobile layout so it works from a phone on a job site.
Aggregation. Live connectors for SAM.gov, USAspending, and Grants.gov, synced daily. Grants are an early signal: the recipient usually issues the construction contract months later, so tracking grants is a way to be early instead of competing on the open notice.
Fit scoring. Every opportunity gets a 0 to 100 score across seven weighted dimensions: NAICS alignment, scope match, geography (the firm's home market scores above the rest of its region), project value, set-aside eligibility, timeline, and procurement stage. Hard disqualifiers, like a set-aside the firm cannot pursue or a passed deadline, force a no-bid. Softer ones cap the call at "consider."
Compliance extraction. Bonding, licensing, experience minimums, site visits, required forms, and wage determinations, pulled from the notice text into a checklist. Where a solicitation has attachments, the app downloads the PDFs and extracts Sections L and M, the instructions and evaluation criteria.
Historical intelligence. For each opportunity: the likely incumbent, top competitors with award totals, agency spend by fiscal year, and specialty-trade subcontractors, all from live USAspending data.
Pipeline and alerts. Nine stages with drag and drop, plus alerts on new matches, amendments, deadline changes, new attachments, site visits, and recompetes. Optional Claude analysis writes a capture brief per opportunity. A map plots every opportunity as a pin colored by fit, with radius search for prospecting.
Scenarios. Scoring profiles can be cloned and compared, so the team can ask what changes if it pursues work with a certified small-business partner. Under one teaming scenario, 14 opportunities moved from no-bid to pursuable.
The competitor database
Early on, competitors were assembled on the fly from intelligence attached to each opportunity, and the same firm showed up twice: once with its federal unique entity ID and once without. A smarter dedupe key would not fix that. Competitors needed to be their own table.
Now every competitor is a row keyed on its federal entity ID and linked to every pursuit it appears on. Before seeding, every name-only firm was resolved to a real ID: 51 of 51, no failures. Each record carries location, federal volume, agencies and NAICS codes worked, and socioeconomic certifications as indexed fields. "Who near us can prime the work we cannot" is now a database query, which turns a teaming shortlist into a data question instead of a round of phone calls. A daily job keeps the records current.
Then we checked the certifications against the source. The app had been reading small-business program status from whatever a firm claimed on its last federal award, which carries no dates. Pulling official certification records from the SBA's free API showed that of 11 competitors flagged as holding one key certification, six had already lost it, some of them years earlier. The app had been crediting firms with status they no longer held. Exit dates now refresh daily, and firms close to losing a certification are flagged.
The fixes that came from one client call
The most useful spec came from a call with the firm's federal contracting partner. Their point: a sources sought notice is the only window where a firm can help shape a requirement. Once a solicitation posts, the scope is fixed, the field is open, and pursuing it costs real money.
The data was already in the database. The product was burying it three ways. There was no filter by notice type. Scoring ranked early-stage notices backwards, giving a posted solicitation full stage points and a sources sought half, so none of the 123 early-stage notices ever scored 70 or higher. And alerts were gated on score, so most of them never fired.
We added a capture posture setting that inverts the stage ranking, a "shapeable window" filter and dashboard tile, an alert type that bypasses the score gate, and a re-score endpoint (there had been none, so model changes never reached stored records). After re-scoring 562 records, early-stage notices went from zero in the top 25 to eight. We also told the team plainly that procurement stage is only 6 points of 100, so the filter does most of the work, and exposed the weight so they can raise it.
The same call surfaced Section L and M extraction, and the answer on the call was that automating it would need dedicated hardware. It did not. The pipeline already worked in the cloud, and nothing in the interface called it. We added the card, a manual upload fallback, and detection rules for commercial-item solicitations that never print section letters. Section L detection went from 0 of 4 real notices to 4 of 4.
What the data taught us
- Measure a rate limit, do not read it. SAM.gov's documented limit, the limit the team expected, and the limit we actually hit were three different numbers. The sync now reads the lockout time from the error, stores it, and skips SAM until then, instead of spending requests to discover it is still locked.
- A score that saturates is useless. The first scoring pass gave six of fourteen test opportunities a perfect 100. Diminishing returns on each extra keyword match fixed the spread.
- A recommendation cannot contradict its own findings. An early version said "bid" on a job it had flagged as below the firm's minimum size. Nobody trusts a tool after that, so hard disqualifiers now override the score.
- A link that returns 200 can still be broken. Legislative funding links pointed at a page shell with none of the document in it. They now point at the actual PDF, with the machine-readable copy kept as a secondary link.
What other operators can take from this
A scoring model is only useful if the team believes it, and they only believe it if it explains itself and never contradicts itself. Build the explanation in from day one, check your data against the official source, and let the people who chase the work tell you which stage matters.
If your business development team is still scrolling notices by hand, book a Systems Audit.
Filed by
John McIntosh
Founder, Salvus AI
Replacing a loan management platform with a tracker that reads the loan documents
A client was pricing an off-the-shelf loan management platform for document imaging and deadline tracking. We built that part instead. Here is how it reads a closing binder, and the part we told them not to build.
Preconstruction software built on the firm's own job history
A client's construction team sat through a preconstruction software demo and decided to build instead. Here is what we built from their real estimates, and the rules that keep AI out of the bid totals.
Talk to us
Want this kind of work shipped for you?
Salvus AI deploys per-client isolated MCP servers and the automations that run on them. Client success with real numbers, no shared tenancy.