openapi: 3.0.3 info: title: DBIS Nostro/Vostro API version: 1.0.0 description: | Standardized API for Nostro/Vostro accounts, balances, transfers, and reconciliations between Central Banks and regulated Financial Institutions under DBIS. This API provides a harmonized integration layer for: - Cross-border settlement - Liquidity management - FX and GRU-based settlement - GAS → Ω-Layer finality via DBIS contact: name: DBIS API Support email: api-support@dbis.org license: name: Proprietary url: https://dbis.org/license servers: - url: https://api.scb.example.com/api/v1/nostro-vostro description: Production - url: https://sandbox.scb.example.com/api/v1/nostro-vostro description: Sandbox security: - OAuth2MTLS: [] tags: - name: Nostro/Vostro description: Core Nostro/Vostro operations - name: GRU/FX description: GRU/FX rate discovery and conversion paths: /participants: get: summary: List participants description: Retrieve a paginated list of participants (SCBs, FIs) operationId: listParticipants tags: [Nostro/Vostro] parameters: - $ref: '#/components/parameters/RegulatoryTier' - $ref: '#/components/parameters/Country' - $ref: '#/components/parameters/Status' - $ref: '#/components/parameters/Page' - $ref: '#/components/parameters/PageSize' responses: '200': description: List of participants content: application/json: schema: $ref: '#/components/schemas/ParticipantListResponse' examples: success: value: success: true data: data: - participantId: "PART-123" name: "Central Bank of Example" bic: "CBEXUS33" lei: "5493000X9ZXSQ9B6Y815" country: "US" regulatoryTier: "SCB" status: "active" createdAt: "2024-01-01T00:00:00Z" updatedAt: "2024-01-01T00:00:00Z" pagination: page: 1 pageSize: 50 total: 1 totalPages: 1 timestamp: "2024-01-15T10:30:00Z" '401': $ref: '#/components/responses/Unauthorized' '500': $ref: '#/components/responses/InternalServerError' post: summary: Create participant description: Register a new participant (SCB or FI) operationId: createParticipant tags: [Nostro/Vostro] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ParticipantCreateRequest' examples: centralBank: value: name: "Central Bank of Example" bic: "CBEXUS33" lei: "5493000X9ZXSQ9B6Y815" country: "US" regulatoryTier: "SCB" financialInstitution: value: name: "Example Bank Ltd" bic: "EXMPGB22" lei: "213800LBQA1Y9L22CC55" country: "GB" regulatoryTier: "Tier1" responses: '201': description: Participant created successfully content: application/json: schema: $ref: '#/components/schemas/ParticipantResponse' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '409': $ref: '#/components/responses/Conflict' /participants/{participantId}: get: summary: Get participant details description: Retrieve details for a specific participant operationId: getParticipant tags: [Nostro/Vostro] parameters: - $ref: '#/components/parameters/ParticipantId' responses: '200': description: Participant details content: application/json: schema: $ref: '#/components/schemas/ParticipantResponse' '404': $ref: '#/components/responses/NotFound' '401': $ref: '#/components/responses/Unauthorized' /accounts: get: summary: List Nostro/Vostro accounts description: Retrieve a paginated list of accounts operationId: listAccounts tags: [Nostro/Vostro] parameters: - name: ownerParticipantId in: query schema: type: string description: Filter by owner participant ID - name: counterpartyParticipantId in: query schema: type: string description: Filter by counterparty participant ID - name: accountType in: query schema: type: string enum: [NOSTRO, VOSTRO] description: Filter by account type - name: currency in: query schema: type: string description: Filter by currency (ISO 4217) - name: status in: query schema: type: string enum: [ACTIVE, SUSPENDED, CLOSED] - $ref: '#/components/parameters/Page' - $ref: '#/components/parameters/PageSize' responses: '200': description: List of accounts content: application/json: schema: $ref: '#/components/schemas/AccountListResponse' '401': $ref: '#/components/responses/Unauthorized' post: summary: Create Nostro/Vostro account description: Create a new Nostro or Vostro account operationId: createAccount tags: [Nostro/Vostro] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AccountCreateRequest' example: ownerParticipantId: "PART-123" counterpartyParticipantId: "PART-456" ibanOrLocalAccount: "US64SVBKUS6S3300958879" currency: "USD" accountType: "NOSTRO" responses: '201': description: Account created successfully content: application/json: schema: $ref: '#/components/schemas/AccountResponse' '400': $ref: '#/components/responses/BadRequest' '404': $ref: '#/components/responses/NotFound' /accounts/{accountId}: get: summary: Get account details description: Retrieve details for a specific account operationId: getAccount tags: [Nostro/Vostro] parameters: - name: accountId in: path required: true schema: type: string description: Account ID responses: '200': description: Account details content: application/json: schema: $ref: '#/components/schemas/AccountResponse' '404': $ref: '#/components/responses/NotFound' /accounts/{accountId}/balances: get: summary: Get balances and liquidity description: Retrieve current balance, available liquidity, and hold amounts operationId: getAccountBalances tags: [Nostro/Vostro] parameters: - name: accountId in: path required: true schema: type: string responses: '200': description: Balance details content: application/json: schema: $ref: '#/components/schemas/BalanceResponse' '404': $ref: '#/components/responses/NotFound' /transfers: post: summary: Initiate a transfer/settlement instruction description: Create a new transfer with idempotency support operationId: createTransfer tags: [Nostro/Vostro] parameters: - name: Idempotency-Key in: header required: false schema: type: string description: Idempotency key for duplicate request prevention requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/TransferCreateRequest' example: fromAccountId: "ACC-123" toAccountId: "ACC-456" amount: "1000.00" currency: "USD" settlementAsset: "FIAT" valueDate: "2024-01-15" reference: "PAYMENT-REF-001" responses: '201': description: Transfer created successfully content: application/json: schema: $ref: '#/components/schemas/TransferResponse' '400': $ref: '#/components/responses/BadRequest' '409': description: Duplicate request (idempotency key conflict) content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '422': $ref: '#/components/responses/UnprocessableEntity' get: summary: List transfers description: Retrieve a paginated list of transfers with optional filters operationId: listTransfers tags: [Nostro/Vostro] parameters: - name: fromAccountId in: query schema: type: string - name: toAccountId in: query schema: type: string - name: status in: query schema: type: string enum: [PENDING, ACCEPTED, SETTLED, REJECTED, CANCELLED] - name: settlementAsset in: query schema: type: string enum: [FIAT, GRU, SSU, CBDC] - $ref: '#/components/parameters/Page' - $ref: '#/components/parameters/PageSize' responses: '200': description: List of transfers content: application/json: schema: $ref: '#/components/schemas/TransferListResponse' /transfers/{transferId}: get: summary: Get transfer status description: Retrieve transfer details and current status operationId: getTransfer tags: [Nostro/Vostro] parameters: - name: transferId in: path required: true schema: type: string responses: '200': description: Transfer details content: application/json: schema: $ref: '#/components/schemas/TransferResponse' '404': $ref: '#/components/responses/NotFound' /reconciliations: post: summary: Request reconciliation report description: Generate a reconciliation report for a participant as of a specific date operationId: requestReconciliation tags: [Nostro/Vostro] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ReconciliationRequest' example: participantId: "PART-123" asOfDate: "2024-01-15" responses: '202': description: Reconciliation request accepted content: application/json: schema: $ref: '#/components/schemas/ReconciliationResponse' '400': $ref: '#/components/responses/BadRequest' '404': $ref: '#/components/responses/NotFound' /reconciliations/{reportId}: get: summary: Get reconciliation report description: Retrieve a reconciliation report by ID operationId: getReconciliation tags: [Nostro/Vostro] parameters: - name: reportId in: path required: true schema: type: string responses: '200': description: Reconciliation report content: application/json: schema: $ref: '#/components/schemas/ReconciliationResponse' '404': $ref: '#/components/responses/NotFound' /webhooks/subscriptions: post: summary: Create webhook subscription description: Subscribe to webhook events for a participant operationId: createWebhookSubscription tags: [Nostro/Vostro] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/WebhookSubscriptionCreateRequest' example: participantId: "PART-123" webhookUrl: "https://example.com/webhooks" eventTypes: ["TRANSFER_CREATED", "TRANSFER_SETTLED"] responses: '201': description: Webhook subscription created content: application/json: schema: $ref: '#/components/schemas/WebhookSubscriptionResponse' '400': $ref: '#/components/responses/BadRequest' get: summary: List webhook subscriptions description: List webhook subscriptions for a participant operationId: listWebhookSubscriptions tags: [Nostro/Vostro] parameters: - name: participantId in: query required: true schema: type: string - name: status in: query schema: type: string enum: [ACTIVE, SUSPENDED, INACTIVE] - $ref: '#/components/parameters/Page' - $ref: '#/components/parameters/PageSize' responses: '200': description: List of webhook subscriptions content: application/json: schema: $ref: '#/components/schemas/WebhookSubscriptionListResponse' /webhooks/subscriptions/{subscriptionId}: get: summary: Get webhook subscription description: Retrieve webhook subscription details operationId: getWebhookSubscription tags: [Nostro/Vostro] parameters: - name: subscriptionId in: path required: true schema: type: string responses: '200': description: Webhook subscription details content: application/json: schema: $ref: '#/components/schemas/WebhookSubscriptionResponse' '404': $ref: '#/components/responses/NotFound' /webhooks/events: post: summary: Receive webhook events (FI side) description: Endpoint implemented by FI to receive notifications. This is a reference endpoint - FIs should implement their own. operationId: receiveWebhookEvent tags: [Nostro/Vostro] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/WebhookEvent' responses: '200': description: Webhook event received /gru-fx/rates: get: summary: Get real-time GRU/FX rate description: Retrieve current exchange rate for a currency pair (including GRU pairs) operationId: getGruFxRate tags: [GRU/FX] parameters: - name: pair in: query required: true schema: type: string description: Currency pair (e.g., "USD/GRU", "GRU/EUR", "USD/EUR") example: "USD/GRU" responses: '200': description: Current exchange rate content: application/json: schema: $ref: '#/components/schemas/GruFxRateResponse' '400': $ref: '#/components/responses/BadRequest' /gru-fx/rates/history: get: summary: Get rate history description: Retrieve historical exchange rates for a currency pair operationId: getGruFxRateHistory tags: [GRU/FX] parameters: - name: pair in: query required: true schema: type: string - name: startDate in: query required: true schema: type: string format: date - name: endDate in: query required: true schema: type: string format: date - name: interval in: query schema: type: string enum: [1h, 1d, 1w] default: 1d responses: '200': description: Rate history content: application/json: schema: $ref: '#/components/schemas/GruFxRateHistoryResponse' '400': $ref: '#/components/responses/BadRequest' /gru-fx/convert: post: summary: Convert currency using GRU/FX rates description: Convert between currencies using GRU as intermediary or direct rates operationId: convertCurrency tags: [GRU/FX] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/GruFxConversionRequest' example: fromCurrency: "USD" toCurrency: "EUR" amount: "1000.00" settlementAsset: "FIAT" valueDate: "2024-01-15" responses: '200': description: Conversion result content: application/json: schema: $ref: '#/components/schemas/GruFxConversionResponse' '400': $ref: '#/components/responses/BadRequest' /gru-fx/pairs: get: summary: Get available currency pairs description: List all available currency pairs (including GRU pairs) operationId: getAvailablePairs tags: [GRU/FX] responses: '200': description: List of available pairs content: application/json: schema: type: object properties: success: type: boolean data: type: object properties: pairs: type: array items: type: string example: ["USD/GRU", "EUR/GRU", "USD/EUR"] components: securitySchemes: OAuth2MTLS: type: oauth2 description: OAuth2 with Mutual TLS authentication flows: clientCredentials: tokenUrl: https://auth.scb.example.com/oauth/token scopes: nv.read: Read Nostro/Vostro data nv.write: Create Nostro/Vostro transactions nv.reconcile: Request reconciliation reports gru.read: Read GRU/FX rates gru.convert: Convert currencies parameters: ParticipantId: name: participantId in: path required: true schema: type: string description: Participant ID RegulatoryTier: name: regulatoryTier in: query schema: type: string enum: [SCB, Tier1, Tier2, PSP] description: Filter by regulatory tier Country: name: country in: query schema: type: string description: Filter by country (ISO 3166-1 alpha-2) Status: name: status in: query schema: type: string enum: [active, suspended, inactive] description: Filter by status Page: name: page in: query schema: type: integer default: 1 minimum: 1 description: Page number PageSize: name: pageSize in: query schema: type: integer default: 50 minimum: 1 maximum: 100 description: Items per page schemas: Participant: type: object required: [participantId, name, country, regulatoryTier, status] properties: participantId: type: string example: "PART-123" name: type: string example: "Central Bank of Example" bic: type: string example: "CBEXUS33" lei: type: string example: "5493000X9ZXSQ9B6Y815" country: type: string pattern: '^[A-Z]{2}$' example: "US" regulatoryTier: type: string enum: [SCB, Tier1, Tier2, PSP] example: "SCB" sovereignBankId: type: string status: type: string enum: [active, suspended, inactive] example: "active" metadata: type: object createdAt: type: string format: date-time updatedAt: type: string format: date-time ParticipantCreateRequest: type: object required: [name, country, regulatoryTier] properties: participantId: type: string description: Auto-generated if not provided name: type: string example: "Central Bank of Example" bic: type: string pattern: '^[A-Z]{4}[A-Z]{2}[A-Z0-9]{2}([A-Z0-9]{3})?$' example: "CBEXUS33" lei: type: string pattern: '^[A-Z0-9]{18}[0-9]{2}$' example: "5493000X9ZXSQ9B6Y815" country: type: string pattern: '^[A-Z]{2}$' example: "US" regulatoryTier: type: string enum: [SCB, Tier1, Tier2, PSP] example: "SCB" sovereignBankId: type: string metadata: type: object ParticipantResponse: type: object properties: success: type: boolean data: $ref: '#/components/schemas/Participant' timestamp: type: string format: date-time ParticipantListResponse: type: object properties: success: type: boolean data: type: object properties: data: type: array items: $ref: '#/components/schemas/Participant' pagination: $ref: '#/components/schemas/Pagination' timestamp: type: string format: date-time Account: type: object required: [accountId, ownerParticipantId, counterpartyParticipantId, currency, accountType, status] properties: accountId: type: string example: "ACC-123" ownerParticipantId: type: string counterpartyParticipantId: type: string ibanOrLocalAccount: type: string example: "US64SVBKUS6S3300958879" currency: type: string pattern: '^[A-Z]{3}$' example: "USD" accountType: type: string enum: [NOSTRO, VOSTRO] example: "NOSTRO" status: type: string enum: [ACTIVE, SUSPENDED, CLOSED] example: "ACTIVE" currentBalance: type: string pattern: '^\d+\.\d{2}$' example: "1000000.00" availableLiquidity: type: string example: "950000.00" holdAmount: type: string example: "50000.00" lastUpdatedAt: type: string format: date-time metadata: type: object createdAt: type: string format: date-time updatedAt: type: string format: date-time AccountCreateRequest: type: object required: [ownerParticipantId, counterpartyParticipantId, currency, accountType] properties: ownerParticipantId: type: string counterpartyParticipantId: type: string ibanOrLocalAccount: type: string currency: type: string pattern: '^[A-Z]{3}$' accountType: type: string enum: [NOSTRO, VOSTRO] metadata: type: object AccountResponse: type: object properties: success: type: boolean data: $ref: '#/components/schemas/Account' timestamp: type: string format: date-time AccountListResponse: type: object properties: success: type: boolean data: type: object properties: data: type: array items: $ref: '#/components/schemas/Account' pagination: $ref: '#/components/schemas/Pagination' timestamp: type: string format: date-time BalanceResponse: type: object properties: success: type: boolean data: type: object properties: accountId: type: string currentBalance: type: string availableLiquidity: type: string holdAmount: type: string currency: type: string lastUpdatedAt: type: string format: date-time timestamp: type: string format: date-time Transfer: type: object required: [transferId, fromAccountId, toAccountId, amount, currency, status] properties: transferId: type: string example: "TRF-123" fromAccountId: type: string toAccountId: type: string fromParticipantId: type: string toParticipantId: type: string amount: type: string pattern: '^\d+\.\d{2}$' example: "1000.00" currency: type: string example: "USD" settlementAsset: type: string enum: [FIAT, GRU, SSU, CBDC] example: "FIAT" valueDate: type: string format: date example: "2024-01-15" fxDetails: type: object properties: rate: type: string fromCurrency: type: string toCurrency: type: string convertedAmount: type: string status: type: string enum: [PENDING, ACCEPTED, SETTLED, REJECTED, CANCELLED] example: "PENDING" rejectionReason: type: string idempotencyKey: type: string reference: type: string metadata: type: object settledAt: type: string format: date-time createdAt: type: string format: date-time updatedAt: type: string format: date-time TransferCreateRequest: type: object required: [fromAccountId, toAccountId, amount, currency] properties: fromAccountId: type: string toAccountId: type: string amount: type: string pattern: '^\d+\.\d{2}$' currency: type: string settlementAsset: type: string enum: [FIAT, GRU, SSU, CBDC] default: FIAT valueDate: type: string format: date fxDetails: type: object reference: type: string metadata: type: object TransferResponse: type: object properties: success: type: boolean data: $ref: '#/components/schemas/Transfer' timestamp: type: string format: date-time TransferListResponse: type: object properties: success: type: boolean data: type: object properties: data: type: array items: $ref: '#/components/schemas/Transfer' pagination: $ref: '#/components/schemas/Pagination' timestamp: type: string format: date-time ReconciliationRequest: type: object required: [participantId, asOfDate] properties: participantId: type: string asOfDate: type: string format: date accountId: type: string description: Optional: specific account reconciliation metadata: type: object Reconciliation: type: object properties: reportId: type: string participantId: type: string asOfDate: type: string format: date openingBalance: type: string closingBalance: type: string totalDebits: type: string totalCredits: type: string breakCount: type: integer status: type: string enum: [PENDING, COMPLETED, FAILED] breaks: type: array items: type: object properties: breakType: type: string description: type: string amount: type: string transactionId: type: string metadata: type: object completedAt: type: string format: date-time createdAt: type: string format: date-time updatedAt: type: string format: date-time ReconciliationResponse: type: object properties: success: type: boolean data: $ref: '#/components/schemas/Reconciliation' timestamp: type: string format: date-time WebhookSubscriptionCreateRequest: type: object required: [participantId, webhookUrl, eventTypes] properties: participantId: type: string webhookUrl: type: string format: uri example: "https://example.com/webhooks" eventTypes: type: array items: type: string enum: [TRANSFER_CREATED, TRANSFER_SETTLED, TRANSFER_REJECTED, ACCOUNT_UPDATED, BALANCE_CHANGED, RECONCILIATION_COMPLETED] example: ["TRANSFER_CREATED", "TRANSFER_SETTLED"] metadata: type: object WebhookSubscription: type: object properties: subscriptionId: type: string participantId: type: string webhookUrl: type: string eventTypes: type: array items: type: string status: type: string enum: [ACTIVE, SUSPENDED, INACTIVE] lastDeliveryAt: type: string format: date-time failureCount: type: integer metadata: type: object createdAt: type: string format: date-time updatedAt: type: string format: date-time WebhookSubscriptionResponse: type: object properties: success: type: boolean data: $ref: '#/components/schemas/WebhookSubscription' timestamp: type: string format: date-time WebhookSubscriptionListResponse: type: object properties: success: type: boolean data: type: object properties: data: type: array items: $ref: '#/components/schemas/WebhookSubscription' pagination: $ref: '#/components/schemas/Pagination' timestamp: type: string format: date-time WebhookEvent: type: object properties: eventId: type: string eventType: type: string timestamp: type: string format: date-time payload: type: object GruFxRate: type: object properties: pair: type: string example: "USD/GRU" rate: type: string example: "0.6667" timestamp: type: string format: date-time source: type: string example: "DBIS_GRU" bid: type: string ask: type: string spread: type: string GruFxRateResponse: type: object properties: success: type: boolean data: $ref: '#/components/schemas/GruFxRate' timestamp: type: string format: date-time GruFxRateHistory: type: object properties: pair: type: string rates: type: array items: type: object properties: rate: type: string timestamp: type: string format: date-time startDate: type: string format: date-time endDate: type: string format: date-time GruFxRateHistoryResponse: type: object properties: success: type: boolean data: $ref: '#/components/schemas/GruFxRateHistory' timestamp: type: string format: date-time GruFxConversionRequest: type: object required: [fromCurrency, toCurrency, amount] properties: fromCurrency: type: string example: "USD" toCurrency: type: string example: "EUR" amount: type: string example: "1000.00" settlementAsset: type: string enum: [FIAT, GRU, SSU, CBDC] valueDate: type: string format: date GruFxConversionResponse: type: object properties: success: type: boolean data: type: object properties: conversionId: type: string fromCurrency: type: string toCurrency: type: string fromAmount: type: string toAmount: type: string rate: type: string settlementAsset: type: string timestamp: type: string format: date-time timestamp: type: string format: date-time Pagination: type: object properties: page: type: integer pageSize: type: integer total: type: integer totalPages: type: integer ErrorResponse: type: object properties: success: type: boolean example: false error: type: object properties: code: type: string example: "VALIDATION_ERROR" message: type: string example: "Invalid request parameters" details: type: object timestamp: type: string format: date-time responses: BadRequest: description: Bad request - validation error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: success: false error: code: "VALIDATION_ERROR" message: "Invalid request parameters" details: field: "amount" reason: "Must be a positive number" timestamp: "2024-01-15T10:30:00Z" Unauthorized: description: Unauthorized - missing or invalid authentication content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: success: false error: code: "UNAUTHORIZED" message: "Missing or invalid Sovereign Identity Token" timestamp: "2024-01-15T10:30:00Z" Forbidden: description: Forbidden - insufficient permissions content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: success: false error: code: "FORBIDDEN" message: "Insufficient permissions for this operation" timestamp: "2024-01-15T10:30:00Z" NotFound: description: Resource not found content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: success: false error: code: "NOT_FOUND" message: "Participant not found" timestamp: "2024-01-15T10:30:00Z" Conflict: description: Conflict - resource already exists content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: success: false error: code: "CONFLICT" message: "Participant with this BIC already exists" timestamp: "2024-01-15T10:30:00Z" UnprocessableEntity: description: Unprocessable entity - business logic error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: success: false error: code: "UNPROCESSABLE_ENTITY" message: "Insufficient balance" details: available: "500.00" required: "1000.00" timestamp: "2024-01-15T10:30:00Z" InternalServerError: description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: success: false error: code: "INTERNAL_ERROR" message: "An internal error occurred" timestamp: "2024-01-15T10:30:00Z"