Vendor Cost Tracking
Use the Balance API to build a verifiable, tamper-evident record of your infrastructure costs. Automate vendor bill ingestion, compare against internal metrics, and generate verifiable proofs of every dollar spent.
Vendor Cost Tracking with PacSpace
Turn your infrastructure spend into a verifiable audit trail. Every cost event becomes a permanently recorded delta — tamper-evident, independently verifiable, and immutable.
Why Track Vendor Costs with PacSpace?
Traditional cost tracking stores numbers in spreadsheets or dashboards that can be silently modified. The Balance API gives you something different:
- Tamper-evident records — every cost delta is permanently recorded on the verification layer. No one can quietly edit a historical cost entry.
- Vendor bill verification — compare what your vendors charge against what your systems actually consumed. Discrepancies are permanently recorded.
- Audit-ready proofs — generate verifiable receipts per vendor per period. Board-ready, auditor-ready, regulator-ready.
- Real-time visibility — customer ledgers give you a live view of cumulative spend per vendor, updated as deltas verify.
Use cases:
- Startups reporting COGS to investors
- Enterprises auditing cloud spend across teams
- Regulated industries requiring verifiable cost records
- Any company that wants to prove their infrastructure costs are accurate
Step 1: Design Your Customer ID Schema
Each vendor or service gets a unique customerId. This creates an isolated ledger per cost center.
Naming Convention
Use {vendor}-{service} format, lowercase and hyphen-separated:
gcp-cloudrun-api # GCP Cloud Run — API service
gcp-cloudsql # GCP Cloud SQL database
stripe # Stripe processing fees
sendgrid # SendGrid email delivery
aws-s3 # AWS S3 storage
datadog # Datadog monitoring
Granularity Decision
Choose the right level of detail for your needs:
| Approach | Example | Best For |
|---|---|---|
| Per service | gcp-cloudrun-api, gcp-cloudrun-worker | Detailed cost attribution |
| Per vendor | gcp, stripe, sendgrid | Simple cost tracking |
| Per category | compute, data, comms | High-level COGS reporting |
You can always start coarse and add granularity later — each new customerId automatically creates a new ledger.
Step 2: Set Up Automated Ingestion
Build a script or service that pulls billing data from each vendor and emits deltas via the SDK.
Install the SDK
npm install @pacspace/sdk
Initialize the Client
import { PacSpace } from '@pacspace/sdk';
const pac = new PacSpace({
apiKey: process.env.PACSPACE_API_KEY,
});
Step 3: Emit Deltas for Each Cost Event
Cloud Provider Billing (GCP BigQuery Export)
import { BigQuery } from '@google-cloud/bigquery';
const bigquery = new BigQuery();
async function ingestGcpCosts(date: string) {
const [rows] = await bigquery.query({
query: `
SELECT service.description, SUM(cost) AS cost
FROM \`my-project.billing_export.gcp_billing\`
WHERE DATE(usage_start_time) = '${date}'
GROUP BY service.description
`,
});
for (const row of rows) {
const customerId = mapServiceToCustomerId(row.description);
await pac.balance.emit(customerId, -row.cost, 'gcp_daily_cost', {
referenceId: `gcp:${customerId}:${date}`,
metadata: {
date,
vendorReported: {
cost: row.cost,
source: 'gcp_billing_export',
service: row.description,
},
},
});
}
}
Payment Processor (Stripe)
import Stripe from 'stripe';
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);
async function ingestStripeFees(date: string) {
const dayStart = Math.floor(new Date(`${date}T00:00:00Z`).getTime() / 1000);
const dayEnd = dayStart + 86400;
let totalFees = 0;
for await (const txn of stripe.balanceTransactions.list({
created: { gte: dayStart, lt: dayEnd },
})) {
totalFees += txn.fee / 100; // cents → dollars
}
if (totalFees > 0) {
await pac.balance.emit('stripe', -totalFees, 'stripe_processing_fee', {
referenceId: `stripe:daily:${date}`,
metadata: {
date,
vendorReported: { cost: totalFees, source: 'stripe_balance_transactions' },
},
});
}
}
SaaS Subscriptions (Fixed Monthly Cost)
// For vendors with fixed monthly pricing (SendGrid, Datadog, etc.)
async function emitMonthlyCost(
customerId: string,
monthlyCost: number,
period: string, // '2026-02'
vendorName: string,
) {
await pac.balance.emit(customerId, -monthlyCost, `${vendorName}_monthly`, {
referenceId: `${customerId}:${period}`,
metadata: {
period,
vendorReported: {
cost: monthlyCost,
source: 'manual_plan_cost',
currency: 'USD',
},
},
});
}
// Examples
await emitMonthlyCost('sendgrid', 19.95, '2026-02', 'sendgrid');
await emitMonthlyCost('datadog', 249.00, '2026-02', 'datadog');
Batch Emit for Multiple Services
When you have many cost lines (e.g., 13 GCP services), use batch emit:
const deltas = gcpServices.map(svc => ({
customerId: svc.customerId,
delta: -svc.cost,
reason: 'gcp_daily_cost',
referenceId: `gcp:${svc.customerId}:${date}`,
metadata: { date, vendorReported: { cost: svc.cost } },
}));
const result = await pac.balance.emitBatch(deltas);
console.log(`Queued: ${result.totalQueued}, Failed: ${result.totalFailed}`);
Step 4: Enrich with Internal Metrics (Trust but Verify)
For maximum value, include your own usage measurements alongside vendor-reported costs:
await pac.balance.emit('gcp-cloudrun-api', -4.23, 'gcp_daily_cost', {
metadata: {
vendorReported: {
cost: 4.23,
source: 'gcp_billing_export',
usage_amount: 1440,
usage_unit: 'vCPU-minutes',
},
internalMeasured: {
requestCount: 12847,
cpuMinutes: 1440,
source: 'cloud_monitoring_api',
},
aligned: true,
discrepancyNote: null,
},
});
When vendor and internal measurements diverge:
{
aligned: false,
discrepancyNote: 'Vendor reported 1500 vCPU-minutes but Cloud Monitoring recorded 1440 (4% diff)',
}
These discrepancies are permanently anchored — creating an immutable audit trail for vendor disputes.
Step 5: Monthly Reconciliation
At month-end, run the full reconciliation cycle:
const vendors = ['gcp-cloudrun-api', 'gcp-cloudsql', 'stripe', 'sendgrid', ...];
for (const vendorId of vendors) {
// 1. Checkpoint — lock the period summary
const checkpoint = await pac.balance.checkpoint(vendorId, { period: '2026-02' });
console.log(`${vendorId}: proof root ${checkpoint.merkleRoot}`);
// 2. Derive — compute the total balance
const derived = await pac.balance.derive(vendorId);
console.log(`${vendorId}: balance $${derived.computedBalance}`);
// 3. Receipt — generate audit-ready proof
const proof = await pac.balance.receipt(vendorId, { period: '2026-02' });
console.log(`${vendorId}: proof root ${proof.proofRoot}`);
// 4. Compare — verify against actual invoice
const report = await pac.balance.compare(vendorId, {
yours: derived.computedBalance,
theirs: actualInvoiceAmount,
});
if (!report.matchesTheirs) {
console.warn(`DISCREPANCY: ${vendorId} — our records show $${derived.computedBalance} but invoice says $${actualInvoiceAmount}`);
}
}
Step 6: Build a COGS Dashboard
Use the Customer Ledgers list endpoint to build a real-time cost dashboard:
// Get all vendor ledgers
const ledgers = await pac.balance.customers();
// Get aggregate summary
const summary = await pac.balance.customersSummary();
console.log(`Total COGS: $${Math.abs(summary.totalBalance)}`);
console.log(`Vendors tracked: ${summary.ledgerCount}`);
console.log(`Total cost events: ${summary.totalDeltas}`);
Or use the built-in Customer Ledgers page in the PacSpace dashboard for an instant visual overview.
Automation Schedule
| Cadence | Sources | What Runs |
|---|---|---|
| Daily | Cloud provider billing, Stripe fees | Pull yesterday's costs, emit deltas |
| Monthly | SaaS subscriptions, GitHub, SendGrid | Emit fixed costs, run reconciliation |
Deploy with Cloud Scheduler, AWS EventBridge, or any cron-like service:
# Daily at 6 AM
0 6 * * * node dogfood/index.ts --mode=daily
# Monthly on the 1st at 8 AM
0 8 1 * * node dogfood/index.ts --mode=monthly
What You Get
After setup, you have:
- Per-vendor ledgers — isolated cost history for every service you pay for
- Verifiable proofs — proof roots permanently recorded for each period
- Discrepancy detection — automatic flagging when vendor bills don't match your measurements
- Audit trail — every cost event is immutable and independently verifiable
- Real-time dashboard — live COGS visibility via Customer Ledgers
This is the same system PacSpace uses internally to track its own infrastructure costs — battle-tested on real production data.