Skip to content

Bermuda Commercial Bank RESTful Open Banking API Implementation (v1)

The Bermuda Commercial Bank (BCB) RESTful Open Banking API provides secure, programmatic access to BCB's banking services, enabling developers to integrate financial services into their applications.

Key Features

  • Account details retrieval
  • Internal transfers
  • Payments (Swift)
  • Virtual Accounts
  • Transaction information access
  • Robust security and compliance
  • Comprehensive documentation

Available Environments

UAT Environment

URL: https://api-uat.bcb.bm

Purpose: Testing and integration

Production Environment

URL: https://api.bcb.bm

Purpose: Live production use

Download OpenAPI description
Overview
URL
Bermuda Commercial Bank Limited, 34 Bermudiana Road, Hamilton HM 11, Bermuda
Languages
Servers
Mock server
https://developers.bcb.bm/_mock/apis/open-banking-api/open-banking-api/
UAT Environment - Used for testing and integration purposes
https://api-uat.bcb.bm/
Production Environment - Live environment for production use
https://api.bcb.bm/

Accounts

Operations

Account Details

Request

Retrieves the account details and balance. This endpoint requires authentication and returns comprehensive information for the specified account. The returned data includes:

  • Number: The human-readable account number assigned by the bank.
  • Label: A label provided by the account owner.
  • Owners: The list of users who own this account.
  • Type: The type of account.
  • Balance: The account's balance including currency and amount.
  • Account Attributes: Additional account information specific to Bermuda Commercial Bank.

Content Negotiation

Clients must use the HTTP Accept header to indicate the desired response format:

  • Set Accept: application/json for JSON responses (default).
  • Set Accept: text/csv for CSV responses. If the Accept header is omitted, application/json is assumed.

Base URL:

All API requests use the versioned base URL:

https://api.bcb.bm/v1/accounts

Sample Request in JavaScript:

async function getAccountDetails(accountNumber) {
  try {
    const response = await fetch(`https://api.bcb.bm/v1/accounts/${accountNumber}`, {
      method: 'GET',
      headers: {
        'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
        'Content-Type': 'application/json',
        'Accept': 'application/json'
      }
    });

    if (!response.ok) {
      const errorData = await response.json();
      throw new Error(`Error: ${errorData.message || 'Unknown error'}`);
    }

    const data = await response.json();
    console.log('Account details:', data);

    // Example processing of the returned object
    const accountId = data.id;
    const accountNumber = data.number;
    const accountBalance = data.balance.amount;
    const accountCurrency = data.balance.currency;
    const accountStatus = data.accountAttributes.find(attr => attr.name === 'STATUS')?.value;
            
    console.log('Account ID:', accountId);
    console.log('Account Number:', accountNumber);
    console.log('Account Balance:', accountBalance);
    console.log('Account Currency:', accountCurrency);
    console.log('Account Status:', accountStatus);
            
    // Process all account attributes
    console.log('Account Attributes:');
    data.accountAttributes.forEach(attribute => {
      console.log(`${attribute.name}: ${attribute.value}`);
    });

    // Additional processing based on account status
    if (accountStatus === 'ACTIVE') {
      console.log('The account is active.');
    } else {
      console.log('The account is not active.');
    }
  } catch (error) {
    console.error('There was a problem with the fetch operation:', error.message);
  }
}

// Example usage:
getAccountDetails('YOUR_ACCOUNT_NUMBER');

Required Permission: get-account

This endpoint requires the permission claim get-account to be present in the JWT token. These permissions are embedded in the token during the authentication process and cannot be modified afterward. The token must be obtained with the appropriate permissions to access this endpoint.

Security
Authorization and Feature Permissions
Path
accountNumberstring[ 1 .. 36 ] charactersrequired

The human-readable account number assigned by the bank.

curl -i -X GET \
  'https://developers.bcb.bm/_mock/apis/open-banking-api/open-banking-api/v1/accounts/{accountNumber}' \
  -H 'Authorization: Bearer <YOUR_jwt_HERE>'

Responses

OK - The request was successful.

Bodyapplication/json
accountIdstringrequired

A unique ID of the account, composed of account number and CIF

cifstringrequired

11-digit ID of the account holder

currencystringrequired

Identification of the currency in which the account is held

accountSubTypestringrequired

Specifies the sub type of account (product)

accountNumberstringrequired

Account number

statusstringrequired

Specifies the status of the account

availableBalanceobjectrequired
availableBalance.​currencystringrequired

Currency ISO code

availableBalance.​amountstringrequired

Amount

accountTypestring or null

Specifies the type of account (personal/business)

nicknamestring or null

