Monnify Reserved Accounts API

Programmatically provision permanent NUBAN virtual accounts (dedicated and one-time invoice variants) for customers and merchants. Supports income-split configuration to multiple sub-accounts, KYC updates (BVN / NIN), allowed-source-account restriction, deallocation, transaction history, and per-account limit profiles. V2 endpoints under /api/v2/bank-transfer/reserved-accounts/.

Monnify Reserved Accounts API is one of 14 APIs that Moniepoint publishes on the APIs.io network, described by a machine-readable OpenAPI specification.

This API exposes 2 machine-runnable capabilities that can be deployed as REST, MCP, or Agent Skill surfaces via Naftiko and 1 JSON Schema definition.

Tagged areas include Reserved Accounts, Virtual Accounts, Bank Transfer, KYC, and Limits. The published artifact set on APIs.io includes API documentation, an OpenAPI specification, 2 Naftiko capability specs, and 1 JSON Schema.

OpenAPI Specification

monnify-reserved-accounts-api-openapi.yml Raw ↑
openapi: 3.1.0
info:
  title: Monnify Reserved Accounts API
  description: >
    Provision permanent NUBAN virtual accounts (dedicated and invoice
    variants) for customers and merchants. V2 endpoints replace earlier
    /api/v1 routes for new integrations; transaction listing remains under
    /api/v1.
  version: '2.0'
  contact:
    name: Monnify Developer Support
    url: https://developers.monnify.com
servers:
  - url: https://api.monnify.com
    description: Production
  - url: https://sandbox.monnify.com
    description: Sandbox
security:
  - BearerAuth: []
tags:
  - name: Reserved Accounts
    description: Manage dedicated and invoice reserved NUBAN accounts.
  - name: Limit Profiles
    description: Per-account transaction limit profiles.
paths:
  /api/v2/bank-transfer/reserved-accounts:
    post:
      summary: Monnify Reserve A Customer Account (V2)
      description: Create a permanent NUBAN virtual account for a customer.
      operationId: reserveAccountV2
      tags: [Reserved Accounts]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ReserveAccountRequest'
      responses:
        '200':
          description: Reserved account created.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ReservedAccountEnvelope'
    put:
      summary: Monnify Update Reserved Account KYC
      description: Update BVN, NIN, or customer details for a reserved account.
      operationId: updateReservedAccountKyc
      tags: [Reserved Accounts]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateKycRequest'
      responses:
        '200':
          description: KYC updated.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ReservedAccountEnvelope'
  /api/v2/bank-transfer/reserved-accounts/{accountReference}:
    get:
      summary: Monnify Get Reserved Account Details (V2)
      description: Fetch a single reserved account by accountReference.
      operationId: getReservedAccountV2
      tags: [Reserved Accounts]
      parameters:
        - name: accountReference
          in: path
          required: true
          schema: { type: string }
      responses:
        '200':
          description: Reserved account details.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ReservedAccountEnvelope'
    delete:
      summary: Monnify Deallocate Reserved Account
      description: Permanently deallocate a reserved account.
      operationId: deallocateReservedAccount
      tags: [Reserved Accounts]
      parameters:
        - name: accountReference
          in: path
          required: true
          schema: { type: string }
      responses:
        '200':
          description: Account deallocated.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ReservedAccountEnvelope'
  /api/v1/bank-transfer/reserved-accounts/transactions:
    get:
      summary: Monnify List Reserved Account Transactions
      description: Paginated list of inbound transactions to a reserved account.
      operationId: listReservedAccountTransactions
      tags: [Reserved Accounts]
      parameters:
        - name: accountReference
          in: query
          required: true
          schema: { type: string }
        - name: page
          in: query
          schema: { type: integer, default: 0 }
        - name: size
          in: query
          schema: { type: integer, default: 10 }
      responses:
        '200':
          description: Transaction page.
          content:
            application/json:
              schema:
                type: object
                properties:
                  requestSuccessful: { type: boolean }
                  responseMessage: { type: string }
                  responseCode: { type: string }
                  responseBody:
                    type: object
                    properties:
                      content:
                        type: array
                        items: { type: object }
                      totalElements: { type: integer }
                      totalPages: { type: integer }
  /api/v1/bank-transfer/reserved-accounts/limit:
    post:
      summary: Monnify Reserve Account With Limit
      description: Create a reserved account with a pre-assigned limit profile.
      operationId: reserveAccountWithLimit
      tags: [Reserved Accounts]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              allOf:
                - $ref: '#/components/schemas/ReserveAccountRequest'
                - type: object
                  properties:
                    limitProfileCode: { type: string }
      responses:
        '200':
          description: Reserved account with limit created.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ReservedAccountEnvelope'
    put:
      summary: Monnify Update Reserved Account Limit
      description: Assign or change the limit profile on an existing reserved account.
      operationId: updateReservedAccountLimit
      tags: [Reserved Accounts]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [accountReference, limitProfileCode]
              properties:
                accountReference: { type: string }
                limitProfileCode: { type: string }
      responses:
        '200':
          description: Reserved account limit updated.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ReservedAccountEnvelope'
  /api/v1/limit-profiles:
    post:
      summary: Monnify Create Limit Profile
      description: Define a per-transaction and daily cap profile to apply to reserved accounts.
      operationId: createLimitProfile
      tags: [Limit Profiles]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LimitProfile'
      responses:
        '200':
          description: Limit profile created.
          content:
            application/json:
              schema:
                type: object
                properties:
                  requestSuccessful: { type: boolean }
                  responseMessage: { type: string }
                  responseCode: { type: string }
                  responseBody: { $ref: '#/components/schemas/LimitProfile' }
    get:
      summary: Monnify List Limit Profiles
      description: Paginated list of limit profiles for the merchant.
      operationId: listLimitProfiles
      tags: [Limit Profiles]
      responses:
        '200':
          description: Limit profiles page.
          content:
            application/json:
              schema:
                type: object
                properties:
                  requestSuccessful: { type: boolean }
                  responseMessage: { type: string }
                  responseCode: { type: string }
                  responseBody:
                    type: object
                    properties:
                      content:
                        type: array
                        items: { $ref: '#/components/schemas/LimitProfile' }
    put:
      summary: Monnify Update Limit Profile
      operationId: updateLimitProfile
      tags: [Limit Profiles]
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: '#/components/schemas/LimitProfile' }
      responses:
        '200':
          description: Updated.
          content:
            application/json:
              schema:
                type: object
                properties:
                  requestSuccessful: { type: boolean }
                  responseMessage: { type: string }
                  responseCode: { type: string }
                  responseBody: { $ref: '#/components/schemas/LimitProfile' }
