Skip to content

Receipts & Verification — Prove Every Line Item

Generate receipts with verifiable proof so your customers can independently confirm every charge.

When you bill a customer, they have to trust your numbers. With PacSpace, every charge is independently verifiable. Your receipt becomes a proof, not a claim.


The Pattern

The receipt-and-verification workflow uses four Balance API endpoints you already know:

  1. Record deltas as usage occurs → POST /api/v1/balance/delta
  2. Lock the periodPOST /api/v1/balance/checkpoint
  3. Generate the receiptGET /api/v1/balance/receipt/:customerId
  4. Embed verification data in your invoice (proof root + link to GET /api/v1/verify/:proofRoot)
  5. Customer verifies independently → public GET /api/v1/verify/:proofRoot (no auth) or your endpoint backed by Derive / Compare

PacSpace is invisible to your customer. They interact only with you. The proof makes the numbers neutral — no third-party arbitrator needed.


Step 1: Record Deltas Throughout the Period

Every time a billable event occurs — an API call, a compute cycle, an operation — record it as a delta. Include metadata so you can trace each charge back to a line item later.

SDK (TypeScript)

typescript
import { PacSpace } from '@pacspace-io/sdk';

const pac = new PacSpace({ apiKey: process.env.PACSPACE_API_KEY });

// Record each billable event as it happens
await pac.balance.emit({
  customerId: 'cust_acme_001',
  delta: -150,                          // negative = charge
  reason: 'api_call',
  referenceId: 'inv_2026_02_item_001',  // your internal line item ID
});

cURL

bash
curl -X POST https://balance-api.pacspace.io/api/v1/balance/delta \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "customerId": "cust_acme_001",
    "delta": -150,
    "reason": "api_call",
    "referenceId": "inv_2026_02_item_001"
  }'

Each delta is fingerprinted and permanently recorded. Once verified, it cannot be altered or deleted.


Step 2: Lock the Period

At the end of the period, commit a checkpoint. This locks a proof root — a single fingerprint covering every verified delta in the period.

SDK (TypeScript)

typescript
const checkpoint = await pac.balance.checkpoint('cust_acme_001', {
  period: '2026-02',
});

// Store this proof root — it goes on the invoice
console.log(checkpoint.merkleRoot); // "0x7f3a9b2c..."

cURL

bash
curl -X POST https://balance-api.pacspace.io/api/v1/balance/checkpoint \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "customerId": "cust_acme_001",
    "period": "2026-02"
  }'

Response:

json
{
  "success": true,
  "data": {
    "checkpointId": "chk_abc123def456",
    "period": "2026-02",
    "merkleRoot": "0x7f3a9b2c...",
    "deltaCount": 42,
    "status": "QUEUED"
  }
}

The merkleRoot (proof root) is the single value your customer needs to verify the entire period.


Step 3: Generate the Receipt

Pull the receipt for the period. This returns all verified deltas, window summaries, and the proof root — everything you need to build the invoice.

SDK (TypeScript)

typescript
// First checkpoint the period, then fetch the receipt
const checkpoint = await pac.balance.checkpoint('cust_acme_001', { period: '2026-02' });
const receipt = await pac.balance.receipt('cust_acme_001', { period: '2026-02' });

console.log(receipt.verification.proofRoot ?? checkpoint.merkleRoot);  // Include in your invoice
console.log(receipt.finalBalance);   // The verified ending balance
console.log(receipt.deltasCount);    // Number of verified deltas

cURL

bash
curl https://balance-api.pacspace.io/api/v1/balance/receipt/cust_acme_001?period=2026-02 \
  -H "X-Api-Key: YOUR_API_KEY"

Response:

json
{
  "success": true,
  "data": {
    "customerId": "cust_acme_001",
    "period": "2026-02",
    "proofRoot": "0x7f3a9b2c...",
    "deltaCount": 42,
    "startingBalance": 0,
    "finalBalance": -6300,
    "windowSummary": {
      "window": "2026-02",
      "deltasCount": 42,
      "netDelta": -6300
    },
    "deltas": [
      {
        "delta": -150,
        "reason": "api_call",
        "referenceId": "inv_2026_02_item_001",
        "status": "verified",
        "time": "2026-02-01T10:00:00.000Z"
      }
    ],
    "verification": {
      "proofRoot": "0x7f3a9b2c...",
      "verifyUrl": "https://balance-api.pacspace.io/api/v1/verify/0x7f3a9b2c..."
    }
  }
}