The nickname of the account, assigned by the account owner

ownersArray of objects(AccountOwner)required

Ownership details of an account object

owners[].​displayNamestringrequired

Account owner name

owners[].​accountHolderTypestringrequired

Type of account holder (Primary/Joint)

accountAttributesArray of objects(AccountAttribute)required

Additional details or characteristics associated with an account object

accountAttributes[].​namestringrequired

Key or identifier of the account attribute.

accountAttributes[].​valuestringrequired

Actual data associated with the attribute name

openingDatestring or null

Date when the account was opened

balanceEffectiveDatestring or null

Date when the balance was last updated

accountRoutingsArray of objects(BankRouting)

Routing details for the account

Response
application/json
{ "openingDate": "2023-01-01T00:00:00.0000000Z", "balanceEffectiveDate": "2023-12-31T00:00:00.0000000Z", "accountRoutings": [ { … } ], "accountId": "1000078766-3000032", "cif": 3000032, "currency": "USD", "accountSubType": "BCB.CURRENT.ACCOUNT.C", "accountNumber": 1000078766, "status": "Active", "availableBalance": { "currency": "USD", "amount": 1000 }, "accountType": "Personal", "nickname": "CURRENT.ACCOUNTS", "owners": [ { … }, { … } ], "accountAttributes": [ { … }, { … }, { … }, { … }, { … }, { … }, { … } ] }

List User Accounts

Request

Retrieves a list of all accounts associated with the authenticated user's profile. This endpoint:

  • Uses the customer account number from the authenticated user's session to fetch all associated accounts.
  • Requires valid authentication.
  • Supports both JSON and CSV response formats based on the Accept header.
  • Returns a summary version of account information (AccountSummary) containing only essential fields
  • Supports cursor-based pagination for efficient handling of large account lists.

Pagination

This endpoint uses cursor-based pagination with server-side result-set management:

  • First Request: Optionally specify pageSize (default: 100, max: 1000). The server creates a cursor and returns a pageToken.
  • Subsequent Requests: Use the pageToken from previous responses with pageStart to navigate pages.
  • Page Token: Contains encoded pagination context including pageSize, so don't specify pageSize in subsequent requests.
  • Total Pages: Calculate using Math.ceil(total_size / page_size) from the response metadata.

Content Negotiation

Clients must use the HTTP Accept header to indicate the desired response format:

  • Set Accept: application/json for JSON responses (default).
  • Set Accept: text/csv for CSV responses. If the Accept header is omitted, application/json is assumed.

Base URL

All API requests use the versioned base URL:

https://api.bcb.bm/v1/accounts

Sample Request in JavaScript

async function getAllAccountsPaginated() {
  try {
    let allAccounts = [];
    let pageStart = 1;
    let pageToken = null;
    let totalPages = 0;

    do {
      // Build URL with pagination parameters
      let url = 'https://api.bcb.bm/v1/accounts';
      const params = new URLSearchParams();
      
      if (pageStart === 1) {
        // First request: optionally specify pageSize
        params.append('pageSize', '100');
      } else {
        // Subsequent requests: use pageToken and pageStart
        params.append('pageToken', pageToken);
        params.append('pageStart', pageStart.toString());
      }
      
      if (params.toString()) {
        url += '?' + params.toString();
      }

      const response = await fetch(url, {
        method: 'GET',
        headers: {
          'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
          'Content-Type': 'application/json',
          'Accept': 'application/json'
        }
      });

      if (!response.ok) {
        const errorData = await response.json();
        throw new Error(`Error: ${errorData.message || 'Unknown error'}`);
      }

      const data = await response.json();
      console.log(`Page ${pageStart} data:`, data);

      // Store pagination info from first request
      if (pageStart === 1 && data.meta && data.meta.pagination) {
        pageToken = data.meta.pagination.page_token;
        totalPages = Math.ceil(data.meta.pagination.total_size / data.meta.pagination.page_size);
        console.log(`Total pages: ${totalPages}, Page token: ${pageToken}`);
      }

      // Collect accounts from this page
      if (data.data && data.data.length > 0) {
        allAccounts.push(...data.data);
        console.log(`Collected ${data.data.length} accounts from page ${pageStart}`);
      }

      pageStart++;
    } while (pageStart <= totalPages);

    console.log(`Total accounts collected: ${allAccounts.length}`);

    // Process all collected accounts
    allAccounts.forEach((account, index) => {
      console.log(`Account ${index + 1}: ${account.number}`);
      console.log(`Balance: ${account.balance.amount} ${account.balance.currency}`);
    });

    return allAccounts;
  } catch (error) {
    console.error('There was a problem with the fetch operation:', error.message);
    throw error;
  }
}

