diff --git a/api-reference/fx-payment/reports/get-report.mdx b/api-reference/fx-payment/reports/get-report.mdx new file mode 100644 index 0000000..e24faab --- /dev/null +++ b/api-reference/fx-payment/reports/get-report.mdx @@ -0,0 +1,5 @@ +--- +title: "Get a report" +description: "Aggregated view of operations over a time window, partitioned by asset." +openapi: "apis/fx-payment/openapi.yml GET /api/reports" +--- diff --git a/apis/fx-account/openapi.yml b/apis/fx-account/openapi.yml index cf5a298..f4084bd 100644 --- a/apis/fx-account/openapi.yml +++ b/apis/fx-account/openapi.yml @@ -359,8 +359,18 @@ components: $ref: "#/components/schemas/RequirementsResponse" tags: type: array + description: > + System-managed labels attached to the account. Some tags + propagate to operations executed against this account. items: $ref: "#/components/schemas/TagResponse" + example: + - key: "psp" + value: "Amazon" + - key: null + value: "hidden" + - key: "compliance-tier" + value: "high" currentState: $ref: "#/components/schemas/AccountState" states: @@ -1160,12 +1170,24 @@ components: - AX TagResponse: type: object + description: > + A label attached to a resource. Tags are system-managed — Trace + assigns them based on routing, compliance, and operational criteria. + Clients cannot create, modify, or remove tags via the API. properties: key: type: string nullable: true + description: > + Category for keyed tags (e.g., `psp`, `compliance-tier`). + `null` for single-value labels. + example: "psp" value: type: string + description: > + For keyed tags, the right-hand side of the label. For + single-value labels, the entire tag. + example: "Amazon" required: - value UBOResponse: diff --git a/apis/fx-payment/openapi.yml b/apis/fx-payment/openapi.yml index 7da51e2..683da86 100644 --- a/apis/fx-payment/openapi.yml +++ b/apis/fx-payment/openapi.yml @@ -15,6 +15,8 @@ security: tags: - name: Operations description: Create deposits, withdrawals, and swaps. Query operation status and history. + - name: Reports + description: Generate aggregated views of operations across a time window. - name: Beneficiaries description: Manage external beneficiaries and their payment instructions for withdrawals. - name: Payment instructions @@ -118,10 +120,35 @@ components: description: > Filter expression using LHS Brackets syntax (`field[operator]=value`). Combine multiple conditions with `and(...)`, `or(...)`, or `;` (implicit AND). - See the [Filtering](/guides/principles/filtering) guide for the full operator catalog and examples. + See the [Filtering](/guides/principles/filtering) guide for the full operator catalog. schema: type: string example: "intent.type[eq]=WITHDRAWAL;currentState.status[eq]=COMPLETED" + PeriodStart: + name: periodStart + in: query + required: true + description: > + Inclusive start of the reporting window. UTC timestamp in ISO 8601 format — + the `Z` suffix is the timezone marker and is required (e.g., `2026-04-01T00:00:00Z`). + See the [Date and time](/guides/principles/datetime) guide for the full format. + schema: + type: string + format: date-time + example: "2026-04-01T00:00:00Z" + PeriodEnd: + name: periodEnd + in: query + required: true + description: > + Exclusive end of the reporting window. UTC timestamp in ISO 8601 format — + the `Z` suffix is the timezone marker and is required (e.g., `2026-05-01T00:00:00Z`). + Must be strictly greater than `periodStart`. + See the [Date and time](/guides/principles/datetime) guide for the full format. + schema: + type: string + format: date-time + example: "2026-05-01T00:00:00Z" schemas: # ── Shared value objects ────────────────────────────────────────── Asset: @@ -229,6 +256,28 @@ components: required: - id - owner + TagResponse: + type: object + description: > + A label attached to a resource. Tags are system-managed — Trace + assigns them based on routing, compliance, and operational criteria. + Clients cannot create, modify, or remove tags via the API. + properties: + key: + type: string + nullable: true + description: > + Category for keyed tags (e.g., `psp`, `compliance-tier`). + `null` for single-value labels. + example: "psp" + value: + type: string + description: > + For keyed tags, the right-hand side of the label. For + single-value labels, the entire tag. + example: "Amazon" + required: + - value Reason: type: object description: Machine- and human-readable explanation. Returned inside an `OperationState` entry when a status transition requires justification (e.g., `FAILED`, `ON_HOLD`). @@ -704,6 +753,66 @@ components: - code - message + # ── Report schemas ──────────────────────────────────────────────── + # Documented here ahead of the Report domain model and controller. + ReportPeriod: + type: object + description: The reporting window. Boundary semantics are half-open — `start` inclusive, `end` exclusive. + properties: + start: + type: string + format: date-time + description: Inclusive start of the reporting window. + example: "2026-04-01T00:00:00Z" + end: + type: string + format: date-time + description: Exclusive end of the reporting window. + example: "2026-05-01T00:00:00Z" + required: + - start + - end + ReportAggregate: + type: object + description: Sum and count of monetary movements on a single side of the ledger within an asset partition. + properties: + sum: + $ref: "#/components/schemas/AmountResponse" + count: + type: integer + minimum: 0 + description: Number of contributing transactions. + example: 3 + required: + - sum + - count + ReportTotal: + type: object + description: Inflows and outflows for one asset over the reporting window. A row is present only when at least one settled transaction in that asset matched the filter. + properties: + asset: + $ref: "#/components/schemas/Asset" + inflows: + $ref: "#/components/schemas/ReportAggregate" + outflows: + $ref: "#/components/schemas/ReportAggregate" + required: + - asset + ReportResponse: + type: object + description: Aggregated view of operations over a time window. Generated on each request — not persisted. + properties: + period: + $ref: "#/components/schemas/ReportPeriod" + totals: + type: array + description: One entry per asset that had at least one settled transaction matching the filter in the period. Empty when nothing matched. + items: + $ref: "#/components/schemas/ReportTotal" + required: + - period + - totals + # ── Quote schemas ───────────────────────────────────────────────── CreateQuoteRequest: type: object @@ -1009,6 +1118,18 @@ components: type: array items: $ref: "#/components/schemas/OperationTransaction" + tags: + type: array + description: > + System-managed labels stamped onto the operation when it is + created. Inherited from the account's propagating tags. + items: + $ref: "#/components/schemas/TagResponse" + example: + - key: "psp" + value: "Amazon" + - key: "compliance-tier" + value: "high" currentState: $ref: "#/components/schemas/OperationState" states: @@ -2164,6 +2285,85 @@ components: message: "Parameter 'body:accountId' not found in request" field: "body:accountId" params: {} + ReportMultiAssetActivity: + summary: Mixed deposits and withdrawals across BRL and USDT + value: + period: + start: "2026-04-01T00:00:00Z" + end: "2026-05-01T00:00:00Z" + totals: + - asset: "BRL" + inflows: + sum: + value: "5000.00" + asset: "BRL" + decimals: 2 + count: 2 + outflows: + sum: + value: "10000.00" + asset: "BRL" + decimals: 2 + count: 2 + - asset: "USDT" + outflows: + sum: + value: "2000.000000" + asset: "USDT" + decimals: 6 + count: 2 + ReportWithdrawalsOnly: + summary: Filtered to withdrawals only — no inflows + value: + period: + start: "2026-04-01T00:00:00Z" + end: "2026-05-01T00:00:00Z" + totals: + - asset: "BRL" + outflows: + sum: + value: "10000.00" + asset: "BRL" + decimals: 2 + count: 2 + - asset: "USDT" + outflows: + sum: + value: "2000.000000" + asset: "USDT" + decimals: 6 + count: 2 + ReportEmptyPeriod: + summary: No settled transactions matched the filter in the period + value: + period: + start: "2026-04-01T00:00:00Z" + end: "2026-05-01T00:00:00Z" + totals: [] + ReportMissingPeriodStart: + summary: periodStart is missing from the query string + value: + code: "INVALID_DATA" + message: "Object contains invalid data" + details: + errors: + - code: "REQUIRED" + message: "Parameter 'query:periodStart' not found in request" + field: "query:periodStart" + params: {} + ReportPeriodEndNotAfterStart: + summary: periodEnd must be strictly greater than periodStart + value: + code: "INVALID_DATA" + message: "Object contains invalid data" + details: + errors: + - code: "INVALID_RANGE" + message: "'periodEnd' must be greater than 'periodStart'" + field: "query:periodEnd" + params: + periodStart: "2026-05-01T00:00:00Z" + periodEnd: "2026-04-01T00:00:00Z" paths: # ── Operations: Withdrawals ─────────────────────────────────────── @@ -2231,6 +2431,11 @@ paths: decimals: 2 fees: [] transactions: [] + tags: + - key: "psp" + value: "Amazon" + - key: "compliance-tier" + value: "high" currentState: status: "REQUESTED" createdAt: "2026-04-25T02:39:17Z" @@ -2455,6 +2660,11 @@ paths: decimals: 2 fees: [] transactions: [] + tags: + - key: "psp" + value: "Amazon" + - key: "compliance-tier" + value: "high" currentState: status: "REQUESTED" createdAt: "2026-04-27T14:12:33Z" @@ -2617,6 +2827,11 @@ paths: decimals: 2 fees: [] transactions: [] + tags: + - key: "psp" + value: "Amazon" + - key: "compliance-tier" + value: "high" currentState: status: "REQUESTED" createdAt: "2026-04-27T15:08:21Z" @@ -3014,6 +3229,63 @@ paths: field: "query:status" params: {} + # ── Reports ─────────────────────────────────────────────────────── + /api/reports: + get: + operationId: getReport + tags: + - Reports + summary: Get a report + description: | + Generates an aggregated view of operations over a time window. Activity is partitioned by `asset` because amounts in different currencies cannot be summed. Only settled transactions (`CONFIRMED` status) on operations matching `filters` contribute — pending and failed are excluded. The report is regenerated on each request and is not persisted. + parameters: + - $ref: "#/components/parameters/TraceVersion" + - $ref: "#/components/parameters/PeriodStart" + - $ref: "#/components/parameters/PeriodEnd" + - $ref: "#/components/parameters/Filters" + description: | + Common filters for reports: + + - `account.id[eq]=a1b2c3d4-5e6f-7890-abcd-ef1234567890` — single account + - `asset[eq]=USD` — specific currency + - `tags.key[eq]=psp` — operations carrying a tag with this key + - `tags.value[eq]=Amazon` — operations carrying a tag with this value + + See the [Filtering](/guides/principles/filtering) guide for the LHS Brackets syntax and the full operator catalog. + responses: + "200": + description: Aggregated report for the requested window. + headers: + X-Request-Id: + $ref: "#/components/headers/RequestId" + content: + application/json: + schema: + $ref: "#/components/schemas/ReportResponse" + examples: + multiAssetActivity: + $ref: "#/components/examples/ReportMultiAssetActivity" + withdrawalsOnly: + $ref: "#/components/examples/ReportWithdrawalsOnly" + emptyPeriod: + $ref: "#/components/examples/ReportEmptyPeriod" + "401": + $ref: "#/components/responses/UnauthorizedError" + "422": + description: Invalid query parameter or filter expression. + headers: + X-Request-Id: + $ref: "#/components/headers/RequestId" + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + examples: + missingPeriodStart: + $ref: "#/components/examples/ReportMissingPeriodStart" + periodEndNotAfterStart: + $ref: "#/components/examples/ReportPeriodEndNotAfterStart" + # ── Beneficiaries ───────────────────────────────────────────────── /api/beneficiaries: post: diff --git a/apis/fx-webhook/openapi.yml b/apis/fx-webhook/openapi.yml index b1fe065..9c8e134 100644 --- a/apis/fx-webhook/openapi.yml +++ b/apis/fx-webhook/openapi.yml @@ -1057,6 +1057,27 @@ components: - relationshipType - instruction - atTime + TagEvent: + type: object + description: > + A label attached to a resource. Tags are system-managed — Trace + assigns them based on routing, compliance, and operational criteria. + properties: + key: + type: string + nullable: true + description: > + Category for keyed tags (e.g., `psp`, `compliance-tier`). + `null` for single-value labels. + example: "psp" + value: + type: string + description: > + For keyed tags, the right-hand side of the label. For + single-value labels, the entire tag. + example: "Amazon" + required: + - value OperationEvent: type: object description: > @@ -1094,6 +1115,16 @@ components: description: Underlying rail transactions executed for this operation. items: $ref: "#/components/schemas/TransactionEvent" + tags: + type: array + description: System-managed labels stamped onto the operation when it is created. Inherited from the account's propagating tags. + items: + $ref: "#/components/schemas/TagEvent" + example: + - key: "psp" + value: "Amazon" + - key: "compliance-tier" + value: "high" atTime: type: string format: date-time diff --git a/docs.json b/docs.json index 83c18d4..0545612 100644 --- a/docs.json +++ b/docs.json @@ -139,6 +139,13 @@ "api-reference/fx-payment/operations/list-operations" ] }, + { + "group": "Reports", + "icon": "chart-line", + "pages": [ + "api-reference/fx-payment/reports/get-report" + ] + }, { "group": "Quotes", "icon": "scale-balanced",