# Reports

> Coming soon, upon request — this feature is turned on for your tenant by the Aurea team. [Contact us](https://www.aureahub.com/contact)

Your tenant's movements, balances, addresses and approvals as a CSV or JSON file — made in the background, downloaded through a signed link that works for five minutes.

## Overview

1. [Ask for a report](https://docs.aureahub.com/docs/report-request.md): its `type`, its `format` (`csv` or `json`) and optional `filters`. The answer is `202` with the report `queued`.
2. [Read it](https://docs.aureahub.com/docs/report-get.md) until its `status` is `ready` — `queued`, `running`, then `ready` or `failed` (`failureCode` says why). A ready report's read carries `download`: a signed link and its `expiresAt`.
3. [Download the file](https://docs.aureahub.com/docs/report-download.md) through that link, before it expires. Each read of a ready report gives a new link. The file is kept for 24 hours by default; then the report is `expired`: ask for it again.

- **Who**: your tenant's `owner`, `tenantadmin`, `non_signing_admin`, `auditor`, `security_admin` and `security_auditor`, with their access token, on their own tenant: a report is a bulk read of your users' data. The routes are `/v1/admin/tenants/{id}/reports`, under **Reports** in the API Reference; [List Reports](https://docs.aureahub.com/docs/reports-list.md) lists them.
- **Recorded** in your [audit trail](https://docs.aureahub.com/docs/audit-events.md) [Coming soon, upon request](https://docs.aureahub.com/docs/feature-availability.md) (category `access`): `report.requested`, `report.generated` and each `report.downloaded`.

## Coming soon, upon request

Reports are available on request [Coming soon, upon request](https://docs.aureahub.com/docs/feature-availability.md). Until then, asking for one answers `503` `REPORTS_OFF` (`Reports are switched off on this platform`), and nothing is recorded.

## The Four Reports

| type | One row per | Columns, in order |
| --- | --- | --- |
| movements | Transaction of your tenant as recorded, and transfer into your wallets Aurea recorded — oldest first (Movements, below). | `source`, `id`, `createdAt`, `chain`, `isTestnet`, `txHash`, `type`, `status`, `direction`, `from`, `to`, `amount`, `tokenAddress`, `tokenSymbol`, `tokenDecimals`, `fee`, `blockNumber`, `blockTime`, `walletId`, `accountId`, `userId` |
| balances | Active wallet, chain and asset: its balance read now (Balances, below). | `walletId`, `accountId`, `userId`, `chain`, `isTestnet`, `address`, `asset`, `symbol`, `decimals`, `balance`, `status`, `readAt` |
| addresses | Wallet of your tenant — deactivated ones too, with `deactivatedAt` —, with its account and the account's `customerRefId`. | `walletId`, `accountId`, `customerRefId`, `userId`, `chain`, `isTestnet`, `address`, `walletType`, `keyManagementScheme`, `isPrimary`, `label`, `createdAt`, `deactivatedAt` |
| approvals | Approval request of your operations ([Approvals](https://docs.aureahub.com/docs/guide-approvals.md)), with its counts and `decidedBy` — `<approver id>:<decision>`, separated by `;`, in time order. | `approvalId`, `operationId`, `status`, `origin`, `ruleName`, `threshold`, `chain`, `chainId`, `asset`, `amount`, `destination`, `initiatorUserId`, `approvals`, `rejections`, `decidedBy`, `createdAt`, `expiresAt`, `decidedAt` |

- **Filters**: `walletIds` and `accountIds` (up to 100 each), `chains` (up to 20, as wallets and tokens name them: `base`, `polygon`, `solana`…); `from` (created at or after) and `to` (created before) for movements and approvals only.
- **Every row names its wallet's [account](https://docs.aureahub.com/docs/guide-accounts.md)** when the report is made: the account that holds the wallet, else its user's default account (the user's id). `accountIds` filters by it.
- Amounts are in the asset's smallest unit, as decimal text.

## Movements

Two sources, merged into one list oldest first by `createdAt`; every filter applies to both.

| Column | source `transaction` | source `inbound_transfer` |
| --- | --- | --- |
| What it is | A transaction your tenant's wallets made, as recorded ([Get Transaction](https://docs.aureahub.com/docs/tx-get.md)). | A transfer into one of your wallets, from any address — the native coin or one of your tenant's tokens —, once received transfers are recorded (coming: [Feature Availability](https://docs.aureahub.com/docs/feature-availability.md)). One a chain re-organisation took away is left out. |
| id, createdAt | The transaction's id, and when it was recorded. | The transfer's id, and when Aurea recorded it. |
| type | As recorded: `transfer`, `token_transfer`, `swap`, `contract_call`, `contract_deployment`. | `transfer` (the native coin) or `token_transfer`. |
| status, direction | Its status; `sent` or `received` as seen from its wallet, `swap`, `contract_call` or `contract_deployment`. | `confirmed`, `received`. |
| from, to, amount, token | As recorded. | As recorded: the token's contract (or mint), symbol and decimals; empty for the native coin. |
| fee | Its fee. | Empty: the sender paid it. |
| blockNumber, blockTime | Its block, once mined. | Its block (a Solana slot) and its time. |

## Balances

- Each active wallet's balance **read now** through your tenant's own node, per chain and asset: the native coin, then every token your tenant lists on that chain.
- An EVM wallet on its own chain and on every EVM chain your tenant enabled on the same network — one address, read once per chain.
- A Solana wallet: its SOL, and the SPL tokens your tenant lists on Solana, each summed over the wallet's accounts of that mint.
- `status` `read`, or `unread` when the node did not answer or answered something else: the balance is then empty — never a guess, never a `0` it was not told. `readAt`: when it was read.

## The File

- **CSV**: RFC 4180 — a header row of the columns above, comma-separated, CRLF line ends, a field quoted when it holds a comma, a quote or a line break —, UTF-8 without a byte-order mark. A text a spreadsheet would run as a formula (one that begins with `=`, `+`, `-`, `@`, a tab or a carriage return and is not a plain number) is written with a leading apostrophe. Empty for what is unknown.
- **JSON**: one object, `{ "report": { "id", "tenantId", "type", "format", "filters", "generatedAt", "columns" }, "rows": [ … ], "rowCount" }`, one row per line, the columns in order; `null` for what is unknown.
- `rowCount`, `byteSize` and `sha256` (the file's SHA-256, hex) are in the report's read once it is ready; the download repeats the hash in `x-content-sha256`.

## The Download Link

- `download.url` is a path on this API, `/v1/admin/tenants/{id}/reports/{reportId}/download?expires=…&signature=…`: prefix it with `https://api.aureahub.com`.
- **It works on its own** — no token, no signature headers — for five minutes (`download.expiresAt`), for this report of your tenant only. Whoever holds it can download the file until then: hand it only to whom it is meant for — an accountant, a script —, and read the report again for a new one.
- Expired: `410` `REPORT_LINK_EXPIRED`. Changed, or another report's or tenant's: `403` `REPORT_LINK_INVALID`. A token sent with it changes nothing: only the link opens the file.

## Limits and Codes

| Status | details.code | When |
| --- | --- | --- |
| 503 | REPORTS_OFF | Asking for a report while your tenant does not have reports. |
| 429 | REPORTS_TOO_MANY | `Too many reports are waiting to be made`: your tenant has 5 queued or running (by default). Ask again once one is made. |
| 400 | REPORT_FILTER_INVALID | `from and to filter movements and approvals only`, or `from must be before to`. Another filter of the wrong form answers `400` `Request validation failed`. |
| 404 | REPORT_NOT_FOUND | `Report not found`: none of your tenant's. |
| 409 | REPORT_NOT_READY | `The report is not ready`: download it once it is. |
| 403 | REPORT_LINK_INVALID | `Not a download link for this report` |
| 410 | REPORT_LINK_EXPIRED | `The download link has expired: read the report for a new one` |
| 410 | REPORT_EXPIRED | `The report's file was deleted: ask for the report again` — after 24 hours, by default. |
| 410 | REPORT_FILE_GONE | `The report's file is not there any more: ask for the report again` |
| — | REPORT_TOO_LARGE | A report's `failureCode`: more than 100,000 rows (by default) — narrow the filters. No file is left. |
| — | REPORT_GENERATION_FAILED | A report's `failureCode`: it could not be made after three attempts. Ask again. |

The download allows 30 requests a minute from one address; more answer `429`.

---

Web version: https://docs.aureahub.com/#guide-reports
