The Movement Report is a transaction history for a date range. Each row reports one transfer, including amounts, fees, on-chain details, and counterparties.
- Send a
POSTrequest to/v1/exports/movementwith your target domain and a date range of up to 30 days. - By default, the report includes only settled transactions. Filter by vault, ticker, account, and status.
- The service returns 39 fixed columns in CSV or JSON, plus a value control total.
Use the Movement Report to reconcile activity for specific audit periods, remediate reconciliation breaks, and satisfy tax reporting requirements. Each row represents one transfer. Transaction-level fields repeat across the rows that belong to the same transaction.
To generate a Movement Report, you need the following:
| Prerequisite | Additional information |
|---|---|
| A valid bearer token (JWT) | See Authentication. |
| A profile in the target domain with a role that grants read access to transactions | See Access control. |
| The target domain's ID | The domain you want to report on. |
POST /v1/exports/movementThe service generates a transaction history for the target domain within the date range you specify.
Send the request body as application/json.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
domainId | string (UUID) | Yes | — | The target domain. You must have read access to transactions in this domain. |
dateRange.start | string (ISO 8601) | Yes | — | The start of the date range. Can't be in the future. |
dateRange.end | string (ISO 8601) | Yes | — | The end of the date range. Can't be before start. The range can't exceed 30 days. |
includeChildDomains | boolean | No | false | Include transfers from descendant domains. The service access-checks each child individually. |
vaultIds | string[] (UUID) | No | — | Include only the listed vaults. Maximum 1,000 entries. |
tickerIds | string[] (UUID) | No | — | Include only the listed assets. Maximum 1,000 entries. The report includes every asset in scope — including locked or unvetted assets — so use this filter to restrict the output to the assets you need. |
accountIds | string[] (UUID) | No | — | Include only the listed accounts. Maximum 1,000 entries. |
custodyStatus | string[] | No | ["Completed"] | Filter by custody status. See Status filtering. |
ledgerStatus | string[] | No | ["Confirmed"] | Filter by ledger status. See Status filtering. |
format | "CSV" | "JSON" | Yes | — | The output format. |
By default, the Movement Report includes only settled transactions—those with a custody status of Completed and a ledger status of Confirmed. This default is designed for reconciliation, where you want only finalized activity.
To include other statuses, pass the full set of values you want:
| Field | Accepted values |
|---|---|
custodyStatus | Broadcasting, Completed, Failed, Interrupted, Pending, Prepared, Preparing, Reserved |
ledgerStatus | Detected, Confirmed, Expired, Replaced |
To retrieve every status, pass all values explicitly. Omit a field to keep its settled-only default. Sending an empty array ([]) returns a 400 error—each status filter must contain at least one value when provided.
curl -X POST "https://{host}/v1/exports/movement" \
-H "Authorization: Bearer <jwt>" \
-H "Content-Type: application/json" \
-d '{
"domainId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"dateRange": {
"start": "2026-06-01T00:00:00Z",
"end": "2026-06-15T23:59:59Z"
},
"includeChildDomains": false,
"custodyStatus": ["Completed"],
"ledgerStatus": ["Confirmed"],
"format": "CSV"
}'The response is returned 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.
Each row represents one transfer. Column order is a fixed contract. The report-level domainId and domainName come from your request. The per-transfer senderDomainId and recipientDomainId identify the domains of the counterparties.
| # | Column | Type | Nullable | Description |
|---|---|---|---|---|
| 1 | domainId | string (UUID) | No | The report-level domain from your request. |
| 2 | domainName | string | No | The report-level domain's display name. |
| 3 | registeredAt | string (ISO 8601) | No | When the service registered the transfer. |
| 4 | transactionId | string (UUID) | No | The transaction identifier. Repeated for all transfers in the same transaction. |
| 5 | onLedgerTransactionId | string | Yes | The on-chain transaction hash. Empty until the transaction is confirmed. |
| 6 | transferId | string (UUID) | No | The transfer identifier, unique per row. |
| 7 | transferKind | string | No | The transfer type. One of Transfer, Fee, or Recovery. |
| 8 | enrichedTransactionValue | string (decimal) | No | The human-readable decimal value, such as 1.5 XRP. |
| 9 | rawTransactionValue | string | No | The raw ledger-native value, such as 1500000 drops. No decimal conversion. |
| 10 | ledgerName | string | No | The blockchain network name as configured by the operator, such as XRPL Testnet August 2024 or Ethereum Mainnet. |
| 11 | tickerId | string (UUID) | No | The asset identifier. |
| 12 | tickerName | string | No | The full asset name. |
| 13 | tickerSymbol | string | Yes | The asset symbol. Empty if not set. |
| 14 | quarantined | boolean | No | Whether this transfer is quarantined. |
| 15 | custodyStatus | string | No | The custody processing status. |
| 16 | ledgerStatus | string | No | The ledger confirmation status. |
| 17 | ledgerTimestamp | string (ISO 8601) | Yes | When the service last updated the ledger status. |
| 18 | blockTime | string (ISO 8601) | Yes | The on-chain block time. Empty until confirmation. |
| 19 | senderAddress | string | Yes | The on-chain sender address. |
| 20 | senderDomainId | string (UUID) | Yes | The sender account's domain. Empty for external senders. |
| 21 | senderMemoTag | string | Yes | The XRPL source tag. Empty for non-XRPL chains. |
| 22 | senderInternal | boolean | No | true if the sender is within the platform. |
| 23 | senderName | string | Yes | The sender account's display name. |
| 24 | senderId | string (UUID) | Yes | The sender account identifier. |
| 25 | senderAccountType | string | Yes | The sender account type, currently vault or gas station. Empty for external senders; pipe-separated for multi-sender transfers. |
| 26 | senderVaultType | string | Yes | The sender vault's backing type passed through from the core system, such as MPC or HSM, or external if the sender is off-platform. |
| 27 | senderVaultId | string (UUID) | Yes | The sender vault identifier. Empty for external senders. |
| 28 | senderVaultName | string | Yes | The sender vault's display name. Empty for external senders. |
| 29 | recipientAddress | string | Yes | The on-chain recipient address. |
| 30 | recipientDomainId | string (UUID) | Yes | The recipient account's domain. Empty for external recipients. |
| 31 | recipientMemoType | string | Yes | The memo type for Stellar transfers (Text, Id, Hash, Return). Empty for XRPL and Hedera. |
| 32 | recipientMemoTag | string | Yes | The XRPL destination tag, Stellar memo value, or Hedera memo string. |
| 33 | recipientInternal | boolean | No | true if the recipient is within the platform. |
| 34 | recipientName | string | Yes | The recipient account's display name. Empty for external recipients. |
| 35 | recipientId | string (UUID) | Yes | The recipient account identifier. Empty for external recipients. |
| 36 | recipientAccountType | string | Yes | The recipient account type, currently vault or gas station. Empty for external recipients. |
| 37 | recipientVaultType | string | Yes | The recipient vault's backing type passed through from the core system, such as MPC or HSM, or external if the recipient is off-platform. |
| 38 | recipientVaultId | string (UUID) | Yes | The recipient vault identifier. Empty for external recipients. |
| 39 | recipientVaultName | string | Yes | The recipient vault's display name. Empty for external recipients. |
The report includes both a converted and a raw value for each transfer:
enrichedTransactionValueis the human-readable decimal value in the asset's native unit, such as1.5XRP. Use this for reconciliation and reporting.rawTransactionValueis the raw ledger-native value in the smallest denomination, such as1500000drops. The service doesn't convert it to decimal.
Both are strings. Always parse them as strings. See Financial precision.
Network fees appear as their own rows with a transferKind of Fee. The report doesn't link a fee row to the transfer that incurred it — if your reconciliation needs fees attributed to specific transfers, match them downstream using the transactionId or onLedgerTransactionId columns.
When a transfer has multiple senders—for example, on UTXO-model chains—the service separates all sender-side fields with a pipe (|) within the cell, in a consistent order across every sender field. This lets you align the sender attributes positionally.
When a sender or recipient is off-platform, the service uses a consistent external convention: the counterparty's ...VaultType is external, its ...DomainId and ID fields are empty, and its ...Internal flag is false.
The metadata header includes the following control total, a sum across every row in the report. Use it to verify that your ingested file is complete and uncorrupted. For how to verify, see Control totals.
| Field | Description |
|---|---|
valueSum | The sum of all enrichedTransactionValue values. |
If the service returns an error, the response body is a client-safe JSON object and never exposes internal details. Common cases for the Movement Report include:
400: A required field is missing, a UUID or timestamp is malformed,dateRange.endis beforestart, the range exceeds 30 days, a status array is empty, or a filter array exceeds 1,000 entries.401: The JWT is missing or invalid.403: You lack access to the target domain.413: The request scope exceeds a report limit — either more than 100 accessible domains, or a result that would exceed 100,000 transfers.429: A duplicate request within 60 seconds while a previous export is still processing, or you already have 2 exports processing.
A single Movement Report can return at most 100,000 transfers. If your scope exceeds this, the service returns a 413 error after resolving your requested scope, before generating the file. Narrow the date range or add filters, then request again.
For the full list, see Error responses.
| Page | Description |
|---|---|
| Position Report | Generate a point-in-time balance snapshot. |
| Export reference | Look up output formats, financial precision rules, access control, operational limits, and error responses. |
| Data export overview | Review report types, export metadata, and control totals. |