// Function to get a specific page of accounts
async function getAccountsPage(pageStart, pageToken = null) {
  try {
    // Build URL
    let url = 'https://api.bcb.bm/v1/accounts';
    const params = new URLSearchParams();
    
    if (pageStart === 1) {
      // First request: optionally specify pageSize
      params.append('pageSize', '100');
    } else {
      // Subsequent requests: use pageToken and pageStart
      params.append('pageToken', pageToken);
      params.append('pageStart', pageStart.toString());
    }
    
    if (params.toString()) {
      url += '?' + params.toString();
    }

    const response = await fetch(url, {
      method: 'GET',
      headers: {
        'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
        'Content-Type': 'application/json',
        'Accept': 'application/json'
      }
    });

    if (!response.ok) {
      const errorData = await response.json();
      throw new Error(`Error: ${errorData.message || 'Unknown error'}`);
    }

    const data = await response.json();
    console.log('Accounts page:', data);
    return data;
  } catch (error) {
    console.error('There was a problem with the fetch operation:', error.message);
    throw error;
  }
}

// Example usage:
getAllAccountsPaginated(); // Retrieves all accounts across multiple pages
// OR
getAccountsPage(1).then(firstPage => {
  console.log('First page:', firstPage);
  // Use firstPage.meta.pagination.page_token for subsequent requests
});

Required Permission: get-all-accounts

This endpoint requires the permission claim get-all-accounts to be present in the JWT token. These permissions are embedded in the token during the authentication process and cannot be modified afterward. The token must be obtained with the appropriate permissions to access this endpoint.

Security
Authorization and Feature Permissions
Query
pageTokenstring or null[ 0 .. 100 ] characters

Optional. Unique cursor ID received from previous response for subsequent requests. Contains encoded pagination context including page_size.

pageStartinteger or null(int32)

Optional. The record from which the response should be displayed (default: 1).

pageSizeinteger or null(int32)

Optional. The total number of records per page (default: 100, max: 1000).

curl -i -X GET \
  'https://developers.bcb.bm/_mock/apis/open-banking-api/open-banking-api/v1/accounts?pageToken=string&pageStart=0&pageSize=0' \
  -H 'Authorization: Bearer <YOUR_jwt_HERE>'

Responses

OK - The request was successful.

Bodyapplication/json
metaobject or null
dataArray of objects or null(Account)

Response data

Response
application/json
{ "meta": { "pagination": { … } }, "data": [ { … }, { … } ] }

List payment statuses for an account

Request

Retrieves status information for all payments associated with a specific account. This endpoint:

  • Provides comprehensive payment status details including type, status, transaction ID, external reference, remittance information, amounts, value date, and exchange rate.
  • Supports both JSON and CSV response formats based on the Accept header.
  • Supports cursor-based pagination for efficient handling of large payment status datasets.

Pagination

This endpoint uses cursor-based pagination with server-side result-set management:

  • First Request: Optionally specify pageSize (default: 100, max: 1000). The server creates a cursor and returns a pageToken.
  • Subsequent Requests: Use the pageToken from previous responses with pageStart to navigate pages.
  • Page Token: Contains encoded pagination context including pageSize, so don't specify pageSize in subsequent requests.
  • Total Pages: Calculate using Math.ceil(total_size / page_size) from the response metadata.

Content Negotiation

Clients must use the HTTP Accept header to indicate the desired response format:

  • Set Accept: application/json for JSON responses (default)
  • Set Accept: text/csv for CSV responses If the Accept header is omitted, application/json is assumed.

Base URL

All API requests use the versioned base URL:

https://api.bcb.bm/v1/accounts/{accountNumber}/payments

Sample Request in JavaScript

