Skip to content

Emit — Record a Delta

Record a delta for a customer. PacSpace queues the delta, verifies it independently, and sends a webhook when complete.

Use this endpoint to record a balance change (delta) for a customer account. Each delta represents an adjustment that PacSpace queues, independently verifies, and confirms via webhook.


Endpoint

POST https://balance-api.pacspace.io/api/v1/balance/delta

Headers

HeaderRequiredDescription
X-Api-KeyYesYour PacSpace API key
Content-TypeYesMust be application/json
Idempotency-KeyNoUnique key to prevent duplicate processing on retries
X-Credit-Pool-IdNoContract routing identifier. Selects which tenant contract to target. Auto-selected when you have a single contract. The header name is historical — it is unrelated to the deprecated credit billing system.

Request Body

ParameterTypeRequiredDescription
customerIdstringYesUnique identifier for the customer account. Alphanumeric with underscores, hyphens, dots, and colons allowed. Max 128 characters.
deltanumberYesAmount to adjust. Positive = increase, negative = decrease. Must be a non-zero finite number between -1,000,000,000 and 1,000,000,000.
reasonstringYesHuman-readable reason for the adjustment (audit trail). Required, max 500 characters.
referenceIdstringNoYour internal reference ID for correlation
metadataobjectNoArbitrary key-value metadata to store with the delta

Examples

SDK (TypeScript)

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

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

const delta = await pac.balance.emit('cust_12345', -1000, 'Monthly subscription charge', {
  referenceId: 'inv_98765',
  metadata: {
    invoiceId: 'inv_98765',
    plan: 'growth',
  },
});

console.log(delta.receiptId); // Store for later verification

Wait for verification: Use emitAndWait() to block until the delta is verified:

typescript
const verified = await pac.balance.emitAndWait('cust_12345', -1000, 'charge', {
  timeout: 30_000,
});

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_12345",
    "delta": -1000,
    "reason": "Monthly subscription charge",
    "referenceId": "inv_98765",
    "metadata": {
      "invoiceId": "inv_98765",
      "plan": "growth"
    }
  }'

JavaScript (Node.js)

javascript
const response = await fetch(
  "https://balance-api.pacspace.io/api/v1/balance/delta",
  {
    method: "POST",
    headers: {
      "X-Api-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      customerId: "cust_12345",
      delta: -1000,
      reason: "Monthly subscription charge",
      referenceId: "inv_98765",
      metadata: {
        invoiceId: "inv_98765",
        plan: "growth",
      },
    }),
  }
);

const result = await response.json();
console.log(result);

Python

python
import requests

response = requests.post(
    "https://balance-api.pacspace.io/api/v1/balance/delta",
    headers={
        "X-Api-Key": "YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={
        "customerId": "cust_12345",
        "delta": -1000,
        "reason": "Monthly subscription charge",
        "referenceId": "inv_98765",
        "metadata": {
            "invoiceId": "inv_98765",
            "plan": "growth",
        },
    },
)

result = response.json()
print(result)

Idempotency

To prevent duplicate deltas from network retries, include the Idempotency-Key header:

bash
curl -X POST https://balance-api.pacspace.io/api/v1/balance/delta \
  -H "X-Api-Key: pk_live_PUBLIC.SECRET" \
  -H "Idempotency-Key: unique-request-id-123" \
  -d '{"customerId": "cust_123", "delta": -42.50, "reason": "usage_charge"}'

If a request with the same key is already processing, you'll receive a 202 Accepted response. If the same key was used with a different request body, you'll receive a 409 Conflict response.


Response

json
{
  "success": true,
  "data": {
    "anchorId": "a_1234567890",
    "customerId": "cust_12345",
    "delta": -1000,
    "status": "QUEUED",
    "receiptId": "0x8f3a9b2c...",
    "itemsRoot": "0x8f3a9b2c...",
    "itemHashes": ["0x2d4e7f1a..."],
    "estimatedVerifiedDeltas": 1,
    "receivedAt": "2026-02-11T10:30:00.000Z",
    "message": "Delta queued for verification. Store receiptId for later proof generation."
  }
}

Response Fields

FieldTypeDescription
anchorIdstringUnique identifier for this delta record
customerIdstringThe customer account this delta belongs to
deltanumberThe recorded adjustment amount
statusstringCurrent processing status (starts as QUEUED)
receiptIdstringProof root hash — store this for later verification and proof generation
itemsRootstringRoot hash covering the items in this submission (same as receiptId)
itemHashesstring[]Individual content hashes for each item in the submission
estimatedVerifiedDeltasnumberEstimated number of verified deltas this submission will produce
receivedAtstringISO 8601 timestamp of when the submission was received
messagestringHuman-readable status message

Status Lifecycle

Every delta moves through three stages:

  1. QUEUED — The delta has been accepted and is waiting to be processed. This is the status returned immediately after a successful request.

  2. PROCESSING — PacSpace is actively verifying the delta. This stage typically completes within a few seconds.

  3. VERIFIED — Verification is complete. The delta is now part of the customer's verified balance history and can be used in balance derivations.

Webhook Notification

When a delta reaches the VERIFIED status, PacSpace sends a delta.verified webhook to your configured endpoint. The webhook payload includes the full delta record with its final receiptId and itemsRoot, so you can update your own systems accordingly.

Tip: You don't need to poll for status. Configure a webhook endpoint in your PacSpace dashboard to receive real-time notifications when deltas are verified.


Check Delta Status

After emitting a delta, check its processing status:

GET https://balance-api.pacspace.io/api/v1/balance/delta/:anchorId

Returns the delta's current status (QUEUED, ANCHORING, ANCHORED, FAILED), along with the customerId, delta, receiptId, and txHash. For batch anchors, the response includes deltaCount and a deltas array containing all deltas in the batch.


Batch Emit

Record up to 100 deltas in a single request:

POST https://balance-api.pacspace.io/api/v1/balance/delta/batch

Request body:

json
{
  "deltas": [
    { "customerId": "cust_123", "delta": -100, "reason": "usage_charge" },
    { "customerId": "cust_456", "delta": -200, "reason": "api_call" }
  ]
}

Response:

json
{
  "success": true,
  "data": {
    "totalQueued": 2,
    "totalFailed": 0,
    "results": [
      {
        "index": 0,
        "customerId": "cust_123",
        "delta": -100,
        "anchorId": "a_batch_001",
        "itemHash": "0x2d4e7f1a...",
        "receiptId": "0x8f3a9b2c...",
        "status": "QUEUED"
      },
      {
        "index": 1,
        "customerId": "cust_456",
        "delta": -200,
        "anchorId": "a_batch_001",
        "itemHash": "0x9c1b3e5d...",
        "receiptId": "0x8f3a9b2c...",
        "status": "QUEUED"
      }
    ],
    "_efficiency": {
      "uniqueCustomers": 2,
      "totalDeltas": 2,
      "estimatedSlots": 2,
      "message": "2 delta(s) packed into 2 verified operation(s)"
    }
  }
}

Each result includes an index (position in your input array for correlation) and an itemHash (individual content hash for proof verification). The _efficiency summary shows how your batch was packed into verified operations — batches with many deltas for the same customer are more cost-efficient.