Step 4: Embed Verification in Your Invoice

Include the proof root and a verification link in your invoice. The link can point directly to GET /api/v1/verify/:proofRoot — no authentication required. Your customer doesn't need to know how the verification works; they just need the proof root or link to check.

Example Invoice

============================================================
  INVOICE #INV-2026-02-ACME
============================================================
  Customer:           Acme Corp (cust_acme_001)
  Period:             February 2026
------------------------------------------------------------
  LINE ITEMS
    42 API calls             -$6,300.00
------------------------------------------------------------
  Starting Balance:          $0.00
  Ending Balance:           -$6,300.00
  Amount Due:                $6,300.00
------------------------------------------------------------
  VERIFICATION
  Proof root:   0x7f3a9b2c...
  Verify at:    https://balance-api.pacspace.io/api/v1/verify/0x7f3a9b2c...
  42 verified deltas covering this period
============================================================

The proof root is a single fingerprint over every delta in the period. If even one delta were changed, the proof root would be completely different.


Step 5: Customer Verifies Independently

Your customer can verify in two ways:

Option A: Public verification (recommended) — Share the proof root or a direct link: https://balance-api.pacspace.io/api/v1/verify/0x7f3a9b2c.... No API key, no account. The proof root is the access key. See Verify — Proof Root & Compare.

Option B: Your custom endpoint — If you need to combine verification with your own data (e.g., starting balance from a previous period), build an endpoint that uses derive or compare and returns your preferred format. PacSpace stays invisible.

typescript
// Your server — optional custom verification
app.get('/verify/:proofRoot', (req, res) => {
  // Redirect to PacSpace's public verify endpoint
  res.redirect(`https://balance-api.pacspace.io/api/v1/verify/${req.params.proofRoot}`);
});

The public GET /api/v1/verify/:proofRoot returns verified, summary, records, and verification.publicLedgerUrl — enough for full independent verification. No trust required.


Step 6: Handle Disputes

When a customer disagrees with an invoice, use Compare to resolve it mathematically:

typescript
app.post('/dispute/:customerId/:period', async (req, res) => {
  const { customerId, period } = req.params;
  const { claimedBalance } = req.body; // What the customer thinks is correct

  // Pull the verified balance
  const invoice = await db.invoices.findByPeriod(customerId, period);

  const comparison = await pac.balance.compare({
    customerId,
    yourBalance: invoice.endingBalance,    // What you invoiced
    theirBalance: claimedBalance,          // What they claim
  });

  res.json({
    invoicedBalance: invoice.endingBalance,
    claimedBalance,
    verifiedBalance: comparison.computedBalance,
    matchesInvoice: comparison.matchesYours,
    matchesClaim: comparison.matchesTheirs,
    discrepancy: comparison.discrepancy,
    resolution: comparison.discrepancy?.resolution,
  });
});

The math resolves the dispute. If your invoice matches the verified record, it's provably correct. If neither matches, the comparison shows exactly where the numbers diverge.


Three Verification Tiers

Not every customer will verify every invoice. That's fine — the system supports a spectrum of trust:

Tier 1: Receipt Only (Most Common)

The customer sees the proof root on the invoice and pays. No friction. PacSpace is invisible. This is how most invoices work — the proof is there if they ever need it.

Tier 2: Proof Root Match

The customer compares the proof root on their current invoice to the one from the previous period. If they match the expected chain, the historical record is intact. Simple spot-checking.

Tier 3: Full Independent Derivation

The customer calls your verification endpoint and independently recomputes the balance from the verified record. This is the gold standard — complete mathematical verification without trusting anyone.


Why This Works

PacSpace is invisible infrastructure. Your customer never interacts with PacSpace directly — they interact with you. The verification endpoint is your URL, returning your data.

What makes it trustworthy is that the underlying data is fingerprinted and permanently recorded. Neither you nor your customer can alter a verified delta after the fact. The proof root is deterministic — anyone recomputing it from the same deltas will get the same value.

This means:

  • You can prove your invoices are accurate
  • Your customer can verify independently without trusting you
  • Neither party needs to trust PacSpace — the math is independently reproducible

Next Steps