Pular para o conteúdo

Omnibus Position Report

Executive summary

The Omnibus Position Report is a point-in-time snapshot of one domain's omnibus structure: the omnibus wallet, its deposit wallets, and the virtual account balances that the pool backs.

  • Send a POST request to /v1/exports/position/omnibus with the domain that owns the omnibus structure and an asOfTimestamp.
  • Filter by virtual account and ticker, and choose whether to include zero balances.
  • The service returns 20 fixed columns in CSV or JSON, with control totals per account type.

The Position Report covers the on-chain custody layer only. An omnibus structure adds a second, off-chain layer: virtual accounts that track each tenant's share of the pooled funds. The Omnibus Position Report serves that layer. It reports the omnibus pool and its per-tenant breakdown in one file, with the mapping columns you need to tie a deposit wallet to its virtual account and every row to its parent omnibus wallet.

The omnibus wallet and deposit wallets appear in both reports on purpose. Those shared on-chain rows are the bridge that lets an auditor tie the two files together.

Availability

Omnibus support in the export service is enabled automatically for SaaS environments that use an omnibus structure. In environments without it, this endpoint returns 404, and the Position and Movement Reports don't apply omnibus account types. On-premises deployments enable it through Helm configuration — see Omnibus support.

Prerequisites

To generate an Omnibus Position Report, you need the following:

PrerequisiteAdditional information
A valid bearer token (JWT)See Authentication.
A profile in the target domain with a role that grants read access to accountsThe same access as the Position Report. See Access control.
The target domain's IDThe domain that owns the omnibus structure.
An omnibus structure in the target domainSee Omnibus setup and governance. A domain without an omnibus structure returns 422.
Omnibus support turned on for your environmentSee Omnibus support.

Endpoint

POST /v1/exports/position/omnibus

The service generates a balance snapshot for the omnibus structure in the target domain as of asOfTimestamp. The report covers one domain. It has no includeChildDomains option, because each omnibus structure belongs to exactly one domain.

Request fields

Send the request body as application/json.

FieldTypeRequiredDefaultDescription
domainIdstring (UUID)Yes—The domain that owns the omnibus structure. You must have read access to accounts in this domain.
asOfTimestampstring (ISO 8601)Yes—The point in time for the balance snapshot. Can't be in the future.
tenantIdsstring[] (UUID)No—Include only the listed virtual accounts and their deposit wallets. Maximum 1,000 entries. The report always includes the omnibus wallet rows, so the file stays reconcilable.
tickerIdsstring[] (UUID)No—Include only the listed assets. Maximum 1,000 entries.
includeZeroBalancesbooleanNofalseInclude rows that hold a zero balance. A virtual account that was funded and later drained to zero appears only when this is true. See Row scope.
format"CSV" | "JSON"Yes—The output format.

Example request

curl -X POST "https://{host}/v1/exports/position/omnibus" \
  -H "Authorization: Bearer <jwt>" \
  -H "Content-Type: application/json" \
  -d '{
    "domainId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "asOfTimestamp": "2026-09-15T23:59:59Z",
    "tenantIds": ["1559bf54-5343-476e-b720-29edfee0edd7"],
    "includeZeroBalances": false,
    "format": "CSV"
  }'

The service returns the report as a single file with a Content-Disposition attachment header and an X-Export-Id header for tracing. For the response structure of each format, see Output formats.

Report structure

Row kinds

Each row represents one account-and-asset balance, as in the Position Report. The report contains three kinds of row, distinguished by accountType:

accountTypeWhat the row representsaccountIdHow the row is linked
omnibusThe domain's omnibus wallet, the custody account that holds the pooled funds on-chain.The custody account ID.parentOmnibusAccountId is empty, because this row is the parent.
deposit walletA deposit wallet, the custody account dedicated to one virtual account for external deposits.The custody account ID.mappedVirtualAccountId names the virtual account that owns the wallet. parentOmnibusAccountId names the omnibus wallet.
virtual accountA virtual account, the off-chain record of one tenant's position in the pool.The virtual account (tenant) ID.parentOmnibusAccountId names the omnibus wallet. isHost is true on the host virtual account.

Row identity is always accountType plus accountId. The accountId value is the same identity the Accounting Service uses for the balance: a custody account ID on on-chain rows and a tenant ID on virtual account rows. When you join accountId to custody account data, filter on accountType in (omnibus, deposit wallet) first. Virtual account IDs resolve only through the Omnibus API /tenants resources.

Each mapping column has one role, and every relationship appears once. The deposit-wallet-to-virtual-account link lives on the deposit wallet row, because that's the direction reconciliation reads it: funds arrive on a wallet, and the question is who owns them.

Row scope

The service builds rows from the Accounting Service's balance records and uses the omnibus structure only to classify and enrich them. This has several consequences:

  • A virtual account that has never been funded produces no row, under any setting. Creating a tenant writes no balance record, so there is no position to report. For the full roster of virtual accounts, including never-funded ones, use the Omnibus API.
  • A virtual account that was funded and later drained to zero has a row, with zero balances and a populated ledgerBalanceTimestamp, when includeZeroBalances is true.
  • A deposit wallet row can appear before its virtual account has a row, for example when a deposit sits in quarantine awaiting its first sweep. The mapping is still visible through the wallet row's mappedVirtualAccountId.
  • The host virtual account is always included, and its balance can be negative. The host absorbs fee compensation, so it can run a fee debt. The service never filters it out, because the reconciliation below depends on it.
  • The report includes all virtual accounts regardless of status. A locked virtual account with a balance still appears.
  • Row order isn't part of the contract. Sort on accountType and accountId downstream if you need a stable order.

