We've been using Consensus for about eight months to track SaaS spend across the engineering org. The core platform is solid for aggregation and categorization, but we hit a wall when it came time to actually negotiate renewals. Flipping between the Consensus dashboard, a spreadsheet of our negotiation targets, a PDF of the current contract, and email threads was a mess. It was clear we needed a single source of truth for each deal.
So we built our own internal "Deal Room" as a lightweight web app that sits on top of Consensus's API. The goal was simple: pull all the data for a specific vendor into one view, add our internal context, and track the negotiation progress in a structured way. It's not a replacement for Consensus; it's a force multiplier that uses its data as the foundation.
Here's the core architecture:
- **Backend:** A simple Go service that acts as a proxy to the Consensus API. It fetches enriched data (invoices, usage trends, cost drivers) for a given vendor ID.
- **Frontend:** A React app that displays this data in three panes: Consensus facts, our internal notes/targets, and a timeline of negotiation events.
- **Data Layer:** We add a PostgreSQL table to store our proprietary fields that Consensus doesn't cover. This includes things like our target discount percentage, the stakeholder responsible for the relationship, internal approval status, and notes from calls with the vendor's sales team.
The key integration is the vendor ID from Consensus. Once we have that, we can pull everything. A snippet of our Go service's main fetch function looks like this:
```go
func fetchDealRoomData(vendorID string) (*DealRoomView, error) {
// Fetch core spend data from Consensus
consensusData, err := consensusClient.GetVendorSpend(vendorID, "last_12_months")
if err != nil {
return nil, err
}
// Fetch our internal negotiation context from our DB
internalContext, err := db.GetNegotiationContext(vendorID)
if err != nil {
return nil, err
}
// Merge and return a unified view
view := &DealRoomView{
VendorName: consensusData.VendorName,
AnnualSpend: consensusData.TotalAnnualized,
UsageTrend: consensusData.UsageTrend,
KeyDrivers: consensusData.CostDrivers,
OurTargetRate: internalContext.TargetDiscount,
Owner: internalContext.Owner,
TimelineEvents: internalContext.Events,
}
return view, nil
}
```
What this lets us do:
- See the cold, hard facts from Consensus (spend is up 30% due to seat count increase) right next to our internal note ("Sales rep agreed to grandfather existing seats at old rate").
- Track every communication in the timeline, logging emails, calls, and concessions.
- Attach future invoices or quotes from the vendor directly to the deal room for comparison against Consensus's forecasts.
The pain point this solved was context switching and losing institutional knowledge. Before, when a renewal was due, someone had to dig through old emails and spreadsheets. Now, we just open the deal room for that vendor. The Consensus data provides the undeniable leverage; our added layer provides the strategy and history.
The build took about two developer-weeks. The ongoing value, especially during Q4 renewal chaos, has been massive. It turns Consensus from a reporting tool into an active negotiation platform. If you're using Consensus at scale and have more than a handful of major vendors, I highly recommend considering a similar custom layer. The API is robust enough to support it.
---
Been there, migrated that
Nice approach. This is exactly the kind of value-add layer that mature platforms often lack. We see a lot of teams just accepting the friction between visibility tools and the actual negotiation process.
How are you handling permissions and audit trails for the internal notes and targets you're adding? That's usually the next hurdle when a tool like this moves from a small pilot to wider procurement use.
I'd also be curious if any other Consensus users have built similar bridges. It feels like a common pain point.
Keep it real, keep it kind.