GuidesReports and snapshots

Build a report and capture a snapshot

Build a live report (account statement), capture an immutable snapshot with a hash, and export it to JSON/CSV.

Reports come in two kinds: live reports (which change along with the data) and snapshots (captured with a hash and reproducible). For statements and reconciliations, you capture a snapshot and then export it. For immutability and point-in-time balances, see Ledger.

The path from data to export:

Prerequisites

  • The Vault's code and a period (from / to).
  • An access token (see Authentication).
  • A snapshot id, for reading and exporting.

When to use a live report and when to use a snapshot:

Live reportSnapshot
datacurrent, changingcaptured as of dataCutoff
reproducibilitynoyes (canonical sha256)
export-json / csv
use casequick reviewstatements, reconciliation, audit

Step 1. Build a live report

GET /api/v1/vaults/{code}/reports/account_statement builds a statement for a period.

curl "[BASE_URL]/api/v1/vaults/acme-otc/reports/account_statement?from=2026-03-01&to=2026-03-31&timezone=UTC" \
  -H "Authorization: Bearer $V3_TOKEN"

Statement parameters:

ParameterRequiredPurpose
from / toyesperiod boundaries
timezonenotime zone for day boundaries
userIdnoadmin: narrow down to a user
breakdownBy=ownernobreakdown by owner

A live report reflects the current state of the data. Other reports are available too:

ReportRequest
account statementGET .../reports/account_statement
approval activityGET .../reports/approval_activity
flat operations register by filtersPOST .../reports/query-operations

Step 2. Capture a snapshot

POST /api/v1/vaults/{code}/report-snapshots generates the report, records the dataCutoff, and stores the result along with an operations manifest and a canonical sha256.

curl -X POST "[BASE_URL]/api/v1/vaults/acme-otc/report-snapshots" \
  -H "Authorization: Bearer $V3_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "reportType": "account_statement",
    "from": "2026-03-01",
    "to": "2026-03-31",
    "timezone": "UTC"
  }'

A snapshot is immutable: viewing it again returns the same figures, even if operations, exchange rates, or names have changed since (retroactive matches, renames). A result that's too large (>~900KB) returns REPORT_PERIOD_TOO_LARGE; narrow the filters. Check the exact body schema in the API Reference.

Step 3. Find and read snapshots

ActionRequest
list (filters: reportType, limit)GET .../report-snapshots
single snapshotGET .../report-snapshots/{id}
deleteDELETE .../report-snapshots/{id}
exportPOST .../report-snapshots/{id}/exports

Step 4. Export the snapshot

The export is built from the snapshot, not from a live query, so it always matches the captured figures:

curl -X POST "[BASE_URL]/api/v1/vaults/acme-otc/report-snapshots/SNAPSHOT_ID/exports" \
  -H "Authorization: Bearer $V3_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "format": "csv" }'

Supported export formats:

FormatStatus
jsonsupported
csvsupported (flat operations register)
xlsxreserved → REPORT_UNSUPPORTED_FORMAT
pdfreserved → REPORT_UNSUPPORTED_FORMAT

Currently, json and csv are supported. xlsx and pdf are reserved for now and return REPORT_UNSUPPORTED_FORMAT until a future release.

Common mistakes

SymptomCause
REPORT_PERIOD_TOO_LARGEthe result is > ~900KB; narrow the period or filters
REPORT_UNSUPPORTED_FORMATxlsx/pdf was requested; only json/csv for now
figures "drift" between exportsthe export came from a live query, not a snapshot
snapshot doesn't match expectationscheck dataCutoff: data after it isn't included
empty reportfrom/to weren't set, or the period has no data

You're done when

  • the live report returns data for the period;
  • POST /report-snapshots returned a snapshot with a dataCutoff and sha256;
  • GET .../report-snapshots/{id} returns the same figures on repeated reads;
  • the export (json/csv) is built from the snapshot and matches it.

Next steps