From de8ba9bba636070bf06d086d8f07bcb152cabf8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rio=20Alvial?= Date: Tue, 14 Apr 2026 20:50:41 -0300 Subject: [PATCH 1/4] docs: complete fx-payment OpenAPI spec with all endpoint schemas Replace all 12 TODO stubs with full request/response schemas, reusable parameters, and examples for deposits, withdrawals, swaps, operations, beneficiaries, and payment instructions. --- apis/fx-payment/openapi.yml | 1416 +++++++++++++++++++++++++++++++---- 1 file changed, 1259 insertions(+), 157 deletions(-) diff --git a/apis/fx-payment/openapi.yml b/apis/fx-payment/openapi.yml index 0c19aaf..68d5dc0 100644 --- a/apis/fx-payment/openapi.yml +++ b/apis/fx-payment/openapi.yml @@ -5,8 +5,6 @@ info: description: | API for deposits, withdrawals, swaps, and beneficiary management on the Trace FX platform. - - **This spec is a scaffold — endpoints require request/response schemas.** servers: - url: https://faas.sandbox.tracefinance.io/payment description: Sandbox @@ -14,6 +12,13 @@ servers: description: Production security: - bearerAuth: [] +tags: + - name: Operations + description: Create deposits, withdrawals, and swaps. Query operation status and history. + - name: Beneficiaries + description: Manage external beneficiaries and their payment instructions for withdrawals. + - name: Payment instructions + description: Add or remove payment instructions on an existing beneficiary. components: securitySchemes: bearerAuth: @@ -21,15 +26,201 @@ components: scheme: bearer bearerFormat: JWT description: "Auth0 JWT token. Include as `Authorization: Bearer `." + parameters: + OperationId: + name: operationId + in: path + required: true + description: UUID of the operation. + schema: + type: string + format: uuid + BeneficiaryId: + name: beneficiaryId + in: path + required: true + description: UUID of the beneficiary. + schema: + type: string + format: uuid + PaymentInstructionId: + name: paymentInstructionId + in: path + required: true + description: UUID of the payment instruction. + schema: + type: string + format: uuid + TraceVersion: + name: X-Trace-Version + in: header + required: false + description: API version. Omit to use the default version. + schema: + type: string + example: "1" + IdempotencyKey: + name: X-Idempotency-Key + in: header + required: true + description: Unique key to ensure idempotent request processing. + schema: + type: string + format: uuid + PaginationLimit: + name: limit + in: query + required: false + description: Maximum number of items to return. Defaults to 20. + schema: + type: integer + default: 20 + minimum: 1 + maximum: 100 + PaginationCursor: + name: cursor + in: query + required: false + description: Opaque cursor for fetching the next page. + schema: + type: string schemas: + # ── Shared value objects ────────────────────────────────────────── + Amount: + type: object + description: Monetary amount in minor units. + properties: + value: + type: integer + format: int64 + description: Amount in minor units (e.g., 500000 = 5000.00 BRL). + example: 500000 + asset: + type: string + description: ISO 4217 currency code or stablecoin ticker. + example: "BRL" + required: + - value + - asset + Quote: + type: object + description: Exchange rate snapshot created at operation time. + properties: + id: + type: string + description: Quote identifier. + example: "q-a1b2c3d4-e5f6-7890-abcd-ef1234567890" + rate: + $ref: "#/components/schemas/SpotRate" + fundingAmount: + $ref: "#/components/schemas/Amount" + settlementAmount: + $ref: "#/components/schemas/Amount" + fees: + type: array + items: + $ref: "#/components/schemas/Fee" + expiresAt: + type: string + format: date-time + description: Quote expiration time. + example: "2026-04-14T12:35:00Z" + required: + - id + - rate + - fundingAmount + - settlementAmount + - fees + - expiresAt + SpotRate: + type: object + description: Exchange rate between two currencies. + properties: + value: + type: string + description: Rate value as a decimal string. + example: "5.25" + base: + type: string + description: Base currency. + example: "USD" + quote: + type: string + description: Quote currency. + example: "BRL" + required: + - value + - base + - quote + Fee: + type: object + properties: + name: + type: string + description: Fee name. + example: "spread" + type: + type: string + description: Fee type. + example: "PERCENTAGE" + percentage: + type: string + nullable: true + description: Fee percentage as a decimal string. Null for flat fees. + example: "1.5" + required: + - name + - type + Reason: + type: object + nullable: true + description: Explains why an operation failed. Null on success. + properties: + code: + type: string + description: Machine-readable error code. + example: "insufficient_balance" + message: + type: string + description: Human-readable description. + example: "Insufficient balance for the requested operation" + details: + type: object + additionalProperties: true + example: {} + required: + - code + - message + PageMetadata: + type: object + properties: + previousCursor: + type: string + nullable: true + description: Cursor for the previous page. + nextCursor: + type: string + nullable: true + description: Cursor for the next page. + total: + type: integer + description: Total number of records. + totalMatches: + type: integer + description: Total records matching the current filter. + required: + - total + - totalMatches ErrorResponse: type: object properties: code: type: string + description: Machine-readable error code. example: "RESOURCE_NOT_FOUND" message: type: string + description: Human-readable description. example: "The requested resource was not found" details: type: object @@ -38,123 +229,868 @@ components: required: - code - message + + # ── Operation schemas ───────────────────────────────────────────── + CreateDepositRequest: + type: object + description: Request body for creating a deposit. + properties: + accountId: + type: string + format: uuid + description: Account to deposit into. + example: "a1b2c3d4-5e6f-7890-abcd-ef1234567890" + sourceAsset: + type: string + description: Asset the customer sends. + example: "BRL" + targetAsset: + type: string + description: Asset the customer receives. May differ for cross-asset deposits. + example: "USDT" + sourceAmountValue: + type: integer + format: int64 + nullable: true + description: Amount in minor units of the source asset. Provide this OR targetAmountValue. + example: 500000 + targetAmountValue: + type: integer + format: int64 + nullable: true + description: Amount in minor units of the target asset. Provide this OR sourceAmountValue. + rail: + type: string + enum: + - PIX + - CRYPTO + - TED + - BOLETO + description: Payment rail for the deposit. + example: "PIX" + required: + - accountId + - sourceAsset + - targetAsset + - rail + CreateWithdrawalRequest: + type: object + description: Request body for creating a withdrawal. + properties: + accountId: + type: string + format: uuid + description: Account to withdraw from. + example: "a1b2c3d4-5e6f-7890-abcd-ef1234567890" + sourceAsset: + type: string + description: Asset to withdraw. + example: "BRL" + targetAsset: + type: string + description: Asset the beneficiary receives. + example: "BRL" + sourceAmountValue: + type: integer + format: int64 + nullable: true + description: Amount in minor units of the source asset. Provide this OR targetAmountValue. + example: 100000 + targetAmountValue: + type: integer + format: int64 + nullable: true + description: Amount in minor units of the target asset. Provide this OR sourceAmountValue. + destination: + $ref: "#/components/schemas/WithdrawalDestination" + required: + - accountId + - sourceAsset + - targetAsset + - destination + WithdrawalDestination: + description: Where to send the withdrawn funds. Discriminated by `type`. + oneOf: + - $ref: "#/components/schemas/BeneficiaryReferenceDestination" + - $ref: "#/components/schemas/InlineBeneficiaryDestination" + - $ref: "#/components/schemas/BoletoDestination" + - $ref: "#/components/schemas/QrCodeDestination" + discriminator: + propertyName: type + mapping: + BENEFICIARY_REFERENCE: "#/components/schemas/BeneficiaryReferenceDestination" + BENEFICIARY: "#/components/schemas/InlineBeneficiaryDestination" + BOLETO: "#/components/schemas/BoletoDestination" + QR_CODE: "#/components/schemas/QrCodeDestination" + BeneficiaryReferenceDestination: + type: object + description: Reference a saved beneficiary payment instruction. + properties: + type: + type: string + enum: + - BENEFICIARY_REFERENCE + paymentInstructionId: + type: string + format: uuid + description: ID of a saved payment instruction on an approved beneficiary. + example: "b2c3d4e5-f6a7-8901-bcde-f12345678901" + required: + - type + - paymentInstructionId + InlineBeneficiaryDestination: + type: object + description: Provide beneficiary details inline. Auto-saved as APPROVED on completion. + properties: + type: + type: string + enum: + - BENEFICIARY + name: + type: string + description: Beneficiary legal name. + example: "João Silva" + taxId: + type: string + nullable: true + description: CPF or CNPJ. + example: "12345678900" + beneficiaryType: + type: string + enum: + - INDIVIDUAL + - COMPANY + description: Whether the beneficiary is an individual or company. + account: + $ref: "#/components/schemas/InlinePaymentInstruction" + required: + - type + - name + - beneficiaryType + - account + BoletoDestination: + type: object + description: Pay a boleto. + properties: + type: + type: string + enum: + - BOLETO + barCode: + type: string + description: Boleto barcode (digitable line). + example: "23793.38128 60800.000003 00000.000400 1 84340000012345" + required: + - type + - barCode + QrCodeDestination: + type: object + description: Pay a PIX QR code (static or dynamic). + properties: + type: + type: string + enum: + - QR_CODE + payload: + type: string + description: PIX QR code payload (EMV format). + example: "00020126580014br.gov.bcb.pix..." + required: + - type + - payload + InlinePaymentInstruction: + description: Payment instruction provided inline with the withdrawal. Discriminated by `type`. + oneOf: + - $ref: "#/components/schemas/PixInstruction" + - $ref: "#/components/schemas/BankAccountInstruction" + - $ref: "#/components/schemas/CryptoWalletInstruction" + discriminator: + propertyName: type + mapping: + PIX: "#/components/schemas/PixInstruction" + BANK_ACCOUNT: "#/components/schemas/BankAccountInstruction" + CRYPTO_WALLET: "#/components/schemas/CryptoWalletInstruction" + PixInstruction: + type: object + properties: + type: + type: string + enum: + - PIX + pixKeyType: + type: string + enum: + - CPF + - CNPJ + - EMAIL + - PHONE + - EVP + description: PIX key type. + pixKey: + type: string + description: PIX key value. + example: "john@example.com" + required: + - type + - pixKeyType + - pixKey + BankAccountInstruction: + type: object + properties: + type: + type: string + enum: + - BANK_ACCOUNT + bankCode: + type: string + description: Bank code (ISPB or COMPE). + example: "001" + branch: + type: string + description: Branch number. + example: "0001" + accountNumber: + type: string + description: Account number. + example: "123456" + accountType: + type: string + enum: + - CHECKING + - SAVINGS + description: Type of bank account. + required: + - type + - bankCode + - branch + - accountNumber + - accountType + CryptoWalletInstruction: + type: object + properties: + type: + type: string + enum: + - CRYPTO_WALLET + address: + type: string + description: Wallet address. + example: "0x742d35Cc6634C0532925a3b844Bc9e7595f2bD18" + chain: + type: string + description: Blockchain network. + example: "ETHEREUM" + asset: + type: string + description: Crypto asset. + example: "USDT" + required: + - type + - address + - chain + - asset + CreateSwapRequest: + type: object + description: Request body for creating a swap (asset conversion). + properties: + accountId: + type: string + format: uuid + description: Account performing the swap. + example: "a1b2c3d4-5e6f-7890-abcd-ef1234567890" + sourceAsset: + type: string + description: Asset to convert from. + example: "USDT" + targetAsset: + type: string + description: Asset to convert to. Must differ from sourceAsset. + example: "BRL" + sourceAmountValue: + type: integer + format: int64 + nullable: true + description: Amount in minor units of the source asset. Provide this OR targetAmountValue. + example: 10000 + targetAmountValue: + type: integer + format: int64 + nullable: true + description: Amount in minor units of the target asset. Provide this OR sourceAmountValue. + required: + - accountId + - sourceAsset + - targetAsset + OperationResponse: + type: object + description: An operation (deposit, withdrawal, or swap). + properties: + id: + type: string + format: uuid + example: "op-a1b2c3d4-5e6f-7890-abcd-ef1234567890" + type: + type: string + enum: + - DEPOSIT + - WITHDRAWAL + - SWAP + description: Operation type. + status: + type: string + enum: + - PENDING + - IN_REVIEW + - PROCESSING + - DEBITED + - COMPLETED + - FAILED + description: Current derived status. + accountId: + type: string + format: uuid + description: Account this operation belongs to. + sourceAsset: + type: string + description: Source currency. + example: "BRL" + targetAsset: + type: string + description: Target currency. + example: "USDT" + quote: + $ref: "#/components/schemas/Quote" + rail: + type: string + nullable: true + enum: + - PIX + - TED + - CRYPTO + - BOLETO + description: Payment rail. Present on deposits and withdrawals. + reason: + $ref: "#/components/schemas/Reason" + createdAt: + type: string + format: date-time + example: "2026-04-14T10:30:00Z" + updatedAt: + type: string + format: date-time + example: "2026-04-14T10:30:00Z" + required: + - id + - type + - status + - accountId + - sourceAsset + - targetAsset + - quote + - createdAt + - updatedAt + + # ── Beneficiary schemas ─────────────────────────────────────────── + CreateBeneficiaryRequest: + type: object + description: Request body for creating a beneficiary. + properties: + holder: + $ref: "#/components/schemas/HolderRequest" + paymentInstruction: + $ref: "#/components/schemas/PaymentInstructionRequest" + required: + - holder + - paymentInstruction + UpdateBeneficiaryRequest: + type: object + description: Request body for updating a beneficiary. Only holder fields can be changed. + properties: + holder: + $ref: "#/components/schemas/HolderRequest" + required: + - holder + HolderRequest: + description: The person or company that receives funds. Discriminated by `type`. + oneOf: + - $ref: "#/components/schemas/IndividualHolderRequest" + - $ref: "#/components/schemas/CompanyHolderRequest" + discriminator: + propertyName: type + mapping: + INDIVIDUAL: "#/components/schemas/IndividualHolderRequest" + COMPANY: "#/components/schemas/CompanyHolderRequest" + IndividualHolderRequest: + type: object + properties: + type: + type: string + enum: + - INDIVIDUAL + name: + type: string + description: Full legal name. + example: "João Silva" + taxId: + type: string + nullable: true + description: CPF. Optional. + example: "12345678900" + required: + - type + - name + CompanyHolderRequest: + type: object + properties: + type: + type: string + enum: + - COMPANY + legalName: + type: string + description: Registered legal name. + example: "Acme Importação Ltda" + tradeName: + type: string + nullable: true + description: Trade name. Optional. + taxId: + type: string + nullable: true + description: CNPJ. Optional. + example: "12345678000100" + required: + - type + - legalName + PaymentInstructionRequest: + description: Payment instruction for receiving funds. Discriminated by `type`. + oneOf: + - $ref: "#/components/schemas/PixInstructionRequest" + - $ref: "#/components/schemas/BankAccountInstructionRequest" + - $ref: "#/components/schemas/CryptoWalletInstructionRequest" + discriminator: + propertyName: type + mapping: + PIX: "#/components/schemas/PixInstructionRequest" + BANK_ACCOUNT: "#/components/schemas/BankAccountInstructionRequest" + CRYPTO_WALLET: "#/components/schemas/CryptoWalletInstructionRequest" + PixInstructionRequest: + type: object + properties: + type: + type: string + enum: + - PIX + pixKeyType: + type: string + enum: + - CPF + - CNPJ + - EMAIL + - PHONE + - EVP + description: PIX key type. + pixKey: + type: string + description: PIX key value. + example: "john@example.com" + required: + - type + - pixKeyType + - pixKey + BankAccountInstructionRequest: + type: object + properties: + type: + type: string + enum: + - BANK_ACCOUNT + bankCode: + type: string + description: Bank code (ISPB or COMPE). + example: "001" + branch: + type: string + description: Branch number. + example: "0001" + accountNumber: + type: string + description: Account number. + example: "123456" + accountType: + type: string + enum: + - CHECKING + - SAVINGS + required: + - type + - bankCode + - branch + - accountNumber + - accountType + CryptoWalletInstructionRequest: + type: object + properties: + type: + type: string + enum: + - CRYPTO_WALLET + address: + type: string + description: Wallet address. + example: "0x742d35Cc6634C0532925a3b844Bc9e7595f2bD18" + chain: + type: string + description: Blockchain network. + example: "ETHEREUM" + asset: + type: string + description: Crypto asset. + example: "USDT" + required: + - type + - address + - chain + - asset + BeneficiaryResponse: + type: object + description: An external beneficiary registered for withdrawals. + properties: + id: + type: string + format: uuid + example: "ben-a1b2c3d4-5e6f-7890-abcd-ef1234567890" + customerId: + type: string + format: uuid + description: Customer that owns this beneficiary. + holder: + $ref: "#/components/schemas/HolderResponse" + status: + type: string + enum: + - PENDING_REVIEW + - APPROVED + - REJECTED + description: Compliance review status. + paymentInstructions: + type: array + items: + $ref: "#/components/schemas/PaymentInstructionResponse" + createdAt: + type: string + format: date-time + example: "2026-04-14T10:30:00Z" + updatedAt: + type: string + format: date-time + example: "2026-04-14T10:30:00Z" + required: + - id + - customerId + - holder + - status + - paymentInstructions + - createdAt + - updatedAt + HolderResponse: + description: The person or company that receives funds. Discriminated by `type`. + oneOf: + - $ref: "#/components/schemas/IndividualHolderResponse" + - $ref: "#/components/schemas/CompanyHolderResponse" + discriminator: + propertyName: type + mapping: + INDIVIDUAL: "#/components/schemas/IndividualHolderResponse" + COMPANY: "#/components/schemas/CompanyHolderResponse" + IndividualHolderResponse: + type: object + properties: + type: + type: string + enum: + - INDIVIDUAL + name: + type: string + example: "João Silva" + taxId: + type: string + nullable: true + example: "12345678900" + required: + - type + - name + CompanyHolderResponse: + type: object + properties: + type: + type: string + enum: + - COMPANY + legalName: + type: string + example: "Acme Importação Ltda" + tradeName: + type: string + nullable: true + taxId: + type: string + nullable: true + example: "12345678000100" + required: + - type + - legalName + PaymentInstructionResponse: + type: object + description: A payment instruction on a beneficiary. + properties: + id: + type: string + format: uuid + example: "pi-a1b2c3d4-5e6f-7890-abcd-ef1234567890" + type: + type: string + enum: + - PIX + - BANK_ACCOUNT + - CRYPTO_WALLET + description: Instruction type. + details: + type: object + description: Type-specific details (see examples). + additionalProperties: true + createdAt: + type: string + format: date-time + example: "2026-04-14T10:30:00Z" + required: + - id + - type + - details + - createdAt + paths: - # --- Operations: Deposits --- + # ── Operations: Deposits ────────────────────────────────────────── /api/deposits: post: operationId: createDeposit tags: - Operations summary: Create a deposit - description: "TODO: Add request/response schemas from fx-payment docs." + description: Creates a deposit intent for the authenticated customer. Returns the operation with a funding instruction for completing the payment. parameters: - - name: X-Idempotency-Key - in: header - required: true - schema: - type: string - - name: X-Trace-Version - in: header - required: false - schema: - type: string + - $ref: "#/components/parameters/IdempotencyKey" + - $ref: "#/components/parameters/TraceVersion" + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/CreateDepositRequest" + examples: + pixDeposit: + summary: PIX deposit (BRL to BRL) + value: + accountId: "a1b2c3d4-5e6f-7890-abcd-ef1234567890" + sourceAsset: "BRL" + targetAsset: "BRL" + sourceAmountValue: 500000 + rail: "PIX" + crossAsset: + summary: Cross-asset deposit (BRL to USDT) + value: + accountId: "a1b2c3d4-5e6f-7890-abcd-ef1234567890" + sourceAsset: "BRL" + targetAsset: "USDT" + targetAmountValue: 10000 + rail: "PIX" responses: "201": description: Deposit created. - "400": - description: Invalid request data. content: application/json: schema: - $ref: '#/components/schemas/ErrorResponse' + $ref: "#/components/schemas/OperationResponse" + "401": + description: Missing or invalid authentication token. + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + "404": + description: Account or funding instruction not found. + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + "422": + description: Validation error (invalid amount, missing amount, invalid rail or asset). + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" - # --- Operations: Withdrawals --- + # ── Operations: Withdrawals ─────────────────────────────────────── /api/withdrawals: post: operationId: createWithdrawal tags: - Operations summary: Create a withdrawal - description: "TODO: Add request/response schemas from fx-payment docs." + description: Creates a withdrawal to an external destination — a saved beneficiary, inline beneficiary, PIX QR code, or boleto. parameters: - - name: X-Idempotency-Key - in: header - required: true - schema: - type: string - - name: X-Trace-Version - in: header - required: false - schema: - type: string + - $ref: "#/components/parameters/IdempotencyKey" + - $ref: "#/components/parameters/TraceVersion" + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/CreateWithdrawalRequest" + examples: + savedBeneficiary: + summary: Withdraw to a saved beneficiary + value: + accountId: "a1b2c3d4-5e6f-7890-abcd-ef1234567890" + sourceAsset: "BRL" + targetAsset: "BRL" + sourceAmountValue: 100000 + destination: + type: "BENEFICIARY_REFERENCE" + paymentInstructionId: "b2c3d4e5-f6a7-8901-bcde-f12345678901" + inlinePix: + summary: Withdraw to an inline PIX beneficiary + value: + accountId: "a1b2c3d4-5e6f-7890-abcd-ef1234567890" + sourceAsset: "BRL" + targetAsset: "BRL" + sourceAmountValue: 50000 + destination: + type: "BENEFICIARY" + name: "João Silva" + taxId: "12345678900" + beneficiaryType: "INDIVIDUAL" + account: + type: "PIX" + pixKeyType: "EMAIL" + pixKey: "joao@example.com" + qrCode: + summary: Pay a PIX QR code + value: + accountId: "a1b2c3d4-5e6f-7890-abcd-ef1234567890" + sourceAsset: "BRL" + targetAsset: "BRL" + sourceAmountValue: 25000 + destination: + type: "QR_CODE" + payload: "00020126580014br.gov.bcb.pix..." responses: "201": description: Withdrawal created. - "400": - description: Invalid request data. content: application/json: schema: - $ref: '#/components/schemas/ErrorResponse' + $ref: "#/components/schemas/OperationResponse" + "401": + description: Missing or invalid authentication token. + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + "404": + description: Account, beneficiary, or payment instruction not found. + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + "422": + description: Validation error (invalid amount, invalid destination, beneficiary not approved). + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" - # --- Operations: Swaps --- + # ── Operations: Swaps ───────────────────────────────────────────── /api/swaps: post: operationId: createSwap tags: - Operations summary: Create a swap - description: "TODO: Add request/response schemas from fx-payment docs." + description: Converts funds between two assets within the same account. A quote is created automatically and included in the response. Swaps are forward-only and cannot be reversed once the balance is debited. parameters: - - name: X-Idempotency-Key - in: header - required: true - schema: - type: string - - name: X-Trace-Version - in: header - required: false - schema: - type: string + - $ref: "#/components/parameters/IdempotencyKey" + - $ref: "#/components/parameters/TraceVersion" + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/CreateSwapRequest" + examples: + usdtToBrl: + summary: Convert USDT to BRL + value: + accountId: "a1b2c3d4-5e6f-7890-abcd-ef1234567890" + sourceAsset: "USDT" + targetAsset: "BRL" + sourceAmountValue: 10000 responses: "201": description: Swap created. - "400": - description: Invalid request data. content: application/json: schema: - $ref: '#/components/schemas/ErrorResponse' + $ref: "#/components/schemas/OperationResponse" + "401": + description: Missing or invalid authentication token. + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + "404": + description: Account not found. + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + "422": + description: Validation error (same asset, invalid amount, invalid source or target asset). + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" - # --- Operations: Read --- + # ── Operations: Read ────────────────────────────────────────────── /api/operations/{operationId}: get: operationId: getOperation tags: - Operations summary: Get an operation - description: "TODO: Add response schema from fx-payment docs." + description: Retrieves the full details of an operation by its ID. parameters: - - name: operationId - in: path - required: true - schema: - type: string - format: uuid - - name: X-Trace-Version - in: header - required: false - schema: - type: string + - $ref: "#/components/parameters/OperationId" + - $ref: "#/components/parameters/TraceVersion" responses: "200": description: Operation details. + content: + application/json: + schema: + $ref: "#/components/schemas/OperationResponse" + "401": + description: Missing or invalid authentication token. + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" "404": description: Operation not found. content: application/json: schema: - $ref: '#/components/schemas/ErrorResponse' + $ref: "#/components/schemas/ErrorResponse" /api/operations: get: @@ -162,60 +1098,185 @@ paths: tags: - Operations summary: List operations - description: "TODO: Add query parameters and response schema from fx-payment docs." + description: Lists all operations for the authenticated customer. Results are paginated and can be filtered by type or status. parameters: - - name: X-Trace-Version - in: header + - $ref: "#/components/parameters/TraceVersion" + - $ref: "#/components/parameters/PaginationLimit" + - $ref: "#/components/parameters/PaginationCursor" + - name: type + in: query + required: false + description: Filter by operation type. + schema: + type: string + enum: + - DEPOSIT + - WITHDRAWAL + - SWAP + - name: status + in: query required: false + description: Filter by operation status. schema: type: string + enum: + - PENDING + - IN_REVIEW + - PROCESSING + - DEBITED + - COMPLETED + - FAILED responses: "200": description: Paginated list of operations. + content: + application/json: + schema: + type: object + properties: + data: + type: array + items: + $ref: "#/components/schemas/OperationResponse" + meta: + $ref: "#/components/schemas/PageMetadata" + required: + - data + - meta + "401": + description: Missing or invalid authentication token. + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + "422": + description: Invalid filter parameter. + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" - # --- Beneficiaries --- + # ── Beneficiaries ───────────────────────────────────────────────── /api/beneficiaries: post: operationId: createBeneficiary tags: - Beneficiaries summary: Create a beneficiary - description: "TODO: Add request/response schemas from fx-payment docs." + description: Registers a new beneficiary for withdrawals. Initiates a compliance review — the beneficiary starts in `PENDING_REVIEW` status and transitions to `APPROVED` or `REJECTED` asynchronously. parameters: - - name: X-Idempotency-Key - in: header - required: true - schema: - type: string - - name: X-Trace-Version - in: header - required: false - schema: - type: string + - $ref: "#/components/parameters/IdempotencyKey" + - $ref: "#/components/parameters/TraceVersion" + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/CreateBeneficiaryRequest" + examples: + pixIndividual: + summary: Individual with PIX key + value: + holder: + type: "INDIVIDUAL" + name: "João Silva" + taxId: "12345678900" + paymentInstruction: + type: "PIX" + pixKeyType: "EMAIL" + pixKey: "joao@example.com" + bankCompany: + summary: Company with bank account + value: + holder: + type: "COMPANY" + legalName: "Acme Importação Ltda" + taxId: "12345678000100" + paymentInstruction: + type: "BANK_ACCOUNT" + bankCode: "001" + branch: "0001" + accountNumber: "123456" + accountType: "CHECKING" + cryptoWallet: + summary: Individual with crypto wallet + value: + holder: + type: "INDIVIDUAL" + name: "Jane Doe" + paymentInstruction: + type: "CRYPTO_WALLET" + address: "0x742d35Cc6634C0532925a3b844Bc9e7595f2bD18" + chain: "ETHEREUM" + asset: "USDT" responses: "201": - description: Beneficiary created. - "400": - description: Invalid request data. + description: Beneficiary created with `PENDING_REVIEW` status. content: application/json: schema: - $ref: '#/components/schemas/ErrorResponse' + $ref: "#/components/schemas/BeneficiaryResponse" + "401": + description: Missing or invalid authentication token. + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + "422": + description: Validation error (invalid holder type, invalid instruction type, missing details). + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" get: operationId: listBeneficiaries tags: - Beneficiaries summary: List beneficiaries - description: "TODO: Add query parameters and response schema from fx-payment docs." + description: Lists all beneficiaries for the authenticated customer. Results are paginated and can be filtered by status. parameters: - - name: X-Trace-Version - in: header + - $ref: "#/components/parameters/TraceVersion" + - $ref: "#/components/parameters/PaginationLimit" + - $ref: "#/components/parameters/PaginationCursor" + - name: status + in: query required: false + description: Filter by beneficiary status. schema: type: string + enum: + - PENDING_REVIEW + - APPROVED + - REJECTED responses: "200": description: Paginated list of beneficiaries. + content: + application/json: + schema: + type: object + properties: + data: + type: array + items: + $ref: "#/components/schemas/BeneficiaryResponse" + meta: + $ref: "#/components/schemas/PageMetadata" + required: + - data + - meta + "401": + description: Missing or invalid authentication token. + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + "422": + description: Invalid filter parameter. + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" /api/beneficiaries/{beneficiaryId}: get: @@ -223,143 +1284,184 @@ paths: tags: - Beneficiaries summary: Get a beneficiary - description: "TODO: Add response schema from fx-payment docs." + description: Retrieves a specific beneficiary by ID. parameters: - - name: beneficiaryId - in: path - required: true - schema: - type: string - format: uuid - - name: X-Trace-Version - in: header - required: false - schema: - type: string + - $ref: "#/components/parameters/BeneficiaryId" + - $ref: "#/components/parameters/TraceVersion" responses: "200": description: Beneficiary details. + content: + application/json: + schema: + $ref: "#/components/schemas/BeneficiaryResponse" + "401": + description: Missing or invalid authentication token. + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" "404": description: Beneficiary not found. content: application/json: schema: - $ref: '#/components/schemas/ErrorResponse' + $ref: "#/components/schemas/ErrorResponse" put: operationId: updateBeneficiary tags: - Beneficiaries summary: Update a beneficiary - description: "TODO: Add request/response schemas from fx-payment docs." + description: Updates the holder information of a beneficiary. Does not modify payment instructions — use the payment instruction endpoints for that. parameters: - - name: beneficiaryId - in: path - required: true - schema: - type: string - format: uuid - - name: X-Trace-Version - in: header - required: false - schema: - type: string + - $ref: "#/components/parameters/BeneficiaryId" + - $ref: "#/components/parameters/TraceVersion" + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/UpdateBeneficiaryRequest" + examples: + updateName: + summary: Update holder name + value: + holder: + type: "INDIVIDUAL" + name: "João Carlos Silva" + taxId: "12345678900" responses: "200": description: Beneficiary updated. + content: + application/json: + schema: + $ref: "#/components/schemas/BeneficiaryResponse" + "401": + description: Missing or invalid authentication token. + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" "404": description: Beneficiary not found. content: application/json: schema: - $ref: '#/components/schemas/ErrorResponse' + $ref: "#/components/schemas/ErrorResponse" + "422": + description: Validation error (invalid holder type). + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" delete: operationId: deleteBeneficiary tags: - Beneficiaries summary: Delete a beneficiary - description: "TODO: Add response details from fx-payment docs." + description: Removes a beneficiary and all its payment instructions. parameters: - - name: beneficiaryId - in: path - required: true - schema: - type: string - format: uuid - - name: X-Trace-Version - in: header - required: false - schema: - type: string + - $ref: "#/components/parameters/BeneficiaryId" + - $ref: "#/components/parameters/TraceVersion" responses: "204": description: Beneficiary deleted. + "401": + description: Missing or invalid authentication token. + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" "404": description: Beneficiary not found. content: application/json: schema: - $ref: '#/components/schemas/ErrorResponse' + $ref: "#/components/schemas/ErrorResponse" + # ── Payment instructions ────────────────────────────────────────── /api/beneficiaries/{beneficiaryId}/payment-instructions: post: operationId: addPaymentInstruction tags: - - Beneficiaries + - Payment instructions summary: Add a payment instruction - description: "TODO: Add request/response schemas from fx-payment docs." + description: Adds a new payment instruction to an existing beneficiary. parameters: - - name: beneficiaryId - in: path - required: true - schema: - type: string - format: uuid - - name: X-Trace-Version - in: header - required: false - schema: - type: string + - $ref: "#/components/parameters/BeneficiaryId" + - $ref: "#/components/parameters/IdempotencyKey" + - $ref: "#/components/parameters/TraceVersion" + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/PaymentInstructionRequest" + examples: + pix: + summary: Add a PIX key + value: + type: "PIX" + pixKeyType: "CPF" + pixKey: "12345678900" + bankAccount: + summary: Add a bank account (TED) + value: + type: "BANK_ACCOUNT" + bankCode: "001" + branch: "0001" + accountNumber: "123456" + accountType: "CHECKING" responses: "201": - description: Payment instruction added. + description: Payment instruction added. Returns the full beneficiary. + content: + application/json: + schema: + $ref: "#/components/schemas/BeneficiaryResponse" + "401": + description: Missing or invalid authentication token. + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" "404": description: Beneficiary not found. content: application/json: schema: - $ref: '#/components/schemas/ErrorResponse' + $ref: "#/components/schemas/ErrorResponse" + "422": + description: Validation error (invalid instruction type, missing details). + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" /api/beneficiaries/{beneficiaryId}/payment-instructions/{paymentInstructionId}: delete: operationId: removePaymentInstruction tags: - - Beneficiaries + - Payment instructions summary: Remove a payment instruction - description: "TODO: Add response details from fx-payment docs." + description: Removes a payment instruction from a beneficiary. parameters: - - name: beneficiaryId - in: path - required: true - schema: - type: string - format: uuid - - name: paymentInstructionId - in: path - required: true - schema: - type: string - format: uuid - - name: X-Trace-Version - in: header - required: false - schema: - type: string + - $ref: "#/components/parameters/BeneficiaryId" + - $ref: "#/components/parameters/PaymentInstructionId" + - $ref: "#/components/parameters/TraceVersion" responses: "204": description: Payment instruction removed. + "401": + description: Missing or invalid authentication token. + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" "404": description: Beneficiary or payment instruction not found. content: application/json: schema: - $ref: '#/components/schemas/ErrorResponse' + $ref: "#/components/schemas/ErrorResponse" From e0cb63aa20adfc5d99e8294f7a863c49e18b9b71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rio=20Alvial?= Date: Tue, 14 Apr 2026 20:50:46 -0300 Subject: [PATCH 2/4] docs: add fx-payment API reference pages and navigation Create 12 MDX stub pages for operations and beneficiary endpoints with openapi frontmatter directives. Add Operations, Beneficiaries, and Payment Instructions groups to the API Reference tab in docs.json. --- .../beneficiaries/add-payment-instruction.mdx | 5 ++ .../beneficiaries/create-beneficiary.mdx | 5 ++ .../beneficiaries/delete-beneficiary.mdx | 5 ++ .../beneficiaries/get-beneficiary.mdx | 5 ++ .../beneficiaries/list-beneficiaries.mdx | 5 ++ .../remove-payment-instruction.mdx | 5 ++ .../beneficiaries/update-beneficiary.mdx | 5 ++ .../fx-payment/operations/create-deposit.mdx | 5 ++ .../fx-payment/operations/create-swap.mdx | 5 ++ .../operations/create-withdrawal.mdx | 5 ++ .../fx-payment/operations/get-operation.mdx | 5 ++ .../fx-payment/operations/list-operations.mdx | 5 ++ docs.json | 66 +++++++++++++++++++ 13 files changed, 126 insertions(+) create mode 100644 api-reference/fx-payment/beneficiaries/add-payment-instruction.mdx create mode 100644 api-reference/fx-payment/beneficiaries/create-beneficiary.mdx create mode 100644 api-reference/fx-payment/beneficiaries/delete-beneficiary.mdx create mode 100644 api-reference/fx-payment/beneficiaries/get-beneficiary.mdx create mode 100644 api-reference/fx-payment/beneficiaries/list-beneficiaries.mdx create mode 100644 api-reference/fx-payment/beneficiaries/remove-payment-instruction.mdx create mode 100644 api-reference/fx-payment/beneficiaries/update-beneficiary.mdx create mode 100644 api-reference/fx-payment/operations/create-deposit.mdx create mode 100644 api-reference/fx-payment/operations/create-swap.mdx create mode 100644 api-reference/fx-payment/operations/create-withdrawal.mdx create mode 100644 api-reference/fx-payment/operations/get-operation.mdx create mode 100644 api-reference/fx-payment/operations/list-operations.mdx diff --git a/api-reference/fx-payment/beneficiaries/add-payment-instruction.mdx b/api-reference/fx-payment/beneficiaries/add-payment-instruction.mdx new file mode 100644 index 0000000..e1d8cba --- /dev/null +++ b/api-reference/fx-payment/beneficiaries/add-payment-instruction.mdx @@ -0,0 +1,5 @@ +--- +title: "Add a payment instruction" +description: "Adds a payment instruction to an existing beneficiary." +openapi: "apis/fx-payment/openapi.yml POST /api/beneficiaries/{beneficiaryId}/payment-instructions" +--- diff --git a/api-reference/fx-payment/beneficiaries/create-beneficiary.mdx b/api-reference/fx-payment/beneficiaries/create-beneficiary.mdx new file mode 100644 index 0000000..6b74c64 --- /dev/null +++ b/api-reference/fx-payment/beneficiaries/create-beneficiary.mdx @@ -0,0 +1,5 @@ +--- +title: "Create a beneficiary" +description: "Registers a new beneficiary for withdrawals." +openapi: "apis/fx-payment/openapi.yml POST /api/beneficiaries" +--- diff --git a/api-reference/fx-payment/beneficiaries/delete-beneficiary.mdx b/api-reference/fx-payment/beneficiaries/delete-beneficiary.mdx new file mode 100644 index 0000000..c3bb833 --- /dev/null +++ b/api-reference/fx-payment/beneficiaries/delete-beneficiary.mdx @@ -0,0 +1,5 @@ +--- +title: "Delete a beneficiary" +description: "Removes a beneficiary and all its payment instructions." +openapi: "apis/fx-payment/openapi.yml DELETE /api/beneficiaries/{beneficiaryId}" +--- diff --git a/api-reference/fx-payment/beneficiaries/get-beneficiary.mdx b/api-reference/fx-payment/beneficiaries/get-beneficiary.mdx new file mode 100644 index 0000000..2c0a2b1 --- /dev/null +++ b/api-reference/fx-payment/beneficiaries/get-beneficiary.mdx @@ -0,0 +1,5 @@ +--- +title: "Get a beneficiary" +description: "Retrieves the details of a beneficiary by its ID." +openapi: "apis/fx-payment/openapi.yml GET /api/beneficiaries/{beneficiaryId}" +--- diff --git a/api-reference/fx-payment/beneficiaries/list-beneficiaries.mdx b/api-reference/fx-payment/beneficiaries/list-beneficiaries.mdx new file mode 100644 index 0000000..4d9c232 --- /dev/null +++ b/api-reference/fx-payment/beneficiaries/list-beneficiaries.mdx @@ -0,0 +1,5 @@ +--- +title: "List beneficiaries" +description: "Lists all beneficiaries for the authenticated customer." +openapi: "apis/fx-payment/openapi.yml GET /api/beneficiaries" +--- diff --git a/api-reference/fx-payment/beneficiaries/remove-payment-instruction.mdx b/api-reference/fx-payment/beneficiaries/remove-payment-instruction.mdx new file mode 100644 index 0000000..7e4c9cc --- /dev/null +++ b/api-reference/fx-payment/beneficiaries/remove-payment-instruction.mdx @@ -0,0 +1,5 @@ +--- +title: "Remove a payment instruction" +description: "Removes a payment instruction from a beneficiary." +openapi: "apis/fx-payment/openapi.yml DELETE /api/beneficiaries/{beneficiaryId}/payment-instructions/{paymentInstructionId}" +--- diff --git a/api-reference/fx-payment/beneficiaries/update-beneficiary.mdx b/api-reference/fx-payment/beneficiaries/update-beneficiary.mdx new file mode 100644 index 0000000..669163c --- /dev/null +++ b/api-reference/fx-payment/beneficiaries/update-beneficiary.mdx @@ -0,0 +1,5 @@ +--- +title: "Update a beneficiary" +description: "Updates a beneficiary's holder information." +openapi: "apis/fx-payment/openapi.yml PUT /api/beneficiaries/{beneficiaryId}" +--- diff --git a/api-reference/fx-payment/operations/create-deposit.mdx b/api-reference/fx-payment/operations/create-deposit.mdx new file mode 100644 index 0000000..a5ee5f2 --- /dev/null +++ b/api-reference/fx-payment/operations/create-deposit.mdx @@ -0,0 +1,5 @@ +--- +title: "Create a deposit" +description: "Creates a new deposit for the authenticated customer." +openapi: "apis/fx-payment/openapi.yml POST /api/deposits" +--- diff --git a/api-reference/fx-payment/operations/create-swap.mdx b/api-reference/fx-payment/operations/create-swap.mdx new file mode 100644 index 0000000..22dd218 --- /dev/null +++ b/api-reference/fx-payment/operations/create-swap.mdx @@ -0,0 +1,5 @@ +--- +title: "Create a swap" +description: "Converts between assets within the same account." +openapi: "apis/fx-payment/openapi.yml POST /api/swaps" +--- diff --git a/api-reference/fx-payment/operations/create-withdrawal.mdx b/api-reference/fx-payment/operations/create-withdrawal.mdx new file mode 100644 index 0000000..c4ea2c4 --- /dev/null +++ b/api-reference/fx-payment/operations/create-withdrawal.mdx @@ -0,0 +1,5 @@ +--- +title: "Create a withdrawal" +description: "Creates a new withdrawal to a beneficiary, QR code, or boleto." +openapi: "apis/fx-payment/openapi.yml POST /api/withdrawals" +--- diff --git a/api-reference/fx-payment/operations/get-operation.mdx b/api-reference/fx-payment/operations/get-operation.mdx new file mode 100644 index 0000000..1aa44f6 --- /dev/null +++ b/api-reference/fx-payment/operations/get-operation.mdx @@ -0,0 +1,5 @@ +--- +title: "Get an operation" +description: "Retrieves the details of an operation by its ID." +openapi: "apis/fx-payment/openapi.yml GET /api/operations/{operationId}" +--- diff --git a/api-reference/fx-payment/operations/list-operations.mdx b/api-reference/fx-payment/operations/list-operations.mdx new file mode 100644 index 0000000..2395361 --- /dev/null +++ b/api-reference/fx-payment/operations/list-operations.mdx @@ -0,0 +1,5 @@ +--- +title: "List operations" +description: "Lists all operations for the authenticated customer." +openapi: "apis/fx-payment/openapi.yml GET /api/operations" +--- diff --git a/docs.json b/docs.json index 1cc0c28..b93bbfc 100644 --- a/docs.json +++ b/docs.json @@ -73,6 +73,72 @@ ] } ] + }, + { + "tab": "API Reference", + "icon": "code", + "groups": [ + { + "group": "Accounts", + "icon": "building-columns", + "pages": [ + "api-reference/fx-account/accounts/create-account", + "api-reference/fx-account/accounts/list-accounts", + "api-reference/fx-account/accounts/get-account", + "api-reference/fx-account/accounts/submit-account-for-review", + "api-reference/fx-account/documents/upload-account-document", + { + "group": "Funding instructions", + "icon": "money-bill-transfer", + "pages": [ + "api-reference/fx-account/funding-instructions/list-funding-instructions" + ] + }, + { + "group": "UBOs", + "icon": "users", + "pages": [ + "api-reference/fx-account/beneficial-owners/add-ubo", + "api-reference/fx-account/beneficial-owners/list-ubos", + "api-reference/fx-account/beneficial-owners/get-ubo", + "api-reference/fx-account/beneficial-owners/update-ubo", + "api-reference/fx-account/beneficial-owners/remove-ubo", + "api-reference/fx-account/documents/upload-ubo-document" + ] + } + ] + }, + { + "group": "Operations", + "icon": "arrows-rotate", + "pages": [ + "api-reference/fx-payment/operations/create-deposit", + "api-reference/fx-payment/operations/create-withdrawal", + "api-reference/fx-payment/operations/create-swap", + "api-reference/fx-payment/operations/get-operation", + "api-reference/fx-payment/operations/list-operations" + ] + }, + { + "group": "Beneficiaries", + "icon": "address-book", + "pages": [ + "api-reference/fx-payment/beneficiaries/create-beneficiary", + "api-reference/fx-payment/beneficiaries/list-beneficiaries", + "api-reference/fx-payment/beneficiaries/get-beneficiary", + "api-reference/fx-payment/beneficiaries/update-beneficiary", + "api-reference/fx-payment/beneficiaries/delete-beneficiary", + { + "group": "Payment instructions", + "icon": "credit-card", + "pages": [ + "api-reference/fx-payment/beneficiaries/add-payment-instruction", + "api-reference/fx-payment/beneficiaries/remove-payment-instruction" + ] + } + ] + } + ] } ], "global": { From 3e36d0929df1073606d436d3aa755f31c9665611 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rio=20Alvial?= Date: Tue, 14 Apr 2026 20:50:51 -0300 Subject: [PATCH 3/4] fix: correct swap journey to use POST /api/swaps endpoint Remove reference to non-existent POST /api/quotes endpoint. The quote is created automatically when creating a swap and returned in the response. --- journeys/swap.mdx | 41 ++++++++++++++--------------------------- 1 file changed, 14 insertions(+), 27 deletions(-) diff --git a/journeys/swap.mdx b/journeys/swap.mdx index 8a9cfad..e33b6fb 100644 --- a/journeys/swap.mdx +++ b/journeys/swap.mdx @@ -19,47 +19,34 @@ Swaps convert funds between currencies within the platform — for example, BRL ## Steps - - Get the current exchange rate and confirm the amounts before executing: + + Specify the source and target assets along with the amount to convert. The platform creates a quote automatically and returns it in the response. ```bash curl --request POST \ - --url {{sandboxUrl}}/api/quotes \ + --url {{sandboxUrl}}/api/swaps \ --header 'Authorization: Bearer ' \ - + --header 'X-Idempotency-Key: ' \ --header 'Content-Type: application/json' \ --data '{ - "from": "BRL", - "to": "USD", - "amount": { - "value": 500000, - "asset": "BRL" - } + "accountId": "", + "sourceAsset": "BRL", + "targetAsset": "USDT", + "sourceAmountValue": 500000 }' ``` - The response includes the quoted rate and the resulting amount. Quotes are valid for a limited time. + The response includes the operation in `PENDING` status with the `quote` object containing the exchange rate, funding amount, settlement amount, and expiration time. - - Submit the swap using the quote ID: + + Listen for `operation.completed` and `operation.failed` webhook events. You can also poll the operation status: ```bash - curl --request POST \ - --url {{sandboxUrl}}/api/operations \ - --header 'Authorization: Bearer ' \ - - --header 'X-Idempotency-Key: ' \ - --header 'Content-Type: application/json' \ - --data '{ - "type": "SWAP", - "quoteId": "", - "accountId": "" - }' + curl --request GET \ + --url {{sandboxUrl}}/api/operations/ \ + --header 'Authorization: Bearer ' ``` - - Listen for `operation.created`, `operation.completed`, and `operation.failed` webhook events. - From d646570b7985338fb1622ba0c1d84a751b4b66aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rio=20Alvial?= Date: Tue, 14 Apr 2026 20:51:06 -0300 Subject: [PATCH 4/4] docs: add fx-account OpenAPI spec and API reference pages Include the complete fx-account OpenAPI spec with all 12 endpoint schemas and 12 MDX stub pages for account, UBO, document, and funding instruction endpoints. --- .../fx-account/accounts/create-account.mdx | 5 + .../fx-account/accounts/get-account.mdx | 5 + .../fx-account/accounts/list-accounts.mdx | 5 + .../accounts/submit-account-for-review.mdx | 5 + .../fx-account/beneficial-owners/add-ubo.mdx | 5 + .../fx-account/beneficial-owners/get-ubo.mdx | 5 + .../beneficial-owners/list-ubos.mdx | 5 + .../beneficial-owners/remove-ubo.mdx | 5 + .../beneficial-owners/update-ubo.mdx | 5 + .../documents/upload-account-document.mdx | 5 + .../documents/upload-ubo-document.mdx | 5 + .../list-funding-instructions.mdx | 5 + apis/fx-account/openapi.yml | 1385 ++++++++++++++++- 13 files changed, 1372 insertions(+), 73 deletions(-) create mode 100644 api-reference/fx-account/accounts/create-account.mdx create mode 100644 api-reference/fx-account/accounts/get-account.mdx create mode 100644 api-reference/fx-account/accounts/list-accounts.mdx create mode 100644 api-reference/fx-account/accounts/submit-account-for-review.mdx create mode 100644 api-reference/fx-account/beneficial-owners/add-ubo.mdx create mode 100644 api-reference/fx-account/beneficial-owners/get-ubo.mdx create mode 100644 api-reference/fx-account/beneficial-owners/list-ubos.mdx create mode 100644 api-reference/fx-account/beneficial-owners/remove-ubo.mdx create mode 100644 api-reference/fx-account/beneficial-owners/update-ubo.mdx create mode 100644 api-reference/fx-account/documents/upload-account-document.mdx create mode 100644 api-reference/fx-account/documents/upload-ubo-document.mdx create mode 100644 api-reference/fx-account/funding-instructions/list-funding-instructions.mdx diff --git a/api-reference/fx-account/accounts/create-account.mdx b/api-reference/fx-account/accounts/create-account.mdx new file mode 100644 index 0000000..48aae49 --- /dev/null +++ b/api-reference/fx-account/accounts/create-account.mdx @@ -0,0 +1,5 @@ +--- +title: "Create an account" +description: "Creates a new multi-currency account for the authenticated customer." +openapi: "apis/fx-account/openapi.yml POST /api/accounts" +--- diff --git a/api-reference/fx-account/accounts/get-account.mdx b/api-reference/fx-account/accounts/get-account.mdx new file mode 100644 index 0000000..f94a0cf --- /dev/null +++ b/api-reference/fx-account/accounts/get-account.mdx @@ -0,0 +1,5 @@ +--- +title: "Get an account" +description: "Retrieves the details of an account by its ID." +openapi: "apis/fx-account/openapi.yml GET /api/accounts/{accountId}" +--- diff --git a/api-reference/fx-account/accounts/list-accounts.mdx b/api-reference/fx-account/accounts/list-accounts.mdx new file mode 100644 index 0000000..073c9c2 --- /dev/null +++ b/api-reference/fx-account/accounts/list-accounts.mdx @@ -0,0 +1,5 @@ +--- +title: "List accounts" +description: "Lists all accounts for the authenticated customer with cursor-based pagination." +openapi: "apis/fx-account/openapi.yml GET /api/accounts" +--- diff --git a/api-reference/fx-account/accounts/submit-account-for-review.mdx b/api-reference/fx-account/accounts/submit-account-for-review.mdx new file mode 100644 index 0000000..56fa6d7 --- /dev/null +++ b/api-reference/fx-account/accounts/submit-account-for-review.mdx @@ -0,0 +1,5 @@ +--- +title: "Submit account for review" +description: "Submits an account for compliance review after all requirements are fulfilled." +openapi: "apis/fx-account/openapi.yml POST /api/accounts/{accountId}/review" +--- diff --git a/api-reference/fx-account/beneficial-owners/add-ubo.mdx b/api-reference/fx-account/beneficial-owners/add-ubo.mdx new file mode 100644 index 0000000..187d941 --- /dev/null +++ b/api-reference/fx-account/beneficial-owners/add-ubo.mdx @@ -0,0 +1,5 @@ +--- +title: "Add a beneficial owner" +description: "Adds a beneficial owner (UBO) to a company-owned account." +openapi: "apis/fx-account/openapi.yml POST /api/accounts/{accountId}/ubos" +--- diff --git a/api-reference/fx-account/beneficial-owners/get-ubo.mdx b/api-reference/fx-account/beneficial-owners/get-ubo.mdx new file mode 100644 index 0000000..d4fb896 --- /dev/null +++ b/api-reference/fx-account/beneficial-owners/get-ubo.mdx @@ -0,0 +1,5 @@ +--- +title: "Get a beneficial owner" +description: "Retrieves a specific beneficial owner by ID." +openapi: "apis/fx-account/openapi.yml GET /api/accounts/{accountId}/ubos/{uboId}" +--- diff --git a/api-reference/fx-account/beneficial-owners/list-ubos.mdx b/api-reference/fx-account/beneficial-owners/list-ubos.mdx new file mode 100644 index 0000000..8726cce --- /dev/null +++ b/api-reference/fx-account/beneficial-owners/list-ubos.mdx @@ -0,0 +1,5 @@ +--- +title: "List beneficial owners" +description: "Lists all beneficial owners for an account." +openapi: "apis/fx-account/openapi.yml GET /api/accounts/{accountId}/ubos" +--- diff --git a/api-reference/fx-account/beneficial-owners/remove-ubo.mdx b/api-reference/fx-account/beneficial-owners/remove-ubo.mdx new file mode 100644 index 0000000..4fcf802 --- /dev/null +++ b/api-reference/fx-account/beneficial-owners/remove-ubo.mdx @@ -0,0 +1,5 @@ +--- +title: "Remove a beneficial owner" +description: "Removes a beneficial owner from an account." +openapi: "apis/fx-account/openapi.yml DELETE /api/accounts/{accountId}/ubos/{uboId}" +--- diff --git a/api-reference/fx-account/beneficial-owners/update-ubo.mdx b/api-reference/fx-account/beneficial-owners/update-ubo.mdx new file mode 100644 index 0000000..2953100 --- /dev/null +++ b/api-reference/fx-account/beneficial-owners/update-ubo.mdx @@ -0,0 +1,5 @@ +--- +title: "Update a beneficial owner" +description: "Updates a beneficial owner using patch semantics. Only provided fields are changed." +openapi: "apis/fx-account/openapi.yml PATCH /api/accounts/{accountId}/ubos/{uboId}" +--- diff --git a/api-reference/fx-account/documents/upload-account-document.mdx b/api-reference/fx-account/documents/upload-account-document.mdx new file mode 100644 index 0000000..16ff069 --- /dev/null +++ b/api-reference/fx-account/documents/upload-account-document.mdx @@ -0,0 +1,5 @@ +--- +title: "Upload an account document" +description: "Uploads a document to fulfill a specific account requirement." +openapi: "apis/fx-account/openapi.yml POST /api/accounts/{accountId}/documents" +--- diff --git a/api-reference/fx-account/documents/upload-ubo-document.mdx b/api-reference/fx-account/documents/upload-ubo-document.mdx new file mode 100644 index 0000000..8028316 --- /dev/null +++ b/api-reference/fx-account/documents/upload-ubo-document.mdx @@ -0,0 +1,5 @@ +--- +title: "Upload a UBO document" +description: "Uploads a document to fulfill a specific beneficial owner requirement." +openapi: "apis/fx-account/openapi.yml POST /api/accounts/{accountId}/ubos/{uboId}/documents" +--- diff --git a/api-reference/fx-account/funding-instructions/list-funding-instructions.mdx b/api-reference/fx-account/funding-instructions/list-funding-instructions.mdx new file mode 100644 index 0000000..3a39f0f --- /dev/null +++ b/api-reference/fx-account/funding-instructions/list-funding-instructions.mdx @@ -0,0 +1,5 @@ +--- +title: "List funding instructions" +description: "Retrieves funding instructions for depositing into an account across all available payment rails." +openapi: "apis/fx-account/openapi.yml GET /api/accounts/{accountId}/fundingInstructions" +--- diff --git a/apis/fx-account/openapi.yml b/apis/fx-account/openapi.yml index 32b0abb..03f57bf 100644 --- a/apis/fx-account/openapi.yml +++ b/apis/fx-account/openapi.yml @@ -1,6 +1,6 @@ -openapi: 3.1.1 +openapi: 3.1.0 info: - title: Trace FX Accounts API + title: FX Account API version: 1.0.0 description: API for managing multi-currency accounts on the Trace FX platform. servers: @@ -10,6 +10,15 @@ servers: description: Production security: - bearerAuth: [] +tags: + - name: Accounts + description: Create, list, and manage multi-currency accounts. + - name: Beneficial owners + description: Manage beneficial owners (UBOs) for company-owned accounts. + - name: Documents + description: Upload documents to fulfill account and UBO requirements. + - name: Funding instructions + description: Retrieve funding instructions for depositing into an account. components: securitySchemes: bearerAuth: @@ -17,19 +26,221 @@ components: scheme: bearer bearerFormat: JWT description: "Auth0 JWT token. Include as `Authorization: Bearer `." + parameters: + AccountId: + name: accountId + in: path + required: true + description: UUID of the account. + schema: + type: string + format: uuid + UboId: + name: uboId + in: path + required: true + description: UUID of the beneficial owner. + schema: + type: string + format: uuid + TraceVersion: + name: X-Trace-Version + in: header + required: false + description: API version. Omit to use the default version. + schema: + type: string + example: "1" + IdempotencyKey: + name: Idempotency-Key + in: header + required: false + description: Unique key to ensure idempotent request processing. + schema: + type: string + format: uuid + PaginationLimit: + name: limit + in: query + required: false + description: Maximum number of items to return. Defaults to 10. + schema: + type: integer + default: 10 + minimum: 1 + maximum: 100 + PaginationCursor: + name: cursor + in: query + required: false + description: Opaque cursor for fetching the next or previous page. + schema: + type: string + PaginationDirection: + name: direction + in: query + required: false + description: Direction of pagination relative to the cursor. + schema: + type: string + enum: + - NEXT + - PREVIOUS + PaginationSortOrder: + name: sortOrder + in: query + required: false + description: Sort order for results. Defaults to DESCENDING. + schema: + type: string + enum: + - ASCENDING + - DESCENDING + default: DESCENDING + PaginationIncludeTotalMatches: + name: includeTotalMatches + in: query + required: false + description: Whether to include the total number of matching records in the response metadata. + schema: + type: boolean + default: false schemas: - AddressResponse: + # ── Request schemas ────────────────────────────────────────────── + CreateAccountRequest: type: object + description: Request body for creating a new account. properties: - street: + assets: + type: array + description: Desired asset currencies. At least one required; each code must be unique. + minItems: 1 + items: + $ref: "#/components/schemas/AssetRequest" + owner: + $ref: "#/components/schemas/OwnerRequest" + required: + - assets + - owner + AssetRequest: + type: object + properties: + code: + type: string + description: ISO 4217 currency code or stablecoin ticker. + example: "BRL" + isVirtual: + type: boolean + description: Whether this is a virtual (non-custodial) asset. + example: false + required: + - code + - isVirtual + OwnerRequest: + description: The legal entity that owns the account. Discriminated by `type`. + oneOf: + - $ref: "#/components/schemas/CompanyOwnerRequest" + - $ref: "#/components/schemas/IndividualOwnerRequest" + discriminator: + propertyName: type + mapping: + COMPANY: "#/components/schemas/CompanyOwnerRequest" + INDIVIDUAL: "#/components/schemas/IndividualOwnerRequest" + CompanyOwnerRequest: + type: object + properties: + type: + type: string + enum: + - COMPANY + legalName: + type: string + description: Registered legal name of the company. + example: "Acme Ltda" + taxId: + type: string + description: CNPJ of the company. + example: "12345678000101" + industry: + type: string + description: Industry classification. + enum: + - ACCOUNTING + - ADVERTISING__MARKETING + - AEROSPACE__DEFENSE + - AGRICULTURE__FORESTRY + - AMUSEMENT_AND_RECREATION + - AUTOMOTIVE + - CONSTRUCTION__CARPENTRY__LANDSCAPING + - CUSTOMER_SERVICE_AND_SUPPORT + - EDUCATION + - ENERGY + - ENGINEERING + - FINANCIAL_SERVICES + - HEALTHCARE__MEDICAL_SERVICES + - HOTEL__HOSPITALITY + - INFORMATION_TECHNOLOGY + - MANUFACTURING + - MEDIA__ENTERTAINMENT + - MINING_OIL_AND_GAS + - NON_PROFIT__NGO__CHARITY + - PHARMACEUTICALS + - PRINTING__PUBLISHING + - REAL_ESTATE + - RESTAURANT__FOOD_SERVICE + - RETAIL_SALES__RETAIL_TRADE + - SECURITY + - TRANSPORTATION + - TRAVEL + - UTILITIES + - WHOLESALE + - OTHERS + example: "INFORMATION_TECHNOLOGY" + address: + $ref: "#/components/schemas/AddressRequest" + required: + - type + - legalName + - taxId + - industry + - address + IndividualOwnerRequest: + type: object + properties: + type: + type: string + enum: + - INDIVIDUAL + firstName: + type: string + description: First name of the individual. + example: "Maria" + lastName: type: string - example: "Rua das Flores" - number: + description: Last name of the individual. + example: "Silva" + taxId: type: string - example: "100" - district: + description: CPF of the individual. + example: "12345678900" + address: + $ref: "#/components/schemas/AddressRequest" + required: + - type + - firstName + - lastName + - taxId + - address + AddressRequest: + type: object + properties: + addressLine1: type: string - example: "Centro" + example: "Rua das Flores, 100" + addressLine2: + type: string + nullable: true + example: "Suite 456" city: type: string example: "São Paulo" @@ -38,43 +249,63 @@ components: example: "SP" country: type: string + description: ISO 3166-1 alpha-2 country code. example: "BR" - zipCode: - type: string - example: "01000-000" - complement: + postalCode: type: string - nullable: true - example: "Apto 101" + example: "01234-567" required: - - street - - number - - district + - addressLine1 - city - state - country - - zipCode - OwnerResponse: + - postalCode + UBORequest: type: object - description: The account owner. + description: Request body for adding a beneficial owner. properties: - id: - type: string - format: uuid - example: "f47ac10b-58cc-4372-a567-0e02b2c3d479" name: type: string - example: "ACME Ltda" + description: Full legal name of the beneficial owner. + example: "João Silva" taxId: type: string - example: "12345678000190" + description: CPF or CNPJ of the beneficial owner. + example: "12345678900" address: - $ref: '#/components/schemas/AddressResponse' + $ref: "#/components/schemas/AddressRequest" + ownershipPercentage: + type: number + format: double + nullable: true + description: Percentage of ownership. Optional. + example: 50.0 required: - - id - name - taxId - address + UpdateUBORequest: + type: object + description: Request body for updating a beneficial owner. All fields are optional (patch semantics). + properties: + name: + type: string + description: Full legal name of the beneficial owner. + example: "João Silva" + taxId: + type: string + description: CPF or CNPJ of the beneficial owner. + example: "12345678900" + address: + $ref: "#/components/schemas/AddressRequest" + ownershipPercentage: + type: number + format: double + nullable: true + description: Percentage of ownership. + example: 75.0 + + # ── Response schemas ───────────────────────────────────────────── AccountResponse: type: object properties: @@ -82,34 +313,525 @@ components: type: string format: uuid example: "a1b2c3d4-5e6f-7890-abcd-ef1234567890" - externalId: + sourceAccountId: type: string + format: uuid nullable: true - description: Your own identifier for this account, if provided at creation. - example: "ext-123" + description: Parent account ID. Null for named accounts. + example: null + customer: + $ref: "#/components/schemas/CustomerResponse" owner: - $ref: '#/components/schemas/OwnerResponse' + $ref: "#/components/schemas/OwnerResponse" + requirements: + $ref: "#/components/schemas/RequirementsResponse" + tags: + type: array + items: + $ref: "#/components/schemas/TagResponse" + currentState: + $ref: "#/components/schemas/AccountState" + states: + type: array + description: Full state history of the account. + items: + $ref: "#/components/schemas/AccountState" createdAt: type: string format: date-time - example: "2025-01-15T10:30:00Z" + example: "2026-01-15T10:30:00Z" updatedAt: type: string format: date-time - example: "2025-01-15T10:30:00Z" + example: "2026-01-15T10:30:00Z" required: - id + - customer - owner + - requirements + - tags + - currentState + - states - createdAt - updatedAt + CustomerResponse: + type: object + properties: + id: + type: string + description: Customer identifier. + example: "c1a2b3c4-d5e6-7890-abcd-ef1234567890" + required: + - id + OwnerResponse: + description: The legal entity that owns the account. Discriminated by `type`. + oneOf: + - $ref: "#/components/schemas/CompanyOwnerResponse" + - $ref: "#/components/schemas/IndividualOwnerResponse" + discriminator: + propertyName: type + mapping: + COMPANY: "#/components/schemas/CompanyOwnerResponse" + INDIVIDUAL: "#/components/schemas/IndividualOwnerResponse" + CompanyOwnerResponse: + type: object + properties: + type: + type: string + enum: + - COMPANY + legalName: + type: string + example: "Acme Ltda" + taxId: + type: string + example: "12345678000101" + industry: + type: string + example: "INFORMATION_TECHNOLOGY" + address: + $ref: "#/components/schemas/AddressResponse" + ubos: + type: array + items: + $ref: "#/components/schemas/UBOResponse" + required: + - type + - legalName + - taxId + - industry + - address + - ubos + IndividualOwnerResponse: + type: object + properties: + type: + type: string + enum: + - INDIVIDUAL + firstName: + type: string + example: "Maria" + lastName: + type: string + example: "Silva" + taxId: + type: string + example: "12345678900" + address: + $ref: "#/components/schemas/AddressResponse" + required: + - type + - firstName + - lastName + - taxId + - address + AddressResponse: + type: object + properties: + addressLine1: + type: string + example: "Rua das Flores, 100" + addressLine2: + type: string + nullable: true + example: "Suite 456" + city: + type: string + example: "São Paulo" + state: + type: string + nullable: true + example: "SP" + country: + type: string + description: ISO 3166-1 alpha-2 country code. + example: "BR" + postalCode: + type: string + example: "01234-567" + required: + - addressLine1 + - city + - country + - postalCode + AccountState: + type: object + description: A point-in-time state of the account. + properties: + status: + type: string + enum: + - ACTION_REQUIRED + - REVIEWING + - OPENING + - ACTIVE + - REJECTED + - CLOSED + example: "ACTION_REQUIRED" + reason: + $ref: "#/components/schemas/Reason" + createdAt: + type: string + format: date-time + example: "2026-01-15T10:30:00Z" + required: + - status + - createdAt + UBOState: + type: object + description: A point-in-time state of a beneficial owner. + properties: + status: + type: string + enum: + - PENDING + - APPROVED + - REJECTED + example: "PENDING" + reason: + $ref: "#/components/schemas/Reason" + createdAt: + type: string + format: date-time + example: "2026-01-15T10:30:00Z" + required: + - status + - createdAt + Reason: + type: object + nullable: true + description: Explains why a state transition occurred. + properties: + code: + type: string + description: Machine-readable error code. + example: "DOCUMENT_REJECTED" + message: + type: string + description: Human-readable description. + example: "Document is illegible" + details: + type: object + additionalProperties: true + description: Additional context. May be empty. + example: {} + required: + - code + - message + - details + RequirementsResponse: + type: object + description: "Stripe-style requirement buckets grouped by lifecycle stage." + properties: + currentlyDue: + type: array + description: Requirements pending submission. + items: + $ref: "#/components/schemas/RequirementResponse" + pendingVerification: + type: array + description: Submitted requirements awaiting verification. + items: + $ref: "#/components/schemas/RequirementResponse" + errors: + type: array + description: Rejected requirements with reasons. + items: + $ref: "#/components/schemas/RequirementResponse" + satisfied: + type: array + description: Fulfilled requirements. + items: + $ref: "#/components/schemas/RequirementResponse" + required: + - currentlyDue + - pendingVerification + - errors + - satisfied + RequirementResponse: + type: object + description: A single requirement. Currently only `DOCUMENT` type is supported. + properties: + type: + type: string + description: Requirement type discriminator. + enum: + - DOCUMENT + example: "DOCUMENT" + documentType: + type: string + nullable: true + description: The type of document required. + enum: + - CNPJ_CERTIFICATE + - PROOF_OF_ADDRESS + - SOCIAL_CONTRACT + - IDENTITY_DOCUMENT + example: "CNPJ_CERTIFICATE" + uboId: + type: string + format: uuid + nullable: true + description: UBO identifier if this requirement belongs to a beneficial owner. + reason: + $ref: "#/components/schemas/Reason" + required: + - type + TagResponse: + type: object + properties: + key: + type: string + nullable: true + value: + type: string + required: + - value + UBOResponse: + type: object + properties: + id: + type: string + format: uuid + example: "b2c3d4e5-f6a7-8901-bcde-f12345678901" + name: + type: string + example: "João Silva" + taxId: + type: string + example: "12345678900" + address: + $ref: "#/components/schemas/AddressResponse" + ownershipPercentage: + type: number + format: double + nullable: true + example: 50.0 + currentState: + $ref: "#/components/schemas/UBOState" + required: + - id + - name + - taxId + - address + - currentState + FundingInstructionResponse: + description: A funding instruction for depositing into an account. Discriminated by `type`. + oneOf: + - $ref: "#/components/schemas/PixKeyFundingInstruction" + - $ref: "#/components/schemas/PixStaticQrCodeFundingInstruction" + - $ref: "#/components/schemas/TedFundingInstruction" + - $ref: "#/components/schemas/BoletoFundingInstruction" + - $ref: "#/components/schemas/CryptoWalletFundingInstruction" + discriminator: + propertyName: type + mapping: + PIX_KEY: "#/components/schemas/PixKeyFundingInstruction" + PIX_STATIC_QR_CODE: "#/components/schemas/PixStaticQrCodeFundingInstruction" + TED: "#/components/schemas/TedFundingInstruction" + BOLETO: "#/components/schemas/BoletoFundingInstruction" + CRYPTO_WALLET: "#/components/schemas/CryptoWalletFundingInstruction" + FundingInstructionBase: + type: object + properties: + asset: + type: string + description: Currency code for this funding instruction. + example: "BRL" + type: + type: string + description: Funding instruction type discriminator. + enum: + - PIX_KEY + - PIX_STATIC_QR_CODE + - TED + - BOLETO + - CRYPTO_WALLET + rail: + type: string + description: Payment rail. Computed from the type. + enum: + - PIX + - TED + - BOLETO + - CRYPTO + readOnly: true + required: + - asset + - type + - rail + PixKeyFundingInstruction: + allOf: + - $ref: "#/components/schemas/FundingInstructionBase" + - type: object + properties: + type: + type: string + enum: + - PIX_KEY + rail: + type: string + enum: + - PIX + keyType: + type: string + description: PIX key type. + enum: + - CPF + - CNPJ + - EMAIL + - PHONE + - RANDOM + example: "CNPJ" + key: + type: string + description: The PIX key value. + example: "12345678000101" + required: + - keyType + - key + PixStaticQrCodeFundingInstruction: + allOf: + - $ref: "#/components/schemas/FundingInstructionBase" + - type: object + properties: + type: + type: string + enum: + - PIX_STATIC_QR_CODE + rail: + type: string + enum: + - PIX + qrCode: + type: string + description: Static QR code payload (EMV format). + example: "00020126580014br.gov.bcb.pix..." + required: + - qrCode + TedFundingInstruction: + allOf: + - $ref: "#/components/schemas/FundingInstructionBase" + - type: object + properties: + type: + type: string + enum: + - TED + rail: + type: string + enum: + - TED + bankCode: + type: string + description: Bank code (ISPB or COMPE). + example: "001" + branch: + type: string + description: Branch number. + example: "0001" + accountNumber: + type: string + description: Account number. + example: "123456-7" + accountType: + type: string + description: Type of bank account. + example: "CHECKING" + required: + - bankCode + - branch + - accountNumber + - accountType + BoletoFundingInstruction: + allOf: + - $ref: "#/components/schemas/FundingInstructionBase" + - type: object + properties: + type: + type: string + enum: + - BOLETO + rail: + type: string + enum: + - BOLETO + barcode: + type: string + description: Boleto barcode (digitable line). + example: "23793.38128 60800.000003 00000.000400 1 84340000012345" + dueDate: + type: string + format: date-time + description: Payment due date. + example: "2026-04-04T00:00:00Z" + required: + - barcode + - dueDate + CryptoWalletFundingInstruction: + allOf: + - $ref: "#/components/schemas/FundingInstructionBase" + - type: object + properties: + type: + type: string + enum: + - CRYPTO_WALLET + rail: + type: string + enum: + - CRYPTO + network: + type: string + description: Blockchain network. + example: "ETHEREUM" + walletAddress: + type: string + description: Deposit wallet address. + example: "0x1234567890abcdef1234567890abcdef12345678" + required: + - network + - walletAddress + DocumentResponse: + type: object + properties: + documentId: + type: string + description: Identifier of the uploaded document. + example: "doc-a1b2c3d4-e5f6-7890-abcd-ef1234567890" + required: + - documentId + PageMetadata: + type: object + properties: + previous: + type: string + nullable: true + description: Cursor for the previous page. + next: + type: string + nullable: true + description: Cursor for the next page. + count: + type: integer + description: Number of items in the current page. + totalMatches: + type: integer + nullable: true + description: Total number of matching records. Only present when `includeTotalMatches` is true. + required: + - count ErrorResponse: type: object properties: code: type: string + description: Machine-readable error code. example: "RESOURCE_NOT_FOUND" message: type: string + description: Human-readable description. example: "The requested resource was not found" details: type: object @@ -118,70 +840,587 @@ components: required: - code - message + paths: + # ── Account endpoints ──────────────────────────────────────────── + /api/accounts: + post: + operationId: createAccount + tags: + - Accounts + summary: Create an account + description: Creates a new multi-currency account for the authenticated customer. + parameters: + - $ref: "#/components/parameters/TraceVersion" + - $ref: "#/components/parameters/IdempotencyKey" + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/CreateAccountRequest" + examples: + company: + summary: Company-owned account + value: + assets: + - code: "BRL" + isVirtual: false + owner: + type: "COMPANY" + legalName: "Acme Ltda" + taxId: "12345678000101" + industry: "INFORMATION_TECHNOLOGY" + address: + addressLine1: "Rua das Flores, 100" + addressLine2: "Suite 456" + city: "São Paulo" + state: "SP" + country: "BR" + postalCode: "01234-567" + individual: + summary: Individually-owned account + value: + assets: + - code: "BRL" + isVirtual: false + owner: + type: "INDIVIDUAL" + firstName: "Maria" + lastName: "Silva" + taxId: "12345678900" + address: + addressLine1: "Rua das Flores, 100" + city: "São Paulo" + state: "SP" + country: "BR" + postalCode: "01234-567" + responses: + "201": + description: Account created. + content: + application/json: + schema: + $ref: "#/components/schemas/AccountResponse" + "400": + description: Invalid request body. + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + "401": + description: Missing or invalid authentication token. + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + "404": + description: Customer not found. + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + "422": + description: Validation error (e.g., individual customer with mismatched tax ID). + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + get: + operationId: listAccounts + tags: + - Accounts + summary: List accounts + description: Lists all accounts for the authenticated customer. Results are paginated using cursor-based pagination. + parameters: + - $ref: "#/components/parameters/TraceVersion" + - $ref: "#/components/parameters/PaginationLimit" + - $ref: "#/components/parameters/PaginationCursor" + - $ref: "#/components/parameters/PaginationDirection" + - $ref: "#/components/parameters/PaginationSortOrder" + - $ref: "#/components/parameters/PaginationIncludeTotalMatches" + responses: + "200": + description: Paginated list of accounts. + content: + application/json: + schema: + type: object + properties: + data: + type: array + items: + $ref: "#/components/schemas/AccountResponse" + meta: + $ref: "#/components/schemas/PageMetadata" + required: + - data + - meta + "401": + description: Missing or invalid authentication token. + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + /api/accounts/{accountId}: get: - operationId: getAccountById + operationId: getAccount tags: - Accounts summary: Get an account - description: Retrieve the details of an account by its ID. + description: Retrieves the details of an account by its ID. parameters: - - name: accountId - in: path - required: true - description: UUID of the account. - schema: - type: string - format: uuid - - name: X-Trace-Version - in: header - required: false - description: API version. Omit to use the default version. - schema: - type: string + - $ref: "#/components/parameters/AccountId" + - $ref: "#/components/parameters/TraceVersion" responses: "200": description: Account details. content: application/json: schema: - $ref: '#/components/schemas/AccountResponse' + $ref: "#/components/schemas/AccountResponse" + "400": + description: Invalid account ID format. + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + "401": + description: Missing or invalid authentication token. + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + "404": + description: Account not found. + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + + /api/accounts/{accountId}/review: + post: + operationId: submitAccountForReview + tags: + - Accounts + summary: Submit account for review + description: Submits an account for compliance review. All required documents and data must be provided before calling this endpoint. + parameters: + - $ref: "#/components/parameters/AccountId" + - $ref: "#/components/parameters/TraceVersion" + - $ref: "#/components/parameters/IdempotencyKey" + responses: + "202": + description: Account submitted for review. + "401": + description: Missing or invalid authentication token. + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + "404": + description: Account not found. + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + "409": + description: Account has no provider accounts requiring analysis. + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + "422": + description: Account has missing documents or unfulfilled requirements. + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + + # ── Funding instructions ───────────────────────────────────────── + /api/accounts/{accountId}/fundingInstructions: + get: + operationId: listFundingInstructions + tags: + - Funding instructions + summary: List funding instructions + description: Retrieves funding instructions for depositing into an account. Returns all available payment rails (PIX, TED, Boleto, crypto). + parameters: + - $ref: "#/components/parameters/AccountId" + - $ref: "#/components/parameters/TraceVersion" + responses: + "200": + description: List of funding instructions. + content: + application/json: + schema: + type: array + items: + $ref: "#/components/schemas/FundingInstructionResponse" examples: - success: + mixed: + summary: PIX and TED instructions value: - id: "a1b2c3d4-5e6f-7890-abcd-ef1234567890" - externalId: "ext-123" - owner: - id: "f47ac10b-58cc-4372-a567-0e02b2c3d479" - name: "ACME Ltda" - taxId: "12345678000190" - address: - street: "Rua das Flores" - number: "100" - district: "Centro" - city: "São Paulo" - state: "SP" - country: "BR" - zipCode: "01000-000" - complement: "Apto 101" - createdAt: "2025-01-15T10:30:00Z" - updatedAt: "2025-01-15T10:30:00Z" + - asset: "BRL" + rail: "PIX" + type: "PIX_KEY" + keyType: "CNPJ" + key: "12345678000101" + - asset: "BRL" + rail: "TED" + type: "TED" + bankCode: "001" + branch: "0001" + accountNumber: "123456-7" + accountType: "CHECKING" + "400": + description: Invalid account ID format. + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + "401": + description: Missing or invalid authentication token. + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + "404": + description: Account not found. + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + + # ── Account documents ──────────────────────────────────────────── + /api/accounts/{accountId}/documents: + post: + operationId: uploadAccountDocument + tags: + - Documents + summary: Upload an account document + description: Uploads a document to fulfill a specific account requirement. + parameters: + - $ref: "#/components/parameters/AccountId" + - $ref: "#/components/parameters/TraceVersion" + - $ref: "#/components/parameters/IdempotencyKey" + requestBody: + required: true + content: + multipart/form-data: + schema: + type: object + properties: + requirementId: + type: string + format: uuid + description: Identifier of the requirement being fulfilled. + file: + type: string + format: binary + description: Document file content. + required: + - requirementId + - file + responses: + "200": + description: Document uploaded. + content: + application/json: + schema: + $ref: "#/components/schemas/DocumentResponse" + "400": + description: Invalid account ID format or missing multipart fields. + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + "401": + description: Missing or invalid authentication token. + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + "404": + description: Account not found. + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + "422": + description: No matching requirement for the given requirement ID. + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + + # ── Beneficial owner endpoints ─────────────────────────────────── + /api/accounts/{accountId}/ubos: + post: + operationId: addUbo + tags: + - Beneficial owners + summary: Add a beneficial owner + description: Adds a beneficial owner (UBO) to a company-owned account. + parameters: + - $ref: "#/components/parameters/AccountId" + - $ref: "#/components/parameters/TraceVersion" + - $ref: "#/components/parameters/IdempotencyKey" + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/UBORequest" + examples: + basic: + summary: Add a UBO + value: + name: "João Silva" + taxId: "12345678900" + address: + addressLine1: "Rua das Flores, 100" + city: "São Paulo" + state: "SP" + country: "BR" + postalCode: "01234-567" + ownershipPercentage: 50.0 + responses: + "201": + description: Beneficial owner added. + content: + application/json: + schema: + $ref: "#/components/schemas/UBOResponse" "400": - description: Invalid request data. + description: Invalid request body. + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + "401": + description: Missing or invalid authentication token. + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + "404": + description: Account not found. + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + "422": + description: Validation error. + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + get: + operationId: listUbos + tags: + - Beneficial owners + summary: List beneficial owners + description: Lists all beneficial owners for an account. + parameters: + - $ref: "#/components/parameters/AccountId" + - $ref: "#/components/parameters/TraceVersion" + responses: + "200": + description: List of beneficial owners. content: application/json: schema: - $ref: '#/components/schemas/ErrorResponse' + type: array + items: + $ref: "#/components/schemas/UBOResponse" "401": description: Missing or invalid authentication token. content: application/json: schema: - $ref: '#/components/schemas/ErrorResponse' + $ref: "#/components/schemas/ErrorResponse" "404": description: Account not found. content: application/json: schema: - $ref: '#/components/schemas/ErrorResponse' + $ref: "#/components/schemas/ErrorResponse" + + /api/accounts/{accountId}/ubos/{uboId}: + get: + operationId: getUbo + tags: + - Beneficial owners + summary: Get a beneficial owner + description: Retrieves a specific beneficial owner by ID. + parameters: + - $ref: "#/components/parameters/AccountId" + - $ref: "#/components/parameters/UboId" + - $ref: "#/components/parameters/TraceVersion" + responses: + "200": + description: Beneficial owner details. + content: + application/json: + schema: + $ref: "#/components/schemas/UBOResponse" + "401": + description: Missing or invalid authentication token. + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + "404": + description: Account or beneficial owner not found. + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + patch: + operationId: updateUbo + tags: + - Beneficial owners + summary: Update a beneficial owner + description: Updates a beneficial owner. All fields are optional (patch semantics) — only provided fields are updated. + parameters: + - $ref: "#/components/parameters/AccountId" + - $ref: "#/components/parameters/UboId" + - $ref: "#/components/parameters/TraceVersion" + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/UpdateUBORequest" + examples: + nameOnly: + summary: Update name only + value: + name: "João Carlos Silva" + full: + summary: Update all fields + value: + name: "João Carlos Silva" + taxId: "98765432100" + address: + addressLine1: "Av. Paulista, 1000" + city: "São Paulo" + state: "SP" + country: "BR" + postalCode: "01310-100" + ownershipPercentage: 75.0 + responses: + "200": + description: Beneficial owner updated. + content: + application/json: + schema: + $ref: "#/components/schemas/UBOResponse" + "400": + description: Invalid request body. + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + "401": + description: Missing or invalid authentication token. + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + "404": + description: Account or beneficial owner not found. + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + "422": + description: Validation error (e.g., ownership below 25%, UBO already approved). + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + delete: + operationId: removeUbo + tags: + - Beneficial owners + summary: Remove a beneficial owner + description: Removes a beneficial owner from an account. + parameters: + - $ref: "#/components/parameters/AccountId" + - $ref: "#/components/parameters/UboId" + - $ref: "#/components/parameters/TraceVersion" + responses: + "204": + description: Beneficial owner removed. + "401": + description: Missing or invalid authentication token. + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + "404": + description: Account or beneficial owner not found. + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + + # ── UBO documents ──────────────────────────────────────────────── + /api/accounts/{accountId}/ubos/{uboId}/documents: + post: + operationId: uploadUboDocument + tags: + - Documents + summary: Upload a UBO document + description: Uploads a document to fulfill a specific beneficial owner requirement. + parameters: + - $ref: "#/components/parameters/AccountId" + - $ref: "#/components/parameters/UboId" + - $ref: "#/components/parameters/TraceVersion" + - $ref: "#/components/parameters/IdempotencyKey" + requestBody: + required: true + content: + multipart/form-data: + schema: + type: object + properties: + requirementId: + type: string + format: uuid + description: Identifier of the requirement being fulfilled. + file: + type: string + format: binary + description: Document file content. + required: + - requirementId + - file + responses: + "200": + description: Document uploaded. + content: + application/json: + schema: + $ref: "#/components/schemas/DocumentResponse" + "400": + description: Invalid parameters or missing multipart fields. + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + "401": + description: Missing or invalid authentication token. + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + "404": + description: Account or beneficial owner not found. + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse"