Query - Derive A Balance
Derive a customer balance for a scoped window. Defaults to the current UTC month and supports flexible day/month windows.
Use this endpoint to derive a customer balance from verified deltas. If you do not provide scope fields, derive defaults to the current UTC month. You can also derive by period, presets, or custom date ranges.
Endpoint
http
GET https://app.pacspace.io/api/v1/balance/derive/:customerId
Scope Limits
Use the limits endpoint to discover the active backend cap before building scope controls:
http
GET https://app.pacspace.io/api/v1/balance/limits
It returns:
maxScopeMonthsmaxLastNDaysmaxRetentionDays
Query Parameters
Query parameters
| Parameter | Type | Description |
|---|---|---|
startingBalance | number | Starting balance applied before replaying scoped verified deltas. Defaults to 0. |
startingCheckpoint | string | Resume from a prior checkpoint using proofRoot or recordId. |
startingCheckpointType | string | Checkpoint type. Use proofRoot or recordId. |
period | string | Scope a single month in YYYY-MM. |
timePreset | string | Preset scope. Use current_month or custom. |
startDate | string | Custom scope start as ISO 8601. |
endDate | string | Custom scope end as ISO 8601. |
granularity | string | Breakdown granularity: day, week, or month. |
limit | number | Number of rows returned in deltas. Range: 1 to 1000. |
offset | number | Offset for deltas pagination. |
Scope Rules
- Use either checkpoint mode (
startingCheckpoint) or scope mode (period/timePreset/startDate+endDate) in one request. - Combining checkpoint and scope fields returns
400 INVALID_SCOPE_COMBINATION. - Requests beyond the configured scope cap return
400 SCOPE_TOO_WIDE.
SDK Examples
typescript
import { PacSpace } from '@pacspace-io/sdk';
const pac = new PacSpace({ apiKey: process.env.PACSPACE_API_KEY! });
// Default scope: current UTC month
const current = await pac.balance.derive('cust_12345');
// Explicit month scope
const april = await pac.balance.deriveForPeriod('cust_12345', '2026-04');
// Last 12 months helper
const trailing12 = await pac.balance.deriveMonthsBack('cust_12345', 12);
// Custom date window (quick-range chips map to this format)
const trailingWindow = await pac.balance.derive('cust_12345', {
timePreset: 'custom',
startDate: '2026-01-01',
endDate: '2026-03-31',
granularity: 'day',
});
// Checkpoint mode
const resumed = await pac.balance.derive('cust_12345', {
startingBalance: current.computedBalance,
startingCheckpoint: current.latestReceiptId ?? undefined,
});
cURL Example
bash
curl -X GET "https://app.pacspace.io/api/v1/balance/derive/cust_12345?period=2026-04&granularity=day" \
-H "X-Api-Key: YOUR_API_KEY"
Response Shape (Highlights)
json
{
"success": true,
"data": {
"customerId": "cust_12345",
"computedBalance": 48500,
"deltasCount": 127,
"latestCheckpoint": "chk_9ec7...",
"latestReceiptId": "chk_9ec7...",
"scope": {
"kind": "period",
"periodId": "2026-04",
"startDate": "2026-04-01T00:00:00.000Z",
"endDateExclusive": "2026-05-01T00:00:00.000Z",
"label": "Apr 2026"
},
"granularity": "day",
"granularBreakdown": [
{
"period": "2026-04-01",
"periodStart": "2026-04-01T00:00:00.000Z",
"periodEndExclusive": "2026-04-02T00:00:00.000Z",
"deltaCount": 5,
"netDelta": -150,
"runningBalance": 49850
}
]
}
}
Structured Errors
Derive returns typed errors with actionable hints:
INVALID_SCOPE_COMBINATIONSCOPE_TOO_WIDEINVALID_PERIODINVALID_DATE_RANGEINVALID_TIME_PRESETDERIVE_CHECKPOINT_REQUIRED
Example:
json
{
"message": "Choose either checkpoint mode or scope mode in this request.",
"code": "INVALID_SCOPE_COMBINATION",
"hint": "Remove startingCheckpoint or remove period/timePreset/startDate/endDate."
}