SettleMint
Developer guidesOperations

Reconcile balances

Compare indexed token balances and token events with your own ledger before investigating a mismatch.

Reconciliation compares a ledger with DALP's indexed token data. Run the check to confirm holders, trace movement history, and separate a pending transaction from a missed event or a ledger-only entry.

This how-to covers read-only checks. The requests below do not change balances or submit corrections. For a pending submission, check transaction status before reconciling.

Rendering diagram...

Indexed data

Balance and event routes read indexed chain data. If you are checking a transaction that was just submitted, first confirm its current status with transaction tracking, then reconcile after the relevant events have been indexed.

Prerequisites

  • Platform URL, such as https://your-platform.example.com.
  • API key. See Getting started with the API.
  • Token contract address for the asset you want to reconcile.
  • Your internal balance records and transaction references for comparison.

Quickstart: query current holder balances

Start with the current indexed holders for one token:

curl -X GET "https://your-platform.example.com/api/token/0xTOKEN_ADDRESS/holders" \
  -H "X-Api-Key: sm_dalp_xxxxxxxxxxxxxxxx"

The response groups holder balances under token.balances. value, available, and frozen are decimal token amounts derived from the token's decimals.

{
  "token": {
    "balances": [
      {
        "account": { "id": "0x1111111111111111111111111111111111111111" },
        "value": "1000.00",
        "available": "800.00",
        "frozen": "200.00",
        "isFrozen": false,
        "lastUpdatedAt": "2026-01-15T10:30:00.000Z"
      },
      {
        "account": { "id": "0x2222222222222222222222222222222222222222" },
        "value": "500.00",
        "available": "500.00",
        "frozen": "0.00",
        "isFrozen": false,
        "lastUpdatedAt": "2026-01-14T15:20:00.000Z"
      }
    ]
  },
  "totalCount": 2
}

For a single holder, include the wallet address as a query parameter:

curl -X GET "https://your-platform.example.com/api/token/0xTOKEN_ADDRESS/holder?holderAddress=0xHOLDER_ADDRESS" \
  -H "X-Api-Key: sm_dalp_xxxxxxxxxxxxxxxx"

Query balance-affecting events

Get token events that can explain balance movement:

curl -X GET "https://your-platform.example.com/api/token/0xTOKEN_ADDRESS/events?eventNames=TransferCompleted&eventNames=MintCompleted&eventNames=BurnCompleted" \
  -H "X-Api-Key: sm_dalp_xxxxxxxxxxxxxxxx"

Use limit and offset when you expect many events.

{
  "events": [
    {
      "id": "evt_01hzzzzzzzzzzzzzzzzzzzzzzz",
      "eventName": "TransferCompleted",
      "txIndex": "0",
      "blockNumber": "12345678",
      "blockTimestamp": "2026-01-15T10:30:00.000Z",
      "transactionHash": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
      "emitter": { "id": "0xTOKEN_ADDRESS" },
      "sender": { "id": "0xSENDER_ADDRESS" },
      "values": [
        { "id": "evt_01hzzzzzzzzzzzzzzzzzzzzzzz-account", "name": "account", "value": "0xACCOUNT_ADDRESS" },
        { "id": "evt_01hzzzzzzzzzzzzzzzzzzzzzzz-amount", "name": "amount", "value": "1000000000000000000" }
      ]
    }
  ]
}

Event amounts are indexed as raw on-chain integer values. Apply the token decimals before comparing the amount with a human-readable ledger value.

Compare with your ledger

For each holder in your ledger:

  1. Match the holder wallet address to the account.id field from the holder-balance response.
  2. Compare your ledger balance with value.
  3. Compare transferable balance with available when your ledger separates frozen or restricted balances.
  4. Use lastUpdatedAt and token events to narrow the period where the mismatch appeared.

For each ledger transaction:

  1. Find the matching token event by transaction hash when you have it.
  2. If you do not have the hash, filter by senderAddress and event type.
  3. Confirm the event name and raw amount match the ledger entry after decimal conversion.
  4. Treat an internal ledger entry with no matching event as a failed or still-pending submission until transaction tracking proves otherwise.

Investigate a mismatch

Filter by transaction hash when your ledger stores the submitted transaction hash:

curl -X GET "https://your-platform.example.com/api/token/0xTOKEN_ADDRESS/events?transactionHashes=0xTX_HASH_1&transactionHashes=0xTX_HASH_2" \
  -H "X-Api-Key: sm_dalp_xxxxxxxxxxxxxxxx"

Filter by sender when you need events initiated by a specific wallet:

curl -X GET "https://your-platform.example.com/api/token/0xTOKEN_ADDRESS/events?eventNames=TransferCompleted&senderAddress=0xYOUR_WALLET" \
  -H "X-Api-Key: sm_dalp_xxxxxxxxxxxxxxxx"

Use senderAddress for transactions submitted by a wallet. Use the event payload and account fields to find events where the wallet participated but did not submit the transaction. Use either senderAddress or walletAddress on token event queries; the endpoint rejects requests that include both filters.

Endpoint reference

PurposeEndpointNotes
List token holdersGET /api/token/{tokenAddress}/holdersReturns positive indexed balances for the token.
Read one holder balanceGET /api/token/{tokenAddress}/holder?holderAddress={wallet}Returns the indexed balance for one wallet.
List token eventsGET /api/token/{tokenAddress}/eventsSupports eventNames, senderAddress, transactionHashes, fromDate, toDate, walletAddress, limit, and offset.
List user assetsGET /api/user/assets?wallet={wallet}Returns balances held by one wallet across assets.
List user eventsGET /api/user/eventsSupports pagination plus eventNames, senderAddress, and transactionHashes for user-scoped event review.

Event types for reconciliation

EventBalance impactUse it to check
TransferCompletedSender decreases, receiver increasesStandard transfers between holders.
MintCompletedRecipient increasesIssuance and additional minting.
BurnCompletedHolder decreasesBurns and redemptions that reduce supply.
ForcedTransferSender decreases, receiver increasesCustodian-initiated movement when policy permits it.

Response fields

Balance fields

FieldTypeMeaning
account.idstringHolder wallet address.
valuestringTotal token balance as a decimal amount.
availablestringBalance available for transfer.
frozenstringBalance locked by freeze controls.
isFrozenbooleanWhether the whole holder balance is frozen.
lastUpdatedAtstringISO 8601 timestamp for the last indexed balance change.

Event fields

FieldTypeMeaning
idstringEvent identifier.
eventNamestringIndexed event type.
transactionHashstringOn-chain transaction hash.
blockTimestampstringISO 8601 timestamp for the indexed block.
blockNumberstringBlock containing the event.
emitter.idstringContract that emitted the event.
sender.idstringWallet that submitted the transaction when indexed.
valuesarrayEvent-specific fields, such as account and raw amount.

Troubleshooting

SymptomCheck
Balance mismatchCheck pending transaction status, then compare indexed holder balances again after the event appears.
Missing eventVerify the event name and token address. Add limit and offset if the event is older than the first page.
Amount looks too largeConvert the raw event amount with the token decimals before comparing it with the ledger amount.
Sender filter misses an eventThe wallet may be involved without being the submitting sender. Search by transaction hash or wallet-scoped events.
Frozen balance differs from ledgerCompare available, frozen, and isFrozen separately instead of comparing only total balance.

On this page