async function getAllPaymentStatusesPaginated(accountNumber) {
  try {
    let allPaymentStatuses = [];
    let pageStart = 1;
    let pageToken = null;
    let totalPages = 0;

    do {
      // Build URL with pagination parameters
      let url = `https://api.bcb.bm/v1/accounts/${accountNumber}/payments`;
      const params = new URLSearchParams();
      
      if (pageStart === 1) {
        // First request: specify pageSize
        params.append('pageSize', '100');
      } else {
        // Subsequent requests: use pageToken and pageStart
        params.append('pageToken', pageToken);
        params.append('pageStart', pageStart.toString());
      }
      
      if (params.toString()) {
        url += '?' + params.toString();
      }

      const response = await fetch(url, {
        method: 'GET',
        headers: {
          'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
          'Content-Type': 'application/json',
          'Accept': 'application/json'
        }
      });

      if (!response.ok) {
        const errorData = await response.json();
        throw new Error(`Error: ${errorData.message || 'Unknown error'}`);
      }

      const data = await response.json();
      console.log(`Page ${pageStart} data:`, data);

      // Store pagination info from first request
      if (pageStart === 1 && data.meta && data.meta.pagination) {
        pageToken = data.meta.pagination.page_token;
        totalPages = Math.ceil(data.meta.pagination.total_size / data.meta.pagination.page_size);
        console.log(`Total pages: ${totalPages}, Page token: ${pageToken}`);
      }

      // Collect payment statuses from this page
      if (data.data && data.data.length > 0) {
        allPaymentStatuses.push(...data.data);
        console.log(`Collected ${data.data.length} payment statuses from page ${pageStart}`);
      }

      pageStart++;
    } while (pageStart <= totalPages);

    console.log(`Total payment statuses collected: ${allPaymentStatuses.length}`);

    // Process all collected payment statuses
    allPaymentStatuses.forEach((payment, index) => {
      console.log(`Payment ${index + 1}:`, payment.transactionId);
      console.log('Type:', payment.type);
      console.log('Status:', payment.status);
      console.log('External Reference:', payment.externalReference);
      console.log('Remittance Information:', payment.remittanceInformation);
      console.log('Value Date:', payment.valueDate);
      console.log('Debit Amount:', `${payment.debitAmount.amount} ${payment.debitAmount.currency}`);
      if (payment.creditAmount && payment.creditAmount.amount) {
        console.log('Credit Amount:', `${payment.creditAmount.amount} ${payment.creditAmount.currency}`);
      }
      console.log('-------------------');
    });

    return allPaymentStatuses;
  } catch (error) {
    console.error('There was a problem with the fetch operation:', error.message);
    throw error;
  }
}

// Alternative: Get single page of payment statuses
async function getPaymentStatusesPage(accountNumber, pageStart = 1, pageToken = null) {
  try {
    let url = `https://api.bcb.bm/v1/accounts/${accountNumber}/payments`;
    const params = new URLSearchParams();
    
    if (pageStart === 1 && !pageToken) {
      params.append('pageSize', '50'); // Custom page size
    } else {
      params.append('pageToken', pageToken);
      params.append('pageStart', pageStart.toString());
    }
    
    if (params.toString()) {
      url += '?' + params.toString();
    }

    const response = await fetch(url, {
      method: 'GET',
      headers: {
        'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
        'Content-Type': 'application/json',
        'Accept': 'application/json'
      }
    });

    if (!response.ok) {
      const errorData = await response.json();
      throw new Error(`Error: ${errorData.message || 'Unknown error'}`);
    }

    const data = await response.json();
    console.log('Payment statuses page:', data);
    return data;
  } catch (error) {
    console.error('There was a problem with the fetch operation:', error.message);
    throw error;
  }
}

// Example usage:
getAllPaymentStatusesPaginated('123456789'); // Retrieves all payment statuses across multiple pages
// OR
getPaymentStatusesPage('123456789', 1).then(firstPage => {
  console.log('First page:', firstPage);
  // Use firstPage.meta.pagination.page_token for subsequent requests
});

Required Permission: get-payment-status

This endpoint requires the permission claim get-payment-status to be present in the JWT token. These permissions are embedded in the token during the authentication process and cannot be modified afterward. The token must be obtained with the appropriate permissions to access this endpoint.

Security
Authorization and Feature Permissions
Path
accountNumberstringrequired

The account number to retrieve payment statuses for.

Query
pageTokenstring or null[ 0 .. 100 ] characters

Optional. Unique cursor ID received from previous response for subsequent requests. Contains encoded pagination context including page_size.

pageStartinteger or null(int32)

Optional. The record from which the response should be displayed (default: 1).

pageSizeinteger or null(int32)

Optional. The total number of records per page (default: 100, max: 1000).

curl -i -X GET \
  'https://developers.bcb.bm/_mock/apis/open-banking-api/open-banking-api/v1/accounts/{accountNumber}/payments?pageToken=string&pageStart=0&pageSize=0' \
  -H 'Authorization: Bearer <YOUR_jwt_HERE>'

Responses

OK - The request was successful.

Bodyapplication/json
metaobject or null
dataArray of objects or null(TransactionStatus)

Response data

Response
application/json
{ "meta": { "pagination": { … } }, "data": [ { … }, { … }, { … } ] }

Credentials

Operations

Fx Quotes

Operations

Internal Transfers

Operations

Payments

Operations

Public Keys

Operations

Token

Operations

Transactions

Operations

Virtual Accounts

Operations

Notifications

Operations

Background Jobs

Operations

System

Operations