Skip to content
Executive summary

This page defines the behaviors shared by every export: authentication, access control, output formats, financial precision, operational limits, and error responses.

  • Requests use bearer-token authentication, and the service authorizes them against the target domain only.
  • Reports are returned as CSV or JSON, with all financial values as strings.
  • Per-request limits protect the service and keep exports predictable.

Authentication

Every request must include a valid JSON Web Token (JWT) in the Authorization header:

Authorization: Bearer <jwt>

The service uses a user-based authentication model. There's no separate machine credential flow: you must register even bot and service accounts as users with the appropriate roles in each domain they need to access. This ensures every export traces back to a specific, verifiable identity.

The token subject identifies the requesting user in providerId:loginId form. The service records this identity as the request author in every export's metadata.

Access control

Authorization is target-domain-only. To generate a report for a domain, all of the following must be true:

  1. You have a profile in the exact target domain.
  2. Your user account is unlocked.
  3. The target domain is unlocked.
  4. One of your roles grants read access to the relevant entity type in that domain.

The entity type depends on the report:

ReportRequired read access
Position Reportaccounts
Movement Reporttransactions

The service verifies domain access before running any data query. If you lack access, it contacts neither the balance source nor the database.

No inheritance from parent domains

A profile in a parent domain does not grant access to its children. You must hold a profile with a matching role in each domain you want to export. This prevents broad, unintended access through high-level parent profiles.

Export access can differ from UI access

The export service's access check can be stricter than the access you appear to have in the Ripple Custody UI. Even where the UI shows you a domain's data, the export service requires a profile with a matching role in that exact domain. If an export returns 403 or omits domains you expect, check your per-domain profiles rather than what the UI displays.

Including child domains

When you set includeChildDomains to true, the service resolves the full domain tree and checks each child domain independently, using the same target-domain-only rule. It includes children you can access and silently omits children you can't access. You receive a valid report containing only the domains you're entitled to, with no error about the domains it excluded.

Common behaviors

Synchronous delivery

Each request returns the complete report file in one synchronous response. The service does not paginate results. To keep reports within the operational limits, narrow the scope with filters or a shorter date range and split large exports into several requests.

Request method and content type

Both endpoints accept POST requests with a Content-Type of application/json.

Response headers

HeaderDescription
Content-Typetext/csv; charset=utf-8 for CSV, or application/json for JSON.
Content-Dispositionattachment with a generated filename based on the report type, domain, and range.
X-Export-IdThe UUID of the export, for support tracing and audit.

Duplicate request protection

If you submit the same parameters again within 60 seconds while a previous export is still processing, the service returns 429. This prevents an accidental double-submission from triggering redundant work.

Concurrency limit

You can have at most 2 exports processing at any time. A third concurrent request returns 429. Wait for an in-flight export to finish, then retry.

Output formats

Select the format with the format field in the request body.

CSV

The service encodes CSV files as UTF-8 with a byte order mark (BOM) for spreadsheet compatibility, and uses \r\n (CRLF) line endings. The structure is:

LineContent
1The metadata header, prefixed with # metadata: followed by a JSON object.
2The column headers, matching the report's column contract.
3+One data row per record.

All financial values are quoted strings (for example, "0.000000000000000001"). This prevents spreadsheet software and CSV parsers from silently truncating high-precision decimals.

JSON

JSON responses wrap the data in a metadata envelope:

{
  "metadata": {
    "exportId": "uuid",
    "requestAuthor": "providerId:loginId",
    "generatedAt": "ISO-8601",
    "filters": { },
    "recordCount": 1234,
    "controlTotals": { }
  },
  "data": [ ]
}

The metadata also carries the report's time parameters: asOfTimestamp for the Position Report, and dateRangeStart and dateRangeEnd for the Movement Report.

Financial values in JSON are strings, never bare numbers. Always parse them as strings.

Financial precision

The service exports every financial value as a decimal string in the asset's native unit, with precision matching the asset's decimal places. It never exports raw blockchain denominations (except the Movement Report's explicit rawTransactionValue column) or scientific notation.

AssetRaw value (stored)DecimalsExported value
XRP300000063.000000
ETH50000000000000000180.050000000000000000
BTC10000000081.00000000
Always parse financial values as strings

Financial values are strings in both CSV and JSON. Never parse them as floating-point numbers. Standard double-precision numbers lose accuracy beyond roughly 15 significant digits, and some assets carry many more decimal places—ETH has 18, and some ledgers support far more. Parsing as a number silently corrupts the value.

The service rounds down, consistent with banking practice: an export never reports more value than actually exists.

Operational limits

LimitValue
Maximum date range (Movement Report)30 days
Maximum filter array size (vaultIds, tickerIds, accountIds)1,000 entries per array
Maximum transfers per Movement Report100,000 rows
Duplicate detection window60 seconds
Maximum concurrent exports per user2
Maximum rows per Position Report100,000 rows
Maximum accessible domains per request (with includeChildDomains)100 domains
Stale export release window5 minutes

Error responses

Errors return a standard HTTP status code with a client-safe JSON body. Error messages never expose internal details such as query fragments, stack traces, service names, or file paths. The service logs detailed diagnostics on the server against the export ID for correlation.

CodeMeaningWhen it occurs
400Bad RequestA validation failure: a missing required field, a malformed UUID or timestamp, a future timestamp, a date range over 30 days, an end before start, an empty status array, or a filter array over 1,000 entries.
401UnauthorizedThe JWT is missing or invalid.
403ForbiddenYou lack access to the target domain: no profile, a locked user, a locked domain, or an insufficient role.
413Payload Too LargeThe request scope exceeds a report limit — either more than 100 accessible domains, or a result that would exceed 100,000 rows. Narrow the range or add filters and retry.
429Too Many RequestsA duplicate request within 60 seconds while a previous export is still processing, or you already have 2 exports processing.
502Bad GatewayThe upstream balance source returned an error (Position Report only).
504Gateway TimeoutThe export exceeded the service's internal time budget.

Error response body

Every error body carries a numeric statusCode, a short error label, and a message:

{
  "message": "Access denied",
  "error": "Forbidden",
  "statusCode": 403
}

For 400 validation failures, message is an array of one or more client-safe validation strings that name the offending field:

{
  "message": ["asOfTimestamp must not be in the future"],
  "error": "Bad Request",
  "statusCode": 400
}

Every message value is client-safe: it never exposes internal details such as query fragments, stack traces, service names, or file paths.


Next steps

PageDescription
Data export overviewReview report types, export metadata, and control totals.
Position ReportGenerate a point-in-time balance snapshot.
Movement ReportGenerate a transaction history for a date range.