components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
  schemas:
    ReserveAccountRequest:
      type: object
      required: [accountReference, accountName, currencyCode, contractCode, customerEmail]
      properties:
        accountReference: { type: string }
        accountName: { type: string }
        currencyCode: { type: string, example: NGN }
        contractCode: { type: string }
        customerEmail: { type: string, format: email }
        customerName: { type: string }
        bvn: { type: string, description: Customer BVN (11 digits). }
        nin: { type: string, description: Customer NIN (11 digits). }
        getAllAvailableBanks: { type: boolean }
        preferredBanks:
          type: array
          items: { type: string, description: Bank code. }
        restrictPaymentSource: { type: boolean }
        allowedPaymentSources:
          type: object
          properties:
            bvns:
              type: array
              items: { type: string }
            accountNumbers:
              type: array
              items:
                type: object
                properties:
                  accountNumber: { type: string }
                  bankCode: { type: string }
            accountNames:
              type: array
              items: { type: string }
        incomeSplitConfig:
          type: array
          items:
            type: object
            properties:
              subAccountCode: { type: string }
              feePercentage: { type: number }
              splitPercentage: { type: number }
              feeBearer: { type: boolean }
    UpdateKycRequest:
      type: object
      properties:
        accountReference: { type: string }
        bvn: { type: string }
        nin: { type: string }
    ReservedAccount:
      type: object
      properties:
        accountReference: { type: string }
        accountName: { type: string }
        currencyCode: { type: string }
        customerEmail: { type: string }
        customerName: { type: string }
        bvn: { type: string }
        nin: { type: string }
        status: { type: string, enum: [ACTIVE, INACTIVE, DEALLOCATED] }
        accounts:
          type: array
          items:
            type: object
            properties:
              bankCode: { type: string }
              bankName: { type: string }
              accountNumber: { type: string }
              accountName: { type: string }
    ReservedAccountEnvelope:
      type: object
      properties:
        requestSuccessful: { type: boolean }
        responseMessage: { type: string }
        responseCode: { type: string }
        responseBody: { $ref: '#/components/schemas/ReservedAccount' }
    LimitProfile:
      type: object
      properties:
        limitProfileCode: { type: string }
        limitProfileName: { type: string }
        singleTransactionValue: { type: number }
        dailyTransactionVolume: { type: integer }
        dailyTransactionValue: { type: number }