SettleMint
Token features

Balance snapshot at a block

Reconstruct holder and total-supply balances as of a specific block across one or more tokens in the active DALP system, for audit and point-in-time reporting.

Use the at-block snapshot endpoint when an auditor or integration needs to reconstruct what a holder owned, or what a token's supply was, as of a specific block. It reads the same checkpoint history as the per-token historical-balances reads, but answers a different question: balances at or before one block number. You address the query by token or by holder across the active system, rather than one token at a time.

Reach for this endpoint when you need point-in-time evidence: a balance proof for a dispute, a holder position for a regulatory snapshot, or a total supply figure tied to an exact block.

Endpoint

EndpointReturns
GET /api/v2/historical-balances/at-blockCheckpointed balances at or before a chosen block, filtered by token, holder, or both.

The endpoint reads checkpoint data for the caller's active system. It requires historical-balances read access. Results never cross system boundaries: a token or holder outside the active system returns no rows rather than an error, so the response cannot reveal whether an address exists in another tenant.

Required parameters

Every request needs two things:

  • A block query parameter: the non-negative block number to read balances at or before.
  • At least one discriminator filter: filter[tokenAddress][eq] or filter[account][eq]. A request with neither is rejected.

The block, tokenAddress, account, and kind inputs are exact-match selectors. They accept the eq operator only. Any other operator is rejected at the request boundary, so a query cannot silently match the wrong rows.

Read one holder across a token

Pass both a token and an account to read that holder's balance in that token as of the block.

curl --globoff "$DALP_API_URL/api/v2/historical-balances/at-block?block=8154000&filter[tokenAddress][eq]=0x00000000000000000000000000000000000000aa&filter[account][eq]=0xabcdef0000000000000000000000000000000001" \
  --header "X-Api-Key: $DALP_API_TOKEN"

The response is a paginated collection envelope with data, meta, and links:

{
  "data": [
    {
      "tokenAddress": "0x00000000000000000000000000000000000000aa",
      "account": "0xabcdef0000000000000000000000000000000001",
      "kind": "account",
      "balance": "1000",
      "balanceExact": "1000000000000000000000",
      "asOfBlockNumber": "8153120",
      "asOfBlockTimestamp": "2026-01-01T00:00:00.000Z",
      "asOfTxHash": "0x0000000000000000000000000000000000000000000000000000000000000045",
      "asOfLogIndex": 0
    }
  ],
  "meta": { "total": 1, "facets": {} },
  "links": {
    "self": "/v2/historical-balances/at-block?block=8154000&filter[tokenAddress][eq]=0x00000000000000000000000000000000000000aa&filter[account][eq]=0xabcdef0000000000000000000000000000000001&page[limit]=50&page[offset]=0&sort=account",
    "first": "/v2/historical-balances/at-block?block=8154000&filter[tokenAddress][eq]=0x00000000000000000000000000000000000000aa&filter[account][eq]=0xabcdef0000000000000000000000000000000001&page[limit]=50&page[offset]=0&sort=account",
    "prev": null,
    "next": null,
    "last": "/v2/historical-balances/at-block?block=8154000&filter[tokenAddress][eq]=0x00000000000000000000000000000000000000aa&filter[account][eq]=0xabcdef0000000000000000000000000000000001&page[limit]=50&page[offset]=0&sort=account"
  }
}

Each row reports the balance from the latest checkpoint at or before the requested block. The asOf fields point to the checkpoint that produced the balance, so you can cite the exact block, timestamp, and transaction the figure came from.

Read every holder of a token

Pass only a token to read all of its holders as of the block. Total-supply rows use the zero address as the account.

curl --globoff "$DALP_API_URL/api/v2/historical-balances/at-block?block=8154000&filter[tokenAddress][eq]=0x00000000000000000000000000000000000000aa&page[limit]=50" \
  --header "X-Api-Key: $DALP_API_TOKEN"

To narrow the result to holders only or to the total-supply row, add filter[kind][eq]=account or filter[kind][eq]=totalSupply. Results sort by account, and equal-key rows stay in a stable order so offset pages do not shift between requests.

Pagination and sorting

The endpoint returns at most 50 rows per page by default and 200 at most. Set page[limit] and page[offset] to walk a large holder set, and follow the links in each response. Every pagination link carries the original block through, so following next or last reads the same point in time as the first page. Sort by account with sort=account or sort=-account.

The meta.facets object is always present but currently returns an empty map. Facet counts for the kind field are not computed by this endpoint, so callers cannot rely on it to size holder versus total-supply segments before paging.

Response fields

FieldMeaning
tokenAddressToken the balance belongs to.
accountHolder address, or the zero address for a total-supply row.
kindaccount for a holder balance, totalSupply for a supply row, no-checkpoint when no balance existed yet.
balanceBalance as a decimal string in token units.
balanceExactSame balance as a base-unit integer string, for exact arithmetic.
asOfBlockNumberBlock of the checkpoint that produced the balance, or null for a no-checkpoint row.
asOfBlockTimestampTimestamp of that checkpoint, or null for a no-checkpoint row.
asOfTxHashTransaction hash of that checkpoint, or null when none applies.
asOfLogIndexLog index within that transaction, or null when none applies.

Reading balances before activity

When you request a holder and token together and no checkpoint exists at or before the block, the response still returns a row. If the holder already held a balance during the window between the feature's enable block and their first recorded activity, the row reports that seeded pre-activity balance. If no balance applied, the row reports a no-checkpoint kind with a zero balance and null checkpoint fields.

This keeps a known holder and token from disappearing from the result just because the block falls before their first transfer. A no-checkpoint zero row means the holder owned nothing at that block, not that the query failed.

Troubleshooting

SymptomWhat to check
Request is rejectedInclude a block value and at least one of filter[tokenAddress][eq] or filter[account][eq].
Filter is rejectedUse the eq operator on tokenAddress, account, and kind. Other operators are not accepted.
Result is emptyConfirm the token and holder belong to the active DALP system and that the block is at or after activity.
A holder shows a zero balanceA no-checkpoint zero row means the holder held nothing at that block, not that the lookup failed.

On this page