TypeScript SDK
Install and use the official PacSpace SDK for TypeScript and Node.js.
The TypeScript SDK wraps the Balance API in a typed Node.js client.
Use it to record usage, derive balances, compare views, create checkpoints, fetch receipts, and verify webhook signatures.
Install
npm install @pacspace-io/sdk
Requires Node.js 18 or later.
Create A Client
import { PacSpace } from '@pacspace-io/sdk';
const pac = new PacSpace({
apiKey: process.env.PACSPACE_API_KEY!,
productionUrl: 'https://app.pacspace.io',
});
Use a pk_live_* key for Production. Use a pk_test_* key for Sandbox and pass the Sandbox URL from your PacSpace dashboard.
Record Usage
const delta = await pac.balance.emit('cust_acme', -42.5, 'compute_minutes', {
referenceId: 'usage_2026_05_001',
metadata: {
product: 'inference',
units: 50,
},
});
console.log(delta.recordId);
console.log(delta.receiptId);
console.log(delta.status);
emit() returns immediately. Store recordId for status checks and receiptId for proof lookup.
To wait for a terminal result:
const verified = await pac.balance.emitAndWait(
'cust_acme',
-42.5,
'compute_minutes',
{
timeout: 30_000,
pollInterval: 1_000,
},
);
console.log(verified.status);
Derive A Balance
const balance = await pac.balance.derive('cust_acme', {
period: '2026-05',
});
console.log(balance.computedBalance);
console.log(balance.deltaCount ?? balance.deltasCount);
You can also use helpers for common windows:
await pac.balance.deriveCurrentMonth('cust_acme');
await pac.balance.deriveForPeriod('cust_acme', '2026-05');
await pac.balance.deriveMonthsBack('cust_acme', 3);
await pac.balance.deriveDaysBack('cust_acme', 30);
Compare Two Views
const report = await pac.balance.compare(
'cust_acme',
{
yours: 95000,
theirs: 98000,
},
{
period: '2026-05',
},
);
console.log(report.neutralBalance);
console.log(report.matchesYours);
console.log(report.matchesTheirs);
Compare tells you whether either submitted view matches the balance PacSpace derives from verified deltas.
Checkpoint A Period
const checkpoint = await pac.balance.checkpoint('cust_acme', {
period: '2026-05',
});
console.log(checkpoint.proofRoot);
console.log(checkpoint.deltaCount);
console.log(checkpoint.status);
A checkpoint gives the period a single proof root that can be included with an invoice or close package.
Receipts
For customer-scoped receipt data:
const receipt = await pac.balance.receipt('cust_acme', {
period: '2026-05',
});
console.log(receipt.proofRoot);
console.log(receipt.verifyUrl);
console.log(receipt.verificationApiUrl);
console.log(receipt.verificationExplorerUrl);
verificationExplorerUrl remains a public response field. Keep it if your integration already stores it.
For receipt-document helpers by receipt ID:
const result = await pac.balance.receipts.list('cust_acme', { limit: 10 });
const doc = await pac.balance.receipts.get(result[0].receiptId);
const receiptId = pac.balance.receipts.fromUrl(doc.links.permalink);
const emailBody = pac.balance.receipts.emailBody(doc);
const pdfBytes = await pac.balance.receipts.downloadPdf(receiptId);
console.log(emailBody);
console.log(pdfBytes.byteLength);
Customer Records
Every new customerId passed to emit() creates a customer record.
const { customers } = await pac.balance.customers({
search: 'cust_',
limit: 25,
});
const customer = await pac.balance.customer('cust_acme', {
period: '2026-05',
});
console.log(customers.length);
console.log(customer.computedBalance);
Dashboard customer helpers are also available on pac.customers. They use Dashboard API credentials, not Balance API keys.
Client-Side Submission Helpers
The SDK includes optional client-side helpers for integrations that summarize usage before sending it.
pac.balance.queueSummary({
customerId: 'cust_acme',
delta: -100,
reason: 'daily_usage',
referenceId: 'usage_day_2026_05_27',
});
const result = await pac.balance.flushSummaries();
console.log(result.accepted);
console.log(result.failed);
These helpers run in your application process. They are not required for normal emit() usage.
Webhook Verification
const pac = new PacSpace({
apiKey: process.env.PACSPACE_API_KEY!,
productionUrl: 'https://app.pacspace.io',
webhookSecret: process.env.PACSPACE_WEBHOOK_SECRET,
});
const event = pac.webhooks!.verify(
req.headers['x-pacspace-signature'] as string,
req.headers['x-pacspace-timestamp'] as string,
rawBody,
);
if (event.event === 'delta.verified') {
console.log(event.data.receiptId);
}
SDK helper types may lag newly launched event names. Signature verification works for any valid PacSpace webhook envelope.
Errors
All SDK errors extend PacSpaceError.
import {
PacSpaceError,
RateLimitError,
ValidationError,
} from '@pacspace-io/sdk';
try {
await pac.balance.emit('cust_acme', -100, 'usage');
} catch (err) {
if (err instanceof RateLimitError) {
console.log(`Retry after ${err.retryAfter} seconds`);
} else if (err instanceof ValidationError) {
console.log(err.message);
} else if (err instanceof PacSpaceError) {
console.log(err.code);
}
}
Package Details
| Detail | Value |
|---|---|
| npm package | @pacspace-io/sdk |
| Current docs target | 0.7.0 |
| Runtime | Node.js 18+ |
| License | MIT |