Reconciliation invariant

For each asset, the sum of availableBalance across the virtual account rows equals the omnibus wallet's totalBalance. The negative host balance is part of that sum. For example, a pool with two virtual accounts at 20.000000 and -1.000200 reconciles to an omnibus wallet total of 18.999800.

Compute this check from the rows of one file, per ticker. Don't use the control totals for it: a control total can span several assets with different decimal scales, so it's an integrity checksum, not a per-asset figure. See Control totals.

Output columns

Column order is a fixed contract.

#ColumnTypeNullableDescription
1domainIdstring (UUID)NoThe domain that owns the omnibus structure.
2domainNamestringNoThe domain's display name.
3accountTypestringNoThe row kind. One of omnibus, deposit wallet, or virtual account.
4accountIdstring (UUID)NoThe custody account ID on omnibus and deposit wallet rows. The virtual account (tenant) ID on virtual account rows.
5accountNamestringNoThe custody account alias on on-chain rows. The virtual account alias on virtual account rows.
6mappedVirtualAccountIdstring (UUID)YesOn deposit wallet rows, the virtual account that owns the wallet. Empty on other rows.
7isHostbooleanNotrue on the host virtual account row. false on every other row.
8parentOmnibusAccountIdstring (UUID)YesThe omnibus wallet's custody account ID, on deposit wallet and virtual account rows. Empty on the omnibus row.
9tickerIdstring (UUID)NoThe asset identifier.
10tickerKindstringNoThe asset kind. One of Native, Token, or Contract.
11tickerNamestringNoThe full asset name.
12tickerSymbolstringYesThe asset symbol. Empty if not set.
13ledgerNamestringNoThe blockchain network name as configured by the operator.
14availableBalancestring (decimal)NoThe available balance at asOfTimestamp. The headline figure for virtual account rows.
15reservedBalancestring (decimal)NoThe balance reserved for in-flight outbound transactions at asOfTimestamp.
16quarantineBalancestring (decimal)NoThe quarantined balance at asOfTimestamp. Meaningful on deposit wallet rows, where compliance holds apply.
17feeBalancestring (decimal)NoThe cumulative fee bucket. On the host virtual account row, it itemizes the accumulated fee debt.
18confiscationBalancestring (decimal)NoThe cumulative confiscation bucket.
19totalBalancestring (decimal)NoThe total balance at asOfTimestamp.
20ledgerBalanceTimestampstring (ISO 8601)YesWhen the Accounting Service last updated the balance. This is a database write time, not the on-chain block time.
Balance semantics

The six balance columns report the Accounting Service's balances as of asOfTimestamp, in the asset's native decimal unit. The export service applies no aggregation, netting, or adjustment. feeBalance and confiscationBalance are cumulative informational buckets. Use totalBalance as the authoritative total rather than recomputing it from other columns. On virtual account rows, reservedBalance and quarantineBalance are normally zero, because the Accounting Service doesn't carry tenant-level holds. Holds appear on the on-chain rows, such as quarantineBalance on deposit wallet rows.

A negative value is valid on the host virtual account row. Always parse balances as strings. See Financial precision.

Backdated reports

Balances reflect asOfTimestamp. Account names, statuses, and the host flag reflect the current state of the omnibus structure. The mappings in mappedVirtualAccountId and parentOmnibusAccountId never change after creation, so they're correct for any asOfTimestamp.

Control totals

The metadata header carries control totals per account type, never a grand total across types. The omnibus wallet's balance is the pool that backs the virtual account rows, so a cross-type sum would double-count by construction.

Each account type carries a record count and the signed sum of each of the six balance columns:

"controlTotals": {
  "omnibus": {
    "recordCount": 3,
    "availableBalance": "41.9868",
    "reservedBalance": "0",
    "quarantineBalance": "0",
    "feeBalance": "0.015",
    "confiscationBalance": "0",
    "totalBalance": "41.9868"
  },
  "depositWallet": { "recordCount": 1, "...": "..." },
  "virtualAccount": { "recordCount": 4, "...": "..." }
}

To verify a file, group the rows by accountType, re-sum each balance column, and compare the results and the record counts against the header. For how control totals work across every report, see Control totals.

Errors

If the service returns an error, the response body is a client-safe JSON object and never exposes internal details. Common cases for the Omnibus Position Report include:

  • 400: A required field is missing, a UUID or timestamp is malformed, asOfTimestamp is in the future, or a filter array exceeds 1,000 entries.
  • 401: The JWT is missing or invalid.
  • 403: You lack read access to accounts in the target domain.
  • 404: Omnibus support isn't enabled for this environment. See Omnibus support.
  • 413: The result would exceed 100,000 rows. Narrow the scope with tenantIds or tickerIds, then request again.
  • 422: The domain has no omnibus structure. The service returns this error rather than an empty file, because an empty file would be indistinguishable from a structure whose balances are all zero.
  • 429: A duplicate request within 60 seconds while a previous export is still processing, or you already have 2 exports processing.
  • 502: The Accounting Service or the Omnibus service is unavailable. The service fails the request rather than emit misclassified rows.

If the omnibus structure changes while the service reads it, for example because someone creates a virtual account mid-export, the export fails with a retryable error instead of returning rows that match no single point in time. Request the report again.

For the full list, see Error responses.


Next steps

PageDescription
Position ReportGenerate the on-chain custody snapshot, including the omnibus wallet and deposit wallets.
Omnibus balances and reconciliationReconcile the on-chain pool against virtual account records.
Export referenceLook up output formats, financial precision rules, access control, omnibus support, operational limits, and error responses.
Data export overviewReview report types, export metadata, and control totals.