API-Based Data Collection + Reconciliation
All endpoints below are GraphQL operations against a single URL:
POST https://api.prod.tres.finance/graphql
with header Authorization: Bearer <access_token> (obtained from the login endpoint — see the API reference's Introduction page).
The core concept
A commit is an asynchronous job: you tell Tres which accounts and which date range to collect, Tres goes and pulls transactions/balances from the source (chain or exchange) and rebuilds the ledger for that window, and then you can ask whether the result reconciles — i.e. whether Tres's computed balance for that account+asset matches the source balance, within tolerance.
triggerParallelCommit processes each account/asset independently in parallel, supports asset-level scoping (assetsToCollect) and throttling (maxTransactionLimit), and — unlike the sequential triggerCommit — its commits can be checked for reconciliation via checkParallelCommitReconciliationStatus. That combination is what makes it the right tool whenever you need to programmatically confirm collected data is reconciled.
End-to-end flow
Trigger a parallel commit for the accounts/assets/date-range you care about → you get back a
commitId.(Optional) Throttle it via
updateCommitMaxTransactionLimitif it's ingesting more than expected.Poll
checkParallelCommitReconciliationStatus(commitId)— this returns one result per account+asset in the commit, each withisReconciledand the underlying diff amounts.Act on the result: if reconciled, you're done. If not reconciled or the job is stuck, cancel it with
killCommits(by ID, or all-at-once as an emergency stop) and re-trigger.
Endpoint reference
1. Trigger Parallel Commit — triggerParallelCommit
The production-grade version. Accounts can be specified either by Tres's internal ID (internalAccountIds) or by their external identifier/address (internalAccountIdentifiers). fromDate/toDate are required.
mutation TriggerParallelCommit( $internalAccountIds: [ID] $internalAccountIdentifiers: [String] $fromDate: DateTime! $toDate: DateTime! $commitId: UUID $assetsToCollect: [String] $fetchFullHistory: Boolean $commitRequestCustomerMetadata: CommitRequestCustomerMetadataInput ) { triggerParallelCommit( internalAccountIds: $internalAccountIds internalAccountIdentifiers: $internalAccountIdentifiers fromDate: $fromDate toDate: $toDate commitId: $commitId assetsToCollect: $assetsToCollect fetchFullHistory: $fetchFullHistory commitRequestCustomerMetadata: $commitRequestCustomerMetadata ) { status message commitId } }
Variables:
{ "internalAccountIdentifiers": ["0x6897938af83502d348720679fe7d8e83e7dd5ff2a13c9cad189302babceb7be9"], "assetsToCollect": ["substrate_kusama_native"], "fetchFullHistory": false, "fromDate": "2025-01-01T00:00:00Z", "toDate": "2025-09-28T23:59:59Z", "commitRequestCustomerMetadata": { "env": "EXAMPLE", "userId": "user" } }
Key fields:
assetsToCollect— narrow the commit to specific assets instead of the account's entire balance sheet. Optional here; required once you also passmaxTransactionLimit(see variant below).fetchFullHistory— collect the account's entire history instead of justfromDate–toDate.commitRequestCustomerMetadata(env,userId) — free-form tags you set so you can trace a commit back to what triggered it on your side. This metadata is echoed back in the reconciliation-status response, so it's the cheapest way to correlate a reconciliation result with your own request/job.
Save the returned commitId — every other endpoint in this set operates on it.
2. Trigger Parallel Commit + Max Transaction Limit
Same mutation, with assetsToCollect: [String]! now required and an added maxTransactionLimit: Int to cap how many transactions a single commit will pull per asset — useful for bounding a large backfill so a single call can't runaway ingest an unexpectedly large history.
mutation TriggerParallelCommit( $internalAccountIds: [ID] $internalAccountIdentifiers: [String] $fromDate: DateTime! $toDate: DateTime! $commitId: UUID $assetsToCollect: [String]! $maxTransactionLimit: Int ) { triggerParallelCommit( internalAccountIds: $internalAccountIds fromDate: $fromDate toDate: $toDate commitId: $commitId assetsToCollect: $assetsToCollect internalAccountIdentifiers: $internalAccountIdentifiers maxTransactionLimit: $maxTransactionLimit ) { status message commitId } }
Variables:
{ "toDate": "2025-08-07T23:59:59+00:00", "fromDate": "2025-07-07T00:00:00+00:00", "assetsToCollect": ["arbitrum_0xff970a61a04b1ca14834a43f5de4533ebddb5cc8"], "internalAccountIds": [679191] }
3. Update Parallel Commit Max Transaction Limit — updateCommitMaxTransactionLimit
Adjust the limit on a commit after it's already been triggered (e.g. you started a broad backfill and realize mid-flight it's larger than expected and want to cap it).
mutation UpdateCommitMaxTransactionLimit($commitId: UUID!, $maxTransactionLimit: Int!) { updateCommitMaxTransactionLimit(commitId: $commitId, maxTransactionLimit: $maxTransactionLimit) { success } }
{ "commitId": "6b16a105-422a-2f68-bafd-b4634eafc801", "maxTransactionLimit": 1000 }
4. Check Parallel Commit Reconciliation — checkParallelCommitReconciliationStatus
This is the endpoint that answers "did it reconcile?". Query it by commitId (poll it periodically after triggering — collection is asynchronous). It returns one entry per account+asset that was part of the commit.
query CheckParallelCommitReconciliationStatus($commitId: UUID!) { checkParallelCommitReconciliationStatus(commitId: $commitId) { inflowAmount outflowAmount feeAmount totalAmount openingBalance closingBalance balanceDiff closingUnbondingBalance openingUnbondingBalance reconciliationDiff internalAccountIdentifier assetKey reconciliationDiffUsd internalAccountName fromDate toDate isReconciled commitRequestCustomerMetadata { env userId } } }
{ "commitId": "1047cc60-dc1c-477a-8104-084ebdf5a74e" }
Field meaning:
Field | Meaning |
|---|---|
| The bottom line. |
| The size of the mismatch (native asset units / USD) when not reconciled — use this to decide if a diff is negligible (dust/rounding) or a real problem. |
| Balance at the start/end of the |
|
|
| Breakdown of activity that produced |
| Same idea, for assets that have a staking/unbonding balance (e.g. bonded/unbonding stake). |
| Which account+asset this row describes — needed because one commit can cover many accounts/assets. |
| Echoes back the |
Polling tip: collection runs asynchronously after you trigger the commit. Poll this query on a backoff (e.g. every 5–15s) rather than immediately — an empty/incomplete result right after triggering just means the job hasn't finished yet, not that it failed.
5. Kill Commits — killCommits
Cancels running/queued commits. Call with no arguments to stop all active commits (emergency stop), or pass specific commitIds to cancel precisely the one(s) you started.
mutation KillCommits { killCommits { status } }
mutation KillCommits($commitIds: [String]) { killCommits(commitIds: $commitIds) { status } }
{ "commitIds": ["51f27092-f6e9-4fd8-a8d9-c36100ba7c05"] }
Use this when a commit is stuck, taking far longer than expected, or you triggered it with the wrong parameters and want to retry cleanly instead of letting it finish.
Putting it all together (worked example)
1) Trigger collection for an account over a date range, scoped to one asset curl --location -g 'https://api.prod.tres.finance/graphql' \ --header 'Authorization: Bearer <access_token>' \ --header 'Content-Type: application/json' \ --data '{ "query": "mutation TriggerParallelCommit($internalAccountIds:[ID],$fromDate:DateTime!,$toDate:DateTime!,$assetsToCollect:[String]){ triggerParallelCommit(internalAccountIds:$internalAccountIds, fromDate:$fromDate, toDate:$toDate, assetsToCollect:$assetsToCollect){ status message commitId } }", "variables": { "internalAccountIds": [679191], "fromDate": "2025-07-07T00:00:00+00:00", "toDate": "2025-08-07T23:59:59+00:00", "assetsToCollect": ["arbitrum_0xff970a61a04b1ca14834a43f5de4533ebddb5cc8"] } }' => { "data": { "triggerParallelCommit": { "status": "PENDING", "commitId": "1047cc60-...", "message": null } } } 2) Poll until the collection settles curl --location -g 'https://api.prod.tres.finance/graphql' \ --header 'Authorization: Bearer <access_token>' \ --header 'Content-Type: application/json' \ --data '{ "query": "query($commitId:UUID!){ checkParallelCommitReconciliationStatus(commitId:$commitId){ assetKey isReconciled reconciliationDiff reconciliationDiffUsd } }", "variables": { "commitId": "1047cc60-..." } }' => { "data": { "checkParallelCommitReconciliationStatus": [ { "assetKey": "arbitrum_0xff97...", "isReconciled": true, "reconciliationDiff": 0, "reconciliationDiffUsd": 0 } ] } } 3) If it's taking too long or you need to abort, cancel it explicitly curl --location -g 'https://api.prod.tres.finance/graphql' \ --header 'Authorization: Bearer <access_token>' \ --header 'Content-Type: application/json' \ --data '{ "query": "mutation($ids:[String]){ killCommits(commitIds:$ids){ status } }", "variables": { "ids": ["1047cc60-..."] } }'
Best practices
Always capture the returned
commitIdimmediately after triggering; you'll need it for every subsequent call in this set.Poll with backoff, don't hammer
checkParallelCommitReconciliationStatusin a tight loop — collection is async and can take time proportional to date range/history size.Scope with
assetsToCollectwhen you only care about specific tokens — it reduces both collection time and the number of reconciliation rows you have to evaluate.Tag requests with
commitRequestCustomerMetadata(env,userId) so reconciliation results are traceable back to whatever triggered them in your system, without needing to separately store a mapping ofcommitId → your job.Guard large backfills with
maxTransactionLimitup front, or throttle mid-flight withupdateCommitMaxTransactionLimitif a commit turns out bigger than expected.Cancel precisely with
killCommits(commitIds: [...]); reserve the no-argumentkillCommits(kill everything) for genuine emergencies, since it affects every commit in flight, not just yours.Treat small non-zero
reconciliationDiff/reconciliationDiffUsdas expected rounding noise; treat large or growing diffs as a signal to investigate before trusting the ledger for that account+asset.