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.bcbank.us
Purpose: Testing and integration
Production Environment
Purpose: Live production use
Accounts
Operationsget/v1/accounts/{accountNumber}Account Details
Account Details
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/jsonfor JSON responses (default). - Set
Accept: text/csvfor CSV responses. If the Accept header is omitted,application/jsonis assumed.
Base URL:
All API requests use the versioned base URL:
https://api.bcbank.us/v1/accounts
Sample Request in JavaScript:
async function getAccountDetails(accountNumber) {
try {
const response = await fetch(`https://api.bcbank.us/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.
Request parameters
path requiredThe human-readable account number assigned by the bank.
string
Responses
OK - The request was successful.
string requiredA unique ID of the account, composed of account number and CIF
string required11-digit ID of the account holder
string requiredAccount number
string requiredSpecifies the status of the account
string requiredIdentification of the currency in which the account is held
object requiredAccount balance
Show properties
string requiredCurrency ISO code
string requiredAmount
string requiredSpecifies the sub type of account (product)
string Specifies the type of account (personal/business)
string The nickname of the account, assigned by the account owner
array requiredOwnership details of an account object
Show properties
arraystring requiredAccount owner name
string requiredType of account holder (Primary/Joint)
array requiredAdditional details or characteristics associated with an account object
Show properties
arraystring requiredKey or identifier of the account attribute.
string requiredActual data associated with the attribute name
string Date when the account was opened
string Date when the balance was last updated
array Routing details for the account
Show properties
arraystring requiredScheme value
string requiredAddress value
Request sample
curl --request GET \
--url 'https://api-uat.bcbank.us/v1/accounts/{accountNumber}' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN'Response sample
{
"accountId": "string",
"cif": "string",
"accountNumber": "string",
"status": "string",
"currency": "string",
"availableBalance": {
"currency": "string",
"amount": "string"
},
"accountSubType": "string",
"accountType": "string",
"nickname": "string",
"owners": [
{
"displayName": "string",
"accountHolderType": "string"
}
],
"accountAttributes": [
{
"name": "string",
"value": "string"
}
],
"openingDate": "string",
"balanceEffectiveDate": "string",
"accountRoutings": [
{
"scheme": "string",
"address": "string"
}
]
}get/v1/accountsList User Accounts
List User Accounts
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 apageToken. - Subsequent Requests: Use the
pageTokenfrom previous responses withpageStartto navigate pages. - Page Token: Contains encoded pagination context including
pageSize, so don't specifypageSizein 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/jsonfor JSON responses (default). - Set
Accept: text/csvfor CSV responses. If the Accept header is omitted,application/jsonis assumed.
Base URL
All API requests use the versioned base URL:
https://api.bcbank.us/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.bcbank.us/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.bcbank.us/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.
Request parameters
query string
query integer (int32)
query integer (int32)
Responses
OK - The request was successful.
object Show properties
object Show properties
integer requiredstring integer requiredinteger requiredarray Show properties
arraystring requiredA unique ID of the account, composed of account number and CIF
string required11-digit ID of the account holder
string requiredAccount number
string requiredSpecifies the status of the account
string requiredIdentification of the currency in which the account is held
object requiredAccount balance
Show properties
string requiredCurrency ISO code
string requiredAmount
string requiredSpecifies the sub type of account (product)
string Specifies the type of account (personal/business)
string The nickname of the account, assigned by the account owner
array requiredOwnership details of an account object
Show properties
arraystring requiredAccount owner name
string requiredType of account holder (Primary/Joint)
array requiredAdditional details or characteristics associated with an account object
Show properties
arraystring requiredKey or identifier of the account attribute.
string requiredActual data associated with the attribute name
string Date when the account was opened
string Date when the balance was last updated
array Routing details for the account
Show properties
arraystring requiredScheme value
string requiredAddress value
Request sample
curl --request GET \ --url 'https://api-uat.bcbank.us/v1/accounts' \ --header 'Authorization: Bearer YOUR_ACCESS_TOKEN'
Response sample
{
"meta": {
"pagination": {
"page_start": {},
"page_token": {},
"total_size": {},
"page_size": {}
}
},
"data": [
{
"accountId": "string",
"cif": "string",
"accountNumber": "string",
"status": "string",
"currency": "string",
"availableBalance": {},
"accountSubType": "string",
"accountType": "string",
"nickname": "string",
"owners": [
{}
],
"accountAttributes": [
{}
],
"openingDate": "string",
"balanceEffectiveDate": "string",
"accountRoutings": [
{}
]
}
]
}get/v1/accounts/{accountNumber}/paymentsList payment statuses for an account
List payment statuses for an account
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 apageToken. - Subsequent Requests: Use the
pageTokenfrom previous responses withpageStartto navigate pages. - Page Token: Contains encoded pagination context including pageSize, so don't specify
pageSizein 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/jsonfor JSON responses (default) - Set
Accept: text/csvfor CSV responses If the Accept header is omitted,application/jsonis assumed.
Base URL
All API requests use the versioned base URL:
https://api.bcbank.us/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.bcbank.us/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.bcbank.us/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.
Request parameters
path requiredThe account number to retrieve payment statuses for.
string
query string
query integer (int32)
query integer (int32)
Responses
OK - The request was successful.
object Show properties
object Show properties
integer requiredstring integer requiredinteger requiredarray Show properties
arraystring requiredThe type of transaction (e.g., "Outward Swift Payment MT103 API")
string External reference number for the transaction
string requiredCurrent status of the transaction (e.g., "Pending", "Completed", "Reversed")
string Free-text remittance information provided by the client, describing the purpose of the transaction.
string requiredUnique transaction number
object requiredThe amount debited from the account
Show properties
string requiredCurrency ISO code
string requiredAmount
string requiredThe date when the transaction will be processed
object requiredThe amount credited from the account
Show properties
string requiredCurrency ISO code
string requiredAmount
number Exchange rate applied to the transaction
Request sample
curl --request GET \
--url 'https://api-uat.bcbank.us/v1/accounts/{accountNumber}/payments' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN'Response sample
{
"meta": {
"pagination": {
"page_start": {},
"page_token": {},
"total_size": {},
"page_size": {}
}
},
"data": [
{
"type": "string",
"externalReference": "string",
"status": "string",
"remittanceInformation": "string",
"transactionId": "string",
"debitAmount": {
"currency": {},
"amount": {}
},
"valueDate": "string",
"creditAmount": {
"currency": {},
"amount": {}
},
"exchangeRate": 0
}
]
}Payments
Operationspost/v1/payments/ach-localACH Local Payment
ACH Local Payment
Initiates a domestic same-currency bank transfer over the ACH clearing network. The request carries debtor account, instructed amount, debit currency, creditor account + bank reference, and 1–2 lines of remittance information. JSON and CSV response formats are supported via the Accept header.
Supported Currencies
Only USD and BMD are accepted. debitCurrency and instructedAmount.currency must be identical - cross-currency is not supported on this endpoint.
Settlement and Cut-Off
Transfers settle same-day when submitted before 3:15 PM local AST; later submissions are queued for the next business day. The value/effective date in the response reflects the settlement date.
Creditor Bank Reference
Provide creditorBank with the destination bank bankCode and currency.
The API validates this combination against the configured bank reference lookup.
If the bankCode and currency combination is not found, the API returns 400 Bad Request
with error code BANK_REFERENCE_NOT_FOUND.
The ACH local bank reference lookup contains the following values:
| Bank Code | Currency | Bank Name |
|---|---|---|
BUTTERFIELD | BMD | Bank of N.T. Butterfield & Sons |
HSBC | BMD | HSBC Bermuda |
CLARIEN | BMD | Clarien Bank Bermuda |
BUTTERFIELD | USD | Bank of N.T. Butterfield & Sons |
HSBC | USD | HSBC Bermuda |
CLARIEN | USD | Clarien Bank Bermuda |
Request basics
- Endpoint:
POST https://api.bcbank.us/v1/payments/ach-local - Authorization:
Bearer {token}(required). - Accept:
application/json(default) ortext/csv. - Idempotency-Key: optional UUID v4 header (≤ 255 chars). See below.
Idempotency
The API supports idempotency through the optional Idempotency-Key header. When supplied, the server caches the successful response and replays it on repeat calls.
- If no idempotency key is provided, the request is processed normally (duplicates are possible).
- If a valid UUID key is supplied, the system stores the response of the first
2xxoutcome and replays it on subsequent calls with the same key. - TTL (cache lifetime): the stored response is retained for a limited window (currently on the order of one hour). After expiry the same key is treated as a new request - but
instructionIdentificationdeduplication still applies for 24 hours. Plan client-side retries to land inside the cache window. - Scope: keys are partitioned by client/user, HTTP method, and request path. The same key on
/payments/ach-localand/payments/swiftis not shared - each endpoint has its own cache slot. - Concurrency: if a second request with the same key arrives while the first is still in flight, the second is rejected with
409 Conflictand message"Request is already being processed."Wait and retry. - Body mismatch: request bodies are not compared on replay. If you reuse a key with a different body, the original cached response is returned - the new body is ignored. Mint a fresh key for any logically different request.
- Non-2xx responses are not cached. A
4xxvalidation failure or5xxserver error can be retried with the same key and will execute again.
Deduplication
A separate, business-level guard on the instructionIdentification field, applied independently of the Idempotency-Key header:
- Reusing an
instructionIdentificationfor an active ACH local payment is rejected with409 ACH_LOCAL_DUPLICATE_INSTRUCTION_ID. - Use a fresh
instructionIdentificationfor each new payment intent. Reuse it (with the sameIdempotency-Key) only when retrying the exact same payment. - The deduplication window is currently configured as 24 hours from the first accepted request.
How Idempotency-Key and instructionIdentification combine
They are independent mechanisms with different purposes.
Idempotency-Key(header) is a transport-level retry token. It lets you safely retry the same HTTP call and get the original response replayed.instructionIdentification(body) is the business identifier of the payment. It is persisted on the payment record and forwarded downstream. To prevent the same payment intent from being submitted twice, a value that is already in flight or recently accepted is rejected with409 ACH_LOCAL_DUPLICATE_INSTRUCTION_ID(window: 24 hours).
Idempotency-Key | instructionIdentification | Behaviour |
|---|---|---|
| no | no | No protection. Each call creates a new payment. |
| yes | no | HTTP retries of the same call replay the original response. A new Idempotency-Key creates a new payment. |
| no | yes | First call is processed normally. Reusing the same business identifier within 24 hours is rejected with 409 ACH_LOCAL_DUPLICATE_INSTRUCTION_ID. The original success response is not replayed - record it client-side. |
| yes | yes | Recommended. HTTP retries of the same call replay the original response. A new Idempotency-Key reusing an in-flight instructionIdentification is rejected with 409. |
Resilience: classifying responses
The dedupe and idempotency layers together cover three distinct failure modes. The status code tells you what to do next:
503 DEDUPE_LOCK_UNAVAILABLE- the duplicate-check store could not acquire its lock forinstructionIdentification. The payment was not submitted to core banking. Safe to retry after a short backoff with the sameinstructionIdentification(and the sameIdempotency-Key, if you used one). This is not "a duplicate was detected" - it is "we could not verify uniqueness right now."409 ACH_LOCAL_DUPLICATE_INSTRUCTION_ID- thisinstructionIdentificationwas already accepted within the 24-hour window. Do not retry thePOST; query payment status to reconcile.5xx, connection timeout, or no response - outcome unknown. Retry with the sameIdempotency-Keyand sameinstructionIdentification. The server will either replay the original201(if the first attempt landed) or return409 ACH_LOCAL_DUPLICATE_INSTRUCTION_ID(also indicating the first attempt landed).
Decision tree in pseudocode:
async function submitAchLocalPayment(paymentRequest, idempotencyKey) {
for (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) {
const res = await postPayment(paymentRequest, idempotencyKey);
switch (res.status) {
case 201:
return res.body; // success - persist paymentId against instructionIdentification
case 409: // ACH_LOCAL_DUPLICATE_INSTRUCTION_ID - intent already submitted
// Do NOT retry with a new instructionId. Reconcile via status lookup.
return await reconcileViaStatusLookup(paymentRequest.instructionIdentification);
case 503: // DEDUPE_LOCK_UNAVAILABLE - NOT submitted, safe to retry as-is
case 502: case 504: // transient gateway
await backoff(attempt); continue;
default:
if (isNetworkError(res)) { // unknown outcome - retry SAME key + SAME instructionId
await backoff(attempt); continue;
}
throw res; // 4xx other - fix request, mint NEW instructionId before retrying
}
}
}
When to rotate instructionIdentification
// NEW payment intent (user clicks "Send" again, new business event)
const intent = {
instructionIdentification: uuid(),
idempotencyKey: uuid()
};
// RETRY of the SAME intent (5xx, 503 DEDUPE_LOCK_UNAVAILABLE, timeout)
// -> keep BOTH values stable; the server will replay or short-circuit safely
retry(intent);
// After 409 ACH_LOCAL_DUPLICATE_INSTRUCTION_ID
// -> do NOT POST again; query status to reconcile
await getPaymentStatus(intent.instructionIdentification);
Idempotency-Key lifecycle (client-side checklist)
- Mint the key before the HTTP call and persist it alongside the payment intent so a process restart or retry can still find it.
- Reuse it for every retry of the same intent; treat it as "spent" only after a terminal (
2xxor non-retryable4xx) response. - Plan retries to land inside the cache window (~1 hour). Beyond that,
instructionIdentification(24 h) is your remaining guard.
Validation Rules
| Field | Constraint |
|---|---|
instructionIdentification | Optional, max 16 characters |
debtorAccount.identification | Required, max 36 characters |
debitCurrency | Required, exactly 3 characters, USD or BMD only |
instructedAmount.amount | Required, max 18 characters, valid decimal (up to 2 decimal places) |
instructedAmount.currency | Required, exactly 3 characters, USD or BMD only, must equal debitCurrency |
creditorAccount.identification | Required, max 17 characters |
creditorAccount.name | Required, max 22 characters |
creditorBank.bankCode | Required, 1-100 characters (see Creditor Bank Reference below) |
creditorBank.currency | Required, exactly 3 characters, must match debitCurrency |
remittanceInformation | Required, 1–2 non-empty lines, each max 35 characters |
Minimal Request Example
const res = await fetch('https://api.bcbank.us/v1/payments/ach-local', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json',
'Accept': 'application/json',
'Idempotency-Key': idempotencyKey, // UUID v4, per payment intent
},
body: JSON.stringify(paymentRequest), // shape: see request schema below
});
The full request and response schemas, including field types and a worked example, are rendered below from the API contract.
Required Permission: payment-ach
This endpoint requires the permission claim payment-ach 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.
Request body application/json
string Unique identification as assigned by an instructing party for an instructed party to unambiguously identify the instruction. Max 16 characters.
object requiredUnambiguous identification of the account of the debtor to which a debit entry will be made as a result of the transaction.
Show properties
string requiredUnique identification of the account, such as an Bank Account Number or a local account number.
string requiredISO 4217 currency code for the debit side of the transfer. Must be USD or BMD and must match InstructedAmount currency.
object requiredAmount of money to be moved between the debtor and creditor, expressed in the currency as ordered by the initiating party. The currency must be USD or BMD and must match DebitCurrency.
Show properties
string requiredCurrency ISO code
string requiredAmount
object requiredIdentification and name of the creditor (beneficiary) account. Identification max 17 characters; name max 22 characters.
object requiredBank reference details used to resolve the creditor bank for the ACH transfer. Includes the bank code and the 3-letter currency code for the destination bank. The currency must be USD or BMD and must match DebitCurrency.
Show properties
string requiredBank code used to identify the destination bank in the bank reference lookup.
string requiredThree-letter ISO currency code used together with BankCode to resolve the destination bank reference. For ACH local transfers, only USD and BMD are supported.
array requiredInformation supplied to enable the matching/reconciliation of an entry with the items that the payment is intended to settle. Required: 1 to 2 lines; each line max 35 characters.
Show properties
arraystring
Responses
Created - The ACH local payment was successfully processed.
string requiredUnique identifier assigned by the bank for the SWIFT transfer. This ID can be used for future reference and tracking of the payment.
string requiredThe current status of the payment processing. Possible values include:
- success: Payment has been accepted for processing
- failed: Payment failed
string requiredDetailed transaction status indicating the current state of the transfer. This provides more granular status information than the main status field.
string requiredA unique identifier specific to this instance of the SWIFT transfer. This identifier remains constant throughout the lifecycle of the payment and can be used for reconciliation purposes.
object requiredDetailed information about the payment transaction including amounts, accounts, and settlement information.
Show properties
string requiredExternal reference number assigned by the bank's payment processing system. This reference can be used for tracking and reconciliation purposes.
object requiredThe amount and currency of the payment as instructed by the payment initiator. This represents the original payment amount before any charges or conversions.
Show properties
string requiredCurrency ISO code
string requiredAmount
object requiredReference information for the account from which the payment is debited. Includes the account identifier and scheme information.
Show properties
string The name of the identification scheme, e.g. "BBAN", "AccountNumber".
string requiredThe identifier within that scheme (e.g. account number).
string requiredThe name of the account, if available (optional).
object requiredReference information for the beneficiary's account. This may differ from the creditor account in certain scenarios.
Show properties
string The name of the identification scheme, e.g. "BBAN", "AccountNumber".
string requiredThe identifier within that scheme (e.g. account number).
string requiredThe name of the account, if available (optional).
object requiredReference information for the account to be credited with the payment. This represents the immediate recipient account of the funds.
Show properties
string The name of the identification scheme, e.g. "BBAN", "AccountNumber".
string requiredThe identifier within that scheme (e.g. account number).
string requiredThe name of the account, if available (optional).
object requiredDetails about the settlement of the payment, including credited and debited amounts, value dates, and settlement status.
Show properties
object requiredThe amount that was credited to the beneficiary account. This may differ from the instructed amount due to currency conversion or intermediary bank charges.
Show properties
string requiredCurrency ISO code
string requiredAmount
object requiredThe total amount debited from the sender's account. This includes the payment amount plus any applicable charges.
Show properties
string requiredCurrency ISO code
string requiredAmount
string requiredThe date on which the payment is settled between banks. This is the date when the funds become available to the beneficiary. Format: ISO 8601 date string (YYYY-MM-DD)
string requiredThe current status of the settlement record.
object requiredInformation about the charges applied to the payment, including charge type, amounts, and the account to which charges are applied.
Show properties
string requiredSpecifies how the charges for the payment are allocated. Possible values:
- OUR: All charges are paid by the sender
- BEN: All charges are paid by the beneficiary
- SHA: Charges are shared between sender and beneficiary
object requiredThe total amount of charges applied to the payment. Includes both sending and receiving bank charges.
Show properties
string requiredCurrency ISO code
string requiredAmount
object requiredReference information for the account from which charges are collected. This may be different from the main debit account.
Show properties
string The name of the identification scheme, e.g. "BBAN", "AccountNumber".
string requiredThe identifier within that scheme (e.g. account number).
string requiredThe name of the account, if available (optional).
object requiredDetailed breakdown of how charges are distributed between the sending and receiving parties.
Show properties
object requiredThe amount of charges applied by and payable to the sending bank. This may include processing fees, wire transfer fees, or other sending bank charges.
Show properties
objectobject requiredThe amount of charges applied by and payable to the receiving bank. This may include processing fees, incoming wire fees, or other receiving bank charges.
Show properties
objectarray Collection of unstructured information provided with the payment to help with reconciliation and payment identification.
Show properties
arraystring requiredThe narrative text (e.g. remittance line, beneficiary note, etc.).
object requiredDetailed information about the ultimate beneficiary of the payment. Includes identification, name, and additional information.
object requiredInformation about the beneficiary's bank or financial institution. Typically, includes the BIC/SWIFT code and bank details.
object requiredDetails of any intermediary bank involved in the payment chain. This is optional and only present for payments requiring intermediary processing.
array requiredCollection of related financial activities associated with this payment. This may include charges, forex conversions, or other related transactions.
Show properties
arraystring requiredThe unique identifier for the activity.
string requiredThe current processing status of the transaction.
string requiredThe general status of the activity.
string A unique identifier specific to this instance of the activity.
object requiredDetailed information about the activity.
Show properties
string requiredUnique identifier for the arrangement associated with this activity.
string requiredIdentifier for the type of activity.
string requiredProduct identifier related to the activity.
string requiredCurrency code for the activity.
string requiredDate when the activity becomes effective.
Request sample
curl --request POST \
--url 'https://api-uat.bcbank.us/v1/payments/ach-local' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"instructionIdentification": "REF-123456",
"debtorAccount": {
"identification": 123456789012
},
"debitCurrency": "USD",
"instructedAmount": {
"currency": "USD",
"amount": 1500
},
"creditorAccount": {
"identification": 9876543210123,
"name": "John Doe",
"additionalInformation": null
},
"creditorBank": {
"bankCode": "HSBC",
"currency": "USD"
},
"remittanceInformation": [
"Invoice 2026-0001"
]
}'Response sample
{
"id": "string",
"status": "string",
"transactionStatus": "string",
"uniqueIdentifier": "string",
"details": {
"extReference": "string",
"instructedAmount": {
"currency": {},
"amount": {}
},
"debtorAccount": {
"schemeName": {},
"identification": {},
"Name": {}
},
"beneficiaryAccount": {
"schemeName": {},
"identification": {},
"Name": {}
},
"creditorAccount": {
"schemeName": {},
"identification": {},
"Name": {}
},
"settlementDetails": {
"amountCredited": {},
"amountDebited": {},
"valueDate": {},
"recordStatus": {}
},
"chargeDetails": {
"chargesType": {},
"chargeAmount": {},
"chargeAccount": {},
"chargeAnalysis": {}
},
"remittanceInformation": [
{
"unstructured": {}
}
],
"beneficiary": "string",
"beneficiaryAgent": "string",
"intermediaryAgent": "string"
},
"linkedActivities": [
{
"id": "string",
"transactionStatus": "string",
"status": "string",
"uniqueIdentifier": "string",
"activityDetails": {
"arrangementId": {},
"activityId": {},
"productId": {},
"currencyId": {},
"effectiveDate": {}
}
}
]
}post/v1/payments/swiftSWIFT Payment
SWIFT Payment
Initiates an international wire transfer over the SWIFT network. The request carries source and destination account information, payment amount and currency, beneficiary details, and remittance/reference information. Both JSON and CSV response formats are supported via the Accept header.
Cross-Currency FX
For cross-currency payments you may supply the debit amount instead of the instructed amount (additive format):
- Send
debitAmount(currency + amount) as the exact amount to be debited. - Send
instructedAmountwithcurrencyonly (amount omitted); the bank assigns the exchange rate and computes the credited amount. - Do not send both
debitAmount.amountandinstructedAmount.amount. - If
debitAmountis omitted,instructedAmount(currency + amount) is used as the standard same-currency behaviour.
Creditor Agent (Beneficiary Bank)
- If
creditorAgent.identification(BIC/bank identifier) is provided,creditorAgent.nameandcreditorAgent.additionalInformationare optional and may be omitted. - If
creditorAgent.identificationis not provided, supplycreditorAgent.nameandcreditorAgent.additionalInformationto identify the beneficiary bank.
Request basics
- Endpoint:
POST https://api.bcbank.us/v1/payments/swift - Authorization:
Bearer {token}. - Accept:
application/json(default) ortext/csv. - Idempotency-Key: optional UUID v4 header (≤ 255 chars). See below.
Idempotency
The API supports idempotency through the optional Idempotency-Key header. When supplied, the server caches the successful response and replays it on repeat calls.
- If no idempotency key is provided, the request is processed normally (duplicates are possible).
- If a valid UUID key is supplied, the system stores the response of the first
2xxoutcome and replays it on subsequent calls with the same key. - TTL (cache lifetime): the stored response is retained for a limited window (currently on the order of one hour). After expiry the same key is treated as a new request - but
instructionIdentificationdeduplication still applies for 24 hours. Plan client-side retries to land inside the cache window. - Scope: keys are partitioned by client/user, HTTP method, and request path. The same key on
/payments/swiftand/payments/ach-localis not shared - each endpoint has its own cache slot. - Concurrency: if a second request with the same key arrives while the first is still in flight, the second is rejected with
409 Conflictand message"Request is already being processed."Wait and retry. - Body mismatch: request bodies are not compared on replay. If you reuse a key with a different body, the original cached response is returned - the new body is ignored. Mint a fresh key for any logically different request.
- Non-2xx responses are not cached. A
4xxvalidation failure or5xxserver error can be retried with the same key and will execute again.
Deduplication
A separate, business-level guard on the instructionIdentification field, applied independently of the Idempotency-Key header:
- Reusing an
instructionIdentificationfor an active payment is rejected with409 PAYMENT_DUPLICATE_INSTRUCTION_ID. - Use a fresh
instructionIdentificationfor each new payment intent. Reuse it (with the sameIdempotency-Key) only when retrying the exact same payment. - The deduplication window is currently configured as 24 hours from the first accepted request.
How Idempotency-Key and instructionIdentification combine
They are independent mechanisms with different purposes.
Idempotency-Key(header) is a transport-level retry token. It lets you safely retry the same HTTP call and get the original response replayed.instructionIdentification(body) is the business identifier of the payment. It is persisted on the payment record and forwarded downstream. To prevent the same payment intent from being submitted twice, a value that is already in flight or recently accepted is rejected with409 PAYMENT_DUPLICATE_INSTRUCTION_ID(window: 24 hours).
Idempotency-Key | instructionIdentification | Behaviour |
|---|---|---|
| no | no | No protection. Each call creates a new payment. |
| yes | no | HTTP retries of the same call replay the original response. A new Idempotency-Key creates a new payment. |
| no | yes | First call is processed normally. Reusing the same business identifier within 24 hours is rejected with 409 PAYMENT_DUPLICATE_INSTRUCTION_ID. The original success response is not replayed - record it client-side. |
| yes | yes | Recommended. HTTP retries of the same call replay the original response. A new Idempotency-Key reusing an in-flight instructionIdentification is rejected with 409. |
Resilience: classifying responses
The dedupe and idempotency layers together cover three distinct failure modes. The status code tells you what to do next:
503 DEDUPE_LOCK_UNAVAILABLE- the duplicate-check store could not acquire its lock forinstructionIdentification. The payment was not submitted to core banking. Safe to retry after a short backoff with the sameinstructionIdentification(and the sameIdempotency-Key, if you used one). This is not "a duplicate was detected" - it is "we could not verify uniqueness right now."409 PAYMENT_DUPLICATE_INSTRUCTION_ID- thisinstructionIdentificationwas already accepted within the 24-hour window. Do not retry thePOST; query payment status to reconcile.5xx, connection timeout, or no response - outcome unknown. Retry with the sameIdempotency-Keyand sameinstructionIdentification. The server will either replay the original201(if the first attempt landed) or return409 PAYMENT_DUPLICATE_INSTRUCTION_ID(also indicating the first attempt landed).
Decision tree in pseudocode:
async function submitPayment(paymentRequest, idempotencyKey) {
for (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) {
const res = await postPayment(paymentRequest, idempotencyKey);
switch (res.status) {
case 201:
return res.body; // success - persist paymentId against instructionIdentification
case 409: // PAYMENT_DUPLICATE_INSTRUCTION_ID - intent already submitted
// Do NOT retry with a new instructionId. Reconcile via status lookup.
return await reconcileViaStatusLookup(paymentRequest.instructionIdentification);
case 503: // DEDUPE_LOCK_UNAVAILABLE - NOT submitted, safe to retry as-is
case 502: case 504: // transient gateway
await backoff(attempt); continue;
default:
if (isNetworkError(res)) { // unknown outcome - retry SAME key + SAME instructionId
await backoff(attempt); continue;
}
throw res; // 4xx other - fix request, mint NEW instructionId before retrying
}
}
}
When to rotate instructionIdentification
// NEW payment intent (user clicks "Send" again, new business event)
const intent = {
instructionIdentification: uuid(),
idempotencyKey: uuid()
};
// RETRY of the SAME intent (5xx, 503 DEDUPE_LOCK_UNAVAILABLE, timeout)
// -> keep BOTH values stable; the server will replay or short-circuit safely
retry(intent);
// After 409 PAYMENT_DUPLICATE_INSTRUCTION_ID
// -> do NOT POST again; query status to reconcile
await getPaymentStatus(intent.instructionIdentification);
Idempotency-Key lifecycle (client-side checklist)
- Mint the key before the HTTP call and persist it alongside the payment intent so a process restart or retry can still find it.
- Reuse it for every retry of the same intent; treat it as "spent" only after a terminal (
2xxor non-retryable4xx) response. - Plan retries to land inside the cache window (~1 hour). Beyond that,
instructionIdentification(24 h) is your remaining guard.
Minimal Request Example
const res = await fetch('https://api.bcbank.us/v1/payments/swift', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json',
'Accept': 'application/json',
'Idempotency-Key': idempotencyKey, // UUID v4, per payment intent
},
body: JSON.stringify(paymentRequest), // shape: see request schema below
});
The full request and response schemas, including field types and a worked example, are rendered below from the API contract.
Required Permission: payment-swift
This endpoint requires the permission claim payment-swift 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.
Request body application/json
string Unique identification as assigned by an instructing party for an instructed party to unambiguously identify the instruction.
object requiredUnambiguous identification of the account of the debtor to which a debit entry will be made as a result of the transaction.
Show properties
string requiredUnique identification of the account, such as an Bank Account Number or a local account number.
object requiredAmount of money to be moved between the debtor and creditor, before deduction of charges, expressed in the currency as ordered by the initiating party.
Show properties
string requiredCurrency ISO code
string requiredAmount
object Optional. FX: debit amount; then only instructedAmount.currency required.
Show properties
string requiredCurrency ISO code
string requiredAmount
object requiredUnambiguous identification of the account of the creditor to which a credit entry will be posted as a result of the payment transaction.
object requiredFinancial institution servicing an account for the creditor.
object Agent between the debtor's agent and the creditor's agent.
string requiredSpecifies which party/parties will bear the charges associated with the processing of the payment transaction. Max length: 3 characters (e.g., OUR/SHA/BEN).
array requiredInformation supplied to enable the matching/reconciliation of an entry with the items that the payment is intended to settle. Limit: up to 4 lines; each line max 35 characters.
Show properties
arraystring
Responses
Created - The payment was successfully processed.
string requiredUnique identifier assigned by the bank for the SWIFT transfer. This ID can be used for future reference and tracking of the payment.
string requiredThe current status of the payment processing. Possible values include:
- success: Payment has been accepted for processing
- failed: Payment failed
string requiredDetailed transaction status indicating the current state of the transfer. This provides more granular status information than the main status field.
string requiredA unique identifier specific to this instance of the SWIFT transfer. This identifier remains constant throughout the lifecycle of the payment and can be used for reconciliation purposes.
object requiredDetailed information about the payment transaction including amounts, accounts, and settlement information.
Show properties
string requiredExternal reference number assigned by the bank's payment processing system. This reference can be used for tracking and reconciliation purposes.
object requiredThe amount and currency of the payment as instructed by the payment initiator. This represents the original payment amount before any charges or conversions.
Show properties
string requiredCurrency ISO code
string requiredAmount
object requiredReference information for the account from which the payment is debited. Includes the account identifier and scheme information.
Show properties
string The name of the identification scheme, e.g. "BBAN", "AccountNumber".
string requiredThe identifier within that scheme (e.g. account number).
string requiredThe name of the account, if available (optional).
object requiredReference information for the beneficiary's account. This may differ from the creditor account in certain scenarios.
Show properties
string The name of the identification scheme, e.g. "BBAN", "AccountNumber".
string requiredThe identifier within that scheme (e.g. account number).
string requiredThe name of the account, if available (optional).
object requiredReference information for the account to be credited with the payment. This represents the immediate recipient account of the funds.
Show properties
string The name of the identification scheme, e.g. "BBAN", "AccountNumber".
string requiredThe identifier within that scheme (e.g. account number).
string requiredThe name of the account, if available (optional).
object requiredDetails about the settlement of the payment, including credited and debited amounts, value dates, and settlement status.
Show properties
object requiredThe amount that was credited to the beneficiary account. This may differ from the instructed amount due to currency conversion or intermediary bank charges.
Show properties
string requiredCurrency ISO code
string requiredAmount
object requiredThe total amount debited from the sender's account. This includes the payment amount plus any applicable charges.
Show properties
string requiredCurrency ISO code
string requiredAmount
string requiredThe date on which the payment is settled between banks. This is the date when the funds become available to the beneficiary. Format: ISO 8601 date string (YYYY-MM-DD)
string requiredThe current status of the settlement record.
object requiredInformation about the charges applied to the payment, including charge type, amounts, and the account to which charges are applied.
Show properties
string requiredSpecifies how the charges for the payment are allocated. Possible values:
- OUR: All charges are paid by the sender
- BEN: All charges are paid by the beneficiary
- SHA: Charges are shared between sender and beneficiary
object requiredThe total amount of charges applied to the payment. Includes both sending and receiving bank charges.
Show properties
string requiredCurrency ISO code
string requiredAmount
object requiredReference information for the account from which charges are collected. This may be different from the main debit account.
Show properties
string The name of the identification scheme, e.g. "BBAN", "AccountNumber".
string requiredThe identifier within that scheme (e.g. account number).
string requiredThe name of the account, if available (optional).
object requiredDetailed breakdown of how charges are distributed between the sending and receiving parties.
Show properties
object requiredThe amount of charges applied by and payable to the sending bank. This may include processing fees, wire transfer fees, or other sending bank charges.
Show properties
objectobject requiredThe amount of charges applied by and payable to the receiving bank. This may include processing fees, incoming wire fees, or other receiving bank charges.
Show properties
objectarray Collection of unstructured information provided with the payment to help with reconciliation and payment identification.
Show properties
arraystring requiredThe narrative text (e.g. remittance line, beneficiary note, etc.).
object requiredDetailed information about the ultimate beneficiary of the payment. Includes identification, name, and additional information.
object requiredInformation about the beneficiary's bank or financial institution. Typically, includes the BIC/SWIFT code and bank details.
object requiredDetails of any intermediary bank involved in the payment chain. This is optional and only present for payments requiring intermediary processing.
array requiredCollection of related financial activities associated with this payment. This may include charges, forex conversions, or other related transactions.
Show properties
arraystring requiredThe unique identifier for the activity.
string requiredThe current processing status of the transaction.
string requiredThe general status of the activity.
string A unique identifier specific to this instance of the activity.
object requiredDetailed information about the activity.
Show properties
string requiredUnique identifier for the arrangement associated with this activity.
string requiredIdentifier for the type of activity.
string requiredProduct identifier related to the activity.
string requiredCurrency code for the activity.
string requiredDate when the activity becomes effective.
Request sample
curl --request POST \
--url 'https://api-uat.bcbank.us/v1/payments/swift' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"instructionIdentification": "PAY-2024-03-21-001",
"debtorAccount": {
"identification": "BM12BCBK00001234567890"
},
"instructedAmount": {
"currency": "USD",
"amount": 50000
},
"debitAmount": null,
"creditorAccount": {
"identification": "US12BCBK00001234567890",
"name": "Global Investment Services Inc",
"additionalInformation": [
"350 Fifth Avenue",
"New York, NY 10118",
"United States"
]
},
"creditorAgent": {
"identification": "CHASUS33",
"name": "JPMorgan Chase Bank",
"additionalInformation": [
"383 Madison Avenue",
"New York, NY 10179",
"United States"
]
},
"intermediaryAgent": {
"identification": "BCBKBMHM",
"name": "Bermuda Commercial Bank",
"additionalInformation": [
"Victoria Place",
"31 Victoria Street",
"Hamilton HM 10, Bermuda"
]
},
"chargesType": "OUR",
"remittanceInformation": [
"Payment for investment management services Q1 2024",
"Invoice #INV-2024-001",
"Service Period: Jan-Mar 2024"
]
}'Response sample
{
"id": "string",
"status": "string",
"transactionStatus": "string",
"uniqueIdentifier": "string",
"details": {
"extReference": "string",
"instructedAmount": {
"currency": {},
"amount": {}
},
"debtorAccount": {
"schemeName": {},
"identification": {},
"Name": {}
},
"beneficiaryAccount": {
"schemeName": {},
"identification": {},
"Name": {}
},
"creditorAccount": {
"schemeName": {},
"identification": {},
"Name": {}
},
"settlementDetails": {
"amountCredited": {},
"amountDebited": {},
"valueDate": {},
"recordStatus": {}
},
"chargeDetails": {
"chargesType": {},
"chargeAmount": {},
"chargeAccount": {},
"chargeAnalysis": {}
},
"remittanceInformation": [
{
"unstructured": {}
}
],
"beneficiary": "string",
"beneficiaryAgent": "string",
"intermediaryAgent": "string"
},
"linkedActivities": [
{
"id": "string",
"transactionStatus": "string",
"status": "string",
"uniqueIdentifier": "string",
"activityDetails": {
"arrangementId": {},
"activityId": {},
"productId": {},
"currencyId": {},
"effectiveDate": {}
}
}
]
}get/v1/accounts/{accountNumber}/paymentsList payment statuses for an account
List payment statuses for an account
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 apageToken. - Subsequent Requests: Use the
pageTokenfrom previous responses withpageStartto navigate pages. - Page Token: Contains encoded pagination context including pageSize, so don't specify
pageSizein 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/jsonfor JSON responses (default) - Set
Accept: text/csvfor CSV responses If the Accept header is omitted,application/jsonis assumed.
Base URL
All API requests use the versioned base URL:
https://api.bcbank.us/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.bcbank.us/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.bcbank.us/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.
Request parameters
path requiredThe account number to retrieve payment statuses for.
string
query string
query integer (int32)
query integer (int32)
Responses
OK - The request was successful.
object Show properties
object Show properties
integer requiredstring integer requiredinteger requiredarray Show properties
arraystring requiredThe type of transaction (e.g., "Outward Swift Payment MT103 API")
string External reference number for the transaction
string requiredCurrent status of the transaction (e.g., "Pending", "Completed", "Reversed")
string Free-text remittance information provided by the client, describing the purpose of the transaction.
string requiredUnique transaction number
object requiredThe amount debited from the account
Show properties
string requiredCurrency ISO code
string requiredAmount
string requiredThe date when the transaction will be processed
object requiredThe amount credited from the account
Show properties
string requiredCurrency ISO code
string requiredAmount
number Exchange rate applied to the transaction
Request sample
curl --request GET \
--url 'https://api-uat.bcbank.us/v1/accounts/{accountNumber}/payments' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN'Response sample
{
"meta": {
"pagination": {
"page_start": {},
"page_token": {},
"total_size": {},
"page_size": {}
}
},
"data": [
{
"type": "string",
"externalReference": "string",
"status": "string",
"remittanceInformation": "string",
"transactionId": "string",
"debitAmount": {
"currency": {},
"amount": {}
},
"valueDate": "string",
"creditAmount": {
"currency": {},
"amount": {}
},
"exchangeRate": 0
}
]
}get/v1/payments/{paymentId}/statusGet payment status
Get payment status
Retrieves detailed status information for a specific payment identified by its payment ID (also known as transaction ID). This endpoint provides comprehensive status details including:
- Type: The type of payment (e.g., "Outward Swift Payment MT103 API")
- Status: Current status of the payment (e.g., "Pending", "Completed", "Reversed")
- TransactionId: Unique payment identifier (or Transaction Id)
- ExternalReference: External reference number for the payment
- RemittanceInformation: Free-text information about the purpose of the payment
- DebitAmount: The amount debited from the account, including currency code
- CreditAmount: The amount credited to the account, including currency code
- ValueDate: The date when the payment was/will be processed
- ExchangeRate: The exchange rate applied to the payment
Content Negotiation
Clients must use the HTTP Accept header to indicate the desired response format:
- Set
Accept: application/jsonfor JSON responses (default) - Set
Accept: text/csvfor CSV responses If the Accept header is omitted,application/jsonis assumed.
Base URL:
All API requests use the versioned base URL:
https://api.bcbank.us/v1/payments/{paymentId}/status
Sample Request in JavaScript:
async function getPaymentStatus(paymentId) {
try {
const response = await fetch(`https://api.bcbank.us/v1/payments/${paymentId}/status`, {
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 paymentStatus = await response.json();
console.log('Payment Status Details:');
console.log('Payment ID:', paymentStatus.transactionId);
console.log('Type:', paymentStatus.type);
console.log('Status:', paymentStatus.status);
console.log('External Reference:', paymentStatus.externalReference);
console.log('Remittance Information:', paymentStatus.remittanceInformation);
console.log('Value Date:', paymentStatus.valueDate);
console.log('Debit Amount:', `${paymentStatus.debitAmount.amount} ${paymentStatus.debitAmount.currency}`);
if (paymentStatus.creditAmount && paymentStatus.creditAmount.amount) {
console.log('Credit Amount:', `${paymentStatus.creditAmount.amount} ${paymentStatus.creditAmount.currency}`);
}
// Implement business logic based on payment status
if (paymentStatus.status === 'Completed') {
console.log('Payment has been successfully completed.');
} else if (paymentStatus.status === 'Pending') {
console.log('Payment is still being processed.');
} else if (paymentStatus.status === 'Failed') {
console.log('Payment failed. Please check the details or contact support.');
}
} catch (error) {
console.error('There was a problem retrieving the payment status:', error.message);
}
}
// Example usage:
getPaymentStatus('PAY-001-2023');
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.
Request parameters
path requiredThe unique identifier of the payment (also known as transactionId) to retrieve status for.
string
Responses
OK - The request was successful.
string requiredThe type of transaction (e.g., "Outward Swift Payment MT103 API")
string External reference number for the transaction
string requiredCurrent status of the transaction (e.g., "Pending", "Completed", "Reversed")
string Free-text remittance information provided by the client, describing the purpose of the transaction.
string requiredUnique transaction number
object requiredThe amount debited from the account
Show properties
string requiredCurrency ISO code
string requiredAmount
string requiredThe date when the transaction will be processed
object requiredThe amount credited from the account
Show properties
string requiredCurrency ISO code
string requiredAmount
number Exchange rate applied to the transaction
Request sample
curl --request GET \
--url 'https://api-uat.bcbank.us/v1/payments/{paymentId}/status' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN'Response sample
{
"type": "string",
"externalReference": "string",
"status": "string",
"remittanceInformation": "string",
"transactionId": "string",
"debitAmount": {
"currency": "string",
"amount": "string"
},
"valueDate": "string",
"creditAmount": {
"currency": "string",
"amount": "string"
},
"exchangeRate": 0
}Credentials
Operationspost/v1/credentialsCreate new API client credentials
Create new API client credentials
Creates new API client credentials based on an existing client's permissions and configuration. The new credentials will inherit the same roles and permissions as the specified existing client.
Key Features:
- A new client ID (GUID) is generated automatically
- A cryptographically secure password (22-30 characters) is generated automatically
- A cryptographically secure message signing secret (32 bytes) is generated automatically for HMAC-SHA256 signing
- All roles and direct permissions are copied from the existing client
- The new credentials can have different IP restrictions if specified
Password Security:
- Generated passwords are 22-30 characters long for enhanced security
- Include uppercase letters, lowercase letters, digits, and special characters
- The generated password is only returned once in the response
Message Signing Secret:
- A 32-byte (256-bit) random key (Base64 encoded) is generated for signing API requests
- This key will be used by the system to sign callback responses - notifications, background job webhooks
- The secret is returned only once in the response
Access Control:
- You can only create credentials based on clients you have access to
- New client inherits exact role and permission set from source client
- IP restrictions can be customized or inherited from source client
Base URL:
All API requests use the versioned base URL:
https://api.bcbank.us/v1/credentials
Idempotency
The API supports idempotency through the optional Idempotency-Key header:
- If no idempotency key is provided, the request is processed normally (duplicates are possible)
- If a valid UUID idempotency key is provided for a new transaction, the system stores the key and associates it with the transaction results
- If the same idempotency key is received again for the same endpoint/action, the system returns the previously stored response
- Idempotency keys are user-specific - different users with the same keys don't share cached responses
- The idempotency key must be a valid UUID format (e.g., "123e4567-e89b-12d3-a456-426614174000").
Sample Request in JavaScript:
async function createCredentials() {
try {
const token = localStorage.getItem('jwt'); // Your JWT token from authentication
const response = await fetch('https://api.bcbank.us/v1/credentials', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': `Bearer ${token}`
},
body: JSON.stringify({
allowedIps: '192.168.1.100,10.0.0.0/24' // Optional: specify IP restrictions, or omit/'*' for all IPs
})
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(`Error: ${errorData.message || response.statusText}`);
}
const data = await response.json();
console.log('New credentials created:', {
clientId: data.clientId,
clientSecret: data.clientSecret, // Save this securely - only shown once!
messageSigningSecret: data.messageSigningSecret, // Save this securely - only shown once!
isActive: data.isActive,
allowedIps: data.allowedIps
});
// Store new credentials securely
// WARNING: This is just an example - use secure storage in production
localStorage.setItem('newClientId', data.clientId);
localStorage.setItem('newClientSecret', data.clientSecret);
localStorage.setItem('newMessageSigningSecret', data.messageSigningSecret);
} catch (error) {
console.error('Error creating credentials:', error);
}
}
createCredentials();
Required Permission: manage-credentials
This endpoint requires the permission claim manage-credentials 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.
Request body application/json
string Optional IP address restrictions for the new client credentials. If omitted (null/empty) or set to "*", all IP addresses will be allowed. Otherwise, specify a comma-separated list of allowed IP addresses and/or CIDR ranges.
Responses
Credentials created successfully
string requiredUnique client identifier (GUID) assigned by the authorization server. This identifier is used in conjunction with the client secret for API authentication.
string requiredClient secret assigned by the authorization server.
boolean requiredValue indicating whether the client credentials are currently active and can be used for authentication.
string IP address restrictions for the client credentials. Defines which IP addresses or IP ranges are allowed to use these credentials for authentication.
string requiredBase64-encoded 32-byte secret used to sign messages for authentication or integrity verification.
Request sample
curl --request POST \
--url 'https://api-uat.bcbank.us/v1/credentials' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"allowedIps": "192.168.1.1,192.168.1.2"
}'Response sample
{
"clientId": "a1b2c3d4-e5f6-4789-b012-3456789abcde",
"clientSecret": "Abc123XyzP9mN7kLAbc123XyzP95",
"isActive": true,
"allowedIps": "192.168.1.1,192.168.1.2",
"messageSigningSecret": "HtYp2oJm5DwQ1xL8bSeRgUkN4vZc3PhYtLwSxV2N9Cs="
}patch/v1/credentials/{clientId}Rotate the client secret for an existing API client
Rotate the client secret for an existing API client
Rotates (changes) the client secret AND the message signing secret for an existing API client while preserving all other settings. This is useful for credential rotation policies, security incident response, or regular maintenance.
Key Features:
- A new cryptographically secure password (22-30 characters) is generated automatically
- A new cryptographically secure message signing secret (32 bytes) is generated automatically
- The existing client's secrets are immediately replaced with the new ones
- All roles, permissions, and other settings remain unchanged
- The old secrets become invalid immediately after successful rotation
- The new secrets are returned in the response (only shown once)
Password Security:
- Generated passwords are 22-30 characters long for enhanced security
- Include uppercase letters, lowercase letters, digits, and special characters
- The new password is only returned once in the response
Access Control:
- You can only rotate secrets for clients you have access to
- The rotated client retains all existing roles and permissions
Important Security Notes:
- The old secret stops working immediately after successful rotation
- Any applications using the old secret will need to be updated with the new secret
- Store the new secret securely as it won't be shown again
Base URL:
All API requests use the versioned base URL:
https://api.bcbank.us/v1/credentials/{clientId}
Idempotency
The API supports idempotency through the optional Idempotency-Key header:
- If no idempotency key is provided, the request is processed normally (duplicates are possible)
- If a valid UUID idempotency key is provided for a new transaction, the system stores the key and associates it with the transaction results
- If the same idempotency key is received again for the same endpoint/action, the system returns the previously stored response
- Idempotency keys are user-specific - different users with the same keys don't share cached responses
- The idempotency key must be a valid UUID format (e.g., "123e4567-e89b-12d3-a456-426614174000").
Sample Request in JavaScript:
async function rotateClientSecret(clientId) {
try {
const token = localStorage.getItem('jwt'); // Your JWT token from authentication
const response = await fetch(`https://api.bcbank.us/v1/credentials/${clientId}`, {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': `Bearer ${token}`
}
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(`Error: ${errorData.message || response.statusText}`);
}
const data = await response.json();
console.log('Client secret rotated successfully:', {
clientId: data.clientId,
newClientSecret: data.clientSecret, // Save this securely - only shown once!
newMessageSigningSecret: data.messageSigningSecret, // Save this securely - only shown once!
isActive: data.isActive,
allowedIps: data.allowedIps
});
// Update stored credentials securely
// WARNING: This is just an example - use secure storage in production
localStorage.setItem('clientSecret', data.clientSecret);
localStorage.setItem('messageSigningSecret', data.messageSigningSecret);
// Important: Update any applications using the old secret
console.warn('IMPORTANT: Update all applications using this client with the new secret!');
} catch (error) {
console.error('Error rotating client secret:', error);
}
}
// Example usage
rotateClientSecret('12345678-1234-1234-1234-123456789abc');
Required Permission: manage-credentials
This endpoint requires the permission claim manage-credentials 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.
Request parameters
path requiredThe unique identifier of the client whose secret should be rotated
string
Responses
Secret rotated successfully
string requiredUnique client identifier (GUID) assigned by the authorization server. This identifier is used in conjunction with the client secret for API authentication.
string requiredClient secret assigned by the authorization server.
boolean requiredValue indicating whether the client credentials are currently active and can be used for authentication.
string IP address restrictions for the client credentials. Defines which IP addresses or IP ranges are allowed to use these credentials for authentication.
string requiredBase64-encoded 32-byte secret used to sign messages for authentication or integrity verification.
Request sample
curl --request PATCH \
--url 'https://api-uat.bcbank.us/v1/credentials/{clientId}' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN'Response sample
{
"clientId": "string",
"clientSecret": "string",
"isActive": true,
"allowedIps": "string",
"messageSigningSecret": "string"
}delete/v1/credentials/{clientId}Disable an existing API client
Disable an existing API client
Disables an existing API client, immediately preventing any further authentication using that client ID and secret. This operation also revokes all active tokens associated with the client.
Key Features:
- Disables the credentials instantly – all authentication requests will fail after this operation
- Revokes all active tokens immediately for enhanced security
- Idempotent: calling the endpoint on an already inactive client returns success
Security Considerations:
- All active tokens are immediately invalidated and removed from the system
- Any applications using the disabled client will lose access immediately
- The client record is preserved for audit and compliance purposes
Access Control:
- You can only disable clients that belong to your organization
Base URL:
All API requests use the versioned base URL:
https://api.bcbank.us/v1/credentials/{clientId}
Sample Request in JavaScript:
async function disableClient(clientId) {
try {
const token = localStorage.getItem('jwt'); // Your JWT token from authentication
const response = await fetch(`https://api.bcbank.us/v1/credentials/${clientId}`, {
method: 'DELETE',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': `Bearer ${token}`
}
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(`Error: ${errorData.message || response.statusText}`);
}
const data = await response.json();
console.log('Client disabled successfully:', {
clientId: data.clientId,
isActive: data.isActive, // Should be false
allowedIps: data.allowedIps
});
// Important: Update any applications that were using this client
console.warn('IMPORTANT: All applications using this client will lose access immediately!');
} catch (error) {
console.error('Error disabling client:', error);
}
}
// Example usage
disableClient('12345678-1234-1234-1234-123456789abc');
Required Permission: manage-credentials
This endpoint requires the permission claim manage-credentials 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.
Request parameters
path requiredThe unique identifier of the client to disable
string
Responses
Client disabled successfully
string requiredUnique client identifier (GUID) assigned by the authorization server. This identifier is used in conjunction with the client secret for API authentication.
string requiredClient secret assigned by the authorization server.
boolean requiredValue indicating whether the client credentials are currently active and can be used for authentication.
string IP address restrictions for the client credentials. Defines which IP addresses or IP ranges are allowed to use these credentials for authentication.
string requiredBase64-encoded 32-byte secret used to sign messages for authentication or integrity verification.
Request sample
curl --request DELETE \
--url 'https://api-uat.bcbank.us/v1/credentials/{clientId}' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN'Response sample
{
"clientId": "a1b2c3d4-e5f6-7890-abcd-123456789def",
"clientSecret": "",
"isActive": false,
"allowedIps": "192.168.1.100,10.0.0.0/24",
"messageSigningSecret": null
}get/v1/credentials/{clientId}/permissionsGet permissions for an existing API client
Get permissions for an existing API client
Retrieves all permissions assigned to the specified API client. The response provides a comprehensive view of what features the client can access.
Key Features:
- Returns all permissions assigned to the client
- Results are sorted alphabetically by permission key for consistent ordering
- Includes human-readable descriptions for each permission
Access Control:
- You can only view permissions for clients that belong to your organization
Use Cases:
- Audit client access capabilities
- Troubleshoot authentication and authorization issues
- Verify client configuration during security reviews
- Document client permissions for compliance purposes
Base URL:
All API requests use the versioned base URL:
https://api.bcbank.us/v1/credentials/{clientId}/permissions
Sample Request in JavaScript:
async function getClientPermissions(clientId) {
try {
const token = localStorage.getItem('jwt'); // Your JWT token from authentication
const response = await fetch(`https://api.bcbank.us/v1/credentials/${clientId}/permissions`, {
method: 'GET',
headers: {
'Accept': 'application/json',
'Authorization': `Bearer ${token}`
}
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(`Error: ${errorData.message || response.statusText}`);
}
const permissions = await response.json();
console.log('Client permissions:', permissions);
// Display permissions in a user-friendly format
permissions.forEach(permission => {
console.log(`- ${permission.key}: ${permission.description || 'No description available'}`);
});
return permissions;
} catch (error) {
console.error('Error retrieving client permissions:', error);
}
}
// Example usage
getClientPermissions('12345678-1234-1234-1234-123456789abc');
Required Permission: manage-credentials
This endpoint requires the permission claim manage-credentials 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.
Request parameters
path requiredThe unique identifier of the client to retrieve permissions for
string
Responses
Permissions retrieved successfully
arraystring requiredUnique permission key that identifies the specific permission. Used in authorization checks and JWT token claims.
string Human-readable description of what this permission allows. Provides context for administrators managing client permissions.
Request sample
curl --request GET \
--url 'https://api-uat.bcbank.us/v1/credentials/{clientId}/permissions' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN'Response sample
[
{
"key": "get-account",
"description": "Allows access to retrieve individual account information"
},
{
"key": "get-all-accounts",
"description": "Allows access to retrieve all accounts for a customer"
},
{
"key": "get-fx-quote",
"description": "Allows access to foreign exchange quote endpoints"
},
{
"key": "get-transactions",
"description": "Allows access to transaction history endpoints"
},
{
"key": "get-payment-status",
"description": "Allows access to payment status tracking endpoints"
},
{
"key": "make-internal-transfer",
"description": "Allows execution of internal transfers between accounts"
},
{
"key": "make-payment-swift",
"description": "Allows execution of SWIFT payment transactions"
},
{
"key": "manage-credentials",
"description": "Allows management of API client credentials and permissions"
}
]get/v1/credentials/{clientId}/keysGet public key metadata
Get public key metadata
Returns metadata for the partner RSA keys:
- Indicates whether primary/secondary keys exist
- Provides short fingerprints, algorithms, and last-updated timestamps
- Shows verification status of the secondary key (after proof-of-possession)
Sample Request in JavaScript:
async function getKeyMetadata(clientId) {
try {
const token = localStorage.getItem('jwt');
const response = await fetch(`https://api.bcbank.us/v1/credentials/${clientId}/keys`, {
method: 'GET',
headers: {
'Accept': 'application/json',
'Authorization': `Bearer ${token}`
}
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(`Error: ${errorData.message || response.statusText}`);
}
const metadata = await response.json();
console.log('Key metadata:', {
hasPrimaryKey: metadata.hasPrimaryKey,
hasSecondaryKey: metadata.hasSecondaryKey,
primaryKeyFingerprint: metadata.primaryKeyFingerprint,
secondaryKeyFingerprint: metadata.secondaryKeyFingerprint,
secondaryKeyVerified: metadata.secondaryKeyVerified
});
return metadata;
} catch (error) {
console.error('Error getting key metadata:', error);
}
}
getKeyMetadata('12345678-1234-1234-1234-123456789abc');
Required Permission: manage-credentials
This endpoint requires the permission claim manage-credentials 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.
Request parameters
path requiredstring
Responses
boolean requiredTrue when a primary partner public key is configured.
boolean requiredTrue when a secondary partner public key is configured (staged for rotation).
string Short fingerprint of the primary key (first 8 bytes of SHA-256 over canonical key).
string Short fingerprint of the secondary key (first 8 bytes of SHA-256 over canonical key).
string Algorithm/size description of the primary key (e.g., RSA-2048).
string Algorithm/size description of the secondary key (e.g., RSA-2048).
string Timestamp when the primary key was last updated.
string Timestamp when the secondary key was last updated.
boolean requiredIndicates whether the secondary key has been verified via challenge.
string Timestamp when the secondary key was last verified.
Request sample
curl --request GET \
--url 'https://api-uat.bcbank.us/v1/credentials/{clientId}/keys' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN'Response sample
{
"hasPrimaryKey": true,
"hasSecondaryKey": true,
"primaryKeyFingerprint": "A1B2C3D4E5F60708",
"secondaryKeyFingerprint": "0F1E2D3C4B5A6978",
"primaryKeyAlgorithm": "RSA-3072",
"secondaryKeyAlgorithm": "RSA-3072",
"primaryKeyUpdatedUtc": "2026-01-05T12:00:00.0000000Z",
"secondaryKeyUpdatedUtc": "2026-01-15T12:00:00.0000000Z",
"secondaryKeyVerified": false,
"secondaryKeyVerifiedUtc": null
}put/v1/credentials/{clientId}/keys/secondaryUpload secondary public key
Upload secondary public key
Upload a new RSA public key (PEM format) into the secondary slot to stage rotation.
Key Features:
- Accepts RSA public keys (2048-bit minimum recommended)
- Resets verification status when a new key is uploaded
- Secondary key becomes active for signature verification alongside primary
Rotation flow:
- Upload secondary key (this endpoint)
- POST challenge → sign locally → POST verify
- POST promote (makes secondary the primary)
- (Optional) DELETE secondary if aborting
Sample Request in JavaScript:
async function uploadSecondaryKey(clientId, publicKeyPem) {
try {
const token = localStorage.getItem('jwt');
const response = await fetch(`https://api.bcbank.us/v1/credentials/${clientId}/keys/secondary`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': `Bearer ${token}`
},
body: JSON.stringify({
publicKeyPem: publicKeyPem
})
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(`Error: ${errorData.message || response.statusText}`);
}
const metadata = await response.json();
console.log('Secondary key uploaded:', {
hasSecondaryKey: metadata.hasSecondaryKey,
secondaryKeyFingerprint: metadata.secondaryKeyFingerprint,
secondaryKeyVerified: metadata.secondaryKeyVerified // Will be false until verified
});
return metadata;
} catch (error) {
console.error('Error uploading secondary key:', error);
}
}
Required Permission: manage-credentials
This endpoint requires the permission claim manage-credentials 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.
Request parameters
path requiredstring
Request body application/json
string requiredResponses
boolean requiredTrue when a primary partner public key is configured.
boolean requiredTrue when a secondary partner public key is configured (staged for rotation).
string Short fingerprint of the primary key (first 8 bytes of SHA-256 over canonical key).
string Short fingerprint of the secondary key (first 8 bytes of SHA-256 over canonical key).
string Algorithm/size description of the primary key (e.g., RSA-2048).
string Algorithm/size description of the secondary key (e.g., RSA-2048).
string Timestamp when the primary key was last updated.
string Timestamp when the secondary key was last updated.
boolean requiredIndicates whether the secondary key has been verified via challenge.
string Timestamp when the secondary key was last verified.
Request sample
curl --request PUT \
--url 'https://api-uat.bcbank.us/v1/credentials/{clientId}/keys/secondary' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAxq1RqYIgYOb7H1uxC5mS\nM8s2Dhrz6sGJYvRq9A0KIf8v0pqm+9B6ZcM+3PEm2rUp7N0CYaUtR32W0bz1gM/b\nd3BFPFdcTnMjYwXomfjAZW9XvsC8t7y7mNLgO2cMYk2fT7k6aQp0yrzmmkCudIsc\nq4drqgG/Kxi4SpwYgYYnZ2hEo6VtV5JpR6TfyxwTXXxoH1WPr5oH7D8fFvG3a7dD\nRZl/vM8UzA2yN6lcn/zoVPQ7xY9qaTYjz4cmOcuQKBgQCQKBgQCQKBgQCQKBgQ\n-----END PUBLIC KEY-----"
}'Response sample
{
"hasPrimaryKey": true,
"hasSecondaryKey": true,
"primaryKeyFingerprint": "A1B2C3D4E5F60708",
"secondaryKeyFingerprint": "0F1E2D3C4B5A6978",
"primaryKeyAlgorithm": "RSA-3072",
"secondaryKeyAlgorithm": "RSA-3072",
"primaryKeyUpdatedUtc": "2026-01-05T12:00:00.0000000Z",
"secondaryKeyUpdatedUtc": "2026-01-15T12:00:00.0000000Z",
"secondaryKeyVerified": false,
"secondaryKeyVerifiedUtc": null
}delete/v1/credentials/{clientId}/keys/secondaryDelete secondary public key
Delete secondary public key
Removes the secondary key from the staging slot. Useful for aborting rotation or correcting mistakes before promotion.
Key Features:
- Clears the secondary key slot
- Idempotent: returns success even if secondary key doesn't exist
- Safe for retries
Sample Request in JavaScript:
async function deleteSecondaryKey(clientId) {
try {
const token = localStorage.getItem('jwt');
const response = await fetch(`https://api.bcbank.us/v1/credentials/${clientId}/keys/secondary`, {
method: 'DELETE',
headers: {
'Accept': 'application/json',
'Authorization': `Bearer ${token}`
}
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(`Error: ${errorData.message || response.statusText}`);
}
const metadata = await response.json();
console.log('Secondary key deleted:', {
hasSecondaryKey: metadata.hasSecondaryKey // Now false
});
return metadata;
} catch (error) {
console.error('Error deleting secondary key:', error);
}
}
Required Permission: manage-credentials
This endpoint requires the permission claim manage-credentials 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.
Request parameters
path requiredstring
Responses
boolean requiredTrue when a primary partner public key is configured.
boolean requiredTrue when a secondary partner public key is configured (staged for rotation).
string Short fingerprint of the primary key (first 8 bytes of SHA-256 over canonical key).
string Short fingerprint of the secondary key (first 8 bytes of SHA-256 over canonical key).
string Algorithm/size description of the primary key (e.g., RSA-2048).
string Algorithm/size description of the secondary key (e.g., RSA-2048).
string Timestamp when the primary key was last updated.
string Timestamp when the secondary key was last updated.
boolean requiredIndicates whether the secondary key has been verified via challenge.
string Timestamp when the secondary key was last verified.
Request sample
curl --request DELETE \
--url 'https://api-uat.bcbank.us/v1/credentials/{clientId}/keys/secondary' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN'Response sample
{
"hasPrimaryKey": true,
"hasSecondaryKey": true,
"primaryKeyFingerprint": "A1B2C3D4E5F60708",
"secondaryKeyFingerprint": "0F1E2D3C4B5A6978",
"primaryKeyAlgorithm": "RSA-3072",
"secondaryKeyAlgorithm": "RSA-3072",
"primaryKeyUpdatedUtc": "2026-01-05T12:00:00.0000000Z",
"secondaryKeyUpdatedUtc": "2026-01-15T12:00:00.0000000Z",
"secondaryKeyVerified": false,
"secondaryKeyVerifiedUtc": null
}post/v1/credentials/{clientId}/keys/promotePromote secondary key to primary
Promote secondary key to primary
Promotes the current secondary key to primary and clears the secondary slot. Use after validating the new key (optionally after challenge/verify).
Key Features:
- Makes the secondary key the new primary
- Clears the secondary slot
- Previous primary key is replaced
Sample Request in JavaScript:
async function promoteSecondaryKey(clientId) {
try {
const token = localStorage.getItem('jwt');
const response = await fetch(`https://api.bcbank.us/v1/credentials/${clientId}/keys/promote`, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Authorization': `Bearer ${token}`
}
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(`Error: ${errorData.message || response.statusText}`);
}
const metadata = await response.json();
console.log('Secondary key promoted to primary:', {
hasPrimaryKey: metadata.hasPrimaryKey,
hasSecondaryKey: metadata.hasSecondaryKey, // Now false
primaryKeyFingerprint: metadata.primaryKeyFingerprint // Updated
});
return metadata;
} catch (error) {
console.error('Error promoting secondary key:', error);
}
}
Required Permission: manage-credentials
This endpoint requires the permission claim manage-credentials 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.
Request parameters
path requiredstring
Responses
boolean requiredTrue when a primary partner public key is configured.
boolean requiredTrue when a secondary partner public key is configured (staged for rotation).
string Short fingerprint of the primary key (first 8 bytes of SHA-256 over canonical key).
string Short fingerprint of the secondary key (first 8 bytes of SHA-256 over canonical key).
string Algorithm/size description of the primary key (e.g., RSA-2048).
string Algorithm/size description of the secondary key (e.g., RSA-2048).
string Timestamp when the primary key was last updated.
string Timestamp when the secondary key was last updated.
boolean requiredIndicates whether the secondary key has been verified via challenge.
string Timestamp when the secondary key was last verified.
Request sample
curl --request POST \
--url 'https://api-uat.bcbank.us/v1/credentials/{clientId}/keys/promote' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN'Response sample
{
"hasPrimaryKey": true,
"hasSecondaryKey": true,
"primaryKeyFingerprint": "A1B2C3D4E5F60708",
"secondaryKeyFingerprint": "0F1E2D3C4B5A6978",
"primaryKeyAlgorithm": "RSA-3072",
"secondaryKeyAlgorithm": "RSA-3072",
"primaryKeyUpdatedUtc": "2026-01-05T12:00:00.0000000Z",
"secondaryKeyUpdatedUtc": "2026-01-15T12:00:00.0000000Z",
"secondaryKeyVerified": false,
"secondaryKeyVerifiedUtc": null
}post/v1/credentials/{clientId}/keys/secondary/challengeGenerate secondary key challenge
Generate secondary key challenge
Returns a time-limited challenge (Base64) that must be signed with the private key corresponding to the secondary public key. Proves ownership before promotion.
Challenge Format:
- Base64 encoding of:
{clientId}.{nonce}.{expiry}.{keyFingerprint} - Sign the decoded raw bytes of this challenge (not the Base64 literal).
- Valid for ~5 minutes
- Bound to the current secondary key (fingerprint included)
Sample Request in JavaScript:
async function requestChallenge(clientId) {
try {
const token = localStorage.getItem('jwt');
const response = await fetch(`https://api.bcbank.us/v1/credentials/${clientId}/keys/secondary/challenge`, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Authorization': `Bearer ${token}`
}
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(`Error: ${errorData.message || response.statusText}`);
}
const { challenge, expiresUtc } = await response.json();
console.log('Challenge received:', { challenge, expiresUtc });
// Sign the challenge with your private key
const crypto = require('crypto');
const privateKeyPem = process.env.PRIVATE_KEY;
const sign = crypto.createSign('RSA-SHA256');
sign.update(Buffer.from(challenge, 'base64'));
const signature = sign.sign({
key: privateKeyPem,
padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
saltLength: crypto.constants.RSA_PSS_SALTLEN_DIGEST
}, 'base64');
console.log('Signature created, ready for verification');
return { challenge, signature };
} catch (error) {
console.error('Error requesting challenge:', error);
}
}
Required Permission: manage-credentials
This endpoint requires the permission claim manage-credentials 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.
Request parameters
path requiredstring
Responses
string requiredBase64-encoded challenge string. Format: {clientId}.{nonce}.{expiry}.{keyFingerprint} (UTF-8 then Base64). Sign this exact Base64 value with your private key using RSA-PSS + SHA-256.
string requiredWhen this challenge expires (UTC). Request a new challenge after this time.
Request sample
curl --request POST \
--url 'https://api-uat.bcbank.us/v1/credentials/{clientId}/keys/secondary/challenge' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN'Response sample
{
"challenge": "Y2xpZW50SWQubm9uY2UuMTcwMDAwMDAwMC5BMTIzRjQ1RjY3OA==",
"expiresUtc": "2026-01-15T12:05:00.0000000Z"
}post/v1/credentials/{clientId}/keys/secondary/verifyVerify secondary key ownership
Verify secondary key ownership
Submit the Base64 challenge and its RSA-PSS signature (SHA-256). Important: sign the decoded raw bytes of the challenge, not the Base64 string literal. On success, the secondary key is marked as verified.
Key Features:
- Validates signature using RSA-PSS + SHA-256
- Checks challenge expiry (5-minute window)
- Verifies challenge matches current secondary key
- Sets
secondaryKeyVerified: trueon success
Sample Request in JavaScript:
async function verifySecondaryKey(clientId, challenge, signature) {
try {
const token = localStorage.getItem('jwt');
const response = await fetch(`https://api.bcbank.us/v1/credentials/${clientId}/keys/secondary/verify`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': `Bearer ${token}`
},
body: JSON.stringify({
challenge: challenge,
signature: signature
})
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(`Error: ${errorData.message || response.statusText}`);
}
const metadata = await response.json();
if (metadata.secondaryKeyVerified) {
console.log('✓ Secondary key verified successfully!');
console.log('You can now promote it to primary or test with production traffic.');
} else {
console.error('✗ Verification failed - signature did not match');
}
return metadata;
} catch (error) {
console.error('Error verifying secondary key:', error);
}
}
// Complete rotation flow example:
// 1. Upload: await uploadSecondaryKey(clientId, publicKeyPem);
// 2. Challenge: const { challenge, signature } = await requestChallenge(clientId);
// 3. Verify: await verifySecondaryKey(clientId, challenge, signature);
// 4. Promote: await promoteSecondaryKey(clientId);
Required Permission: manage-credentials
This endpoint requires the permission claim manage-credentials 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.
Request parameters
path requiredstring
Request body application/json
string requiredBase64-encoded challenge issued by the bank (unchanged from the response).
string requiredBase64-encoded RSA-PSS (SHA-256) signature of the Base64 challenge, generated with the partner private key.
Responses
boolean requiredTrue when a primary partner public key is configured.
boolean requiredTrue when a secondary partner public key is configured (staged for rotation).
string Short fingerprint of the primary key (first 8 bytes of SHA-256 over canonical key).
string Short fingerprint of the secondary key (first 8 bytes of SHA-256 over canonical key).
string Algorithm/size description of the primary key (e.g., RSA-2048).
string Algorithm/size description of the secondary key (e.g., RSA-2048).
string Timestamp when the primary key was last updated.
string Timestamp when the secondary key was last updated.
boolean requiredIndicates whether the secondary key has been verified via challenge.
string Timestamp when the secondary key was last verified.
Request sample
curl --request POST \
--url 'https://api-uat.bcbank.us/v1/credentials/{clientId}/keys/secondary/verify' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"challenge": "Y2xpZW50SWQubm9uY2UuMTcwMDAwMDAwMC5BMTIzRjQ1RjY3OA==",
"signature": "MEUCIQC0j7Xf7PqJ8n+q2eVY7k1nqM+UogYNDpFQ2a3E7Xy1zwIgFqYY3d3rVfJq8zlfjtqZ5rXwzBkVxH93+zVTe6y8ygE="
}'Response sample
{
"hasPrimaryKey": true,
"hasSecondaryKey": true,
"primaryKeyFingerprint": "A1B2C3D4E5F60708",
"secondaryKeyFingerprint": "0F1E2D3C4B5A6978",
"primaryKeyAlgorithm": "RSA-3072",
"secondaryKeyAlgorithm": "RSA-3072",
"primaryKeyUpdatedUtc": "2026-01-05T12:00:00.0000000Z",
"secondaryKeyUpdatedUtc": "2026-01-15T12:00:00.0000000Z",
"secondaryKeyVerified": false,
"secondaryKeyVerifiedUtc": null
}Testing
Operationspost/v1/test-deposits/swift/simulateCreate a test SWIFT deposit
Create a test SWIFT deposit
Creates a SWIFT deposit in the system using test-environment data and returns the created deposit details. This endpoint is available only in non-production environments and is intended for integration testing, validation of payload formatting, and pre-production workflow checks.
Although the route contains the word simulate, the request creates a deposit record in the system.
If there is a matching and active deposit notification subscription, the created deposit may also trigger
a deposit notification workflow.
Content Negotiation
Clients must use the HTTP Accept header to indicate the desired response format:
- Set
Accept: application/jsonfor JSON responses (default) If theAcceptheader is omitted,application/jsonis assumed.
Headers
Authorization: Bearer {token}Idempotency-Key: {uuid}(optional, but recommended for safe retries)
Validation Rules / Constraints
creditAccountNumberis required and must not exceed 36 characters.instructedAmount.currencyis required and must be a 3-letter ISO currency code.instructedAmount.amountis required and must be a valid decimal number with up to 2 decimal places.externalAccountNumberis required and must not exceed 34 characters.orderingBankis required and must not exceed 35 characters.orderingCustomermust contain between 1 and 4 lines, each up to 35 characters.remittanceInformationmust contain at least 1 line, up to 4 lines total, each up to 35 characters.
Request / Response Signing
This endpoint uses request signature verification and response signing. Clients should sign requests according to their configured signing method, and should verify the signature on the response when response signing is enabled for their API credentials.
Base URL
All API requests use the versioned base URL:
https://api.bcbank.us/v1/test-deposits/swift/simulate
Sample Request in JavaScript
async function simulateDeposit(token, idempotencyKey) {
const response = await fetch('https://api.bcbank.us/v1/test-deposits/swift/simulate', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json',
'Accept': 'application/json',
'Idempotency-Key': idempotencyKey
},
body: JSON.stringify({
creditAccountNumber: '1000078766',
instructedAmount: {
currency: 'USD',
amount: '5000.00'
},
externalAccountNumber: 'GB29NWBK60161331926819',
orderingBank: 'DEUTDEFF',
orderingCustomer: [
'Global Trading Corp',
'100 Finance Street',
'London, EC2V 8AB'
],
remittanceInformation: [
'Invoice INV-2024-0042',
'Q1 advisory fees'
]
})
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.message || 'Deposit simulation failed');
}
return await response.json();
}
Required Permission: simulate-deposit
This endpoint requires the permission claim simulate-deposit 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.
Request body application/json
string requiredobject requiredShow properties
string requiredCurrency ISO code
string requiredAmount
string requiredstring requiredarray requiredShow properties
arraystring
array requiredShow properties
arraystring
Responses
OK - The test deposit was created successfully.
string requiredstring requiredstring requiredstring requiredobject requiredShow properties
object requiredShow properties
string requiredCurrency ISO code
string requiredAmount
object requiredShow properties
string requiredCurrency ISO code
string requiredAmount
string requiredstring requiredstring requiredobject requiredShow properties
string requiredCurrency ISO code
string requiredAmount
string requiredarray requiredShow properties
arraystring requiredThe narrative text (e.g. remittance line, beneficiary note, etc.).
array requiredShow properties
arraystring requiredThe narrative text (e.g. remittance line, beneficiary note, etc.).
array requiredShow properties
arraystring requiredThe unique identifier for the activity.
string requiredThe current processing status of the transaction.
string requiredThe general status of the activity.
string A unique identifier specific to this instance of the activity.
object requiredDetailed information about the activity.
Show properties
string requiredUnique identifier for the arrangement associated with this activity.
string requiredIdentifier for the type of activity.
string requiredProduct identifier related to the activity.
string requiredCurrency code for the activity.
string requiredDate when the activity becomes effective.
Request sample
curl --request POST \
--url 'https://api-uat.bcbank.us/v1/test-deposits/swift/simulate' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"creditAccountNumber": 1000078766,
"instructedAmount": {
"currency": "USD",
"amount": 5000
},
"externalAccountNumber": "GB29NWBK60161331926819",
"orderingBank": "DEUTDEFF",
"orderingCustomer": [
"Global Trading Corp",
"100 Finance Street",
"London, EC2V 8AB"
],
"remittanceInformation": [
"Invoice INV-2024-0042",
"Q1 advisory fees"
]
}'Response sample
{
"id": "DEP-SIM-20240321-001",
"status": "success",
"transactionStatus": "SIMULATED",
"uniqueIdentifier": "dep-sim-uid-001",
"details": {
"amountCredited": {
"currency": "USD",
"amount": 5000
},
"amountDebited": {
"currency": "USD",
"amount": 5000
},
"orderingBank": "DEUTDEFF",
"debitCurrency": "USD",
"creditAccountNumber": 1000078766,
"instructedAmount": {
"currency": "USD",
"amount": 5000
},
"externalAccountNumber": "GB29NWBK60161331926819",
"orderingCustomer": [
{
"unstructured": "Global Trading Corp"
},
{
"unstructured": "100 Finance Street"
},
{
"unstructured": "London, EC2V 8AB"
}
],
"remittanceInformation": [
{
"unstructured": "Invoice INV-2024-0042"
},
{
"unstructured": "Q1 advisory fees"
}
]
},
"linkedActivities": [
{
"id": "ACT-DEP-SIM-001",
"transactionStatus": "SIMULATED",
"status": "SUCCESS",
"uniqueIdentifier": "act-dep-sim-001",
"activityDetails": {
"arrangementId": "arr-123456",
"activityId": "act-123456",
"productId": "swift-deposit-simulation",
"currencyId": "USD",
"effectiveDate": "2024-03-21"
}
}
]
}Fx Quotes
Operationsget/v1/fx-quotesGet FX Quote
Get FX Quote
Retrieves a foreign exchange quote for converting between currencies (for the requested pair and amount). The same quote will be automatically applied by the system to any internal transfer or payment involving two different currencies, provided it is used within its expiry time.
High-Value Exchange Requests (> 100 000 BMD)
If the requested exchange amount exceeds 100 000 BMD, the system will not return an automatic quote in the GET /v1/fx-quotes response.
Instead, the request is routed for manual processing by our treasury desk to secure the most competitive rate available.
Content Negotiation
Clients must use the HTTP Accept header to indicate the desired response format:
- Set
Accept: application/jsonfor JSON responses (default) - Set
Accept: text/csvfor CSV responses If the Accept header is omitted,application/jsonis assumed.
Base URL:
All API requests use the versioned base URL:
https://api.bcbank.us/v1/fx-quotes
Validation Rules
- Currencies must be valid three-letter ISO 4217 codes
- Unit currency and currency of transfer must be different
- Instructed amount must be a valid decimal number with up to 2 decimal places
Sample Request in JavaScript:
// Get FX quote for converting 100 USD to EUR
const getFxQuote = async (unitCurrency, currencyOfTransfer, instructedAmount) => {
try {
const response = await fetch(
'https://api.bcbank.us/v1/fx-quotes?' +
new URLSearchParams({
unitCurrency: unitCurrency,
currencyOfTransfer: currencyOfTransfer,
instructedAmount: instructedAmount
}), {
method: 'GET',
headers: {
'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
});
// Check if the response is ok (status in the range 200-299)
if (!response.ok) {
// Parse error response
const errorData = await response.json();
throw new Error(`Error ${response.status}: ${errorData.error} - ${errorData.message}`);
}
// Parse successful response
const quote = await response.json();
// Log the complete quote details
console.log('FX Quote Details:');
console.log(`Source Currency: ${quote.sourceCurrency.currency}`);
console.log(`Source Amount: ${quote.sourceCurrency.amount}`);
console.log(`Target Currency: ${quote.targetCurrency.currency}`);
console.log(`Target Amount: ${quote.targetCurrency.amount}`);
console.log(`Exchange Rate: ${quote.exchangeRate}`);
console.log(`Quote Expires: ${new Date(quote.expiryDateTime).toLocaleString()}`);
// Return the processed quote
return {
...quote,
// Add formatted values for display
formattedSourceAmount: new Intl.NumberFormat('en-US', {
style: 'currency',
currency: quote.sourceCurrency.currency
}).format(quote.sourceCurrency.amount),
formattedTargetAmount: new Intl.NumberFormat('en-US', {
style: 'currency',
currency: quote.targetCurrency.currency
}).format(quote.targetCurrency.amount)
};
} catch (error) {
// Handle different types of errors
if (error.name === 'TypeError') {
console.error('Network error:', error.message);
} else {
console.error('API error:', error.message);
}
throw error; // Re-throw to let caller handle it
}
};
// Example usage with error handling:
try {
const quote = await getFxQuote('USD', 'EUR', '100.00');
console.log('Formatted Quote:', quote.formattedSourceAmount, '→', quote.formattedTargetAmount);
} catch (error) {
console.error('Failed to get FX quote:', error.message);
}
Required Permission: get-fx-quote
This endpoint requires the permission claim get-fx-quote 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.
Request parameters
query requiredCurrency that will be converted from. Must be a valid 3-letter ISO currency code (e.g., USD, EUR, GBP).
string
query requiredCurrency that will be converted to. Must be a valid 3-letter ISO currency code (e.g., USD, EUR, GBP). Must be different from the unit currency.
string
query requiredThe amount to be converted from the unit currency. Must be a valid decimal number with up to 2 decimal places (e.g., "100.00").
string
Responses
OK - The request was successful. Returns the FX quote details
object requiredThe source currency and amount.
Show properties
string requiredCurrency ISO code
string requiredAmount
object requiredThe target currency and amount.
Show properties
string requiredCurrency ISO code
string requiredAmount
string The expiry date and time of the quote, expressed in UTC and formatted per ISO 8601 (yyyy-MM-ddTHH:mm:ssZ).
number requiredThe exchange rate for the currency conversion.
Request sample
curl --request GET \ --url 'https://api-uat.bcbank.us/v1/fx-quotes' \ --header 'Authorization: Bearer YOUR_ACCESS_TOKEN'
Response sample
{
"sourceCurrency": {
"currency": "string",
"amount": "string"
},
"targetCurrency": {
"currency": "string",
"amount": "string"
},
"expiryDateTime": "string",
"exchangeRate": 0
}Internal Transfers
Operationspost/v1/internal-transfersInternal Transfer
Internal Transfer
Initiates an internal funds transfer between two accounts within the institution. The request must include source and destination account details, along with the amount and currency to be transferred. Optionally, clients may provide a transaction reference and remittance information describing the purpose of the payment.
- debitAccountNumber: The account number from which funds will be debited.
- debitAmountCurrency: The currency code for the debit amount. Must match the credit account currency.
- creditAccountNumber: The account number to be credited.
- creditAmountCurrency: The currency code for the credit amount. Must match the debit account currency.
- debitAmount: The amount to be transferred.
- endToEndIdentification: (Optional) A unique reference provided by the client to identify the transaction end-to-end.
- remittanceInformation: (Optional) Free-text remittance information describing the purpose of the transaction.
Important Notes:
- Transfers between accounts with different currencies are not allowed. The debit and credit account currencies must match.
- Ensure all inputs are validated and the source account has sufficient funds before making the request.
High-Value Exchange Requests (> 100 000 BMD)
If the requested exchange amount exceeds 100 000 BMD, the POST /v1/transfers/internal endpoint will not return an immediate confirmation.
Instead, the request is routed for manual processing by our treasury desk to secure the most competitive rate available.
Idempotency
The API supports idempotency through the optional Idempotency-Key header:
- If no idempotency key is provided, the request is processed normally (duplicates are possible)
- If a valid UUID idempotency key is provided for a new transaction, the system stores the key and associates it with the transaction results
- If the same idempotency key is received again for the same endpoint/action, the system returns the previously stored response
- Idempotency keys are user-specific - different users with the same keys don't share cached responses
- The idempotency key must be a valid UUID format (e.g., "123e4567-e89b-12d3-a456-426614174000").
Content Negotiation
Clients must use the HTTP Accept header to indicate the desired response format:
- Set
Accept: application/jsonfor JSON responses (default). - Set
Accept: text/csvfor CSV responses. If the Accept header is omitted,application/jsonis assumed.
Base URL:
All API requests use the versioned base URL:
https://api.bcbank.us/v1/internal-transfers
Sample Request in JavaScript:
async function executeInternalTransfer() {
try {
const response = await fetch('https://api.bcbank.us/v1/internal-transfers', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
'Content-Type': 'application/json',
'Accept': 'application/json',
'Idempotency-Key': '123e4567-e89b-12d3-a456-426614174000' // Optional: UUID format required if provided
},
body: JSON.stringify({
debitAccountNumber: "12345678901234567890123456",
debitAmountCurrency: "USD",
creditAccountNumber: "98765432109876543210987654",
creditAmountCurrency: "USD", // Must match debitAmountCurrency
debitAmount: "100.00",
endToEndIdentification: "REF-INV-20250417-001", // Optional external transaction reference
remittanceInformationUnstructured: "Payment for invoice #12345" // Optional payment description
})
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(`Transfer failed: ${JSON.stringify(errorData)}`);
}
const data = await response.json();
console.log('Transfer result:', data);
// Example processing of the returned object
const { id, status, uniqueIdentifier, internalTransferDetails, linkedActivities } = data;
const { amountCredited, creditAmountCurrency, debitAmount, amountDebited, chargeAmount, valueDate, chargeAnalysisReceiver, chargeAnalysisSender, debitAccountNumber, creditAccountNumber, chargeAccountNumber } = internalTransferDetails;
// Log the main transfer details.
console.log('Transaction ID:', id);
console.log('Status:', status);
console.log('Unique Identifier:', uniqueIdentifier);
console.log('Amount Credited:', amountCredited.amount, amountCredited.currency);
console.log('Credit Amount Currency:', creditAmountCurrency);
console.log('Debit Amount:', debitAmount.amount, debitAmount.currency);
console.log('Amount Debited:', amountDebited.amount, amountDebited.currency);
console.log('Charge Amount:', chargeAmount.amount, chargeAmount.currency);
console.log('Value Date:', valueDate);
console.log('Charge Analysis Receiver:', chargeAnalysisReceiver);
console.log('Charge Analysis Sender:', chargeAnalysisSender);
// Process debit account information.
console.log('Debit Account Number:', debitAccountNumber.number);
if (debitAccountNumber.accountRoutings) {
debitAccountNumber.accountRoutings.forEach(routing => {
console.log('Debit Account Routing Scheme:', routing.scheme);
console.log('Debit Account Routing Address:', routing.address);
});
}
// Process credit account information.
console.log('Credit Account Number:', creditAccountNumber.number);
if (creditAccountNumber.accountRoutings) {
creditAccountNumber.accountRoutings.forEach(routing => {
console.log('Credit Account Routing Scheme:', routing.scheme);
console.log('Credit Account Routing Address:', routing.address);
});
}
// Process charge account information.
console.log('Charge Account Number:', chargeAccountNumber.number);
if (chargeAccountNumber.accountRoutings) {
chargeAccountNumber.accountRoutings.forEach(routing => {
console.log('Charge Account Routing Scheme:', routing.scheme);
console.log('Charge Account Routing Address:', routing.address);
});
}
// Process linked activities.
linkedActivities.forEach(activity => {
console.log('Linked Activity ID:', activity.id);
console.log('Linked Activity Transaction Status:', activity.transactionStatus);
console.log('Linked Activity Status:', activity.status);
console.log('Linked Activity Unique Identifier:', activity.uniqueIdentifier);
const { arrangementId, activityId, productId, currencyId, effectiveDate } = activity.activityDetails;
console.log('Linked Activity Arrangement ID:', arrangementId);
console.log('Linked Activity Activity ID:', activityId);
console.log('Linked Activity Product ID:', productId);
console.log('Linked Activity Currency ID:', currencyId);
console.log('Linked Activity Effective Date:', effectiveDate);
});
// Final status logging.
if (status === 'SUCCESS') {
console.log('The transfer was successful.');
} else {
console.log('The transfer failed:', status);
}
} catch (error) {
console.error('Error executing internal transfer:', error);
}
}
executeInternalTransfer();
Required Permission: internal-transfer
This endpoint requires the permission claim internal-transfer 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.
Request body application/json
string requiredThe account number from which the money will be taken. Please ensure this account has enough funds before initiating the transfer.
string requiredGets or sets the currency code of the debit amount. Exactly 3 letters (ISO 4217).
string The account number of the recipient's account.
string requiredThe currency code for the credit amount, such as "USD", "EUR", etc. Exactly 3 letters (ISO 4217).
string requiredThe amount of money to be debited from the sender's account and credited to the recipient's account. Ensure the amount does not exceed the available balance in the debit account.
string Reference provided by the client to identify the transaction end-to-end.
string Free-text remittance information provided by the client, describing the purpose of the transaction.
Responses
The transfer was created successfully.
string requiredUnique identifier for the internal transfer
string requiredThe current processing status of the transaction, e.g. Completed, Pending, Failed
string requiredUnique identifier specific to this instance of the internal transfer
object requiredTransfer data
Show properties
object requiredAmount that has been deposited into or added to a recipient's account
Show properties
string requiredCurrency ISO code
string requiredAmount
string requiredCredit amount currency
object requiredAmount that was intended to be transferred or paid, not including any additional fees or charges. It's the raw amount before any processing fees or other costs are added.
Show properties
string requiredCurrency ISO code
string requiredAmount
object requiredThe total amount that has been debited from an account. This includes any and all deductions that have been finalized and processed out of an account.
Show properties
string requiredCurrency ISO code
string requiredAmount
object requiredSum of money that is charged as a fee or cost associated with a financial transaction
Show properties
string requiredCurrency ISO code
string requiredAmount
string requiredDate on which the transaction is officially settled, meaning the funds are considered to have been transferred legally and are available for use by the recipient
string Refers to the analysis or breakdown of charges that are applied to the receiver or beneficiary of an internal transfer.
string Refers to the breakdown or details of charges that are applied to the sender of a transaction
object requiredUnique identifier of a bank account from which funds are being withdrawn or debited
Show properties
string requiredAccount number
array requiredAccount routing details
Show properties
arraystring requiredScheme value
string requiredAddress value
object requiredUnique identifier of a bank account that is set to receive funds
Show properties
string requiredAccount number
array requiredAccount routing details
Show properties
arraystring requiredScheme value
string requiredAddress value
object Bank account number from which fees associated with a transaction are debited
Show properties
string requiredAccount number
array requiredAccount routing details
Show properties
arraystring requiredScheme value
string requiredAddress value
array requiredList of related financial activities
Show properties
arraystring requiredThe unique identifier for the activity.
string requiredThe current processing status of the transaction.
string requiredThe general status of the activity.
string A unique identifier specific to this instance of the activity.
object requiredDetailed information about the activity.
Show properties
string requiredUnique identifier for the arrangement associated with this activity.
string requiredIdentifier for the type of activity.
string requiredProduct identifier related to the activity.
string requiredCurrency code for the activity.
string requiredDate when the activity becomes effective.
Request sample
curl --request POST \
--url 'https://api-uat.bcbank.us/v1/internal-transfers' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"endToEndIdentification": "REF-INV-20250417-001",
"remittanceInformation": "Payment for invoice #12345",
"debitAccountNumber": 987654321098765,
"debitAmountCurrency": "USD",
"creditAccountNumber": 123456789012345,
"creditAmountCurrency": "USD",
"debitAmount": 100
}'Response sample
{
"id": "string",
"status": "string",
"uniqueIdentifier": "string",
"internalTransferDetails": {
"amountCredited": {
"currency": {},
"amount": {}
},
"creditAmountCurrency": "string",
"debitAmount": {
"currency": {},
"amount": {}
},
"amountDebited": {
"currency": {},
"amount": {}
},
"chargeAmount": {
"currency": {},
"amount": {}
},
"valueDate": "string",
"chargeAnalysisReceiver": "string",
"chargeAnalysisSender": "string",
"debitAccountNumber": {
"number": {},
"accountRoutings": {}
},
"creditAccountNumber": {
"number": {},
"accountRoutings": {}
},
"chargeAccountNumber": {
"number": {},
"accountRoutings": {}
}
},
"linkedActivities": [
{
"id": "string",
"transactionStatus": "string",
"status": "string",
"uniqueIdentifier": "string",
"activityDetails": {
"arrangementId": {},
"activityId": {},
"productId": {},
"currencyId": {},
"effectiveDate": {}
}
}
]
}Investments
Operationsget/v1/investments/ordersList Investment Orders
List Investment Orders
Retrieves the customer's orders, newest first with a deterministic tie-break.
Filtering
Optional portfolioCode is exact and case-sensitive (maximum 50 characters).
Optional clientReference is exact after trimming (maximum 100 characters before trimming).
Optional status selects the current public status, including PendingCancellation.
Failed can include a partially executed order whose remaining quantity was cancelled while its fills await settlement.
Executed quantity and average price remain in the response; the order can later become Completed.
fromDate and toDate are independent inclusive UTC bounds on createdAt.
When both are supplied, fromDate must not exceed toDate and the span must not exceed one calendar year.
An unknown or non-owned portfolio returns an empty list; an unknown customer returns 404.
Pagination
This endpoint uses numeric pagination.
- First page: Omit
pageStartor pass1. It is a 1-based page number;0is invalid. - Page size:
pageSizedefaults to100; the allowed range is1–1000. - Next page: Increase
pageStartby1and send the samepageSizeand filters. - Page token: Do not send
pageToken; it is unsupported.meta.pagination.page_tokenis empty. - Response:
meta.pagination.page_startis the current page number,meta.pagination.page_sizeis the page size, andmeta.pagination.total_sizeis the total number of matching orders, including orders omitted because they cannot be represented in the response. - Last page: Using the response metadata, stop when
page_start * page_size >= total_size. A short or empty page does not necessarily mean the end because some orders may be omitted from the response. - Beyond the last page: Returns
200 OKwith an emptydataarray. - Ordering: Newest creation time first, then highest OMS order ID for orders with the same creation time. Pages are read separately; concurrent changes can shift results between pages.
Content Negotiation
Use Accept: application/json (default) or Accept: text/csv.
Base URL
GET https://api.bcbank.us/v1/investments/orders
Sample Request in JavaScript
const response = await fetch('https://api.bcbank.us/v1/investments/orders?pageStart=1&pageSize=25', {
headers: { 'Authorization': 'Bearer YOUR_ACCESS_TOKEN', 'Accept': 'application/json' }
});
const orders = await response.json();
Required Permission: read-investments
This endpoint requires the permission claim read-investments 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.
Request parameters
query Optional exact, case-sensitive portfolio code; maximum 50 characters.
string
query Optional exact client reference, trimmed before matching; maximum 100 characters before trimming.
string
query Optional current order status.
string Describes the externally observable state of an investment order. Allowed: Accepted, PendingApproval, Working, PartiallyFilled, Filled, Completed, Cancelled, Rejected, Failed, PendingCancellation
query Optional inclusive UTC creation date lower bound.
string
query Optional inclusive UTC creation date upper bound; at most one calendar year after fromDate when both are supplied.
string
query string
query integer (int32)
query integer (int32)
Responses
OK - The order page was retrieved.
object Show properties
object Show properties
integer requiredstring integer requiredinteger requiredarray Show properties
arraystring requiredstring Optional client-supplied correlation reference stored when the order was created.
string requiredstring requiredobject requiredIdentifies the security associated with an order.
Show properties
string requiredstring string requiredstring requiredSpecifies whether an order purchases or sells a security.
Allowed: Buy, Sell
string requiredSpecifies how the order price is determined.
Allowed: Market, Limit
number requirednumber string requiredSpecifies how long an unfilled order remains eligible for execution.
Allowed: Day, GoodTillCancelled, ImmediateOrCancel, FillOrKill
string requiredDescribes the externally observable state of an investment order.
Allowed: Accepted, PendingApproval, Working, PartiallyFilled, Filled, Completed, Cancelled, Rejected, Failed, PendingCancellation
number requirednumber string requiredstring requiredobject Show properties
string requiredDescribes a safe, categorized reason for an order rejection.
Allowed: RejectedByApprover, Other
string requiredRequest sample
curl --request GET \ --url 'https://api-uat.bcbank.us/v1/investments/orders' \ --header 'Authorization: Bearer YOUR_ACCESS_TOKEN'
Response sample
{
"meta": {
"pagination": {
"page_start": {},
"page_token": {},
"total_size": {},
"page_size": {}
}
},
"data": [
{
"orderReference": "string",
"clientReference": "string",
"portfolioCode": "string",
"accountNumber": "string",
"security": {
"isin": "string",
"symbol": "string",
"name": "string"
},
"side": "Buy",
"orderType": "Market",
"quantity": 0,
"limitPrice": 0,
"timeInForce": "Day",
"status": "Accepted",
"filledQuantity": 0,
"averagePrice": 0,
"createdAt": "string",
"updatedAt": "string",
"rejectionReason": {
"code": "RejectedByApprover",
"message": {}
}
}
]
}post/v1/investments/ordersPlace Investment Order
Place Investment Order
Submits a buy or sell order for a security identified by ISIN, using the authenticated customer's
portfolio and account. Send a JSON request to POST /v1/investments/orders.
Order Instructions
portfolioCodeandaccountNumberare required and must not exceed 50 characters each. They must identify an active portfolio and account belonging to the customer; the account must belong to the portfolio.security.isinis required and must be a valid 12-character ISIN. The security must be tradable.- Supply
sideexplicitly asBuyorSell, andorderTypeasMarketorLimit. quantitymust be positive and satisfy the security's trading rules.- For a
Limitorder,limitPriceis required and must be positive. For aMarketorder, omit it or send null. - Supply
timeInForceexplicitly asDay,GoodTillCancelled,ImmediateOrCancel, orFillOrKill.
Client Reference
clientReference is an optional client-supplied reference for tracking and reconciliation.
- It may be omitted or null. Empty or whitespace-only values are stored as null.
- The supplied value must not exceed 100 characters, including surrounding whitespace; longer values return
400 Bad Request. - Surrounding whitespace is trimmed. Casing and internal characters are preserved.
- It is fixed at creation and returned in the acceptance and order-detail responses when present.
- Duplicates are allowed. Reusing a client reference does not prevent another order from being created.
Acceptance and Tracking
202 Accepted means the order was persisted and the required funds or securities were reserved.
Acceptance does not guarantee execution; approval or further processing may still be required.
The JSON response contains the server-generated UUID orderReference, the stored clientReference
when present, the current status, and createdAt.
Follow the Location response header to retrieve the order and poll its current status.
orderReference identifies one order; clientReference is customer-provided correlation metadata.
Idempotency
The Idempotency-Key header is optional. Use a nonblank key of at most 256 characters to enable replay.
While a successful response remains cached, reusing the key on this endpoint in the same caller scope
returns that response and its Location header. Replay is keyed by the header, not by the request body
or clientReference; use a new key for every new order, including orders with identical instructions.
If the same keyed request is still being processed, the endpoint may return 409 Conflict.
A timeout does not establish whether the order was created. clientReference alone does not make a retry idempotent.
Required Permission: create-investments
This endpoint requires the permission claim create-investments 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.
Request parameters
header Optional replay key. Reusing the key returns the original response and Location; use GET for the current order state.
string
Request body application/json
string Optional client-supplied correlation reference, at most 100 characters. Surrounding whitespace is trimmed and blank values become null. Duplicates are allowed. Fixed at creation; separate from orderReference and the Idempotency-Key header.
string requiredstring requiredobject requiredIdentifies the security to order.
Show properties
string requiredInternational Securities Identification Number.
string requiredSpecifies whether an order purchases or sells a security.
Allowed: Buy, Sell
string requiredSpecifies how the order price is determined.
Allowed: Market, Limit
number requirednumber string requiredSpecifies how long an unfilled order remains eligible for execution.
Allowed: Day, GoodTillCancelled, ImmediateOrCancel, FillOrKill
Responses
Accepted - The order was accepted for processing; the response includes its references, status, and creation time.
string requiredstring Optional client-supplied correlation reference stored when the order was created.
string requiredDescribes the externally observable state of an investment order.
Allowed: Accepted, PendingApproval, Working, PartiallyFilled, Filled, Completed, Cancelled, Rejected, Failed, PendingCancellation
string requiredRequest sample
curl --request POST \
--url 'https://api-uat.bcbank.us/v1/investments/orders' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"clientReference": "string",
"portfolioCode": "string",
"accountNumber": "string",
"security": {
"isin": "string"
},
"side": "Buy",
"orderType": "Market",
"quantity": 0,
"limitPrice": 0,
"timeInForce": "Day"
}'Response sample
{
"orderReference": "0198f0a3-7c4e-7d21-9c30-6f0b1d2e3a44",
"clientReference": "Mobile-AbC-001",
"status": "Accepted",
"createdAt": "2026-09-01T12:30:00.0000000+02:00"
}post/v1/investments/orders/{orderReference}/cancelCancel Investment Order
Cancel Investment Order
Requests cancellation of an Accepted, PendingApproval, Working, or PartiallyFilled order.
Partial fills remain part of the order. The request has no body.
Response and Polling
202 Accepted returns the current order and a Location pointing to its GET route.
Acceptance does not guarantee cancellation. Poll Location while the status is PendingCancellation.
It can resolve to Cancelled, another terminal state, or a working state after cancellation rejection.
A racing execution can make the 202 response already terminal. Persistent uncertainty requires support.
Repeating while pending returns current state without another cancellation attempt.
Already-cancelled orders return 202; other terminal states at the initial check return 409 ORDER_NOT_CANCELLABLE.
A rejected request returns 400 ORDER_CANCEL_REJECTED; temporarily unavailable cancellation returns 503.
Cancellation after a partial fill
Cancelling the remainder does not undo executed fills. For example, if 3 of 10 shares execute
at 100 and the remaining 7 are cancelled, the response retains filledQuantity: 3 and averagePrice: 100.
The order can report Failed while those fills await settlement, then Completed after settlement.
Failed does not necessarily mean that nothing executed, and a successful cancellation does not always produce Cancelled.
Idempotency
The optional Idempotency-Key is a nonblank key of at most 256 characters. Reusing it replays the original response and Location;
use GET to retrieve the latest state. An identical request still in progress can return 409.
Base URL
POST https://api.bcbank.us/v1/investments/orders/{orderReference}/cancel
Sample Request in JavaScript
const response = await fetch(`https://api.bcbank.us/v1/investments/orders/${orderReference}/cancel`, {
method: 'POST', headers: { 'Authorization': 'Bearer YOUR_ACCESS_TOKEN', 'Idempotency-Key': crypto.randomUUID() }
});
Required Permission: create-investments
This endpoint requires the permission claim create-investments 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.
Request parameters
path requiredThe customer-owned order UUID.
string (guid)
header Optional replay key. Reusing the key returns the original response and Location; use GET for the current order state.
string
Responses
Accepted - The cancellation request was accepted.
string requiredstring Optional client-supplied correlation reference stored when the order was created.
string requiredstring requiredobject requiredIdentifies the security associated with an order.
Show properties
string requiredstring string requiredstring requiredSpecifies whether an order purchases or sells a security.
Allowed: Buy, Sell
string requiredSpecifies how the order price is determined.
Allowed: Market, Limit
number requirednumber string requiredSpecifies how long an unfilled order remains eligible for execution.
Allowed: Day, GoodTillCancelled, ImmediateOrCancel, FillOrKill
string requiredDescribes the externally observable state of an investment order.
Allowed: Accepted, PendingApproval, Working, PartiallyFilled, Filled, Completed, Cancelled, Rejected, Failed, PendingCancellation
number requirednumber string requiredstring requiredobject Show properties
string requiredDescribes a safe, categorized reason for an order rejection.
Allowed: RejectedByApprover, Other
string requiredRequest sample
curl --request POST \
--url 'https://api-uat.bcbank.us/v1/investments/orders/{orderReference}/cancel' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN'Response sample
{
"orderReference": "string",
"clientReference": "string",
"portfolioCode": "string",
"accountNumber": "string",
"security": {
"isin": "string",
"symbol": "string",
"name": "string"
},
"side": "Buy",
"orderType": "Market",
"quantity": 0,
"limitPrice": 0,
"timeInForce": "Day",
"status": "Accepted",
"filledQuantity": 0,
"averagePrice": 0,
"createdAt": "string",
"updatedAt": "string",
"rejectionReason": {
"code": "RejectedByApprover",
"message": "string"
}
}get/v1/investments/positionsList Investment Positions
List Investment Positions
Retrieves a paginated list of investment positions associated with the authenticated customer. Each item represents one security position in one portfolio.
Filtering
portfolioCodeis optional, case-insensitive, and must not exceed 50 characters.- If
portfolioCodeis omitted, the endpoint returns positions from all associated portfolios. - If the customer exists but no positions match, the endpoint returns
200 OKwith an emptydataarray. - If the investment customer does not exist, the endpoint returns
404 Not Found.
Pagination
This endpoint uses numeric pagination.
- First page: Omit
pageStartor pass1. It is a 1-based page number;0is invalid. - Page size:
pageSizedefaults to100; the allowed range is1–1000. - Next page: Increase
pageStartby1and send the samepageSizeand filters. - Page token: This endpoint does not use
pageToken.meta.pagination.page_tokenis empty. - Response:
meta.pagination.page_startis the current page number,meta.pagination.page_sizeis the page size, andmeta.pagination.total_sizeis the total number of matching positions. - Last page: Using the response metadata, stop when
page_start * page_size >= total_size. - Beyond the last page: Returns
200 OKwith an emptydataarray. - Ordering: Portfolio code, then security ISIN, then symbol. Pages are read separately; concurrent changes can shift results between pages.
Content Negotiation
Clients must use the HTTP Accept header to select the response format:
- Set
Accept: application/jsonfor JSON responses (default). - Set
Accept: text/csvfor CSV responses. If the Accept header is omitted,application/jsonis assumed.
Base URL
All API requests use the versioned base URL:
https://api.bcbank.us/v1/investments/positions
Sample Request in JavaScript
const url = new URL('https://api.bcbank.us/v1/investments/positions');
url.searchParams.set('portfolioCode', 'PTF-001');
url.searchParams.set('pageStart', '1');
url.searchParams.set('pageSize', '25');
const response = await fetch(url, {
headers: {
'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
'Accept': 'application/json'
}
});
if (!response.ok) {
throw new Error(`Request failed with status ${response.status}`);
}
const positions = await response.json();
Required Permission: read-investments
This endpoint requires the permission claim read-investments 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.
Request parameters
query Optional portfolio filter. When supplied, only holdings in this portfolio are returned. Max 50 characters.
string
query integer (int32)
query integer (int32)
Responses
OK - The request was successful.
object Show properties
object Show properties
integer requiredstring integer requiredinteger requiredarray Show properties
arrayobject requiredPortfolio that contains the position.
Show properties
string requiredCustomer-visible portfolio code.
string requiredDescriptive portfolio name.
object requiredSecurity held in the portfolio.
Show properties
string International Securities Identification Number, when available.
string Trading symbol, when available (e.g. "AAPL").
string requiredDescriptive name of the security.
string Specifies the classification of an investment security.
Allowed: Shares, Bonds, Mutual Funds, Other
string Exchange on which the security is listed, when available.
string Specifies how a security price is quoted.
Allowed: PerUnit, PercentageOfPar
number requiredNominal number of units held.
number Net number of units currently available after unsettled and blocked quantities. The value can be negative.
number Quantity from purchases that have not settled, when available.
number Quantity from sales that have not settled, when available.
number Quantity that is blocked and unavailable for transactions, when available.
number Total cost of the position including commission, when available.
number Average executed price including commission, expressed using the security's price convention, when available.
number Latest market price, expressed using the security's price convention. Null when a valuation is not available.
number Current market value of the holding. Null when a valuation is not available.
number Change in market price from the previous close, expressed using the security's price convention, when available.
number Percentage change in market price from the previous close, when available.
number Unrealized profit or loss based on market value and cost basis, when available.
number Unrealized profit or loss as a percentage of cost basis, when available.
string requiredISO 4217 currency the monetary fields are expressed in.
string Date and time of the market price, including its UTC offset, when available.
Request sample
curl --request GET \ --url 'https://api-uat.bcbank.us/v1/investments/positions' \ --header 'Authorization: Bearer YOUR_ACCESS_TOKEN'
Response sample
{
"meta": {
"pagination": {
"page_start": {},
"page_token": {},
"total_size": {},
"page_size": {}
}
},
"data": [
{
"portfolio": {
"code": {},
"name": {}
},
"security": {
"isin": {},
"symbol": {},
"name": {},
"assetClass": "Shares",
"exchange": {},
"priceConvention": "PerUnit"
},
"quantity": 0,
"availableQuantity": 0,
"unsettledBuyQuantity": 0,
"unsettledSellQuantity": 0,
"blockedQuantity": 0,
"costBasis": 0,
"averageCost": 0,
"marketPrice": 0,
"marketValue": 0,
"priceChange": 0,
"priceChangePercentage": 0,
"unrealizedProfitLoss": 0,
"unrealizedProfitLossPercentage": 0,
"currency": "string",
"priceAsOf": "string"
}
]
}get/v1/investments/tradesList Investment Trades
List Investment Trades
Retrieves a paginated list of settled investment trades associated with the authenticated customer. Each item represents one completed purchase or sale.
Trade reference and dates
transactionReferenceis the reference assigned to the trade.tradeDateis the execution date andsettlementDateis the settlement date. Both useYYYY-MM-DDformat without a time component.transactionDateis the recorded transaction date and time in UTC, for example2026-08-24T10:30:00+00:00. Fractional seconds are preserved when present.- Unavailable dates are
nullin JSON and omitted from CSV.transactionDateis not inferred fromcreatedAtwhen unavailable.
Filtering
portfolioCodeis required, case-insensitive, and must not exceed 50 characters.- If the portfolio does not exist, is not associated with the customer, or has no trades, the endpoint returns
200 OKwith an emptydataarray. - If the investment customer does not exist, the endpoint returns
404 Not Found.
Pagination
This endpoint uses cursor pagination.
- First page: Omit
pageStartor pass1. It is a 1-based page number;0is invalid. OmitpageTokenon the first request. - Page size:
pageSizedefaults to100; the allowed range is1–1000. Set it on the first request. - Next page: Increase
pageStartby1, send the returnedmeta.pagination.page_tokenaspageTokenunchanged, keep the same filters, and omitpageSize; the token carries the page size. - Page token:
pageTokenmust not exceed100characters. - Response:
meta.pagination.page_startis the current page number,meta.pagination.page_sizeis the page size, andmeta.pagination.total_sizeis the total number of trades in the portfolio. - Last page: Using the response metadata, stop when
page_start * page_size >= total_size.
Content Negotiation
Clients must use the HTTP Accept header to select the response format:
- Set
Accept: application/jsonfor JSON responses (default). - Set
Accept: text/csvfor CSV responses. If the Accept header is omitted,application/jsonis assumed.
Base URL
All API requests use the versioned base URL:
https://api.bcbank.us/v1/investments/trades
Sample Request in JavaScript
const url = new URL('https://api.bcbank.us/v1/investments/trades');
url.searchParams.set('portfolioCode', '2000592-1');
url.searchParams.set('pageStart', '1');
url.searchParams.set('pageSize', '25');
const response = await fetch(url, {
headers: {
'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
'Accept': 'application/json'
}
});
if (!response.ok) {
throw new Error(`Request failed with status ${response.status}`);
}
const trades = await response.json();
Required Permission: read-investments
This endpoint requires the permission claim read-investments 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.
Request parameters
query requiredRequired portfolio code. Only trades in this portfolio are returned. Max 50 characters.
string
query string
query integer (int32)
query integer (int32)
Responses
OK - The request was successful.
object Show properties
object Show properties
integer requiredstring integer requiredinteger requiredarray Show properties
arraystring requiredTransaction reference assigned to the trade.
object requiredPortfolio associated with the trade.
Show properties
string requiredCustomer-visible portfolio code.
string requiredDescriptive portfolio name.
object requiredSettlement account associated with the trade.
Show properties
string requiredCustomer-visible settlement account number.
string Descriptive settlement account name, when available.
object requiredSecurity bought or sold.
Show properties
string International Securities Identification Number, when available.
string Trading symbol, when available (e.g. "AAPL").
string requiredDescriptive name of the security.
string Specifies the classification of an investment security.
Allowed: Shares, Bonds, Mutual Funds, Other
string Exchange on which the security is listed, when available.
string Specifies how a security price is quoted.
Allowed: PerUnit, PercentageOfPar
string requiredSpecifies whether an investment trade is a purchase or sale.
Allowed: Buy, Sell
number requiredNumber of security units associated with the trade.
number Price expressed using the security's price convention. Null when a price is unavailable.
number Gross value calculated as quantity multiplied by price, before commission and handling fee. Null when a price is unavailable.
string requiredISO 4217 currency of the price, total, commission, and handling fee.
number Bank commission charged for the trade, when available.
number Handling fee charged for the trade, when available. Zero represents a waived fee.
string requiredSpecifies the public settlement status of an investment trade.
Allowed: Settled
string requiredDate and time at which the trade instruction was created, including its UTC offset.
string Date the trade was executed, in YYYY-MM-DD format without a time component. Null when unavailable.
string Settlement date, in YYYY-MM-DD format without a time component. Null when unavailable.
string Recorded transaction date and time in UTC, in ISO 8601 format with a +00:00 offset and fractional seconds when present. Null when unavailable; not inferred from createdAt.
Request sample
curl --request GET \ --url 'https://api-uat.bcbank.us/v1/investments/trades' \ --header 'Authorization: Bearer YOUR_ACCESS_TOKEN'
Response sample
{
"meta": {
"pagination": {
"page_start": {},
"page_token": {},
"total_size": {},
"page_size": {}
}
},
"data": [
{
"transactionReference": "string",
"portfolio": {
"code": {},
"name": {}
},
"account": {
"number": {},
"name": {}
},
"security": {
"isin": {},
"symbol": {},
"name": {},
"assetClass": "Shares",
"exchange": {},
"priceConvention": "PerUnit"
},
"side": "Buy",
"quantity": 0,
"price": 0,
"total": 0,
"currency": "string",
"commission": 0,
"handlingFee": 0,
"status": "Settled",
"createdAt": "string",
"tradeDate": "string",
"settlementDate": "string",
"transactionDate": "string"
}
]
}get/v1/investments/orders/{orderReference}Get Investment Order
Get Investment Order
Retrieves one order owned by the authenticated customer using
GET /v1/investments/orders/{orderReference}. Use the UUID returned by placement or follow
the Location header from the acceptance response.
References and Response
The response includes the order instructions, security, aggregate fill quantity and average price,
current status, and creation and update times. clientReference contains the normalized reference
supplied at creation, when present; orders created without one have no client reference.
This route accepts the server-generated orderReference UUID. Use the list-orders endpoint
to filter by clientReference.
Status Values
Accepted: accepted for processing; execution has not yet been acknowledged.PendingApproval: awaiting approval before further processing.Working: acknowledged for execution, with no fills reported yet.PartiallyFilled: part of the requested quantity has been executed.PendingCancellation: a cancellation request is unresolved; cancellation is not guaranteed.Filled: the requested quantity has been executed; final processing may still be pending.Completed: execution and final processing have completed.Cancelled: the remaining order has been cancelled; any reported fills remain part of the order.Rejected: the order was rejected.rejectionReasonprovides a public code and message.Failed: the order's state cannot be represented by another public status. This includes a partially executed order whose remainder was cancelled while its fills await settlement.
Cancelling the remainder does not undo fills. For example, 3 of 10 shares execute at 100 and
the remaining 7 are cancelled: filledQuantity remains 3 and averagePrice remains 100.
The order can report Failed while those fills await settlement, then Completed after settlement.
A successful GET returns 200 OK even when the order status is Rejected or Failed.
Unknown references and orders outside the customer's scope return 404 Not Found.
Required Permission: read-investments
This endpoint requires the permission claim read-investments 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.
Request parameters
path requiredThe server-generated order UUID returned by placement, separate from the optional client reference.
string (guid)
Responses
OK - The order details were retrieved.
string requiredstring Optional client-supplied correlation reference stored when the order was created.
string requiredstring requiredobject requiredIdentifies the security associated with an order.
Show properties
string requiredstring string requiredstring requiredSpecifies whether an order purchases or sells a security.
Allowed: Buy, Sell
string requiredSpecifies how the order price is determined.
Allowed: Market, Limit
number requirednumber string requiredSpecifies how long an unfilled order remains eligible for execution.
Allowed: Day, GoodTillCancelled, ImmediateOrCancel, FillOrKill
string requiredDescribes the externally observable state of an investment order.
Allowed: Accepted, PendingApproval, Working, PartiallyFilled, Filled, Completed, Cancelled, Rejected, Failed, PendingCancellation
number requirednumber string requiredstring requiredobject Show properties
string requiredDescribes a safe, categorized reason for an order rejection.
Allowed: RejectedByApprover, Other
string requiredRequest sample
curl --request GET \
--url 'https://api-uat.bcbank.us/v1/investments/orders/{orderReference}' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN'Response sample
{
"orderReference": "string",
"clientReference": "string",
"portfolioCode": "string",
"accountNumber": "string",
"security": {
"isin": "string",
"symbol": "string",
"name": "string"
},
"side": "Buy",
"orderType": "Market",
"quantity": 0,
"limitPrice": 0,
"timeInForce": "Day",
"status": "Accepted",
"filledQuantity": 0,
"averagePrice": 0,
"createdAt": "string",
"updatedAt": "string",
"rejectionReason": {
"code": "RejectedByApprover",
"message": "string"
}
}Public Keys
Operationsget/v1/.well-known/jwks.jsonGets the bank's current signing public key.
Gets the bank's current signing public key.
Gets the bank’s current signing public key in JWKS format. Returns a JWKS containing one RSA key with fields:
- kid: rsa-{keyVersion}
- kty: RSA
- alg: PS256
- use: sig
- n/e: base64url-encoded modulus and exponent This endpoint requires OpenBankApi authorization; no private key material is exposed.
Responses
JWKS payload with the active signing key.
array requiredCollection of JSON Web Keys (JWK). Only one key is expected.
Show properties
arraystring requiredKey type. Always "RSA" for this endpoint.
string requiredIntended use of the key. "sig" indicates signature verification.
string requiredAlgorithm used with the key. "PS256" indicates RSA-PSS with SHA-256.
string requiredKey identifier in the form "rsa-{version}".
string requiredBase64Url-encoded RSA modulus.
string requiredBase64Url-encoded RSA public exponent (typically "AQAB").
Request sample
curl --request GET \ --url 'https://api-uat.bcbank.us/v1/.well-known/jwks.json' \ --header 'Authorization: Bearer YOUR_ACCESS_TOKEN'
Response sample
{
"keys": [
{
"kty": "RSA",
"use": "sig",
"alg": "PS256",
"kid": "rsa-v1",
"n": "u8Jx7zV9KkWlZqS5qZ1e8E6-hwFkZl0ob8BZqC5JxW0SP-L9c7szw1Zcrw1xwqXkDFFG8sUiDqJcVQnI-AVS4fRNn2drXr6IJuE5i2jxEwHkJq9e-3KifxHbK7WfG5A0yXspwxvzI8vEOwUlTta_yYB5kAEV1kZkH6yN2V_2Q7vJz0ZfM_kqfC1M3G2aCQ6U7gCgN_Qmfrj7q6kP2zR9a7vSg9QZyYxBrS_ImV1LhNWDKqHeX5vKQ1CW6m6Qd4y9P7Q",
"e": "AQAB"
}
]
}Token
Operationspost/auth/tokenGenerate Token
Generate Token
Generates a JWT access token based on provided client credentials. Use this POST endpoint to authenticate using your clientId and clientSecret and receive a JWT token.
Token Validity: 40 minutes from the time of issuance.
Endpoint: https://api.bcbank.us/auth/token
Required Headers:
Content-Type: application/jsonAccept: application/json
Sample Request in JavaScript:
async function getToken() {
try {
const response = await fetch('https://api.bcbank.us/auth/token', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify({
clientId: 'your-client-id',
clientSecret: 'your-client-secret'
})
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(`Error: ${errorData.message || response.statusText}`);
}
const data = await response.json();
console.log('JWT Token:', data.token);
// Store token securely
localStorage.setItem('jwt', data.token);
} catch (error) {
console.error('Fetch error:', error);
}
}
getToken();
Request body application/json
string requiredThe client ID assigned by the authorization server.
string requiredThe client secret assigned by the authorization server.
Responses
Token generated successfully.
string requiredGets or sets the JWT token.
string requiredGets or sets the expiration date and time of the token.
Request sample
curl --request POST \
--url 'https://api-uat.bcbank.us/auth/token' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"clientId": "your-client-id-here",
"clientSecret": "your-client-secret-here"
}'Response sample
{
"token": "string",
"expiration": "string"
}Transactions
Operationsget/v1/accounts/{accountNumber}/transactionsAccount Transactions
Account Transactions
Retrieves transaction details for the specified account and date range. This endpoint:
- Validates the provided date parameters. The accepted date formats are
yyyy-MM-ddoryyyyMMdd. - Maximum date range is one year.
- Supports both JSON and CSV response formats based on the Accept header.
- Supports cursor-based pagination for efficient handling of large transaction datasets.
Transaction ID Uniqueness
Important: Transaction IDs are globally unique across the entire banking system. For internal transfers, the same transaction ID appears on both accounts (debit and credit entries) with only the transaction type differing. When fees apply, multiple entries may share the same transaction ID.
📖 For detailed information about transaction ID behavior, see: https://developers.bcbank.us/guides/transaction-id-uniqueness-guide
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 apageToken. - Subsequent Requests: Use the
pageTokenfrom previous responses withpageStartto navigate pages. - Page Token: Contains encoded pagination context including pageSize, so don't specify
pageSizein 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/jsonfor JSON responses (default) - Set
Accept: text/csvfor CSV responses If the Accept header is omitted,application/jsonis assumed.
Base URL
All API requests use the versioned base URL:
https://api.bcbank.us/v1/accounts/{accountNumber}/transactions
Sample Request in JavaScript
async function getAllTransactionsPaginated(accountNumber, fromDate, toDate) {
try {
let allTransactions = [];
let pageStart = 1;
let pageToken = null;
let totalPages = 0;
do {
// Build URL with pagination parameters
let url = `https://api.bcbank.us/v1/accounts/${accountNumber}/transactions`;
const params = new URLSearchParams();
// Always include date range
params.append('fromDate', fromDate);
params.append('toDate', toDate);
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());
}
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 transactions from this page
if (data.data && data.data.length > 0) {
allTransactions.push(...data.data);
console.log(`Collected ${data.data.length} transactions from page ${pageStart}`);
}
pageStart++;
} while (pageStart <= totalPages);
console.log(`Total transactions collected: ${allTransactions.length}`);
// Process all collected transactions
allTransactions.forEach((transaction, index) => {
console.log(`Transaction ${index + 1}:`, transaction.id);
console.log('Account Number:', transaction.thisAccount.number);
console.log('Other Account Number:', transaction.otherAccount.number);
console.log('Type:', transaction.details.type);
console.log('Description:', transaction.details.description);
console.log('Posted Date:', transaction.details.posted);
console.log('Amount:', transaction.details.value.amount);
console.log('Currency:', transaction.details.value.currency);
console.log('Narrative:', transaction.metadata.narrative);
if (transaction.transactionAttributes && transaction.transactionAttributes.length > 0) {
transaction.transactionAttributes.forEach(attribute => {
console.log(`${attribute.name}: ${attribute.value}`);
});
}
});
return allTransactions;
} catch (error) {
console.error('There was a problem with the fetch operation:', error.message);
throw error;
}
}
// Alternative: Get single page of transactions
async function getTransactionsPage(accountNumber, fromDate, toDate, pageStart = 1, pageToken = null) {
try {
let url = `https://api.bcbank.us/v1/accounts/${accountNumber}/transactions`;
const params = new URLSearchParams();
// Always include date range
params.append('fromDate', fromDate);
params.append('toDate', toDate);
if (pageStart === 1 && !pageToken) {
params.append('pageSize', '250'); // Custom page size
} else {
params.append('pageToken', pageToken);
params.append('pageStart', pageStart.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('Transactions page:', data);
return data;
} catch (error) {
console.error('There was a problem with the fetch operation:', error.message);
throw error;
}
}
// Example usage:
getAllTransactionsPaginated('1234567890', '2023-01-25', '2023-02-25'); // Retrieves all transactions across multiple pages
// OR
getTransactionsPage('1234567890', '2023-01-25', '2023-02-25', 1).then(firstPage => {
console.log('First page:', firstPage);
// Use firstPage.meta.pagination.page_token for subsequent requests
});
Required Permission: get-transactions
This endpoint requires the permission claim get-transactions 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.
Request parameters
path requiredThe account number to retrieve transactions for.
string
query requiredThe start date for the transaction range (format: yyyy-MM-dd).
string
query requiredThe end date for the transaction range (format: yyyy-MM-dd).
string
query string
query integer (int32)
query integer (int32)
Responses
OK - The request was successful.
object Show properties
object Show properties
integer requiredstring integer requiredinteger requiredarray Show properties
arraystring requiredA unique ID of the transaction
object requiredAccount associated with the transaction
Show properties
string requiredAccount number
array requiredAccount routing details
Show properties
arraystring requiredScheme value
string requiredAddress value
object Refers to the counter-party's account in a transaction
Show properties
string requiredAccount number
array requiredAccount routing details
Show properties
arraystring requiredScheme value
string requiredAddress value
object requiredProvides further transaction details
Show properties
string requiredBalance type, in a coded form.
string requiredTransaction description
string requiredDate and time when a transaction entry is posted to an account on the account servicer's books
string requiredDate and time at which assets become available to the account owner in case of a credit entry, or cease to be available to the account owner in case of a debit transaction entry.
object New balance after a transaction entry is posted to an account on the account servicer's books
Show properties
string requiredCurrency ISO code
string requiredAmount
object requiredAmount of money in the transaction entry
Show properties
string requiredCurrency ISO code
string requiredAmount
object requiredProvides transaction metadata
Show properties
string Provide additional details about the transaction
array requiredAdditional details or characteristics associated with an transaction object.
Show properties
arraystring requiredrefers to a specific property or characteristic associated with the transaction, such as "amount" or "transaction_type".
string requiredCorresponds to the actual data or content assigned to that particular property, e.g., "100.00" for "amount" or "debit" for "transaction_type"
Request sample
curl --request GET \
--url 'https://api-uat.bcbank.us/v1/accounts/{accountNumber}/transactions' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN'Response sample
{
"meta": {
"pagination": {
"page_start": {},
"page_token": {},
"total_size": {},
"page_size": {}
}
},
"data": [
{
"id": "string",
"thisAccount": {
"number": {},
"accountRoutings": {}
},
"otherAccount": {
"number": {},
"accountRoutings": {}
},
"details": {
"type": {},
"description": {},
"posted": {},
"completed": {},
"newBalance": {},
"value": {}
},
"metadata": {
"narrative": {}
},
"transactionAttributes": [
{
"name": {},
"value": {}
}
]
}
]
}Virtual Accounts
Operationspost/v1/virtual-accounts/balancesGet Virtual Account Balances
Get Virtual Account Balances
Retrieves balances for a provided list of virtual account numbers. This endpoint:
- Accepts a JSON payload with one or more
accountNumbers - Returns a JSON envelope with
metaanddatafields - Supports both JSON and CSV response formats based on the Accept header
- Pagination: This endpoint does not accept pagination parameters
Required Request Properties
- accountNumbers: Array of virtual account numbers (minimum 1, maximum 1000)
Response shape
datais an array of{ accountNumber, balance { currency, amount } }
Content Negotiation
Clients must use the HTTP Accept header to indicate the desired response format:
- Set
Accept: application/jsonfor JSON responses (default) - Set
Accept: text/csvfor CSV responses If the Accept header is omitted,application/jsonis assumed.
Base URL
All API requests use the versioned base URL:
https://api.bcbank.us/v1/virtual-accounts/balances
Sample Request in JavaScript
async function getVirtualAccountBalances(accountNumbers) {
const response = await fetch('https://api.bcbank.us/v1/virtual-accounts/balances', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify({ accountNumbers })
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(`Failed to retrieve balances: ${JSON.stringify(errorData)}`);
}
const result = await response.json();
// result.data is an array of balances
result.data.forEach(item => {
console.log(item.accountNumber, item.balance?.amount, item.balance?.currency);
});
return result;
}
// Example usage:
getVirtualAccountBalances(['1000331038', '1000331062']);
Required Permission: get-virtual-account-transactions
This endpoint requires the permission claim get-virtual-account-transactions 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.
Request body application/json
array requiredVirtual account numbers to retrieve balances for.
Show properties
arraystring
Responses
OK - The request was successful.
object Show properties
object Show properties
integer requiredstring integer requiredinteger requiredarray Show properties
arraystring requiredVirtual account number.
object requiredCurrent balance of the virtual account.
Show properties
string requiredCurrency ISO code
string requiredAmount
Request sample
curl --request POST \
--url 'https://api-uat.bcbank.us/v1/virtual-accounts/balances' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"accountNumbers": [
1000331038,
1000331062
]
}'Response sample
{
"meta": {
"pagination": {
"page_start": 0,
"page_token": null,
"total_size": 0,
"page_size": 0
}
},
"data": [
{
"accountNumber": 1000331038,
"balance": {
"currency": "USD",
"amount": 192.98
}
},
{
"accountNumber": 1000331062,
"balance": {
"currency": "USD",
"amount": 0
}
}
]
}get/v1/virtual-accounts/balances/totalGet Virtual Account Balances Total
Get Virtual Account Balances Total
Retrieves the total balance across all virtual accounts. This endpoint:
- Returns a single object
{ currency, amount }(one record) - Supports both JSON and CSV response formats based on the Accept header
- Pagination: This endpoint does not accept pagination parameters
Sample Response (JSON)
{
"currency": "USD",
"amount": "6755.67"
}
Content Negotiation
Clients must use the HTTP Accept header to indicate the desired response format:
- Set
Accept: application/jsonfor JSON responses (default) - Set
Accept: text/csvfor CSV responses If the Accept header is omitted,application/jsonis assumed.
Base URL
All API requests use the versioned base URL:
https://api.bcbank.us/v1/virtual-accounts/balances/total
Sample Request in JavaScript
async function getVirtualAccountBalancesTotal() {
const response = await fetch('https://api.bcbank.us/v1/virtual-accounts/balances/total', {
method: 'GET',
headers: {
'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
'Accept': 'application/json'
}
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(`Failed to retrieve total balance: ${JSON.stringify(errorData)}`);
}
const result = await response.json();
console.log(result.data?.amount, result.data?.currency);
return result;
}
Required Permission: get-virtual-account-transactions
This endpoint requires the permission claim get-virtual-account-transactions 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.
Responses
OK - The request was successful.
string requiredCurrency ISO code
string requiredAmount
Request sample
curl --request GET \ --url 'https://api-uat.bcbank.us/v1/virtual-accounts/balances/total' \ --header 'Authorization: Bearer YOUR_ACCESS_TOKEN'
Response sample
{
"currency": "USD",
"amount": 6755.67
}post/v1/virtual-accountsCreate Virtual Accounts
Create Virtual Accounts
Creates one or more virtual (sub) accounts for a corporate client. Virtual accounts allow funds to be segregated and tracked independently while remaining linked to a single settlement account.
Migration notice: v1 is being retained for backward compatibility only and is planned to be discontinued in the future.
New integrations should use POST /v2/virtual-accounts and existing consumers should plan their migration to v2.
Schema scope: v1 supports currency, accountHolderName, accountName, optional dob,
optional nativeLanguageName, optional unallocated, and optional clientReference.
Use v2 when you need nationality, taxIdentificationNumber, or countryOfResidence at create time.
Required Request Properties
- items: Array of virtual account creation requests (minimum 1, maximum 1000)
- currency: ISO-4217 currency code for the virtual account (e.g., USD, BMD)
- accountHolderName: Human-readable label for the virtual account (required unless
unallocatedis true). Immutable after first update. - accountName: Official account title that will appear on statements (required unless
unallocatedis true). Immutable after first update. - Allowed characters (accountHolderName, accountName): A-Z, a-z, 0-9, space, and
! " # $ % & ' ( ) + , - . / [ \ ]. Common symbols such as* _ @ : ; ? { }are not allowed.
Optional Request Properties
- unallocated: When set to
true, creates the account in "for allocation" mode with placeholder values ("UNALLOCATED") foraccountHolderNameandaccountName. This allows bulk pre-creation of virtual accounts for later assignment to end-customers via a one-time PATCH update. - dob: Date of birth of the account holder, if applicable. Immutable after first update.
- nativeLanguageName: Native name of the account holder's language, if applicable (max 255 characters). Immutable after first update.
- callbackUrl: URL to receive notifications when the batch job completes (optional)
- clientReference: External reference provided by the client to aid reconciliation (max 35 characters) - per item
- customHeaders: Object of string key/value pairs to be echoed back in the completion callback. Limits: up to 10 headers; each key ≤ 50 characters; each value ≤ 500 characters.
Unallocated Accounts
Operationally, clients often need to pre-create many virtual accounts to allocate later. The unallocated flag enables a safe "for allocation" mode:
- Creates accounts with generic placeholder values: "UNALLOCATED" for
accountHolderNameandaccountName - When
unallocatedistrue, theaccountHolderNameandaccountNamefields become optional - Allows a one-time update via PATCH when the account is assigned to a real end-customer
- Important: The following fields are immutable after the first update:
accountHolderName,accountName,dob, andnativeLanguageName
Asynchronous Processing
Virtual account creation requests are processed asynchronously to ensure optimal performance and reliability:
- Immediate Response: You receive a job ID and status URLs immediately upon submission
- Status Monitoring: Use the provided status URL to monitor job progress
- Result Retrieval: Use the provided result URL to fetch final outcomes when complete
- Callback Notifications: Optionally provide a callback URL for automatic notifications after the job completes
Message Signing
Callback notifications are signed. When your client configuration enables response signing, callbacks use the asymmetric option (RSA-PSS + SHA-256) and include Bcb-Signature, Bcb-Timestamp, Bcb-Nonce, and Bcb-Signature-Version (e.g., rsa-v1). If asymmetry is not configured, callbacks use the HMAC option with your Message Signing Secret and no Bcb-Signature-Version header. See the Message Signing guide for verification steps.
Virtual Account Structure
Each successfully created virtual account will contain the following properties:
{
"virtualAccountNumber": "1000327642",
"bicCode": "BPBKBMHMXXX",
"bicCodeFx": "BEOEBMH2",
"accountHolderName": "T1 Project Alpha Escrow",
"accountName": "New Title T2",
"currency": "USD",
"balance": {
"amount": "0",
"currency": "USD"
},
"category": "CMS Sub Acct"
}
Job Status Tracking
The response includes URLs for monitoring your batch job:
- Status URL: Poll this URL to check job progress and completion status
- Result URL: Access this URL to retrieve detailed results for each virtual account
- Job ID: Unique identifier for tracking your batch job
Content Negotiation
Clients must use the HTTP Accept header to indicate the desired response format:
- Set
Accept: application/jsonfor JSON responses (default) - Set
Accept: text/csvfor CSV responses If the Accept header is omitted,application/jsonis assumed.
Base URL
All API requests use the versioned base URL:
https://api.bcbank.us/v1/virtual-accounts
Idempotency
The API supports idempotency through the optional Idempotency-Key header:
- If no idempotency key is provided, the request is processed normally (duplicates are possible)
- If a valid UUID idempotency key is provided, the system stores the key and associates it with the batch job
- If the same idempotency key is received again, the system returns the previously stored response
- Idempotency keys are user-specific - different users with the same keys don't share cached responses
- The idempotency key must be a valid UUID format (e.g., "123e4567-e89b-12d3-a456-426614174000")
Sample Request in JavaScript
async function createVirtualAccounts() {
try {
const response = await fetch('https://api.bcbank.us/v1/virtual-accounts', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
'Content-Type': 'application/json',
'Accept': 'application/json',
'Idempotency-Key': '123e4567-e89b-12d3-a456-426614174000' // Optional
},
body: JSON.stringify({
callbackUrl: 'https://my-callback-url.com', // Optional
// Optional: custom headers echoed in the completion webhook
customHeaders: {
'X-Custom-Header-1': 'CustomValue1',
'X-Custom-Header-2': 'CustomValue2',
'X-Custom-Header-3': 'CustomValue3'
},
items: [
{
currency: 'USD',
accountHolderName: 'Test Company Ltd',
accountName: 'Test Virtual Account 001',
clientReference: 'BATCH-REF-001'
},
{
currency: 'USD',
accountHolderName: 'Test Company Ltd',
accountName: 'Test Virtual Account 002',
clientReference: 'BATCH-REF-002'
},
// Example: Pre-create unallocated accounts for later assignment
{
currency: 'USD',
unallocated: true,
clientReference: 'UNALLOC-001'
}
]
})
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(`Virtual account creation failed: ${JSON.stringify(errorData)}`);
}
// Parse JSON response
const batchResponse = await response.json();
// Display batch job information
console.log('Batch Job Created:');
console.log(` Job ID: ${batchResponse.jobId}`);
console.log(` Status: ${batchResponse.status}`);
console.log(` Status URL: ${batchResponse.statusUrl}`);
console.log(` Result URL: ${batchResponse.resultUrl}`);
// Store these URLs for monitoring the job
// Use statusUrl to check progress
// Use resultUrl to get final outcomes
return batchResponse;
} catch (error) {
console.error('Failed to create virtual accounts:', error.message);
throw error;
}
}
// Example usage:
// Create multiple virtual accounts
createVirtualAccounts();
Required Permission: create-virtual-account
This endpoint requires the permission claim create-virtual-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.
Request body application/json
string Optional URL to receive asynchronous notifications about the async job processing status.
object Optional custom headers to include in the account creation request. It will be sent back in callbacks. Max 10 headers, each key max 50 chars, each value max 500 chars
array requiredPayload containing the details of virtual accounts to be created in batch.
Show properties
arraystring requiredISO 4217 currency code for the virtual account (e.g., USD, EUR, BMD). Must be a supported currency by the bank.
string Human-readable nickname or label for the virtual account. Used for display purposes and client identification. Optional when Unallocated is true; otherwise required. Allowed characters: A-Z, a-z, 0-9, space, and ! " # $ % & ' ( ) + , - . / [ \ ]. Common characters such as * _ @ : ; ? { } are not allowed.
string Official account name as it will appear on statements and official documents. This is the formal name of the virtual account. Optional when Unallocated is true; otherwise required. Allowed characters: A-Z, a-z, 0-9, space, and ! " # $ % & ' ( ) + , - . / [ \ ]. Common characters such as * _ @ : ; ? { } are not allowed.
string Client-provided reference identifier for tracking and identification purposes. This reference should be unique within the client's system for easier reconciliation.
string Date of birth of the account holder, if applicable.
string Native name of the account holder's language, if applicable.
boolean requiredIndicates whether the virtual account is pre-created for future allocation. When set to true, the account is created in "for allocation" mode with placeholder values ("UNALLOCATED") for AccountHolderName and AccountName, which become optional. This allows clients to bulk-create virtual accounts and later perform a one-time update to assign them to real end-customers.
Responses
Accepted - Virtual account creation job has been queued for processing.
string requiredUnique identifier assigned to the batch job.
string requiredCurrent lifecycle state of the batch job (e.g.Pending, InProgress, Completed, CompletedWithErrors, Cancelled).
string requiredAbsolute URL that can be polled to retrieve up-to-date job status information.
string requiredAbsolute URL to obtain the final per-item results once the job has completed.
Request sample
curl --request POST \
--url 'https://api-uat.bcbank.us/v1/virtual-accounts' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"callbackUrl": "https://my-callback-url.com",
"customHeaders": {
"X-Custom-Header-1": "Custom Value 1",
"X-Custom-Header-2": "Custom Value 2"
},
"items": [
{
"currency": "USD",
"accountHolderName": null,
"accountName": null,
"clientReference": "BATCH-UNALLOC-001",
"dob": null,
"nativeLanguageName": null,
"unallocated": true
},
{
"currency": "USD",
"accountHolderName": "Test Company Ltd",
"accountName": "Test Virtual Account 001",
"clientReference": "BATCH-REF-001",
"dob": "1990-01-01T00:00:00.0000000",
"nativeLanguageName": "Native Name",
"unallocated": false
},
{
"currency": "USD",
"accountHolderName": "Test Company Ltd",
"accountName": "Test Virtual Account 002",
"clientReference": "BATCH-REF-002",
"dob": null,
"nativeLanguageName": null,
"unallocated": false
},
{
"currency": "USD",
"accountHolderName": "Test Company Ltd",
"accountName": "Test Virtual Account 003",
"clientReference": "BATCH-REF-003",
"dob": null,
"nativeLanguageName": null,
"unallocated": false
}
]
}'Response sample
{
"jobId": "550e8400-e29b-41d4-a716-446655440001",
"status": "Pending",
"statusUrl": "https://api.bcbank.us/v1/jobs/550e8400-e29b-41d4-a716-446655440001",
"resultUrl": "https://api.bcbank.us/v1/jobs/550e8400-e29b-41d4-a716-446655440001/results"
}get/v1/virtual-accountsGet All Virtual Accounts
Get All Virtual Accounts
Retrieves all virtual accounts for the authenticated corporate client. This endpoint:
- Returns a paginated list of virtual accounts for the client
- Response contains the client’s real (non-virtual) accounts as well:
- Settlement Account – the primary clearing account used for cash movements. Account category: "CMS Settlement".
- Parent Account – the parent account under which all virtual accounts are organised. Account category: "CMS Parent Cate".
- Virtual accounts have the category "CMS Sub Acct".
- Supports optional currency filtering to return only accounts in a specific currency
- Supports pagination for efficient handling of large account datasets
Filtering
Use the optional currency query parameter to filter results:
- Must be a valid 3-letter ISO currency code (e.g., USD, BMD, EUR)
- If omitted, accounts in all currencies are returned
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 apageToken. - Subsequent Requests: Use the
pageTokenfrom previous responses withpageStartto navigate pages. - Page Token: Contains encoded pagination context including pageSize, so don't specify
pageSizein 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/jsonfor JSON responses (default) - Set
Accept: text/csvfor CSV responses If the Accept header is omitted,application/jsonis assumed.
Base URL
All API requests use the versioned base URL:
https://api.bcbank.us/v1/virtual-accounts
Sample Request in JavaScript
async function getAllVirtualAccounts(currency = null, pageSize = 25, pageStart = 1, pageToken = null) {
try {
// Build URL with optional parameters
let url = 'https://api.bcbank.us/v1/virtual-accounts';
const params = new URLSearchParams();
if (currency) {
params.append('currency', currency);
}
if (pageStart === 1 && !pageToken) {
// First request only: optionally specify pageSize
params.append('pageSize', pageSize.toString());
} else {
// Subsequent requests: use pageToken + pageStart and do NOT send pageSize again
params.append('pageToken', pageToken);
params.append('pageStart', pageStart.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(`Virtual accounts retrieval failed: ${JSON.stringify(errorData)}`);
}
// Parse JSON response
const result = await response.json();
// Access pagination info
const pagination = result.meta.pagination;
console.log(`Page: ${pagination.page_start}, Size: ${pagination.page_size}, Total: ${pagination.total_size}`);
// Process virtual accounts
result.data.forEach((account, index) => {
console.log(`Account ${index + 1}:`);
console.log(` Virtual Account Number: ${account.virtualAccountNumber}`);
console.log(` BIC: ${account.bicCode}`);
console.log(` BIC (FX): ${account.bicCodeFx}`);
console.log(` Account Holder: ${account.accountHolderName}`);
console.log(` Account Name: ${account.accountName}`);
console.log(` Currency: ${account.currency}`);
console.log(` Balance: ${account.balance ? account.balance.amount + ' ' + account.balance.currency : 'N/A'}`);
console.log(` Category: ${account.category}`);
if (account.clientReference) {
console.log(` Client Reference: ${account.clientReference}`);
}
if (account.effectiveDate) {
console.log(` Effective Date: ${account.effectiveDate}`);
}
if (account.createdAt) {
console.log(` Created At: ${account.createdAt}`);
}
// Log parent/settlement account relationships
if (account.parentAccount) {
console.log(` Parent Account: ${account.parentAccount.accountNumber} (${account.parentAccount.accountName})`);
}
if (account.settlementAccount) {
console.log(` Settlement Account: ${account.settlementAccount.accountNumber} (${account.settlementAccount.accountName})`);
}
console.log('---');
});
return result;
} catch (error) {
console.error('Failed to retrieve virtual accounts:', error.message);
throw error;
}
}
// Example usage:
// Get all virtual accounts
getAllVirtualAccounts();
// Get only USD virtual accounts
getAllVirtualAccounts('USD');
// Get first 10 virtual accounts
getAllVirtualAccounts(null, 10);
Required Permission: get-virtual-accounts
This endpoint requires the permission claim get-virtual-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.
Request parameters
query Optional. The currency of the virtual accounts to filter by. If not specified, all virtual accounts will be returned.
string
query string
query integer (int32)
query integer (int32)
Responses
OK - The request was successful.
object Show properties
object Show properties
integer requiredstring integer requiredinteger requiredarray Show properties
arraystring requiredAccount number for the virtual account
string requiredBIC (Bank Identifier Code)
string requiredBIC (Bank Identifier Code) used for FX transactions
string requiredOwner for the virtual account
string requiredVirtual account name as it appears on statements and official documents
string requiredISO 4217 currency code for the virtual account
object requiredCurrent balance of the virtual account
Show properties
string requiredCurrency ISO code
string requiredAmount
string requiredCategory or type of the (virtual) account, if applicable
string Client-provided reference identifier for the virtual account
string Date of birth of the account holder, if applicable.
string string string string Native name of the account holder's language, if applicable.
boolean requiredIndicates whether the virtual account is pre-created for future allocation.
Request sample
curl --request GET \ --url 'https://api-uat.bcbank.us/v1/virtual-accounts' \ --header 'Authorization: Bearer YOUR_ACCESS_TOKEN'
Response sample
{
"meta": {
"pagination": {
"page_start": {},
"page_token": {},
"total_size": {},
"page_size": {}
}
},
"data": [
{
"virtualAccountNumber": "string",
"bicCode": "string",
"bicCodeFx": "string",
"accountHolderName": "string",
"accountName": "string",
"currency": "string",
"balance": {
"currency": {},
"amount": {}
},
"category": "string",
"clientReference": "string",
"dob": "string",
"nationality": "string",
"taxIdentificationNumber": "string",
"countryOfResidence": "string",
"nativeLanguageName": "string",
"unallocated": true
}
]
}patch/v1/virtual-accounts/{virtualAccountNumber}Update Virtual Account
Update Virtual Account
Updates an existing virtual (sub) account for a corporate client. Only the fields provided in the request body will be updated.
Migration notice: v1 is being retained for backward compatibility only and is planned to be discontinued in the future.
New integrations should use PATCH /v2/virtual-accounts/{virtualAccountNumber} and existing consumers should plan their migration to v2.
Updatable Properties
- accountHolderName: Human-readable label for the virtual account. Immutable after first update – can only be changed once from the "UNALLOCATED" state.
- accountName: Official account title that will appear on statements. Immutable after first update – can only be changed once from the "UNALLOCATED" state.
- Allowed characters (accountHolderName, accountName): A-Z, a-z, 0-9, space, and
! " # $ % & ' ( ) + , - . / [ \ ]. Common symbols such as* _ @ : ; ? { }are not allowed. - dob: Date of birth of the account holder. Immutable after first update – can only be set once.
- nativeLanguageName: Native name of the account holder's language (max 255 characters). Immutable after first update – can only be set once.
- clientReference: External reference provided by the client to aid reconciliation (max 35 characters). This field can be updated multiple times.
Schema scope: v1 supports accountHolderName, accountName, dob, nativeLanguageName, and clientReference.
Use v2 when you need nationality, taxIdentificationNumber, or countryOfResidence.
Allocating Unallocated Accounts
For virtual accounts created with unallocated: true, use this endpoint to perform a one-time assignment to a real end-customer:
- Update
accountHolderName,accountName,dob, andnativeLanguageNamefrom their initial/placeholder values to the actual customer details - Important: This is a one-time operation. Once these fields are set, they become immutable:
accountHolderNameandaccountNamecan only be changed from "UNALLOCATED" statedobandnativeLanguageNamecan only be set once (if not provided during creation)
- Attempting to update immutable fields after the first update will result in a
409 Conflicterror with codeACCOUNT_NAMES_IMMUTABLE - Only
clientReferencecan be updated after allocation
Content Negotiation
Clients must use the HTTP Accept header to indicate the desired response format:
- Set
Accept: application/jsonfor JSON responses (default) - Set
Accept: text/csvfor CSV responses If the Accept header is omitted,application/jsonis assumed.
Base URL:
All API requests use the versioned base URL:
https://api.bcbank.us/v1/virtual-accounts
Idempotency
The API supports idempotency through the optional Idempotency-Key header:
- If no idempotency key is provided, the request is processed normally (duplicates are possible)
- If a valid UUID idempotency key is provided for a new transaction, the system stores the key and associates it with the transaction results
- If the same idempotency key is received again for the same endpoint/action, the system returns the previously stored response
- Idempotency keys are user-specific - different users with the same keys don't share cached responses
- The idempotency key must be a valid UUID format (e.g., "123e4567-e89b-12d3-a456-426614174000").
Sample Request (JavaScript)
async function updateVirtualAccount(virtualAccountNumber) {
try {
const response = await fetch(`https://api.bcbank.us/v1/virtual-accounts/${virtualAccountNumber}`, {
method: 'PATCH',
headers: {
'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify({
// Note: Only clientReference can be updated after first allocation
// accountHolderName, accountName, dob, and nativeLanguageName are immutable after first update
clientReference: 'updated-reference-123'
})
});
if (!response.ok) {
const errorData = await response.json();
// Handle immutable field error
if (response.status === 409 && errorData.code === 'ACCOUNT_NAMES_IMMUTABLE') {
console.error('Cannot update immutable fields - already set after first update');
return;
}
throw new Error(`Virtual account update failed: ${JSON.stringify(errorData)}`);
}
// Parse JSON response
const result = await response.json();
const virtualAccount = result.data;
// Log updated details
console.log('Virtual Account Updated Successfully:');
console.log(` Account Number: ${virtualAccount.virtualAccountNumber}`);
console.log(` Account Holder: ${virtualAccount.accountHolderName}`);
console.log(` Account Name: ${virtualAccount.accountName}`);
console.log(` Currency: ${virtualAccount.currency}`);
console.log(` Category: ${virtualAccount.category}`);
if (virtualAccount.balance) {
console.log(` Balance: ${virtualAccount.balance.amount} ${virtualAccount.balance.currency}`);
}
if (virtualAccount.clientReference) {
console.log(` Client Reference: ${virtualAccount.clientReference}`);
}
console.log(` Effective Date: ${virtualAccount.effectiveDate}`);
console.log(` Created: ${virtualAccount.createdAt}`);
// Log parent/settlement account info
if (virtualAccount.parentAccount) {
console.log(` Parent Account: ${virtualAccount.parentAccount.accountNumber} (${virtualAccount.parentAccount.accountSubType})`);
}
if (virtualAccount.settlementAccount) {
console.log(` Settlement Account: ${virtualAccount.settlementAccount.accountNumber} (${virtualAccount.settlementAccount.accountSubType})`);
}
return result;
} catch (err) {
console.error('Error updating virtual account:', err);
throw err;
}
}
// Example usage:
updateVirtualAccount('1000327642');
// Example: Allocating an unallocated account to a customer (ONE-TIME OPERATION)
async function allocateUnallocatedAccount(virtualAccountNumber, customerName, accountTitle, dob, nativeLanguageName) {
try {
const response = await fetch(`https://api.bcbank.us/v1/virtual-accounts/${virtualAccountNumber}`, {
method: 'PATCH',
headers: {
'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify({
// All these fields are immutable after this update!
accountHolderName: customerName,
accountName: accountTitle,
dob: dob, // Optional - immutable after set
nativeLanguageName: nativeLanguageName // Optional - immutable after set
})
});
if (!response.ok) {
const errorData = await response.json();
// Handle case where account was already allocated
if (response.status === 409 && errorData.code === 'ACCOUNT_NAMES_IMMUTABLE') {
throw new Error('Account has already been allocated. Immutable fields cannot be changed after first update.');
}
throw new Error(`Account allocation failed: ${JSON.stringify(errorData)}`);
}
const result = await response.json();
console.log('Account successfully allocated to:', customerName);
return result;
} catch (err) {
console.error('Error allocating account:', err);
throw err;
}
}
// Allocate a pre-created unallocated account (can only be done once!)
allocateUnallocatedAccount('1000327650', 'Acme Corporation', 'Acme Trading Account', '1990-05-15', 'John Smith');
Required Permission: update-virtual-account
This endpoint requires the permission claim update-virtual-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.
Request parameters
path requiredVirtual account identifier (ID) that uniquely identifies the virtual account
string
Request body application/json
object
string Virtual account name Used for display purposes and client identification. Allowed characters: A-Z, a-z, 0-9, space, and ! " # $ % & ' ( ) + , - . / [ \ ]. Common characters such as * _ @ : ; ? { } are not allowed.
string Official account title as it will appear on statements and official documents. This is the formal name of the virtual account. Allowed characters: A-Z, a-z, 0-9, space, and ! " # $ % & ' ( ) + , - . / [ \ ]. Common characters such as * _ @ : ; ? { } are not allowed.
string Client-provided reference identifier for tracking and identification purposes. This reference should be unique within the client's system for easier reconciliation.
string Date of birth of the account holder, if applicable.
string Native name of the account holder's language, if applicable.
Responses
Virtual account updated successfully.
string requiredAccount number for the virtual account
string requiredBIC (Bank Identifier Code)
string requiredBIC (Bank Identifier Code) used for FX transactions
string requiredOwner for the virtual account
string requiredVirtual account name as it appears on statements and official documents
string requiredISO 4217 currency code for the virtual account
object requiredCurrent balance of the virtual account
Show properties
string requiredCurrency ISO code
string requiredAmount
string requiredCategory or type of the (virtual) account, if applicable
string Client-provided reference identifier for the virtual account
string Date of birth of the account holder, if applicable.
string string string string Native name of the account holder's language, if applicable.
boolean requiredIndicates whether the virtual account is pre-created for future allocation.
string Date when the virtual account becomes effective (YYYY-MM-DD format)
string Date when the virtual account was created (ISO 8601 format). Bermuda Time Zone.
object Parent account summary
Show properties
string requiredA unique ID of the account, composed of account number and CIF
string required11-digit ID of the account holder
string requiredAccount number
string requiredSpecifies the status of the account
string requiredIdentification of the currency in which the account is held
object requiredAccount balance
Show properties
string requiredCurrency ISO code
string requiredAmount
string requiredSpecifies the sub type of account (product)
string Specifies the type of account (personal/business)
string The nickname of the account, assigned by the account owner
array requiredOwnership details of an account object
Show properties
arraystring requiredAccount owner name
string requiredType of account holder (Primary/Joint)
array requiredAdditional details or characteristics associated with an account object
Show properties
arraystring requiredKey or identifier of the account attribute.
string requiredActual data associated with the attribute name
object Settlement account summary
Show properties
string requiredA unique ID of the account, composed of account number and CIF
string required11-digit ID of the account holder
string requiredAccount number
string requiredSpecifies the status of the account
string requiredIdentification of the currency in which the account is held
object requiredAccount balance
Show properties
string requiredCurrency ISO code
string requiredAmount
string requiredSpecifies the sub type of account (product)
string Specifies the type of account (personal/business)
string The nickname of the account, assigned by the account owner
array requiredOwnership details of an account object
Show properties
arraystring requiredAccount owner name
string requiredType of account holder (Primary/Joint)
array requiredAdditional details or characteristics associated with an account object
Show properties
arraystring requiredKey or identifier of the account attribute.
string requiredActual data associated with the attribute name
Request sample
curl --request PATCH \
--url 'https://api-uat.bcbank.us/v1/virtual-accounts/{virtualAccountNumber}' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"accountHolderName": "Updated Project Alpha Escrow",
"accountName": "Updated Project Alpha Virtual Account",
"clientReference": "ref-1234567890",
"dob": "1990-05-15T00:00:00.0000000",
"nativeLanguageName": "Native Name"
}'Response sample
{
"virtualAccountNumber": "string",
"bicCode": "string",
"bicCodeFx": "string",
"accountHolderName": "string",
"accountName": "string",
"currency": "string",
"balance": {
"currency": "string",
"amount": "string"
},
"category": "string",
"clientReference": "string",
"dob": "string",
"nationality": "string",
"taxIdentificationNumber": "string",
"countryOfResidence": "string",
"nativeLanguageName": "string",
"unallocated": true,
"effectiveDate": "string",
"createdAt": "string",
"parentAccount": {
"accountId": "string",
"cif": "string",
"accountNumber": "string",
"status": "string",
"currency": "string",
"availableBalance": {},
"accountSubType": "string",
"accountType": "string",
"nickname": "string",
"owners": [
{}
],
"accountAttributes": [
{}
]
},
"settlementAccount": {
"accountId": "string",
"cif": "string",
"accountNumber": "string",
"status": "string",
"currency": "string",
"availableBalance": {},
"accountSubType": "string",
"accountType": "string",
"nickname": "string",
"owners": [
{}
],
"accountAttributes": [
{}
]
}
}get/v1/virtual-accounts/{virtualAccountNumber}Get Virtual Account Details
Get Virtual Account Details
Retrieves comprehensive information about a specific virtual account, including all its sub-accounts, parent account details, and settlement account information. This endpoint:
- Returns the virtual account details as a single object
- Includes parent account information (the account this virtual account is derived from)
- Provides settlement account details (the account used for settlement operations)
Content Negotiation
Clients must use the HTTP Accept header to indicate the desired response format:
- Set
Accept: application/jsonfor JSON responses (default) - Set
Accept: text/csvfor CSV responses If the Accept header is omitted,application/jsonis assumed.
Base URL
All API requests use the versioned base URL:
https://api.bcbank.us/v1/virtual-accounts/{accountNumber}
Sample Request in JavaScript
async function getVirtualAccountDetails(accountNumber) {
try {
const url = `https://api.bcbank.us/v1/virtual-accounts/${encodeURIComponent(accountNumber)}`;
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(`Virtual account details retrieval failed: ${JSON.stringify(errorData)}`);
}
// Parse JSON response
const result = await response.json();
// Get the virtual account details (single object, not an array)
const virtualAccount = result.data;
console.log('Virtual Account Details:');
console.log(` Account Number: ${virtualAccount.virtualAccountNumber}`);
console.log(` BIC: ${virtualAccount.bicCode}`);
console.log(` BIC (FX): ${virtualAccount.bicCodeFx}`);
console.log(` Account Holder: ${virtualAccount.accountHolderName}`);
console.log(` Account Name: ${virtualAccount.accountName}`);
console.log(` Currency: ${virtualAccount.currency}`);
console.log(` Category: ${virtualAccount.category}`);
if (virtualAccount.balance) {
console.log(` Balance: ${virtualAccount.balance.amount} ${virtualAccount.balance.currency}`);
}
console.log(` Effective Date: ${virtualAccount.effectiveDate}`);
console.log(` Created: ${virtualAccount.createdAt}`);
if (virtualAccount.clientReference) {
console.log(` Client Reference: ${virtualAccount.clientReference}`);
}
// Log parent account details
if (virtualAccount.parentAccount) {
console.log(' Parent Account:');
console.log(` Account Number: ${virtualAccount.parentAccount.accountNumber}`);
console.log(` Account ID: ${virtualAccount.parentAccount.accountId}`);
console.log(` CIF: ${virtualAccount.parentAccount.cif}`);
console.log(` Currency: ${virtualAccount.parentAccount.currency}`);
console.log(` Sub Type: ${virtualAccount.parentAccount.accountSubType}`);
console.log(` Status: ${virtualAccount.parentAccount.status}`);
if (virtualAccount.parentAccount.availableBalance) {
console.log(` Available Balance: ${virtualAccount.parentAccount.availableBalance.amount} ${virtualAccount.parentAccount.availableBalance.currency}`);
}
if (virtualAccount.parentAccount.owners && virtualAccount.parentAccount.owners.length > 0) {
console.log(` Owner: ${virtualAccount.parentAccount.owners[0].displayName} (${virtualAccount.parentAccount.owners[0].accountHolderType})`);
}
}
// Log settlement account details
if (virtualAccount.settlementAccount) {
console.log(' Settlement Account:');
console.log(` Account Number: ${virtualAccount.settlementAccount.accountNumber}`);
console.log(` Account ID: ${virtualAccount.settlementAccount.accountId}`);
console.log(` CIF: ${virtualAccount.settlementAccount.cif}`);
console.log(` Currency: ${virtualAccount.settlementAccount.currency}`);
console.log(` Sub Type: ${virtualAccount.settlementAccount.accountSubType}`);
console.log(` Status: ${virtualAccount.settlementAccount.status}`);
if (virtualAccount.settlementAccount.availableBalance) {
console.log(` Available Balance: ${virtualAccount.settlementAccount.availableBalance.amount} ${virtualAccount.settlementAccount.availableBalance.currency}`);
}
if (virtualAccount.settlementAccount.owners && virtualAccount.settlementAccount.owners.length > 0) {
console.log(` Owner: ${virtualAccount.settlementAccount.owners[0].displayName} (${virtualAccount.settlementAccount.owners[0].accountHolderType})`);
}
}
return result;
} catch (error) {
console.error('Failed to retrieve virtual account details:', error.message);
throw error;
}
}
// Example usage:
// Get details for a specific virtual account
getVirtualAccountDetails('1000326808');
Required Permission: get-a-virtual-account
This endpoint requires the permission claim get-a-virtual-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.
Request parameters
path requiredThe virtual account number assigned by the bank.
string
Responses
OK - The request was successful.
string requiredAccount number for the virtual account
string requiredBIC (Bank Identifier Code)
string requiredBIC (Bank Identifier Code) used for FX transactions
string requiredOwner for the virtual account
string requiredVirtual account name as it appears on statements and official documents
string requiredISO 4217 currency code for the virtual account
object requiredCurrent balance of the virtual account
Show properties
string requiredCurrency ISO code
string requiredAmount
string requiredCategory or type of the (virtual) account, if applicable
string Client-provided reference identifier for the virtual account
string Date of birth of the account holder, if applicable.
string string string string Native name of the account holder's language, if applicable.
boolean requiredIndicates whether the virtual account is pre-created for future allocation.
string Date when the virtual account becomes effective (YYYY-MM-DD format)
string Date when the virtual account was created (ISO 8601 format). Bermuda Time Zone.
object Parent account summary
Show properties
string requiredA unique ID of the account, composed of account number and CIF
string required11-digit ID of the account holder
string requiredAccount number
string requiredSpecifies the status of the account
string requiredIdentification of the currency in which the account is held
object requiredAccount balance
Show properties
string requiredCurrency ISO code
string requiredAmount
string requiredSpecifies the sub type of account (product)
string Specifies the type of account (personal/business)
string The nickname of the account, assigned by the account owner
array requiredOwnership details of an account object
Show properties
arraystring requiredAccount owner name
string requiredType of account holder (Primary/Joint)
array requiredAdditional details or characteristics associated with an account object
Show properties
arraystring requiredKey or identifier of the account attribute.
string requiredActual data associated with the attribute name
object Settlement account summary
Show properties
string requiredA unique ID of the account, composed of account number and CIF
string required11-digit ID of the account holder
string requiredAccount number
string requiredSpecifies the status of the account
string requiredIdentification of the currency in which the account is held
object requiredAccount balance
Show properties
string requiredCurrency ISO code
string requiredAmount
string requiredSpecifies the sub type of account (product)
string Specifies the type of account (personal/business)
string The nickname of the account, assigned by the account owner
array requiredOwnership details of an account object
Show properties
arraystring requiredAccount owner name
string requiredType of account holder (Primary/Joint)
array requiredAdditional details or characteristics associated with an account object
Show properties
arraystring requiredKey or identifier of the account attribute.
string requiredActual data associated with the attribute name
Request sample
curl --request GET \
--url 'https://api-uat.bcbank.us/v1/virtual-accounts/{virtualAccountNumber}' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN'Response sample
{
"virtualAccountNumber": "string",
"bicCode": "string",
"bicCodeFx": "string",
"accountHolderName": "string",
"accountName": "string",
"currency": "string",
"balance": {
"currency": "string",
"amount": "string"
},
"category": "string",
"clientReference": "string",
"dob": "string",
"nationality": "string",
"taxIdentificationNumber": "string",
"countryOfResidence": "string",
"nativeLanguageName": "string",
"unallocated": true,
"effectiveDate": "string",
"createdAt": "string",
"parentAccount": {
"accountId": "string",
"cif": "string",
"accountNumber": "string",
"status": "string",
"currency": "string",
"availableBalance": {},
"accountSubType": "string",
"accountType": "string",
"nickname": "string",
"owners": [
{}
],
"accountAttributes": [
{}
]
},
"settlementAccount": {
"accountId": "string",
"cif": "string",
"accountNumber": "string",
"status": "string",
"currency": "string",
"availableBalance": {},
"accountSubType": "string",
"accountType": "string",
"nickname": "string",
"owners": [
{}
],
"accountAttributes": [
{}
]
}
}post/v2/virtual-accountsCreate Virtual Accounts (V2)
Create Virtual Accounts (V2)
Creates one or more virtual (sub) accounts using the v2 request schema.
V2 difference: v2 introduces an accountHolderType discriminator (Individual | Business) and moves
the holder-specific KYC fields into nested individual / business objects. Only the block matching
accountHolderType may be supplied. Holder fields are required only for allocated accounts (unallocated = false).
clientReference, callback handling, and batch job semantics behave the same as v1.
Required Request Properties
- items: Array of virtual account creation requests (minimum 1, maximum 1000)
- currency: ISO-4217 currency code for the virtual account (e.g., USD, BMD)
- accountHolderName: Full legal name of the holder (required unless
unallocatedis true). Immutable after first update. - accountName: Account name that appears on statements (required unless
unallocatedis true). Immutable after first update. - Allowed characters (accountHolderName, accountName, address fields): A-Z, a-z, 0-9, space, and
! " # $ % & ' ( ) + , - . / [ \ ]. Common symbols such as* _ @ : ; ? { }are not allowed. - accountHolderType:
IndividualorBusiness. When omitted, the original v2 rule applies (individual.dob+individual.nationalityrequired when allocated). - For
Individual(allocated): individual.dob (ISO 8601 date, in the past and at least 18 years ago) and individual.nationality (ISO 3166-1 alpha-2) are required. Immutable after first update. - For
Business(allocated): business.registeredAddress is required with addressLine1, city, postalCode, and country (ISO 3166-1 alpha-2).business.dateOfIncorporationandbusiness.countryOfIncorporationare optional (sole traders / partnerships are not incorporated).
Optional Request Properties
- taxIdentificationNumber: Optional customer tax identifier (max 30 characters)
- countryOfResidence: Optional ISO 3166-1 alpha-2 country code
- individual.nativeLanguageName: Native name of the account holder's language, if applicable (max 255 characters). Immutable after first update.
- business.dateOfIncorporation / business.countryOfIncorporation: Optional even for a
Business; immutable after first update when set. - business.registeredAddress.addressLine2: Optional (max 70 characters).
addressLine1/addressLine2max 70;city/postalCodemax 35. - unallocated: When set to
true, creates the account in "for allocation" mode and defers the mandatory v2 holder fields until the one-time allocation PATCH. - callbackUrl: URL to receive notifications when the batch job completes (optional)
- clientReference: External reference provided by the client to aid reconciliation (max 35 characters) - per item
- customHeaders: Object of string key/value pairs to be echoed back in the completion callback. Limits: up to 10 headers; each key ≤ 50 characters; each value ≤ 500 characters.
Unallocated Accounts
When unallocated is true, the batch can pre-create accounts for later assignment.
The mandatory v2 holder fields (per accountHolderType) are enforced when the account is allocated via PATCH rather than during creation.
Asynchronous Processing
This endpoint queues a background job and immediately returns job tracking URLs.
Message Signing
Callback notifications are signed using the same rules and headers as v1.
Job Status Tracking
The response includes a job ID plus status and result URLs for monitoring completion.
Content Negotiation
Clients must use the HTTP Accept header to indicate the desired response format:
- Set
Accept: application/jsonfor JSON responses (default) - Set
Accept: text/csvfor CSV responses If the Accept header is omitted,application/jsonis assumed.
Base URL
All API requests use the versioned base URL:
https://api.bcbank.us/v2/virtual-accounts
Idempotency
Idempotency behaviour is identical to v1.
Required Permission: create-virtual-account
This endpoint requires the permission claim create-virtual-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.
Request body application/json
string object array requiredShow properties
arraystring requiredstring Human-readable nickname or label for the virtual account. Optional when Unallocated is true; otherwise required. Allowed characters: A-Z, a-z, 0-9, space, and ! " # $ % & ' ( ) + , - . / [ \ ]. Common characters such as * _ @ : ; ? { } are not allowed.
string Official account name as it will appear on statements and official documents. Optional when Unallocated is true; otherwise required. Allowed characters: A-Z, a-z, 0-9, space, and ! " # $ % & ' ( ) + , - . / [ \ ]. Common characters such as * _ @ : ; ? { } are not allowed.
string string string string Discriminator (Individual | Business) that selects the conditional KYC rules. When omitted, an allocated account is treated as an individual: individual.dob and individual.nationality are required.
object Individual holder details. Must be absent when AccountHolderType is Business.
Show properties
string Date of birth of the account holder. Required for an allocated individual.
string ISO 3166-1 alpha-2 nationality of the account holder. Required for an allocated individual.
string object Business holder details. Must be absent when AccountHolderType is Individual.
Show properties
string Date the business was incorporated. Optional; immutable after allocation.
string ISO 3166-1 alpha-2 country of incorporation. Optional; immutable after allocation.
object Registered / trading address. Required (line1 + city + postalCode + country) for an allocated business.
Show properties
string string string string string ISO 3166-1 alpha-2 country code of the registered address.
boolean requiredResponses
Accepted - Virtual account creation job has been queued for processing.
string requiredUnique identifier assigned to the batch job.
string requiredCurrent lifecycle state of the batch job (e.g.Pending, InProgress, Completed, CompletedWithErrors, Cancelled).
string requiredAbsolute URL that can be polled to retrieve up-to-date job status information.
string requiredAbsolute URL to obtain the final per-item results once the job has completed.
Request sample
curl --request POST \
--url 'https://api-uat.bcbank.us/v2/virtual-accounts' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"callbackUrl": "https://my-callback-url.com",
"customHeaders": {
"X-Custom-Header-1": "Custom Value 1",
"X-Custom-Header-2": "Custom Value 2"
},
"items": [
{
"currency": "USD",
"unallocated": true,
"clientReference": "BATCH-UNALLOC-V2-001"
},
{
"currency": "USD",
"accountHolderName": "Jonathan Michael Adebayo-Okoro",
"accountName": "Adebayo Trading",
"clientReference": "BATCH-V2-IND-001",
"taxIdentificationNumber": "TIN-001",
"countryOfResidence": "BM",
"accountHolderType": "Individual",
"individual": {
"dob": "1985-04-23",
"nationality": "HK",
"nativeLanguageName": "Native Name"
},
"unallocated": false
},
{
"currency": "USD",
"accountHolderName": "Titan Logistics Holdings Ltd",
"accountName": "Titan",
"clientReference": "BATCH-V2-BUS-001",
"taxIdentificationNumber": "98-7654321",
"accountHolderType": "Business",
"business": {
"dateOfIncorporation": "2014-09-30",
"countryOfIncorporation": "BM",
"registeredAddress": {
"addressLine1": "44 Front Street",
"addressLine2": "Suite 300",
"city": "Hamilton",
"postalCode": "HM 12",
"country": "BM"
}
},
"unallocated": false
}
]
}'Response sample
{
"jobId": "550e8400-e29b-41d4-a716-446655440001",
"status": "Pending",
"statusUrl": "https://api.bcbank.us/v1/jobs/550e8400-e29b-41d4-a716-446655440001",
"resultUrl": "https://api.bcbank.us/v1/jobs/550e8400-e29b-41d4-a716-446655440001/results"
}get/v2/virtual-accountsGet All Virtual Accounts (V2)
Get All Virtual Accounts (V2)
Identical to the v1 list endpoint, but returns the v2 read schema: holder KYC is nested under
accountHolderType + individual / business (with business.registeredAddress). taxIdentificationNumber
and countryOfResidence remain at the top level.
Required Permission: get-virtual-accounts
This endpoint requires the permission claim get-virtual-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.
Request parameters
query Optional. The currency of the virtual accounts to filter by. If not specified, all virtual accounts will be returned.
string
query string
query integer (int32)
query integer (int32)
Responses
OK - The request was successful.
object Show properties
object Show properties
integer requiredstring integer requiredinteger requiredarray Show properties
arraystring requiredstring requiredstring requiredstring requiredstring requiredstring requiredobject requiredShow properties
string requiredCurrency ISO code
string requiredAmount
string requiredstring string Optional customer tax identifier (max 30 characters).
string ISO 3166-1 alpha-2 country of residence.
boolean requiredstring Holder discriminator (Individual | Business), when set.
object Individual holder details. Populated only when AccountHolderType is Individual.
Show properties
string Date of birth of the account holder. Required for an allocated individual.
string ISO 3166-1 alpha-2 nationality of the account holder. Required for an allocated individual.
string object Business holder details. Populated only when AccountHolderType is Business.
Show properties
string Date the business was incorporated. Optional; immutable after allocation.
string ISO 3166-1 alpha-2 country of incorporation. Optional; immutable after allocation.
object Registered / trading address. Required (line1 + city + postalCode + country) for an allocated business.
Show properties
string string string string string ISO 3166-1 alpha-2 country code of the registered address.
Request sample
curl --request GET \ --url 'https://api-uat.bcbank.us/v2/virtual-accounts' \ --header 'Authorization: Bearer YOUR_ACCESS_TOKEN'
Response sample
{
"meta": {
"pagination": {
"page_start": 1,
"page_token": "202506234881430088.01,99",
"total_size": 3,
"page_size": 99
}
},
"data": [
{
"virtualAccountNumber": 1000327197,
"bicCode": "BPBKBMHMXXX",
"bicCodeFx": "BEOEBMH2",
"accountHolderName": "Jonathan Michael Adebayo-Okoro",
"accountName": "Adebayo Trading",
"currency": "USD",
"balance": {
"currency": "USD",
"amount": 0
},
"category": "CMS Sub Acct",
"clientReference": "REF-10293",
"taxIdentificationNumber": "123-45-6789",
"countryOfResidence": "BM",
"unallocated": false,
"accountHolderType": "Individual",
"individual": {
"dob": "1985-04-12T00:00:00.0000000",
"nationality": "GB",
"nativeLanguageName": "Native Name"
},
"business": null
},
{
"virtualAccountNumber": 1000327642,
"bicCode": "BPBKBMHMXXX",
"bicCodeFx": "BEOEBMH2",
"accountHolderName": "Titan Logistics Holdings Ltd",
"accountName": "Titan",
"currency": "USD",
"balance": {
"currency": "USD",
"amount": 130492.24
},
"category": "CMS Sub Acct",
"clientReference": "REF-10294",
"taxIdentificationNumber": "98-7654321",
"countryOfResidence": null,
"unallocated": false,
"accountHolderType": "Business",
"individual": null,
"business": {
"dateOfIncorporation": "2014-09-30T00:00:00.0000000",
"countryOfIncorporation": "BM",
"registeredAddress": {
"addressLine1": "44 Front Street",
"addressLine2": "Suite 300",
"city": "Hamilton",
"postalCode": "HM 12",
"country": "BM"
}
}
},
{
"virtualAccountNumber": 1000327887,
"bicCode": "BPBKBMHMXXX",
"bicCodeFx": "BEOEBMH2",
"accountHolderName": "UNALLOCATED",
"accountName": "UNALLOCATED",
"currency": "USD",
"balance": {
"currency": "USD",
"amount": 0
},
"category": "CMS Sub Acct",
"clientReference": "POOL-0001",
"taxIdentificationNumber": null,
"countryOfResidence": null,
"unallocated": true,
"accountHolderType": null,
"individual": null,
"business": null
}
]
}patch/v2/virtual-accounts/{virtualAccountNumber}Update Virtual Account (V2)
Update Virtual Account (V2)
Updates an existing virtual account using the v2 schema. Only the fields provided in the request body will be updated.
V2 difference: v2 uses an accountHolderType discriminator (Individual | Business) and nests the
holder-specific fields under individual / business. Only the block matching accountHolderType may be supplied.
Updatable Properties
- accountHolderName: Full legal name of the holder. Immutable after first update – can only be changed once from the "UNALLOCATED" state.
- accountName: Account name that appears on statements. Immutable after first update – can only be changed once from the "UNALLOCATED" state.
- Allowed characters (accountHolderName, accountName, address fields): A-Z, a-z, 0-9, space, and
! " # $ % & ' ( ) + , - . / [ \ ]. Common symbols such as* _ @ : ; ? { }are not allowed. - accountHolderType:
IndividualorBusiness. When supplied, the conditional rules for that holder type apply. Immutable after first allocation. - individual.dob: Date of birth (ISO 8601, past, at least 18 years ago). Immutable after first update.
- individual.nationality: ISO 3166-1 alpha-2 nationality. Immutable after first update.
- business.registeredAddress:
addressLine1,city,postalCode,country(ISO 3166-1 alpha-2) are required for aBusiness;addressLine2is optional. The registered address is mutable and may be amended after allocation. - business.dateOfIncorporation / business.countryOfIncorporation: Optional; immutable after first update when set.
- taxIdentificationNumber: Optional tax identifier for the account holder (max 30 characters)
- countryOfResidence: Optional ISO 3166-1 alpha-2 country code
- individual.nativeLanguageName: Native name of the account holder's language (max 255 characters). Immutable after first update.
- clientReference: External reference provided by the client to aid reconciliation (max 35 characters). This field can be updated multiple times.
Allocating Unallocated Accounts
For virtual accounts created with unallocated: true, use this endpoint to perform a one-time assignment to a real end-customer.
Validation Rules
For v2 updates the conditional rules fire when accountHolderType is present: an Individual requires individual.dob
individual.nationality, and aBusinessrequiresbusiness.registeredAddress(line1 + city + postalCode + country). The effective account state is evaluated server-side, so a request may rely on values already stored, but the update fails if the merged result still leaves a required field missing or invalid. When allocating an unallocated account,accountHolderNameandaccountNamemust still be supplied.taxIdentificationNumber,countryOfResidence, andindividual.nativeLanguageNameremain optional additional profile fields. Once immutable customer profile fields have been set, later attempts to change them may result in a409 Conflict(incorporation date/country and holder type are immutable; the registered address is not).clientReferenceand the registered address are the fields intended for ongoing updates after allocation.
Content Negotiation
Clients must use the HTTP Accept header to indicate the desired response format:
- Set
Accept: application/jsonfor JSON responses (default) - Set
Accept: text/csvfor CSV responses If the Accept header is omitted,application/jsonis assumed.
Base URL
All API requests use the versioned base URL:
https://api.bcbank.us/v2/virtual-accounts
Idempotency
Idempotency behaviour is identical to v1.
Required Permission: update-virtual-account
This endpoint requires the permission claim update-virtual-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.
Request parameters
path requiredVirtual account identifier (ID) that uniquely identifies the virtual account
string
Request body application/json
object
string Human-readable nickname or label for the virtual account. Allowed characters: A-Z, a-z, 0-9, space, and ! " # $ % & ' ( ) + , - . / [ \ ]. Common characters such as * _ @ : ; ? { } are not allowed.
string Official account name as it will appear on statements and official documents. Allowed characters: A-Z, a-z, 0-9, space, and ! " # $ % & ' ( ) + , - . / [ \ ]. Common characters such as * _ @ : ; ? { } are not allowed.
string string string string Discriminator (Individual | Business). When present, the conditional rules for that holder type apply. The holder type (and any incorporation fields) become immutable once set (typically after allocation).
object Individual holder details. Must be absent when AccountHolderType is Business.
Show properties
string Date of birth of the account holder. Required for an allocated individual.
string ISO 3166-1 alpha-2 nationality of the account holder. Required for an allocated individual.
string object Business holder details. Must be absent when AccountHolderType is Individual.
Show properties
string Date the business was incorporated. Optional; immutable after allocation.
string ISO 3166-1 alpha-2 country of incorporation. Optional; immutable after allocation.
object Registered / trading address. Required (line1 + city + postalCode + country) for an allocated business.
Show properties
string string string string string ISO 3166-1 alpha-2 country code of the registered address.
Responses
Virtual account updated successfully.
string requiredstring requiredstring requiredstring requiredstring requiredstring requiredobject requiredShow properties
string requiredCurrency ISO code
string requiredAmount
string requiredstring string Optional customer tax identifier (max 30 characters).
string ISO 3166-1 alpha-2 country of residence.
boolean requiredstring Holder discriminator (Individual | Business), when set.
object Individual holder details. Populated only when AccountHolderType is Individual.
Show properties
string Date of birth of the account holder. Required for an allocated individual.
string ISO 3166-1 alpha-2 nationality of the account holder. Required for an allocated individual.
string object Business holder details. Populated only when AccountHolderType is Business.
Show properties
string Date the business was incorporated. Optional; immutable after allocation.
string ISO 3166-1 alpha-2 country of incorporation. Optional; immutable after allocation.
object Registered / trading address. Required (line1 + city + postalCode + country) for an allocated business.
Show properties
string string string string string ISO 3166-1 alpha-2 country code of the registered address.
string Date when the virtual account becomes effective (YYYY-MM-DD format).
string Date when the virtual account was created (ISO 8601). Bermuda Time Zone.
object Summary view of a bank account for listing purposes
Show properties
string requiredA unique ID of the account, composed of account number and CIF
string required11-digit ID of the account holder
string requiredAccount number
string requiredSpecifies the status of the account
string requiredIdentification of the currency in which the account is held
object requiredAccount balance
Show properties
string requiredCurrency ISO code
string requiredAmount
string requiredSpecifies the sub type of account (product)
string Specifies the type of account (personal/business)
string The nickname of the account, assigned by the account owner
array requiredOwnership details of an account object
Show properties
arraystring requiredAccount owner name
string requiredType of account holder (Primary/Joint)
array requiredAdditional details or characteristics associated with an account object
Show properties
arraystring requiredKey or identifier of the account attribute.
string requiredActual data associated with the attribute name
object Summary view of a bank account for listing purposes
Show properties
string requiredA unique ID of the account, composed of account number and CIF
string required11-digit ID of the account holder
string requiredAccount number
string requiredSpecifies the status of the account
string requiredIdentification of the currency in which the account is held
object requiredAccount balance
Show properties
string requiredCurrency ISO code
string requiredAmount
string requiredSpecifies the sub type of account (product)
string Specifies the type of account (personal/business)
string The nickname of the account, assigned by the account owner
array requiredOwnership details of an account object
Show properties
arraystring requiredAccount owner name
string requiredType of account holder (Primary/Joint)
array requiredAdditional details or characteristics associated with an account object
Show properties
arraystring requiredKey or identifier of the account attribute.
string requiredActual data associated with the attribute name
Request sample
curl --request PATCH \
--url 'https://api-uat.bcbank.us/v2/virtual-accounts/{virtualAccountNumber}' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"accountHolderName": "Titan Logistics Holdings Ltd",
"accountName": "Titan",
"clientReference": "updated-reference-v2",
"taxIdentificationNumber": "98-7654321",
"accountHolderType": "Business",
"business": {
"registeredAddress": {
"addressLine1": "44 Front Street",
"city": "Hamilton",
"postalCode": "HM 12",
"country": "BM"
}
}
}'Response sample
{
"virtualAccountNumber": 1000327642,
"bicCode": "BPBKBMHMXXX",
"bicCodeFx": "BEOEBMH2",
"accountHolderName": "Titan Logistics Holdings Ltd",
"accountName": "Titan",
"currency": "USD",
"balance": {
"currency": "USD",
"amount": 0
},
"category": "CMS Sub Acct",
"clientReference": "T12cc62d3fb446e7950ffd0797d0a6f41",
"taxIdentificationNumber": "98-7654321",
"countryOfResidence": "BM",
"unallocated": false,
"accountHolderType": "Business",
"individual": null,
"business": {
"dateOfIncorporation": "2014-09-30T00:00:00.0000000",
"countryOfIncorporation": "BM",
"registeredAddress": {
"addressLine1": "44 Front Street",
"addressLine2": "Suite 300",
"city": "Hamilton",
"postalCode": "HM 12",
"country": "BM"
}
},
"effectiveDate": "2025-06-20",
"createdAt": "2025-07-25T08:23:00.0000000Z",
"parentAccount": {
"accountId": "1000326956-2000365",
"cif": 2000365,
"accountNumber": 1000326956,
"status": "AUTH",
"currency": "USD",
"availableBalance": {
"currency": "USD",
"amount": 0
},
"accountSubType": "CMS Parent Cate",
"accountType": null,
"nickname": null,
"owners": [
{
"displayName": "GLOB-INVEST BOND FUND LTD",
"accountHolderType": "Primary"
}
],
"accountAttributes": []
},
"settlementAccount": {
"accountId": "1000326948-2000365",
"cif": 2000365,
"accountNumber": 1000326948,
"status": "AUTH",
"currency": "USD",
"availableBalance": {
"currency": "USD",
"amount": 0
},
"accountSubType": "CMS Settlement",
"accountType": null,
"nickname": null,
"owners": [
{
"displayName": "GLOB-INVEST BOND FUND LTD",
"accountHolderType": "Primary"
}
],
"accountAttributes": []
}
}get/v2/virtual-accounts/{virtualAccountNumber}Get Virtual Account Details (V2)
Get Virtual Account Details (V2)
Identical to the v1 details endpoint, but returns the v2 read schema: holder KYC is nested under
accountHolderType + individual / business (with business.registeredAddress). taxIdentificationNumber
and countryOfResidence remain at the top level.
Required Permission: get-a-virtual-account
This endpoint requires the permission claim get-a-virtual-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.
Request parameters
path requiredThe virtual account number assigned by the bank.
string
Responses
OK - The request was successful.
string requiredstring requiredstring requiredstring requiredstring requiredstring requiredobject requiredShow properties
string requiredCurrency ISO code
string requiredAmount
string requiredstring string Optional customer tax identifier (max 30 characters).
string ISO 3166-1 alpha-2 country of residence.
boolean requiredstring Holder discriminator (Individual | Business), when set.
object Individual holder details. Populated only when AccountHolderType is Individual.
Show properties
string Date of birth of the account holder. Required for an allocated individual.
string ISO 3166-1 alpha-2 nationality of the account holder. Required for an allocated individual.
string object Business holder details. Populated only when AccountHolderType is Business.
Show properties
string Date the business was incorporated. Optional; immutable after allocation.
string ISO 3166-1 alpha-2 country of incorporation. Optional; immutable after allocation.
object Registered / trading address. Required (line1 + city + postalCode + country) for an allocated business.
Show properties
string string string string string ISO 3166-1 alpha-2 country code of the registered address.
string Date when the virtual account becomes effective (YYYY-MM-DD format).
string Date when the virtual account was created (ISO 8601). Bermuda Time Zone.
object Summary view of a bank account for listing purposes
Show properties
string requiredA unique ID of the account, composed of account number and CIF
string required11-digit ID of the account holder
string requiredAccount number
string requiredSpecifies the status of the account
string requiredIdentification of the currency in which the account is held
object requiredAccount balance
Show properties
string requiredCurrency ISO code
string requiredAmount
string requiredSpecifies the sub type of account (product)
string Specifies the type of account (personal/business)
string The nickname of the account, assigned by the account owner
array requiredOwnership details of an account object
Show properties
arraystring requiredAccount owner name
string requiredType of account holder (Primary/Joint)
array requiredAdditional details or characteristics associated with an account object
Show properties
arraystring requiredKey or identifier of the account attribute.
string requiredActual data associated with the attribute name
object Summary view of a bank account for listing purposes
Show properties
string requiredA unique ID of the account, composed of account number and CIF
string required11-digit ID of the account holder
string requiredAccount number
string requiredSpecifies the status of the account
string requiredIdentification of the currency in which the account is held
object requiredAccount balance
Show properties
string requiredCurrency ISO code
string requiredAmount
string requiredSpecifies the sub type of account (product)
string Specifies the type of account (personal/business)
string The nickname of the account, assigned by the account owner
array requiredOwnership details of an account object
Show properties
arraystring requiredAccount owner name
string requiredType of account holder (Primary/Joint)
array requiredAdditional details or characteristics associated with an account object
Show properties
arraystring requiredKey or identifier of the account attribute.
string requiredActual data associated with the attribute name
Request sample
curl --request GET \
--url 'https://api-uat.bcbank.us/v2/virtual-accounts/{virtualAccountNumber}' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN'Response sample
{
"virtualAccountNumber": 1000327642,
"bicCode": "BPBKBMHMXXX",
"bicCodeFx": "BEOEBMH2",
"accountHolderName": "Titan Logistics Holdings Ltd",
"accountName": "Titan",
"currency": "USD",
"balance": {
"currency": "USD",
"amount": 0
},
"category": "CMS Sub Acct",
"clientReference": "T12cc62d3fb446e7950ffd0797d0a6f41",
"taxIdentificationNumber": "98-7654321",
"countryOfResidence": "BM",
"unallocated": false,
"accountHolderType": "Business",
"individual": null,
"business": {
"dateOfIncorporation": "2014-09-30T00:00:00.0000000",
"countryOfIncorporation": "BM",
"registeredAddress": {
"addressLine1": "44 Front Street",
"addressLine2": "Suite 300",
"city": "Hamilton",
"postalCode": "HM 12",
"country": "BM"
}
},
"effectiveDate": "2025-06-20",
"createdAt": "2025-07-25T08:23:00.0000000Z",
"parentAccount": {
"accountId": "1000326956-2000365",
"cif": 2000365,
"accountNumber": 1000326956,
"status": "AUTH",
"currency": "USD",
"availableBalance": {
"currency": "USD",
"amount": 0
},
"accountSubType": "CMS Parent Cate",
"accountType": null,
"nickname": null,
"owners": [
{
"displayName": "GLOB-INVEST BOND FUND LTD",
"accountHolderType": "Primary"
}
],
"accountAttributes": []
},
"settlementAccount": {
"accountId": "1000326948-2000365",
"cif": 2000365,
"accountNumber": 1000326948,
"status": "AUTH",
"currency": "USD",
"availableBalance": {
"currency": "USD",
"amount": 0
},
"accountSubType": "CMS Settlement",
"accountType": null,
"nickname": null,
"owners": [
{
"displayName": "GLOB-INVEST BOND FUND LTD",
"accountHolderType": "Primary"
}
],
"accountAttributes": []
}
}get/v1/virtual-accounts/{virtualAccountNumber}/transactionsVirtual Account Transactions
Virtual Account Transactions
Retrieves transaction entries for a specific virtual (sub) account within a given date range. This endpoint:
- Validates the provided date parameters. Accepted formats:
yyyy-MM-ddoryyyyMMdd. - Supports a maximum date range of one year.
- Supports both JSON and CSV response formats based on the Accept header.
- Uses cursor-based pagination with server-side result-set management.
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 apageToken. - Subsequent Requests: Use the
pageTokenfrom previous responses withpageStartto navigate pages. - Page Token: Contains encoded pagination context including
pageSize, so don't specifypageSizein 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/jsonfor JSON responses (default) - Set
Accept: text/csvfor CSV responses If the Accept header is omitted,application/jsonis assumed.
Base URL
All API requests use the versioned base URL:
https://api.bcbank.us/v1/virtual-accounts/{virtualAccountNumber}/transactions
Sample Request in JavaScript
// Get first page
async function getVirtualAccountTransactions(virtualAccountNumber, fromDate, toDate) {
const url = new URL(`https://api.bcbank.us/v1/virtual-accounts/${encodeURIComponent(virtualAccountNumber)}/transactions`);
url.searchParams.set('fromDate', fromDate); // yyyy-MM-dd or yyyyMMdd
url.searchParams.set('toDate', toDate); // yyyy-MM-dd or yyyyMMdd
url.searchParams.set('pageSize', '100'); // optional (first call only)
const response = await fetch(url.toString(), {
method: 'GET',
headers: {
'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
'Accept': 'application/json'
}
});
if (!response.ok) {
const error = await response.json();
throw new Error(`Failed to get VA transactions: ${error.message || 'Unknown error'}`);
}
const result = await response.json();
// result.meta.pagination: { page_start, page_token, total_size, page_size }
// result.data: Array of VA transactions
// Example: inspect first item
if (result.data?.length) {
const t = result.data[0];
console.log('Tx:', t.id, t.description, t.valueDate, t.value?.amount, t.value?.currency, t.debitAccountNumber?.number, t.creditAccountNumber?.number);
}
return result;
}
// Paginate through all pages
async function getAllVirtualAccountTransactions(virtualAccountNumber, fromDate, toDate) {
let pageStart = 1;
let pageToken = null;
let totalPages = 0;
const all = [];
do {
const url = new URL(`https://api.bcbank.us/v1/virtual-accounts/${encodeURIComponent(virtualAccountNumber)}/transactions`);
url.searchParams.set('fromDate', fromDate);
url.searchParams.set('toDate', toDate);
if (pageStart === 1) {
url.searchParams.set('pageSize', '100'); // first call only
} else {
url.searchParams.set('pageStart', String(pageStart));
url.searchParams.set('pageToken', pageToken);
}
const res = await fetch(url.toString(), {
headers: { 'Authorization': 'Bearer YOUR_ACCESS_TOKEN', 'Accept': 'application/json' }
});
if (!res.ok) throw new Error('Request failed');
const body = await res.json();
if (pageStart === 1) {
const p = body.meta?.pagination;
pageToken = p?.page_token;
totalPages = Math.ceil((p?.total_size ?? 0) / (p?.page_size ?? 100));
console.log('First page meta:', p);
}
if (Array.isArray(body.data)) all.push(...body.data);
pageStart++;
} while (pageStart <= totalPages);
return all;
}
Required Permission: get-virtual-account-transactions
This endpoint requires the permission claim get-virtual-account-transactions 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.
Request parameters
path requiredVirtual account identifier (number) to retrieve transactions for.
string
query requiredThe start date for the transaction range (format: yyyy-MM-dd).
string
query requiredThe end date for the transaction range (format: yyyy-MM-dd).
string
query string
query integer (int32)
query integer (int32)
Responses
OK - The request was successful.
object Show properties
object Show properties
integer requiredstring integer requiredinteger requiredarray Show properties
arraystring requiredA unique identifier of the virtual account transaction.
string Human-readable description of the transaction.
string requiredThe booking date of the transaction in YYYY-MM-DD format.
string requiredThe value date of the transaction in YYYY-MM-DD format.
object requiredTransaction amount with currency. Positive values indicate credits; negative values indicate debits.
Show properties
string requiredCurrency ISO code
string requiredAmount
string Bank-specific transaction-type code (e.g. PARENT.TO.SUB, SUB.TO.PARENT).
object Unique identifier of a bank account from which funds are being withdrawn or debited
Show properties
string requiredAccount number
array requiredAccount routing details
Show properties
arrayBankRoutingobject Unique identifier of a bank account that is set to receive funds
Show properties
string requiredAccount number
array requiredAccount routing details
Show properties
arrayBankRoutingstring requiredTransaction Status
string Reference supplied by the counterparty (e.g. their own transaction or message identifier). Returned as provided by the bank.
object Conversion details, when available on the transaction detail endpoint. Omitted otherwise. These details retain the original conversion even if the returned value is adjusted.
Show properties
string requiredThree-letter currency code of the original instructed amount.
string requiredThree-letter currency code obtained through the conversion.
string requiredApplied source-to-target exchange rate, expressed as a decimal string without rounding. The string may use exponent notation for very small values.
object requiredOriginal amount and currency before conversion. Amount text retains its original precision.
Show properties
CurrencyAmountRequest sample
curl --request GET \
--url 'https://api-uat.bcbank.us/v1/virtual-accounts/{virtualAccountNumber}/transactions' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN'Response sample
{
"meta": {
"pagination": {
"page_start": {},
"page_token": {},
"total_size": {},
"page_size": {}
}
},
"data": [
{
"id": "string",
"description": "string",
"bookingDate": "string",
"valueDate": "string",
"value": {},
"proprietaryBankTransactionCode": "string",
"debitAccountNumber": {},
"creditAccountNumber": {},
"status": "string",
"counterpartyReference": "string",
"currencyExchange": {}
}
]
}get/v1/virtual-accounts/transaction/reportVirtual Account Transaction Report
Virtual Account Transaction Report
Retrieves a transaction report for all virtual (sub) accounts belonging to the authenticated customer within a given date range.
Response shape
- The endpoint returns a JSON object with
metaanddatafields. meta.paginationcontains pagination metadata (cursor-based).datacontains the raw CSV report content as a single string (RFC4180, CRLF line endings).
Note: This endpoint does not return an array of transaction objects. The report is provided as CSV text inside the JSON envelope.
This endpoint:
- Validates the provided date parameters. Accepted formats:
yyyy-MM-ddoryyyyMMdd. - Supports a maximum date range of one year.
- Uses cursor-based pagination with server-side result-set management.
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 apageToken. - Subsequent Requests: Use the
pageTokenfrom previous responses withpageStartto navigate pages. - Page Token: Contains encoded pagination context including pageSize, so don't specify
pageSizein subsequent requests. - Total Pages: Calculate using
Math.ceil(total_size / page_size)from the response metadata.
Content Negotiation
- Set
Accept: application/jsonto receive the JSON envelope wheredatais the raw CSV report string. - If you request
Accept: text/csv, the platform CSV formatter will attempt to serialize the entire response object as CSV, which is different from returning the report payload itself. For the raw report content, useapplication/json.
Base URL
All API requests use the versioned base URL:
https://api.bcbank.us/v1/virtual-accounts/transaction/report
Sample Request in JavaScript
// Fetch the report (JSON envelope, report CSV in result.data)
async function getVirtualAccountTransactionsReport(fromDate, toDate) {
const url = new URL(`https://api.bcbank.us/v1/virtual-accounts/transaction/report`);
url.searchParams.set('fromDate', fromDate); // yyyy-MM-dd or yyyyMMdd
url.searchParams.set('toDate', toDate); // yyyy-MM-dd or yyyyMMdd
const response = await fetch(url.toString(), {
method: 'GET',
headers: {
'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
'Accept': 'application/json'
}
});
if (!response.ok) {
const error = await response.json();
throw new Error(`Failed to get VA transaction report: ${error.message || 'Unknown error'}`);
}
const result = await response.json();
// result.meta.pagination: { page_start, page_token, total_size, page_size }
// result.data: raw CSV report string (may include header + summary sections)
const csvText = result.data || '';
console.log(csvText);
return result;
}
// Download the CSV report from the JSON envelope
async function downloadVirtualAccountTransactionsReport(fromDate, toDate) {
const { data: csvText } = await getVirtualAccountTransactionsReport(fromDate, toDate);
const blob = new Blob([csvText || ''], { type: 'text/csv;charset=utf-8' });
const a = document.createElement('a');
a.href = URL.createObjectURL(blob);
a.download = `vas-transaction-report-${fromDate}-${toDate}.csv`;
a.click();
URL.revokeObjectURL(a.href);
}
Required Permission: get-virtual-account-transactions
This endpoint requires the permission claim get-virtual-account-transactions 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.
Request parameters
query requiredThe start date for the transaction range (format: yyyy-MM-dd).
string
query requiredThe end date for the transaction range (format: yyyy-MM-dd).
string
query string
query integer (int32)
query integer (int32)
Responses
OK - The request was successful.
object Show properties
object Show properties
integer requiredstring integer requiredinteger requiredstring Request sample
curl --request GET \ --url 'https://api-uat.bcbank.us/v1/virtual-accounts/transaction/report' \ --header 'Authorization: Bearer YOUR_ACCESS_TOKEN'
Response sample
{
"meta": {
"pagination": {
"page_start": 1,
"page_token": null,
"total_size": 20,
"page_size": 20
}
},
"data": "Reference,Date,Time,Transaction Type,From Account,To Account,Direction,Amount,Currency,Customer Name,Sub Account,Leg,Settlement Balance\n=== VAS TRANSACTION REPORT (***DUMMY DATA***) ===,2025-12-01 to 2025-12-31,,,,,,,,,,,,Opening Balance: 0.00 USD\n---,---,---,---,---,---,---,---,---,---,---,---,---\nFT9A2B7XQ1LZ,15/12/2025,19:20,Deposit Received,Nostro,Sub: JOHN SMITH,IN,150,USD,JOHN SMITH,1029384756,1,0\n---,---,---,---,---,---,---,---,---,---,---,---,---\n=== SUMMARY ===,,,Total Deposits (1),,,,IN,150,USD,,,,\n,,,Net Position,,,,150,USD,,,,,Closing Balance: 150.00 USD\n"
}get/v1/virtual-accounts/transactions/{transactionId}Virtual Account Transaction Details
Virtual Account Transaction Details
Retrieves detailed information for a specific virtual-account transaction identified by its globally unique transaction ID. This endpoint:
- Returns a single transaction detail object with full context (accounts, amounts, value date, narrative, attributes)
- Supports both JSON and CSV response formats based on the Accept header
Content Negotiation
Clients must use the HTTP Accept header to indicate the desired response format:
- Set
Accept: application/jsonfor JSON responses (default) - Set
Accept: text/csvfor CSV responses If the Accept header is omitted,application/jsonis assumed.
Currency Exchange
When complete currency conversion details are available, the response includes currencyExchange:
sourceCurrency: the original instructed currency.targetCurrency: the currency obtained through the conversion.exchangeRate: the source-to-target rate, returned as a decimal string without rounding. Very small rates may use exponent notation.instructedAmount: the original amount and currency, with the amount's precision preserved.
The object is omitted if conversion details are unavailable.
The transaction can still be returned successfully.
Conversion details remain unchanged if the returned value is adjusted.
Do not assume that multiplying instructedAmount.amount by exchangeRate equals value.amount.
Example of the optional response property:
{
"currencyExchange": {
"sourceCurrency": "USD",
"targetCurrency": "ZAR",
"exchangeRate": "17.638333",
"instructedAmount": { "currency": "USD", "amount": "9000.00" }
}
}
A response without conversion details omits the property. For example, this response fragment contains only the transaction value:
{ "value": { "currency": "USD", "amount": "9000.00" } }
CSV responses include currency_exchange_source_currency, currency_exchange_target_currency,
currency_exchange_exchange_rate, currency_exchange_instructed_amount_currency, and
currency_exchange_instructed_amount_amount only when conversion details are available.
Account Routing Metadata
The transaction detail response includes routing metadata for
debitAccountNumber or/and creditAccountNumber depending of transaction type.
Account entity contains an accountRoutings collection with up to four entries (when data is available):
BankId– BIC / SWIFT identifier of the bank handling the accountBankName– Legal name of the bankAccountName– Account holder or counterparty nameAccountAddress– Postal address details associated with the account
Entries are ordered as listed above and only appear when the upstream system
returns the corresponding value. Consumers can rely on the scheme field to
differentiate each routing record.
Base URL
All API requests use the versioned base URL:
https://api.bcbank.us/v1/virtual-accounts/transactions/{transactionId}
Sample Request in JavaScript
async function getVirtualAccountTransactionDetail(transactionId) {
const url = `https://api.bcbank.us/v1/virtual-accounts/transactions/${encodeURIComponent(transactionId)}`;
const response = await fetch(url, {
method: 'GET',
headers: {
'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
'Accept': 'application/json'
}
});
if (!response.ok) {
const error = await response.json();
throw new Error(`Failed to get VA transaction detail: ${error.message || 'Unknown error'}`);
}
const result = await response.json();
// result is a single transaction detail object
console.log('Transaction ID:', result.id);
console.log('Description:', result.description);
console.log('Value Date:', result.valueDate);
if (result.value) {
console.log('Amount:', result.value.amount, result.value.currency);
}
return result;
}
Required Permission: get-virtual-account-transactions
This endpoint requires the permission claim get-virtual-account-transactions 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.
Request parameters
path requiredThe globally unique transaction identifier to retrieve details for.
string
Responses
OK - The transaction was returned, with optional currency conversion details.
string requiredA unique identifier of the virtual account transaction.
string Human-readable description of the transaction.
string requiredThe booking date of the transaction in YYYY-MM-DD format.
string requiredThe value date of the transaction in YYYY-MM-DD format.
object requiredTransaction amount with currency. Positive values indicate credits; negative values indicate debits.
Show properties
string requiredCurrency ISO code
string requiredAmount
string Bank-specific transaction-type code (e.g. PARENT.TO.SUB, SUB.TO.PARENT).
object Unique identifier of a bank account from which funds are being withdrawn or debited
Show properties
string requiredAccount number
array requiredAccount routing details
Show properties
arraystring requiredScheme value
string requiredAddress value
object Unique identifier of a bank account that is set to receive funds
Show properties
string requiredAccount number
array requiredAccount routing details
Show properties
arraystring requiredScheme value
string requiredAddress value
string requiredTransaction Status
string Reference supplied by the counterparty (e.g. their own transaction or message identifier). Returned as provided by the bank.
object Conversion details, when available on the transaction detail endpoint. Omitted otherwise. These details retain the original conversion even if the returned value is adjusted.
Show properties
string requiredThree-letter currency code of the original instructed amount.
string requiredThree-letter currency code obtained through the conversion.
string requiredApplied source-to-target exchange rate, expressed as a decimal string without rounding. The string may use exponent notation for very small values.
object requiredOriginal amount and currency before conversion. Amount text retains its original precision.
Show properties
string requiredCurrency ISO code
string requiredAmount
Request sample
curl --request GET \
--url 'https://api-uat.bcbank.us/v1/virtual-accounts/transactions/{transactionId}' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN'Response sample
{
"id": "string",
"description": "string",
"bookingDate": "string",
"valueDate": "string",
"value": {
"currency": "string",
"amount": "string"
},
"proprietaryBankTransactionCode": "string",
"debitAccountNumber": {
"number": "string",
"accountRoutings": [
{}
]
},
"creditAccountNumber": {
"number": "string",
"accountRoutings": [
{}
]
},
"status": "string",
"counterpartyReference": "string",
"currencyExchange": {
"sourceCurrency": "string",
"targetCurrency": "string",
"exchangeRate": "string",
"instructedAmount": {}
}
}delete/v1/virtual-accounts/transactions/{transactionId}Reverse Virtual Account Transaction
Reverse Virtual Account Transaction
Reverses a specific virtual-account transaction identified by its globally unique transaction ID. This endpoint:
- Reverses the specified transaction and returns the reversal details
- Supports both JSON and CSV response formats based on the Accept header
- Requires appropriate permissions to perform transaction reversals
Important Business Rules
- Same-Day Reversal Only: The current development design allows only to reverse records created on the same day
- Completed Status Required: The transaction status must have "Completed" status to be eligible for reversal
Content Negotiation
Clients must use the HTTP Accept header to indicate the desired response format:
- Set
Accept: application/jsonfor JSON responses (default) - Set
Accept: text/csvfor CSV responses If the Accept header is omitted,application/jsonis assumed.
Idempotency
The API supports idempotency through the optional Idempotency-Key header:
- If no idempotency key is provided, the request is processed normally (duplicates are possible)
- If a valid UUID idempotency key is provided for a new transaction, the system stores the key and associates it with the transaction results
- If the same idempotency key is received again for the same endpoint/action, the system returns the previously stored response
- Idempotency keys are user-specific - different users with the same keys don't share cached responses
- The idempotency key must be a valid UUID format (e.g., "123e4567-e89b-12d3-a456-426614174000").
Base URL
All API requests use the versioned base URL:
https://api.bcbank.us/v1/virtual-accounts/transactions/{transactionId}
Sample Request in JavaScript
async function reverseVirtualAccountTransaction(transactionId) {
const url = `https://api.bcbank.us/v1/virtual-accounts/transactions/${encodeURIComponent(transactionId)}`;
const response = await fetch(url, {
method: 'DELETE',
headers: {
'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
'Accept': 'application/json',
'Idempotency-Key': '123e4567-e89b-12d3-a456-426614174000' // Optional
}
});
if (!response.ok) {
const error = await response.json();
throw new Error(`Failed to reverse VA transaction: ${error.message || 'Unknown error'}`);
}
const result = await response.json();
// result is a transaction reversal object
console.log('Reversal Transaction ID:', result.transactionId);
console.log('Status:', result.status);
console.log('Transaction Status:', result.transactionStatus);
if (result.value) {
console.log('Amount:', result.value.amount, result.value.currency);
}
return result;
}
Required Permission: reverse-virtual-account-transaction
This endpoint requires the permission claim reverse-virtual-account-transaction 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.
Request parameters
path requiredThe globally unique transaction identifier to reverse.
string
Responses
Created - The transaction reversal was successful.
string requiredUnique identifier of the original (now reversed) transaction (e.g., FT1234567).
string requiredReversal processing status reported by the core system (e.g., Reversed). Typically reflects the system's internal status code for the reversal lifecycle.
string requiredHigh-level execution status of the reversal request (e.g., success, failed).
string requiredUnique correlation / tracking identifier supplied by or derived from the core system (e.g., message or processing reference).
object requiredTransaction amount with currency
Show properties
string requiredCurrency ISO code
string requiredAmount
Request sample
curl --request DELETE \
--url 'https://api-uat.bcbank.us/v1/virtual-accounts/transactions/{transactionId}' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN'Response sample
{
"transactionId": "FT252255GBQS",
"transactionStatus": "Reversed",
"status": "success",
"uniqueIdentifier": "FT252255GBQS",
"value": {
"currency": "USD",
"amount": 0.03
}
}get/v1/virtual-accounts/{virtualAccountNumber}/depositsGet Virtual Account Deposits
Get Virtual Account Deposits
Retrieves deposit transaction entries for a specific virtual (sub) account. This endpoint:
- Returns detailed deposit transaction information including account numbers, amounts, and transaction status.
- Supports both JSON and CSV response formats based on the Accept header.
- Uses cursor-based pagination with server-side result-set management.
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 apageToken. - Subsequent Requests: Use the
pageTokenfrom previous responses withpageStartto navigate pages. - Page Token: Contains encoded pagination context including
pageSize, so don't specifypageSizein 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/jsonfor JSON responses (default) - Set
Accept: text/csvfor CSV responses If the Accept header is omitted,application/jsonis assumed.
Base URL
All API requests use the versioned base URL:
https://api.bcbank.us/v1/virtual-accounts/{virtualAccountNumber}/deposits
Sample Request in JavaScript
// Get first page of deposits
async function getVirtualAccountDeposits(virtualAccountNumber, fromDate, toDate) {
const url = new URL(`https://api.bcbank.us/v1/virtual-accounts/${encodeURIComponent(virtualAccountNumber)}/deposits`);
url.searchParams.set('fromDate', fromDate); // yyyy-MM-dd or yyyyMMdd
url.searchParams.set('toDate', toDate); // yyyy-MM-dd or yyyyMMdd
url.searchParams.set('pageSize', '100'); // optional (first call only)
const response = await fetch(url.toString(), {
method: 'GET',
headers: {
'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
'Accept': 'application/json'
}
});
if (!response.ok) {
const error = await response.json();
throw new Error(`Failed to get VA deposits: ${error.message || 'Unknown error'}`);
}
const result = await response.json();
// result.meta.pagination: { page_start, page_token, total_size, page_size }
// result.data: Array of VA deposit transactions
// Example: inspect first deposit
if (result.data?.length) {
const d = result.data[0];
console.log('Deposit:', d.id, d.valueDate, d.value?.amount, d.value?.currency, d.proprietaryBankTransactionCode);
console.log('From:', d.debitAccountNumber?.number, 'To:', d.creditAccountNumber?.number);
console.log('Status:', d.status);
}
return result;
}
// Paginate through all deposit pages
async function getAllVirtualAccountDeposits(virtualAccountNumber, fromDate, toDate) {
let pageStart = 1;
let pageToken = null;
let totalPages = 0;
const all = [];
do {
const url = new URL(`https://api.bcbank.us/v1/virtual-accounts/${encodeURIComponent(virtualAccountNumber)}/deposits`);
url.searchParams.set('fromDate', fromDate);
url.searchParams.set('toDate', toDate);
if (pageStart === 1) {
url.searchParams.set('pageSize', '100'); // first call only
} else {
url.searchParams.set('pageStart', String(pageStart));
url.searchParams.set('pageToken', pageToken);
}
const res = await fetch(url.toString(), {
headers: { 'Authorization': 'Bearer YOUR_ACCESS_TOKEN', 'Accept': 'application/json' }
});
if (!res.ok) throw new Error('Request failed');
const body = await res.json();
if (pageStart === 1) {
const p = body.meta?.pagination;
pageToken = p?.page_token;
totalPages = Math.ceil((p?.total_size ?? 0) / (p?.page_size ?? 100));
console.log('First page meta:', p);
}
if (Array.isArray(body.data)) all.push(...body.data);
pageStart++;
} while (pageStart <= totalPages);
return all;
}
Required Permission: deposit-virtual-account
This endpoint requires the permission claim deposit-virtual-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.
Request parameters
path requiredVirtual account identifier (number) to retrieve deposits for.
string
query requiredThe start date for the transaction range (format: yyyy-MM-dd).
string
query requiredThe end date for the transaction range (format: yyyy-MM-dd).
string
query string
query integer (int32)
query integer (int32)
Responses
OK - The request was successful.
object Show properties
object Show properties
integer requiredstring integer requiredinteger requiredarray Show properties
arraystring requiredA unique identifier of the virtual account transaction.
string Human-readable description of the transaction.
string requiredThe booking date of the transaction in YYYY-MM-DD format.
string requiredThe value date of the transaction in YYYY-MM-DD format.
object requiredTransaction amount with currency. Positive values indicate credits; negative values indicate debits.
Show properties
string requiredCurrency ISO code
string requiredAmount
string Bank-specific transaction-type code (e.g. PARENT.TO.SUB, SUB.TO.PARENT).
object Unique identifier of a bank account from which funds are being withdrawn or debited
Show properties
string requiredAccount number
array requiredAccount routing details
Show properties
arrayBankRoutingobject Unique identifier of a bank account that is set to receive funds
Show properties
string requiredAccount number
array requiredAccount routing details
Show properties
arrayBankRoutingstring requiredTransaction Status
string Reference supplied by the counterparty (e.g. their own transaction or message identifier). Returned as provided by the bank.
object Conversion details, when available on the transaction detail endpoint. Omitted otherwise. These details retain the original conversion even if the returned value is adjusted.
Show properties
string requiredThree-letter currency code of the original instructed amount.
string requiredThree-letter currency code obtained through the conversion.
string requiredApplied source-to-target exchange rate, expressed as a decimal string without rounding. The string may use exponent notation for very small values.
object requiredOriginal amount and currency before conversion. Amount text retains its original precision.
Show properties
CurrencyAmountRequest sample
curl --request GET \
--url 'https://api-uat.bcbank.us/v1/virtual-accounts/{virtualAccountNumber}/deposits' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN'Response sample
{
"meta": {
"pagination": {
"page_start": {},
"page_token": {},
"total_size": {},
"page_size": {}
}
},
"data": [
{
"id": "string",
"description": "string",
"bookingDate": "string",
"valueDate": "string",
"value": {},
"proprietaryBankTransactionCode": "string",
"debitAccountNumber": {},
"creditAccountNumber": {},
"status": "string",
"counterpartyReference": "string",
"currencyExchange": {}
}
]
}post/v1/virtual-accounts/{accountNumber}/transfers/creditCredit Virtual Account
Credit Virtual Account
Credits funds to a virtual account from a parent account. This endpoint allows clients to transfer funds into a virtual account.
The request must include source account details, the amount to be credited, and currency information.
Key Features:
- Transfers funds from a source account to a virtual account
- Supports idempotency to prevent duplicate transactions
- Validates account numbers and currency matching
- Supports both JSON and CSV response formats
- Automatic account number validation and matching
Important Notes:
- The virtual account number (creditAccountNumber) is specified in the URL route, not in the request body
- Ensure the source account has sufficient funds before making the request
- Virtual accounts must be in an active state to receive credits
Virtual Account Hierarchy Virtual accounts are sub-accounts linked to a parent account:
Parent Account → Virtual Account (Sub-Account)
When crediting a virtual account, funds flow from the parent account to the virtual account.
Idempotency
The API supports idempotency through the optional Idempotency-Key header:
- If no idempotency key is provided, the request is processed normally (duplicates are possible)
- If a valid UUID idempotency key is provided for a new transaction, the system stores the key and associates it with the transaction results
- If the same idempotency key is received again for the same endpoint/action, the system returns the previously stored response
- Idempotency keys are user-specific - different users with the same keys don't share cached responses
- The idempotency key must be a valid UUID format (e.g., "123e4567-e89b-12d3-a456-426614174000").
Content Negotiation
Clients must use the HTTP Accept header to indicate the desired response format:
- Set
Accept: application/jsonfor JSON responses (default) - Set
Accept: text/csvfor CSV responses If the Accept header is omitted,application/jsonis assumed.
Base URL:
All API requests use the versioned base URL:
https://api.bcbank.us/v1/virtual-accounts/{accountNumber}/transfers/credit
Sample Request in JavaScript:
async function creditVirtualAccount() {
try {
const virtualAccountNumber = "1556008272";
const response = await fetch(`https://api.bcbank.us/v1/virtual-accounts/${virtualAccountNumber}/transfers/credit`, {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
'Content-Type': 'application/json',
'Accept': 'application/json',
'Idempotency-Key': '123e4567-e89b-12d3-a456-426614174000' // Optional
},
body: JSON.stringify({
debitAccountNumber: "1000320567",
debitAmountCurrency: "USD",
creditAmountCurrency: "USD", // Must match debitAmountCurrency
debitAmount: "100.00"
})
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(`Credit transfer failed: ${JSON.stringify(errorData)}`);
}
const data = await response.json();
console.log('Credit transfer result:', data);
// Example processing of the returned object
const { id, status, uniqueIdentifier, details, linkedActivities } = data;
const { debitAmount, valueDate, childTransactionId, creditAmountCurrency, debitAccountNumber, creditAccountNumber } = details;
// Log the main transfer details
console.log('Transaction ID:', id);
console.log('Status:', status);
console.log('Unique Identifier:', uniqueIdentifier);
console.log('Debit Amount:', debitAmount.amount, debitAmount.currency);
console.log('Value Date:', valueDate);
console.log('Child Transaction ID:', childTransactionId);
console.log('Credit Amount Currency:', creditAmountCurrency);
// Process debit account information
console.log('Debit Account Number:', debitAccountNumber.number);
// Process credit account information (virtual account)
console.log('Credit Account Number:', creditAccountNumber.number);
// Process linked activities
linkedActivities.forEach(activity => {
console.log('Linked Activity ID:', activity.id);
console.log('Linked Activity Transaction Status:', activity.transactionStatus);
console.log('Linked Activity Status:', activity.status);
console.log('Linked Activity Unique Identifier:', activity.uniqueIdentifier);
const { arrangementId, activityId, productId, currencyId, effectiveDate } = activity.activityDetails;
console.log('Linked Activity Arrangement ID:', arrangementId);
console.log('Linked Activity Activity ID:', activityId);
console.log('Linked Activity Product ID:', productId);
console.log('Linked Activity Currency ID:', currencyId);
console.log('Linked Activity Effective Date:', effectiveDate);
});
// Final status logging
if (status === 'success') {
console.log('The virtual account credit was successful.');
} else {
console.log('The virtual account credit failed:', status);
}
} catch (error) {
console.error('Error crediting virtual account:', error);
}
}
creditVirtualAccount();
Required Permission: deposit-virtual-account
This endpoint requires the permission claim deposit-virtual-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.
Request parameters
path requiredThe virtual account number to be credited.
string
Request body application/json
string requiredGets or sets the currency code of the debit amount. Exactly 3 letters (ISO 4217).
string requiredThe currency code for the credit amount, such as "USD", "EUR", etc. Exactly 3 letters (ISO 4217).
string requiredThe amount of money to be transferred. Ensure the amount does not exceed the available balance in the debit account.
string requiredThe account number from which the money will be taken (source/parent account). Please ensure this account has enough funds before initiating the transfer.
Responses
The virtual account was credited successfully.
string requiredUnique identifier for the transfer
string requiredThe current processing status of the transaction, e.g. Completed, Pending, Failed
string requiredUnique identifier specific to this instance of the transfer
object Transfer data
Show properties
object requiredAmount that was intended to be transferred or paid, not including any additional fees or charges. It's the raw amount before any processing fees or other costs are added.
Show properties
string requiredCurrency ISO code
string requiredAmount
string requiredDate on which the transaction is officially settled, meaning the funds are considered to have been transferred legally and are available for use by the recipient
string Child transaction ID
string requiredCredit amount currency
object requiredUnique identifier of a bank account from which funds are being withdrawn or debited
Show properties
string requiredAccount number
array requiredAccount routing details
Show properties
arraystring requiredScheme value
string requiredAddress value
object requiredUnique identifier of a bank account that is set to receive funds
Show properties
string requiredAccount number
array requiredAccount routing details
Show properties
arraystring requiredScheme value
string requiredAddress value
array requiredList of related financial activities
Show properties
arraystring requiredThe unique identifier for the activity.
string requiredThe current processing status of the transaction.
string requiredThe general status of the activity.
string A unique identifier specific to this instance of the activity.
object requiredDetailed information about the activity.
Show properties
string requiredUnique identifier for the arrangement associated with this activity.
string requiredIdentifier for the type of activity.
string requiredProduct identifier related to the activity.
string requiredCurrency code for the activity.
string requiredDate when the activity becomes effective.
Request sample
curl --request POST \
--url 'https://api-uat.bcbank.us/v1/virtual-accounts/{accountNumber}/transfers/credit' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"debitAccountNumber": 1000320567,
"debitAmountCurrency": "USD",
"creditAmountCurrency": "USD",
"debitAmount": 100
}'Response sample
{
"id": "string",
"status": "string",
"uniqueIdentifier": "string",
"details": {
"debitAmount": {
"currency": {},
"amount": {}
},
"valueDate": "string",
"childTransactionId": "string",
"creditAmountCurrency": "string",
"debitAccountNumber": {
"number": {},
"accountRoutings": {}
},
"creditAccountNumber": {
"number": {},
"accountRoutings": {}
}
},
"linkedActivities": [
{
"id": "string",
"transactionStatus": "string",
"status": "string",
"uniqueIdentifier": "string",
"activityDetails": {
"arrangementId": {},
"activityId": {},
"productId": {},
"currencyId": {},
"effectiveDate": {}
}
}
]
}post/v1/virtual-accounts/{accountNumber}/transfers/debitDebit Virtual Account
Debit Virtual Account
Initiates a debit transfer from a virtual (sub) account to transfer funds to the parent account and ultimately to the settlement account. This endpoint allows corporate clients to withdraw funds from their virtual accounts for settlement purposes.
Use Case: As a corporate client, I want to debit a sub account to transfer funds to the parent account and ultimately to the settlement account.
Key Features:
- Transfers funds from a virtual account to a main account
- Supports idempotency to prevent duplicate transactions
- Validates account numbers and currency matching
- Supports both JSON and CSV response formats
- Automatic account number validation and matching
Important Notes:
- The virtual account number (debitAccountNumber) is specified in the URL route, not in the request body
- Ensure the virtual account has sufficient funds before making the request
Virtual Account Hierarchy Virtual accounts are sub-accounts linked to a parent account:
Virtual Account (Sub-Account) → Parent Account
When debiting a virtual account, funds flow from the virtual account to the parent account.
Idempotency
The API supports idempotency through the optional Idempotency-Key header:
- If no idempotency key is provided, the request is processed normally (duplicates are possible)
- If a valid UUID idempotency key is provided for a new transaction, the system stores the key and associates it with the transaction results
- If the same idempotency key is received again for the same endpoint/action, the system returns the previously stored response
- Idempotency keys are user-specific - different users with the same keys don't share cached responses
- The idempotency key must be a valid UUID format (e.g., "123e4567-e89b-12d3-a456-426614174000").
Content Negotiation
Clients must use the HTTP Accept header to indicate the desired response format:
- Set
Accept: application/jsonfor JSON responses (default) - Set
Accept: text/csvfor CSV responses If the Accept header is omitted,application/jsonis assumed.
Base URL:
All API requests use the versioned base URL:
https://api.bcbank.us/v1/virtual-accounts/{accountNumber}/transfers/debit
Sample Request in JavaScript:
async function debitVirtualAccount() {
try {
const accountNumber = "1000000000"; // Virtual account number
const response = await fetch(`https://api.bcbank.us/v1/virtual-accounts/${accountNumber}/transfers/debit`, {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
'Content-Type': 'application/json',
'Accept': 'application/json',
'Idempotency-Key': '123e4567-e89b-12d3-a456-426614174000' // Optional
},
body: JSON.stringify({
debitAmount: "1000.00",
debitAmountCurrency: "USD",
creditAccountNumber: "1000320567", // Parent/settlement account
creditAmountCurrency: "USD", // Must match debitAmountCurrency
})
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(`Debit transfer failed: ${JSON.stringify(errorData)}`);
}
const data = await response.json();
console.log('Debit transfer result:', data);
// Example processing of the returned object
const { id, status, uniqueIdentifier, details, linkedActivities } = data;
const { debitAmount, valueDate, childTransactionId, creditAmountCurrency, debitAccountNumber, creditAccountNumber } = details;
// Log the main transfer details
console.log('Transaction ID:', id);
console.log('Status:', status);
console.log('Unique Identifier:', uniqueIdentifier);
console.log('Debit Amount:', debitAmount.amount, debitAmount.currency);
console.log('Value Date:', valueDate);
console.log('Child Transaction ID:', childTransactionId);
console.log('Credit Amount Currency:', creditAmountCurrency);
// Process debit account information
console.log('Debit Account Number:', debitAccountNumber.number);
// Process credit account information
console.log('Credit Account Number:', creditAccountNumber.number);
// Process linked activities
linkedActivities.forEach(activity => {
console.log('Linked Activity ID:', activity.id);
console.log('Linked Activity Transaction Status:', activity.transactionStatus);
console.log('Linked Activity Status:', activity.status);
console.log('Linked Activity Unique Identifier:', activity.uniqueIdentifier);
const { arrangementId, activityId, productId, currencyId, effectiveDate } = activity.activityDetails;
console.log('Linked Activity Arrangement ID:', arrangementId);
console.log('Linked Activity Activity ID:', activityId);
console.log('Linked Activity Product ID:', productId);
console.log('Linked Activity Currency ID:', currencyId);
console.log('Linked Activity Effective Date:', effectiveDate);
});
// Final status logging
if (status === 'SUCCESS') {
console.log('The debit transfer was successful.');
} else {
console.log('The debit transfer failed:', status);
}
} catch (error) {
console.error('Error debiting virtual account:', error);
}
}
// Execute example
debitVirtualAccount();
Required Permission: withdraw-virtual-account
This endpoint requires the permission claim withdraw-virtual-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.
Request parameters
path requiredThe virtual account number to be debited.
string
Request body application/json
string requiredGets or sets the currency code of the debit amount. Exactly 3 letters (ISO 4217).
string requiredThe currency code for the credit amount, such as "USD", "EUR", etc. Exactly 3 letters (ISO 4217).
string requiredThe amount of money to be transferred. Ensure the amount does not exceed the available balance in the debit account.
string requiredThe account number of the recipient's account (destination/parent/settlement account).
Responses
The virtual account was debited successfully.
string requiredUnique identifier for the transfer
string requiredThe current processing status of the transaction, e.g. Completed, Pending, Failed
string requiredUnique identifier specific to this instance of the transfer
object Transfer data
Show properties
object requiredAmount that was intended to be transferred or paid, not including any additional fees or charges. It's the raw amount before any processing fees or other costs are added.
Show properties
string requiredCurrency ISO code
string requiredAmount
string requiredDate on which the transaction is officially settled, meaning the funds are considered to have been transferred legally and are available for use by the recipient
string Child transaction ID
string requiredCredit amount currency
object requiredUnique identifier of a bank account from which funds are being withdrawn or debited
Show properties
string requiredAccount number
array requiredAccount routing details
Show properties
arraystring requiredScheme value
string requiredAddress value
object requiredUnique identifier of a bank account that is set to receive funds
Show properties
string requiredAccount number
array requiredAccount routing details
Show properties
arraystring requiredScheme value
string requiredAddress value
array requiredList of related financial activities
Show properties
arraystring requiredThe unique identifier for the activity.
string requiredThe current processing status of the transaction.
string requiredThe general status of the activity.
string A unique identifier specific to this instance of the activity.
object requiredDetailed information about the activity.
Show properties
string requiredUnique identifier for the arrangement associated with this activity.
string requiredIdentifier for the type of activity.
string requiredProduct identifier related to the activity.
string requiredCurrency code for the activity.
string requiredDate when the activity becomes effective.
Request sample
curl --request POST \
--url 'https://api-uat.bcbank.us/v1/virtual-accounts/{accountNumber}/transfers/debit' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"creditAccountNumber": 1556008272,
"debitAmountCurrency": "USD",
"creditAmountCurrency": "USD",
"debitAmount": 100
}'Response sample
{
"id": "string",
"status": "string",
"uniqueIdentifier": "string",
"details": {
"debitAmount": {
"currency": {},
"amount": {}
},
"valueDate": "string",
"childTransactionId": "string",
"creditAmountCurrency": "string",
"debitAccountNumber": {
"number": {},
"accountRoutings": {}
},
"creditAccountNumber": {
"number": {},
"accountRoutings": {}
}
},
"linkedActivities": [
{
"id": "string",
"transactionStatus": "string",
"status": "string",
"uniqueIdentifier": "string",
"activityDetails": {
"arrangementId": {},
"activityId": {},
"productId": {},
"currencyId": {},
"effectiveDate": {}
}
}
]
}post/v1/virtual-accounts/{settlementAccountNumber}/settlements/internalCounter-party Settlement Transfer (Internal)
Counter-party Settlement Transfer (Internal)
Corporate Client initiates Settlement request to BCB to debit Settlement Account and credit to Counterparty Account. This endpoint allows clients to transfer funds from a settlement account to an internal counterparty account.
Key Features:
- Transfers funds from a settlement account to an internal counterparty account
- Supports idempotency to prevent duplicate transactions
- Validates account numbers and currency matching
- Supports both JSON and CSV response formats
- Automatic settlement account number validation
Important Notes:
- The settlementAccountNumber in the route parameter identifies the source settlement account
- The creditAccountNumber in the request body specifies the destination counterparty account
- Ensure the settlement account has sufficient funds before making the request
- Settlement accounts must be in an active state to process transfers
Settlement Account Structure
Settlement accounts are special accounts used for counterparty transactions:
Settlement Account → Counterparty Account (Internal)
When processing a settlement transfer, funds flow from the settlement account to the counterparty account.
Idempotency
The API supports idempotency through the optional Idempotency-Key header:
- If no idempotency key is provided, the request is processed normally (duplicates are possible)
- If a valid UUID idempotency key is provided for a new transaction, the system stores the key and associates it with the transaction results
- If the same idempotency key is received again for the same endpoint/action, the system returns the previously stored response
- Idempotency keys are user-specific - different users with the same keys don't share cached responses
- The idempotency key must be a valid UUID format (e.g., "123e4567-e89b-12d3-a456-426614174000").
Content Negotiation
Clients must use the HTTP Accept header to indicate the desired response format:
- Set
Accept: application/jsonfor JSON responses (default) - Set
Accept: text/csvfor CSV responses If the Accept header is omitted,application/jsonis assumed.
Base URL:
All API requests use the versioned base URL:
https://api.bcbank.us/v1/virtual-accounts/{settlementAccountNumber}/settlements/internal
Sample Request in JavaScript:
async function processInternalSettlement() {
try {
const settlementAccountNumber = "1000320559";
const response = await fetch(`https://api.bcbank.us/v1/virtual-accounts/${settlementAccountNumber}/settlements/internal`, {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
'Content-Type': 'application/json',
'Accept': 'application/json',
'Idempotency-Key': '123e4567-e89b-12d3-a456-426614174000' // Optional
},
body: JSON.stringify({
debitCurrency: "USD",
creditAmount: {
amount: "1000.00",
currency: "USD"
},
creditAccountNumber: "1000076925"
})
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(`Internal settlement failed: ${JSON.stringify(errorData)}`);
}
const data = await response.json();
console.log('Internal settlement result:', data);
// Example processing of the returned object
const { id, status, uniqueIdentifier, details, linkedActivities } = data;
const { creditAmount, debitAmountCurrency, debitAccountNumber, creditAccountNumber, valueDate } = details;
// Log the main transfer details
console.log('Transaction ID:', id);
console.log('Status:', status);
console.log('Unique Identifier:', uniqueIdentifier);
console.log('Credit Amount:', creditAmount.amount, creditAmount.currency);
console.log('Debit Amount Currency:', debitAmountCurrency);
console.log('Value Date:', valueDate);
// Process debit account information (settlement account)
console.log('Debit Account Number:', debitAccountNumber.number);
// Process credit account information (counterparty account)
console.log('Credit Account Number:', creditAccountNumber.number);
// Final status logging
if (status === 'success') {
console.log('The internal settlement was successful.');
} else {
console.log('The internal settlement failed:', status);
}
} catch (error) {
console.error('Error processing internal settlement:', error);
}
}
processInternalSettlement();
Required Permission: counter-party-settlement-transaction
This endpoint requires the permission claim counter-party-settlement-transaction 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.
Request parameters
path requiredThe settlement account number from which funds will be debited.
string
Request body application/json
string requiredThe currency code for the debit amount (e.g., "USD", "EUR"). Exactly 3 letters (ISO 4217).
object requiredThe amount to be credited to the destination account (amount and currency).
Show properties
string requiredCurrency ISO code
string requiredAmount
string requiredThe account number to which funds will be credited (destination account). Max length: 36 characters.
Responses
The settlement transfer was processed successfully.
string requiredUnique identifier for the transfer
string requiredThe current processing status of the transaction, e.g. Completed, Pending, Failed
string requiredUnique identifier specific to this instance of the transfer
object Transfer data
Show properties
object requiredAmount moved from settlement account to the account
Show properties
string requiredCurrency ISO code
string Amount. May be null when not yet known (e.g. cross-currency FX response before bank assigns rate).
string requiredDebit amount currency
object requiredUnique identifier of a bank account from which funds are being withdrawn or debited
Show properties
string requiredAccount number
array requiredAccount routing details
Show properties
arraystring requiredScheme value
string requiredAddress value
object requiredUnique identifier of a bank account that is set to receive funds
Show properties
string requiredAccount number
array requiredAccount routing details
Show properties
arraystring requiredScheme value
string requiredAddress value
string requiredDate on which the transaction
array requiredList of related financial activities
Show properties
arraystring requiredThe unique identifier for the activity.
string requiredThe current processing status of the transaction.
string requiredThe general status of the activity.
string A unique identifier specific to this instance of the activity.
object requiredDetailed information about the activity.
Show properties
string requiredUnique identifier for the arrangement associated with this activity.
string requiredIdentifier for the type of activity.
string requiredProduct identifier related to the activity.
string requiredCurrency code for the activity.
string requiredDate when the activity becomes effective.
Request sample
curl --request POST \
--url 'https://api-uat.bcbank.us/v1/virtual-accounts/{settlementAccountNumber}/settlements/internal' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"debitCurrency": "USD",
"creditAmount": {
"currency": "USD",
"amount": 0.01
},
"creditAccountNumber": 1000076925
}'Response sample
{
"id": "FT252324K67K",
"status": "success",
"uniqueIdentifier": "IRFX252332872527361.00",
"details": {
"creditAmount": {
"currency": "USD",
"amount": 10.01
},
"debitAmountCurrency": "USD",
"debitAccountNumber": {
"number": 1000320559,
"accountRoutings": []
},
"creditAccountNumber": {
"number": 1000076925,
"accountRoutings": []
},
"valueDate": "2025-08-20T07:36:00.0000000Z"
},
"linkedActivities": []
}post/v1/virtual-accounts/{settlementAccountNumber}/settlements/externalCounter-party Settlement Transfer (External)
Counter-party Settlement Transfer (External)
Corporate Client initiates External Settlement request to BCB to debit Settlement Account and credit to External Counterparty Account. This endpoint allows clients to transfer funds from a settlement account to an external counterparty account.
Key Features:
- Transfers funds from a settlement account to an external counterparty account
- Supports idempotency to prevent duplicate transactions
- Supports both JSON and CSV response formats
- Automatic settlement account number validation
- Includes beneficiary and ordering customer information for external transfers
- Supports both the existing same-currency payload and the additive cross-currency FX payload
Supported Request Formats
Use one of the following request shapes:
Existing format - same-currency:
{
"debitCurrency": "USD",
"creditAmount": {
"currency": "USD",
"amount": 2500
}
}
Additive format - cross-currency FX:
{
"debitAmount": {
"currency": "USD",
"amount": 2500
},
"creditAmount": {
"currency": "HKD"
}
}
Cross-Currency FX
-
Provide
debitAmount(currency and amount) when you want the debit side to be authoritative. -
Provide only
creditAmount.currencyin that case; the bank assigns the exchange rate and final credited amount before forwarding to the beneficiary. -
If
debitAmountis omitted, the existingdebitCurrency+creditAmount(currency + amount) format applies with no change to current behaviour. -
debitCurrencyis not deprecated and remains fully supported. -
Both payload formats are accepted and return a successful response.
Important Notes:
- The settlementAccountNumber in the route parameter identifies the source settlement account
- The request body specifies the destination external counterparty account via
creditorAccount.identification - Ensure the settlement account has sufficient funds before making the request
- Settlement accounts must be in an active state to process transfers
- External transfers require additional beneficiary information for compliance
Settlement Account Structure
Settlement accounts are special accounts used for counterparty transactions:
Settlement Account → External Counterparty Account
When processing an external settlement transfer, funds flow from the settlement account to the external counterparty account.
External Transfer Requirements
External transfers require additional information for regulatory compliance:
- debitCurrency: Currency to debit from the settlement account (e.g., "USD")
- creditAmount: Amount and currency to credit externally (e.g., { amount: "19", currency: "GBP" })
- debtor: Ordering customer information (e.g., company name or reference)
- debtorAgent: Ordering bank/agent identifier (free text)
- creditorAccount.identification: External beneficiary account identifier
- creditorAccount.name / additionalInformation: Beneficiary name and auxiliary details
- chargesType: Who bears charges (e.g., OUR, BEN, SHA)
- creditorAgent: Beneficiary bank info (identification, name, additionalInformation)
- intermediaryAgent (optional): Intermediary bank info (identification, name, additionalInformation)
- remittanceInformation (optional): Unstructured remittance lines
Creditor Agent (Beneficiary Bank)
- If
creditorAgent.identification(BIC/bank identifier) is provided,creditorAgent.nameandcreditorAgent.additionalInformationare optional and may be omitted. - If
creditorAgent.identificationis not provided, supplycreditorAgent.nameandcreditorAgent.additionalInformationto identify the beneficiary bank.
Idempotency
The API supports idempotency through the optional Idempotency-Key header:
- If no idempotency key is provided, the request is processed normally (duplicates are possible)
- If a valid UUID idempotency key is provided for a new transaction, the system stores the key and associates it with the transaction results
- If the same idempotency key is received again for the same endpoint/action, the system returns the previously stored response
- Idempotency keys are user-specific - different users with the same keys don't share cached responses
- The idempotency key must be a valid UUID format (e.g., "123e4567-e89b-12d3-a456-426614174000").
Content Negotiation
Clients must use the HTTP Accept header to indicate the desired response format:
- Set
Accept: application/jsonfor JSON responses (default) - Set
Accept: text/csvfor CSV responses If the Accept header is omitted,application/jsonis assumed.
Base URL:
All API requests use the versioned base URL:
https://api.bcbank.us/v1/virtual-accounts/{settlementAccountNumber}/settlements/external
Sample Request in JavaScript (Existing same-currency format):
async function processExternalSettlement() {
try {
const settlementAccountNumber = "1000320559";
const response = await fetch(`https://api.bcbank.us/v1/virtual-accounts/${settlementAccountNumber}/settlements/external`, {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
'Content-Type': 'application/json',
'Accept': 'application/json',
'Idempotency-Key': '123e4567-e89b-12d3-a456-426614174000' // Optional
},
body: JSON.stringify({
debitCurrency: "USD",
creditAmount: {
amount: "19",
currency: "GBP"
},
debtor: "ACME GLOBAL TRADING INC.",
debtorAgent: "FIRST ATLANTIC BANK",
creditorAccount: {
identification: "GB29NWBK60161331926819",
name: "OMEGA INTERNATIONAL LTD.",
additionalInformation: ["LONDON", "GB"]
},
chargesType: "OUR",
creditorAgent: {
identification: "//ZZ123456789",
name: "OMEGA BANK",
additionalInformation: ["LONDON", "UK"]
},
intermediaryAgent: {
identification: "INTL",
name: "EURO CLEAR BANK",
additionalInformation: ["BRUSSELS", "BE"]
},
remittanceInformation: ["INVOICE 2025-00042"]
})
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(`External settlement failed: ${JSON.stringify(errorData)}`);
}
const data = await response.json();
console.log('External settlement result:', data);
// Example processing of the returned object
const { id, status, uniqueIdentifier, details, linkedActivities } = data;
const { creditAmount, debitAmountCurrency, debitAccountNumber, creditAccountNumber, valueDate } = details;
// Log the main transfer details
console.log('Transaction ID:', id);
console.log('Status:', status);
console.log('Unique Identifier:', uniqueIdentifier);
console.log('Credit Amount:', creditAmount.amount, creditAmount.currency);
console.log('Debit Amount Currency:', debitAmountCurrency);
console.log('Value Date:', valueDate);
// Process debit account information (settlement account)
console.log('Debit Account Number:', debitAccountNumber.number);
// Process credit account information (external counterparty account)
console.log('Credit Account Number:', creditAccountNumber.number);
// Final status logging
if (status === 'success') {
console.log('The external settlement was successful.');
} else {
console.log('The external settlement failed:', status);
}
} catch (error) {
console.error('Error processing external settlement:', error);
}
}
processExternalSettlement();
Required Permission: counter-party-settlement-transaction
This endpoint requires the permission claim counter-party-settlement-transaction 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.
Request parameters
path requiredThe settlement account number from which funds will be debited.
string
Request body application/json
string requiredThe currency code for the debit amount (e.g., "USD", "EUR"). Exactly 3 letters (ISO 4217).
object requiredThe amount to be credited to the destination account (amount and currency).
Show properties
string requiredCurrency ISO code
string requiredAmount
string requiredThe account number to which funds will be credited (destination account). Max length: 36 characters.
string requiredThe ordering customer information or reference Max length: 35 characters.
string requiredThe ordering customer agent (e.g., bank identifier code). Max length: 35 characters.
object requiredUnambiguous identification of the account of the creditor to which a credit entry will be posted as a result of the payment transaction.
string requiredSpecifies which party/parties will bear the charges associated with the processing of the transaction, e.g. 'OUR' Max length: 3 characters.
object requiredFinancial institution servicing an account for the creditor.
object Agent between the debtor's agent and the creditor's agent.
array Remittance Information. Limit: up to 4 lines; each line max 35 characters.
Show properties
arraystring
object Optional. FX: debit amount; then only creditAmount.currency required.
Show properties
string requiredCurrency ISO code
string requiredAmount
Responses
The settlement transfer was processed successfully.
string requiredUnique identifier for the transfer
string requiredThe current processing status of the transaction, e.g. Completed, Pending, Failed
string requiredUnique identifier specific to this instance of the transfer
object Transfer data
Show properties
object requiredAmount moved from settlement account to the account
Show properties
string requiredCurrency ISO code
string Amount. May be null when not yet known (e.g. cross-currency FX response before bank assigns rate).
string requiredDebit amount currency
object requiredUnique identifier of a bank account from which funds are being withdrawn or debited
Show properties
string requiredAccount number
array requiredAccount routing details
Show properties
arraystring requiredScheme value
string requiredAddress value
object requiredUnique identifier of a bank account that is set to receive funds
Show properties
string requiredAccount number
array requiredAccount routing details
Show properties
arraystring requiredScheme value
string requiredAddress value
string requiredDate on which the transaction
array requiredList of related financial activities
Show properties
arraystring requiredThe unique identifier for the activity.
string requiredThe current processing status of the transaction.
string requiredThe general status of the activity.
string A unique identifier specific to this instance of the activity.
object requiredDetailed information about the activity.
Show properties
string requiredUnique identifier for the arrangement associated with this activity.
string requiredIdentifier for the type of activity.
string requiredProduct identifier related to the activity.
string requiredCurrency code for the activity.
string requiredDate when the activity becomes effective.
Request sample
curl --request POST \
--url 'https://api-uat.bcbank.us/v1/virtual-accounts/{settlementAccountNumber}/settlements/external' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"debitAmount": {
"currency": "USD",
"amount": 2500
},
"creditAmount": {
"currency": "HKD"
},
"debtor": "ACME GLOBAL TRADING INC.",
"debtorAgent": "FIRST ATLANTIC BANK",
"creditorAccount": {
"identification": "GB29NWBK60161331926819",
"name": "OMEGA INTERNATIONAL LTD.",
"additionalInformation": [
"LONDON",
"GB"
]
},
"chargesType": "OUR",
"creditorAgent": {
"identification": "//ZZ123456789",
"name": "OMEGA BANK",
"additionalInformation": [
"LONDON",
"UK"
]
},
"intermediaryAgent": {
"identification": "INTL",
"name": "EURO CLEAR BANK",
"additionalInformation": [
"BRUSSELS",
"BE"
]
},
"remittanceInformation": [
"INVOICE 2025-00042"
]
}'Response sample
{
"id": "FT252324K67K",
"status": "success",
"uniqueIdentifier": "IRFX252332872527361.00",
"details": {
"creditAmount": {
"currency": "USD",
"amount": 10.01
},
"debitAmountCurrency": "USD",
"debitAccountNumber": {
"number": 1000320559,
"accountRoutings": []
},
"creditAccountNumber": {
"number": 1000076925,
"accountRoutings": []
},
"valueDate": "2025-08-20T07:36:00.0000000Z"
},
"linkedActivities": []
}post/v1/virtual-accounts/{virtualAccountId}/withdrawals/internalWithdraw funds (Internal)
Withdraw funds (Internal)
Initiates an internal withdrawal transfer from a virtual account to an internal destination account. This endpoint allows clients to withdraw funds from a virtual account to an internal account within the institution.
Key Features:
- Withdraws funds from a virtual account to an internal destination account
- Supports idempotency to prevent duplicate transactions
- Validates account numbers and currency matching
- Supports both JSON and CSV response formats
- Automatic virtual account number validation
Important Notes:
- The virtualAccountId in the route parameter identifies the source virtual account
- The creditAccountNumber in the request body specifies the destination internal account
- Ensure the virtual account has sufficient funds before making the request
- Virtual accounts must be in an active state to process withdrawals
Virtual Account Withdrawal Structure
Virtual account withdrawals transfer funds from virtual accounts to internal accounts:
Virtual Account → Internal Destination Account
When processing a withdrawal transfer, funds flow from the virtual account to the internal destination account.
Idempotency
The API supports idempotency through the optional Idempotency-Key header:
- If no idempotency key is provided, the request is processed normally (duplicates are possible)
- If a valid UUID idempotency key is provided for a new transaction, the system stores the key and associates it with the transaction results
- If the same idempotency key is received again for the same endpoint/action, the system returns the previously stored response
- Idempotency keys are user-specific - different users with the same keys don't share cached responses
- The idempotency key must be a valid UUID format (e.g., "123e4567-e89b-12d3-a456-426614174000").
Content Negotiation
Clients must use the HTTP Accept header to indicate the desired response format:
- Set
Accept: application/jsonfor JSON responses (default) - Set
Accept: text/csvfor CSV responses If the Accept header is omitted,application/jsonis assumed.
Base URL:
All API requests use the versioned base URL:
https://api.bcbank.us/v1/virtual-accounts/{virtualAccountId}/withdrawals/internal
Sample Request in JavaScript:
async function withdrawFromVirtualAccount() {
try {
const virtualAccountId = "1000320575";
const response = await fetch(`https://api.bcbank.us/v1/virtual-accounts/${virtualAccountId}/withdrawals/internal`, {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
'Content-Type': 'application/json',
'Accept': 'application/json',
'Idempotency-Key': '123e4567-e89b-12d3-a456-426614174000' // Optional
},
body: JSON.stringify({
debitCurrency: "USD",
creditAmount: {
currency: "USD",
amount: "100.00"
},
creditAccountNumber: "1000076925"
})
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(`Withdrawal transfer failed: ${JSON.stringify(errorData)}`);
}
const data = await response.json();
console.log('Withdrawal transfer result:', data);
// Example processing of the returned object
const { id, status, uniqueIdentifier, details, linkedActivities } = data;
const { debitAmount, valueDate, childTransactionId, creditAmountCurrency, debitAccountNumber, creditAccountNumber } = details;
// Log the main transfer details
console.log('Transaction ID:', id);
console.log('Status:', status);
console.log('Unique Identifier:', uniqueIdentifier);
console.log('Debit Amount:', debitAmount.amount, debitAmount.currency);
console.log('Value Date:', valueDate);
console.log('Child Transaction ID:', childTransactionId);
console.log('Credit Amount Currency:', creditAmountCurrency);
// Process debit account information (virtual account)
console.log('Debit Account Number:', debitAccountNumber.number);
// Process credit account information (internal destination)
console.log('Credit Account Number:', creditAccountNumber.number);
// Process linked activities
linkedActivities.forEach(activity => {
console.log('Linked Activity ID:', activity.id);
console.log('Linked Activity Transaction Status:', activity.transactionStatus);
console.log('Linked Activity Status:', activity.status);
console.log('Linked Activity Unique Identifier:', activity.uniqueIdentifier);
const { arrangementId, activityId, productId, currencyId, effectiveDate } = activity.activityDetails;
console.log('Linked Activity Arrangement ID:', arrangementId);
console.log('Linked Activity Activity ID:', activityId);
console.log('Linked Activity Product ID:', productId);
console.log('Linked Activity Currency ID:', currencyId);
console.log('Linked Activity Effective Date:', effectiveDate);
});
// Final status logging
if (status === 'success') {
console.log('The virtual account withdrawal was successful.');
} else {
console.log('The virtual account withdrawal failed:', status);
}
} catch (error) {
console.error('Error withdrawing from virtual account:', error);
}
}
// Example usage:
withdrawFromVirtualAccount();
Required Permission: withdraw-virtual-account
This endpoint requires the permission claim withdraw-virtual-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.
Request parameters
path requiredThe virtual account number from which funds will be withdrawn.
string
Request body application/json
string requiredThe currency code for the debit amount (e.g., "USD", "EUR"). Exactly 3 letters (ISO 4217).
object requiredThe amount to be credited to the destination account (amount and currency).
Show properties
string requiredCurrency ISO code
string requiredAmount
string requiredThe account number to which funds will be credited (destination account). Max length: 36 characters.
object
Responses
The withdrawal transfer was processed successfully.
string requiredUnique identifier for the transfer
string requiredThe current processing status of the transaction, e.g. Completed, Pending, Failed
string requiredUnique identifier specific to this instance of the transfer
object Transfer data
array requiredList of related financial activities
Show properties
arraystring requiredThe unique identifier for the activity.
string requiredThe current processing status of the transaction.
string requiredThe general status of the activity.
string A unique identifier specific to this instance of the activity.
object requiredDetailed information about the activity.
Show properties
string requiredUnique identifier for the arrangement associated with this activity.
string requiredIdentifier for the type of activity.
string requiredProduct identifier related to the activity.
string requiredCurrency code for the activity.
string requiredDate when the activity becomes effective.
Request sample
curl --request POST \
--url 'https://api-uat.bcbank.us/v1/virtual-accounts/{virtualAccountId}/withdrawals/internal' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"debitCurrency": "USD",
"creditAmount": {
"currency": "USD",
"amount": 0.01
},
"creditAccountNumber": 1000076925
}'Response sample
{
"id": "FT252324K67K",
"status": "success",
"uniqueIdentifier": "IRFX252332872527361.00",
"details": {
"creditAmount": {
"currency": "USD",
"amount": 10.01
},
"debitAmountCurrency": "USD",
"debitAccountNumber": {
"number": 1000320559,
"accountRoutings": []
},
"creditAccountNumber": {
"number": 1000076925,
"accountRoutings": []
},
"valueDate": "2025-08-20T07:36:00.0000000Z"
},
"linkedActivities": []
}post/v1/virtual-accounts/{virtualAccountId}/withdrawals/externalWithdraw funds (External)
Withdraw funds (External)
Corporate Client initiates External Withdrawal request to BCB to debit Virtual Account and credit to External Beneficiary Account. This endpoint allows clients to withdraw funds from a virtual account to an external beneficiary account.
Key Features:
- Withdraws funds from a virtual account to an external beneficiary account
- Supports idempotency to prevent duplicate transactions
- Supports both JSON and CSV response formats
- Automatic virtual account number validation
- Includes comprehensive beneficiary and ordering customer information for external transfers
- Supports both the existing same-currency payload and the additive cross-currency FX payload
Supported Request Formats
Use one of the following request shapes:
Existing format - same-currency:
{
"debitCurrency": "USD",
"creditAmount": {
"currency": "USD",
"amount": 2500
}
}
Additive format - cross-currency FX:
{
"debitAmount": {
"currency": "USD",
"amount": 2500
},
"creditAmount": {
"currency": "HKD"
}
}
Cross-Currency FX
-
Provide
debitAmount(currency and amount) when you want the debit side to be authoritative. -
Provide only
creditAmount.currencyin that case; the bank assigns the exchange rate and final credited amount before forwarding to the beneficiary. -
If
debitAmountis omitted, the existingdebitCurrency+creditAmount(currency + amount) format applies with no change to current behaviour. -
debitCurrencyis not deprecated and remains fully supported. -
Both payload formats are accepted and return a successful response.
Important Notes:
- The virtualAccountId in the route parameter identifies the source virtual account
- The request body specifies the destination external beneficiary account via
creditorAccount.identification - Ensure the virtual account has sufficient funds before making the request
- Virtual accounts must be in an active state to process withdrawals
- External transfers require additional beneficiary information for compliance
Virtual Account Withdrawal Structure
Virtual account withdrawals transfer funds from virtual accounts to external beneficiary accounts:
Virtual Account → External Beneficiary Account
When processing an external withdrawal transfer, funds flow from the virtual account to the external beneficiary account.
External Transfer Requirements
External transfers require additional information for regulatory compliance:
- debitCurrency: Currency to debit from the virtual account (e.g., "USD")
- creditAmount: Amount and currency to credit externally (e.g., { amount: "2500.00", currency: "USD" })
- debtor: Ordering customer name or reference (required, max 35 characters)
- debtorAgent: Ordering bank/agent identifier (free text, max 35 characters) - Optional
- creditorAccount.identification: External beneficiary account identifier (required, max 35 characters)
- creditorAccount.name / additionalInformation: Beneficiary name and auxiliary details (optional)
- chargesType: Who bears charges (e.g., OUR, BEN, SHA)
- creditorAgent: Beneficiary bank info (identification, name, additionalInformation)
- intermediaryAgent (optional): Intermediary bank info (identification, name, additionalInformation)
- remittanceInformation (optional): Unstructured remittance lines
Creditor Agent (Beneficiary Bank)
- If
creditorAgent.identification(BIC/bank identifier) is provided,creditorAgent.nameandcreditorAgent.additionalInformationare optional and may be omitted. - If
creditorAgent.identificationis not provided, supplycreditorAgent.nameandcreditorAgent.additionalInformationto identify the beneficiary bank.
Idempotency
The API supports idempotency through the optional Idempotency-Key header:
- If no idempotency key is provided, the request is processed normally (duplicates are possible)
- If a valid UUID idempotency key is provided for a new transaction, the system stores the key and associates it with the transaction results
- If the same idempotency key is received again for the same endpoint/action, the system returns the previously stored response
- Idempotency keys are user-specific - different users with the same keys don't share cached responses
- The idempotency key must be a valid UUID format (e.g., "123e4567-e89b-12d3-a456-426614174000").
Content Negotiation
Clients must use the HTTP Accept header to indicate the desired response format:
- Set
Accept: application/jsonfor JSON responses (default) - Set
Accept: text/csvfor CSV responses If the Accept header is omitted,application/jsonis assumed.
Base URL:
All API requests use the versioned base URL:
https://api.bcbank.us/v1/virtual-accounts/{virtualAccountId}/withdrawals/external
Sample Request in JavaScript (Existing same-currency format):
async function processExternalWithdrawal() {
try {
const virtualAccountId = "1000320575";
const response = await fetch(`https://api.bcbank.us/v1/virtual-accounts/${virtualAccountId}/withdrawals/external`, {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
'Content-Type': 'application/json',
'Accept': 'application/json',
'Idempotency-Key': '123e4567-e89b-12d3-a456-426614174000' // Optional
},
body: JSON.stringify({
debitCurrency: "USD",
creditAmount: {
currency: "USD",
amount: "2500.00"
},
debtor: "John Smith Corporation",
debtorAgent: "CHASUS33XXX",
creditorAccount: {
identification: "GB29NWBK60161331926819",
name: "Acme Manufacturing Ltd",
additionalInformation: [
"123 Business Street",
"London, UK SW1A 1AA"
]
},
chargesType: "OUR",
creditorAgent: {
identification: "NWBKGB2L",
name: "NatWest Bank",
additionalInformation: [
"250 Bishopsgate",
"London, UK EC2M 4AA"
]
},
intermediaryAgent: {
identification: "CHASUS33",
name: "JPMorgan Chase Bank",
additionalInformation: [
"383 Madison Avenue",
"New York, NY 10017"
]
},
remittanceInformation: [
"Withdrawal from Virtual Account VA-2024-001",
"Transfer to external beneficiary account",
"Reference: WD-2024-789456"
]
})
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(`External withdrawal transfer failed: ${JSON.stringify(errorData)}`);
}
const data = await response.json();
console.log('External withdrawal transfer result:', data);
// Example processing of the returned object
const { id, status, uniqueIdentifier, details, linkedActivities } = data;
const { debitAmount, valueDate, childTransactionId, creditAmountCurrency, debitAccountNumber, creditAccountNumber } = details;
// Log the main transfer details
console.log('Transaction ID:', id);
console.log('Status:', status);
console.log('Unique Identifier:', uniqueIdentifier);
console.log('Debit Amount:', debitAmount.amount, debitAmount.currency);
console.log('Value Date:', valueDate);
console.log('Child Transaction ID:', childTransactionId);
console.log('Credit Amount Currency:', creditAmountCurrency);
// Process debit account information (virtual account)
console.log('Debit Account Number:', debitAccountNumber.number);
// Process credit account information (external beneficiary account)
console.log('Credit Account Number:', creditAccountNumber.number);
// Process linked activities
linkedActivities.forEach(activity => {
console.log('Linked Activity ID:', activity.id);
console.log('Linked Activity Transaction Status:', activity.transactionStatus);
console.log('Linked Activity Status:', activity.status);
console.log('Linked Activity Unique Identifier:', activity.uniqueIdentifier);
const { arrangementId, activityId, productId, currencyId, effectiveDate } = activity.activityDetails;
console.log('Linked Activity Arrangement ID:', arrangementId);
console.log('Linked Activity Activity ID:', activityId);
console.log('Linked Activity Product ID:', productId);
console.log('Linked Activity Currency ID:', currencyId);
console.log('Linked Activity Effective Date:', effectiveDate);
});
// Final status logging
if (status === 'success') {
console.log('The external withdrawal was successful.');
} else {
console.log('The external withdrawal failed:', status);
}
} catch (error) {
console.error('Error processing external withdrawal:', error);
}
}
// Example usage:
processExternalWithdrawal();
Required Permission: withdraw-virtual-account
This endpoint requires the permission claim withdraw-virtual-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.
Request parameters
path requiredThe virtual account number from which funds will be withdrawn.
string
Request body application/json
string requiredThe currency code for the debit amount (e.g., "USD", "EUR"). Exactly 3 letters (ISO 4217).
object requiredThe amount to be credited to the destination account (amount and currency).
Show properties
string requiredCurrency ISO code
string requiredAmount
string requiredThe account number to which funds will be credited (destination account). Max length: 36 characters.
object
string requiredThe ordering customer information or reference Max length: 35 characters.
string The ordering customer agent (e.g., bank identifier code). Max length: 35 characters.
object requiredUnambiguous identification of the account of the creditor to which a credit entry will be posted as a result of the payment transaction.
string requiredSpecifies which party/parties will bear the charges associated with the processing of the transaction, e.g. 'OUR' Max length: 3 characters.
object requiredFinancial institution servicing an account for the creditor.
object Agent between the debtor's agent and the creditor's agent.
array Remittance Information. Limit: up to 4 lines; each line max 35 characters.
Show properties
arraystring
object Optional. FX: debit amount; then only creditAmount.currency required.
Show properties
string requiredCurrency ISO code
string requiredAmount
Responses
The withdrawal transfer was processed successfully.
string requiredUnique identifier for the transfer
string requiredThe current processing status of the transaction, e.g. Completed, Pending, Failed
string requiredUnique identifier specific to this instance of the transfer
object Transfer data
array requiredList of related financial activities
Show properties
arraystring requiredThe unique identifier for the activity.
string requiredThe current processing status of the transaction.
string requiredThe general status of the activity.
string A unique identifier specific to this instance of the activity.
object requiredDetailed information about the activity.
Show properties
string requiredUnique identifier for the arrangement associated with this activity.
string requiredIdentifier for the type of activity.
string requiredProduct identifier related to the activity.
string requiredCurrency code for the activity.
string requiredDate when the activity becomes effective.
Request sample
curl --request POST \
--url 'https://api-uat.bcbank.us/v1/virtual-accounts/{virtualAccountId}/withdrawals/external' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"debitAmount": {
"currency": "USD",
"amount": 2500
},
"creditAmount": {
"currency": "HKD"
},
"debtor": "John Smith Corporation",
"debtorAgent": "CHASUS33XXX",
"creditorAccount": {
"identification": "GB29NWBK60161331926819",
"name": "Acme Manufacturing Ltd",
"additionalInformation": [
"123 Business Street",
"London, UK SW1A 1AA"
]
},
"chargesType": "OUR",
"creditorAgent": {
"identification": "NWBKGB2L",
"name": "NatWest Bank",
"additionalInformation": [
"250 Bishopsgate",
"London, UK EC2M 4AA"
]
},
"intermediaryAgent": {
"identification": "CHASUS33",
"name": "JPMorgan Chase Bank",
"additionalInformation": [
"383 Madison Avenue",
"New York, NY 10017"
]
},
"remittanceInformation": [
"Withdrawal from Virtual Account VA-2024-001",
"Transfer to external beneficiary account",
"Reference: WD-2024-789456"
]
}'Response sample
{
"id": "FT252324K67K",
"status": "success",
"uniqueIdentifier": "IRFX252332872527361.00",
"details": {
"creditAmount": {
"currency": "USD",
"amount": 10.01
},
"debitAmountCurrency": "USD",
"debitAccountNumber": {
"number": 1000320559,
"accountRoutings": []
},
"creditAccountNumber": {
"number": 1000076925,
"accountRoutings": []
},
"valueDate": "2025-08-20T07:36:00.0000000Z"
},
"linkedActivities": []
}post/v2/virtual-accounts/{virtualAccountId}/withdrawals/externalWithdraw funds (External V2)
Withdraw funds (External V2)
Corporate Client initiates External Withdrawal request to BCB to debit Virtual Account and credit to External Beneficiary Account. This endpoint allows clients to withdraw funds from a virtual account to an external beneficiary account.
V2 difference: The debtor field is a structured object ({ name, additionalInformation[] }) instead of the v1 plain string.
All other fields, behaviour, response shape, idempotency, and content negotiation are identical to v1.
Key Features:
- Withdraws funds from a virtual account to an external beneficiary account
- Supports idempotency to prevent duplicate transactions
- Supports both JSON and CSV response formats
- Automatic virtual account number validation
- Includes comprehensive beneficiary and ordering customer information for external transfers
- Supports both the existing same-currency payload and the additive cross-currency FX payload
- V2: Structured debtor with name and up to 3 address lines
Structured Debtor (V2)
The debtor field must be an object containing the ordering customer name and optional address lines:
{
"debtor": {
"name": "John Smith Corporation",
"additionalInformation": [
"123 Business Street",
"London, UK SW1A 1AA"
]
}
}
debtor.name: Required, max 35 charactersdebtor.additionalInformation: Optional, up to 3 lines, each max 35 characters
Supported Request Formats
Use one of the following request shapes:
Existing format - same-currency:
{
"debitCurrency": "USD",
"creditAmount": {
"currency": "USD",
"amount": 2500
}
}
Additive format - cross-currency FX:
{
"debitAmount": {
"currency": "USD",
"amount": 2500
},
"creditAmount": {
"currency": "HKD"
}
}
Cross-Currency FX
-
Provide
debitAmount(currency and amount) when you want the debit side to be authoritative. -
Provide only
creditAmount.currencyin that case; the bank assigns the exchange rate and final credited amount before forwarding to the beneficiary. -
If
debitAmountis omitted, the existingdebitCurrency+creditAmount(currency + amount) format applies with no change to current behaviour. -
debitCurrencyis not deprecated and remains fully supported. -
Both payload formats are accepted and return a successful response.
Important Notes:
- The virtualAccountId in the route parameter identifies the source virtual account
- The request body specifies the destination external beneficiary account via
creditorAccount.identification - Ensure the virtual account has sufficient funds before making the request
- Virtual accounts must be in an active state to process withdrawals
- External transfers require additional beneficiary information for compliance
Virtual Account Withdrawal Structure
Virtual account withdrawals transfer funds from virtual accounts to external beneficiary accounts:
Virtual Account → External Beneficiary Account
When processing an external withdrawal transfer, funds flow from the virtual account to the external beneficiary account.
External Transfer Requirements
External transfers require additional information for regulatory compliance:
- debitCurrency: Currency to debit from the virtual account (e.g., "USD")
- creditAmount: Amount and currency to credit externally (e.g., { amount: "2500.00", currency: "USD" })
- debtor: Ordering customer information as
{ name, additionalInformation[] }(V2: structured object; V1 uses a plain string) - debtor.additionalInformation: Up to 3 lines, each max 35 characters
- debtorAgent: Ordering bank/agent identifier (free text, max 35 characters) - Optional
- creditorAccount.identification: External beneficiary account identifier (required, max 35 characters)
- creditorAccount.name / additionalInformation: Beneficiary name and auxiliary details (optional)
- chargesType: Who bears charges (e.g., OUR, BEN, SHA)
- creditorAgent: Beneficiary bank info (identification, name, additionalInformation)
- intermediaryAgent (optional): Intermediary bank info (identification, name, additionalInformation)
- remittanceInformation (optional): Unstructured remittance lines
Creditor Agent (Beneficiary Bank)
- If
creditorAgent.identification(BIC/bank identifier) is provided,creditorAgent.nameandcreditorAgent.additionalInformationare optional and may be omitted. - If
creditorAgent.identificationis not provided, supplycreditorAgent.nameandcreditorAgent.additionalInformationto identify the beneficiary bank.
Idempotency
The API supports idempotency through the optional Idempotency-Key header:
- If no idempotency key is provided, the request is processed normally (duplicates are possible)
- If a valid UUID idempotency key is provided for a new transaction, the system stores the key and associates it with the transaction results
- If the same idempotency key is received again for the same endpoint/action, the system returns the previously stored response
- Idempotency keys are user-specific - different users with the same keys don't share cached responses
- The idempotency key must be a valid UUID format (e.g., "123e4567-e89b-12d3-a456-426614174000").
Content Negotiation
Clients must use the HTTP Accept header to indicate the desired response format:
- Set
Accept: application/jsonfor JSON responses (default) - Set
Accept: text/csvfor CSV responses If the Accept header is omitted,application/jsonis assumed.
Base URL:
All API requests use the versioned base URL:
https://api.bcbank.us/v2/virtual-accounts/{virtualAccountId}/withdrawals/external
Sample Request in JavaScript (Cross-currency FX format):
async function processExternalWithdrawalV2() {
try {
const virtualAccountId = "1000320575";
const response = await fetch(`https://api.bcbank.us/v2/virtual-accounts/${virtualAccountId}/withdrawals/external`, {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
'Content-Type': 'application/json',
'Accept': 'application/json',
'Idempotency-Key': '123e4567-e89b-12d3-a456-426614174000' // Optional
},
body: JSON.stringify({
debitAmount: {
currency: "USD",
amount: "2500.00"
},
creditAmount: {
currency: "HKD"
},
debtor: {
name: "John Smith Corporation",
additionalInformation: [
"123 Business Street",
"London, UK SW1A 1AA"
]
},
debtorAgent: "CHASUS33XXX",
creditorAccount: {
identification: "GB29NWBK60161331926819",
name: "Acme Manufacturing Ltd",
additionalInformation: [
"123 Business Street",
"London, UK SW1A 1AA"
]
},
chargesType: "OUR",
creditorAgent: {
identification: "NWBKGB2L",
name: "NatWest Bank",
additionalInformation: [
"250 Bishopsgate",
"London, UK EC2M 4AA"
]
},
intermediaryAgent: {
identification: "CHASUS33",
name: "JPMorgan Chase Bank",
additionalInformation: [
"383 Madison Avenue",
"New York, NY 10017"
]
},
remittanceInformation: [
"Withdrawal from Virtual Account VA-2024-001",
"Transfer to external beneficiary account",
"Reference: WD-2024-789456"
]
})
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(`External withdrawal transfer failed: ${JSON.stringify(errorData)}`);
}
const data = await response.json();
console.log('External withdrawal transfer result:', data);
// Example processing of the returned object
const { id, status, uniqueIdentifier, details, linkedActivities } = data;
const { debitAmount, valueDate, childTransactionId, creditAmountCurrency, debitAccountNumber, creditAccountNumber } = details;
// Log the main transfer details
console.log('Transaction ID:', id);
console.log('Status:', status);
console.log('Unique Identifier:', uniqueIdentifier);
console.log('Debit Amount:', debitAmount.amount, debitAmount.currency);
console.log('Value Date:', valueDate);
console.log('Child Transaction ID:', childTransactionId);
console.log('Credit Amount Currency:', creditAmountCurrency);
// Process debit account information (virtual account)
console.log('Debit Account Number:', debitAccountNumber.number);
// Process credit account information (external beneficiary account)
console.log('Credit Account Number:', creditAccountNumber.number);
// Process linked activities
linkedActivities.forEach(activity => {
console.log('Linked Activity ID:', activity.id);
console.log('Linked Activity Transaction Status:', activity.transactionStatus);
console.log('Linked Activity Status:', activity.status);
console.log('Linked Activity Unique Identifier:', activity.uniqueIdentifier);
const { arrangementId, activityId, productId, currencyId, effectiveDate } = activity.activityDetails;
console.log('Linked Activity Arrangement ID:', arrangementId);
console.log('Linked Activity Activity ID:', activityId);
console.log('Linked Activity Product ID:', productId);
console.log('Linked Activity Currency ID:', currencyId);
console.log('Linked Activity Effective Date:', effectiveDate);
});
// Final status logging
if (status === 'success') {
console.log('The external withdrawal was successful.');
} else {
console.log('The external withdrawal failed:', status);
}
} catch (error) {
console.error('Error processing external withdrawal:', error);
}
}
// Example usage:
processExternalWithdrawalV2();
Required Permission: withdraw-virtual-account
This endpoint requires the permission claim withdraw-virtual-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.
Request parameters
path requiredThe virtual account number from which funds will be withdrawn.
string
Request body application/json
string requiredThe currency code for the debit amount (e.g., "USD", "EUR"). Exactly 3 letters (ISO 4217).
object requiredThe amount to be credited to the destination account (amount and currency).
Show properties
string requiredCurrency ISO code
string requiredAmount
string requiredThe account number to which funds will be credited (destination account). Max length: 36 characters.
object
string requiredThe ordering customer information or reference Max length: 35 characters.
string The ordering customer agent (e.g., bank identifier code). Max length: 35 characters.
object requiredUnambiguous identification of the account of the creditor to which a credit entry will be posted as a result of the payment transaction.
string requiredSpecifies which party/parties will bear the charges associated with the processing of the transaction, e.g. 'OUR' Max length: 3 characters.
object requiredFinancial institution servicing an account for the creditor.
object Agent between the debtor's agent and the creditor's agent.
array Remittance Information. Limit: up to 4 lines; each line max 35 characters.
Show properties
arraystring
object Optional. FX: debit amount; then only creditAmount.currency required.
Show properties
string requiredCurrency ISO code
string requiredAmount
object Structured ordering customer information for v2. Shadows the v1 string debtor property on the base type.
Show properties
string Name by which the party is known and which is usually used to identify the party.
array Additional information about the party that may be required for processing the payment, such as address details, country codes, or specific payment instructions. Max 3 lines; each line max 35 characters.
Show properties
arraystring
Responses
The withdrawal transfer was processed successfully.
string requiredUnique identifier for the transfer
string requiredThe current processing status of the transaction, e.g. Completed, Pending, Failed
string requiredUnique identifier specific to this instance of the transfer
object Transfer data
array requiredList of related financial activities
Show properties
arraystring requiredThe unique identifier for the activity.
string requiredThe current processing status of the transaction.
string requiredThe general status of the activity.
string A unique identifier specific to this instance of the activity.
object requiredDetailed information about the activity.
Show properties
string requiredUnique identifier for the arrangement associated with this activity.
string requiredIdentifier for the type of activity.
string requiredProduct identifier related to the activity.
string requiredCurrency code for the activity.
string requiredDate when the activity becomes effective.
Request sample
curl --request POST \
--url 'https://api-uat.bcbank.us/v2/virtual-accounts/{virtualAccountId}/withdrawals/external' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"debitAmount": {
"currency": "USD",
"amount": 2500
},
"creditAmount": {
"currency": "HKD"
},
"debtor": {
"name": "John Smith Corporation",
"additionalInformation": [
"123 Business Street",
"London, UK SW1A 1AA"
]
},
"debtorAgent": "CHASUS33XXX",
"creditorAccount": {
"identification": "GB29NWBK60161331926819",
"name": "Acme Manufacturing Ltd",
"additionalInformation": [
"123 Business Street",
"London, UK SW1A 1AA"
]
},
"chargesType": "OUR",
"creditorAgent": {
"identification": "NWBKGB2L",
"name": "NatWest Bank",
"additionalInformation": [
"250 Bishopsgate",
"London, UK EC2M 4AA"
]
},
"intermediaryAgent": {
"identification": "CHASUS33",
"name": "JPMorgan Chase Bank",
"additionalInformation": [
"383 Madison Avenue",
"New York, NY 10017"
]
},
"remittanceInformation": [
"Withdrawal from Virtual Account VA-2024-001",
"Transfer to external beneficiary account",
"Reference: WD-2024-789456"
]
}'Response sample
{
"id": "FT252324K67K",
"status": "success",
"uniqueIdentifier": "IRFX252332872527361.00",
"details": {
"creditAmount": {
"currency": "USD",
"amount": 10.01
},
"debitAmountCurrency": "USD",
"debitAccountNumber": {
"number": 1000320559,
"accountRoutings": []
},
"creditAccountNumber": {
"number": 1000076925,
"accountRoutings": []
},
"valueDate": "2025-08-20T07:36:00.0000000Z"
},
"linkedActivities": []
}Notifications
Operationspost/v1/notifications/subscriptionsCreate a new notification subscription
Create a new notification subscription
Registers a webhook subscription to receive real-time deposit notifications.
Notification Pipeline Overview:
This endpoint is part of a two-stage deposit notification system:
Stage 1: Subscription Setup (this endpoint)
- Customers register their webhook URL and topic (e.g., "Deposits")
- The system stores the subscription with optional custom headers
- Subscriptions can be activated or deactivated
Stage 2: Webhook Delivery
- The system matches received events with active subscriptions
- Webhooks are delivered to registered endpoints with retry logic
Webhook Payload Structure:
When a deposit matches your subscription, you'll receive a POST request to your webhook URL containing:
{
"subscriptionId": "e2a55504-3924-4b48-9d7e-540efcd6fa30",
"topic": "Deposits",
"accountNumber": "1046406142",
"transactionId": "FT2384654NXF6",
"type": "Credit",
"value": {
"amount": "1000.00",
"currency": "USD"
},
"transactionType": "Swift payment",
"transactionDetails": "Payment details"
}
The webhook payload is defined by the NotificationResponse model.
Message Signing:
Webhook requests are signed for authenticity and replay protection.
- Asymmetric option (RSA-PSS + SHA-256): When response signing is enabled for your client configuration, webhooks include
Bcb-Signature,Bcb-Timestamp,Bcb-Nonce, andBcb-Signature-Version(e.g.,rsa-v1). Verify using the bank public key from/v1/.well-known/jwks.jsonand the canonical string{timestamp}{nonce}{METHOD}{path}{body}. - HMAC option: If
Bcb-Signature-Versionis absent, the webhook uses your Message Signing Secret returned by the credentials endpoints. Use the same signature string{timestamp}{nonce}{METHOD}{path}{body}and compare an HMAC-SHA256 hash. - Replay protection: Enforce ±5 minute timestamp tolerance and reject any repeated
{timestamp}:{nonce}pairs (cache the nonce for 5 minutes). See the Message Signing guide for full RSA and HMAC verification examples.
Idempotency:
This endpoint supports idempotency through the optional Idempotency-Key header:
- If no idempotency key is provided, the request is processed normally
- If a valid UUID idempotency key is provided, the system prevents duplicate subscriptions
- The idempotency key must be a valid UUID format (e.g., "123e4567-e89b-12d3-a456-426614174000")
Required Permission: receive-notifications
This endpoint requires the permission claim receive-notifications 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.
Request body application/json
string requiredobject string requiredAllowed: Deposits
Responses
string string requiredAllowed: Deposits
string requiredboolean requiredstring requiredstring object Request sample
curl --request POST \
--url 'https://api-uat.bcbank.us/v1/notifications/subscriptions' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"topic": "Deposits",
"callbackUrl": "https://your-webhook-endpoint.example.com/notifications/deposits",
"customHeaders": {
"X-Custom-Header": "your-custom-value",
"X-Api-Key": "your-api-key"
}
}'Response sample
{
"subscriptionId": "e2a55504-3924-4b48-9d7e-540efcd6fa30",
"topic": "Deposits",
"webhookUrl": "https://your-webhook-endpoint.example.com/notifications/deposits",
"isActive": true,
"createdUtc": "2025-01-15T11:30:00.0000000+01:00",
"updatedUtc": "2025-01-15T11:30:00.0000000+01:00",
"customHeaders": {
"X-Custom-Header": "your-custom-value",
"X-Api-Key": "your-api-key"
}
}get/v1/notifications/subscriptionsList subscriptions
List subscriptions
Retrieves all notification subscriptions for the authenticated client with pagination support.
Pagination:
- Use
pageStartto specify the starting page (default: 1) - Use
pageSizeto specify the number of items per page (default: 100, max: 500) - The response includes total count and pagination metadata
Response Details:
Returns a paginated list of subscriptions, each containing:
- Subscription ID (guid)
- Topic (e.g., "Deposits")
- Webhook URL
- Status (IsActive flag)
- Creation and update timestamps
Filtering:
- Only returns subscriptions owned by the authenticated client
- Includes both active and inactive subscriptions
- Results are ordered by creation date (newest first)
Required Permission: receive-notifications
This endpoint requires the permission claim receive-notifications 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.
Request parameters
query integer (int32)
query integer (int32)
Responses
object Show properties
object Show properties
integer requiredstring integer requiredinteger requiredarray Show properties
arraystring string requiredAllowed: Deposits
string requiredboolean requiredstring requiredstring object Request sample
curl --request GET \ --url 'https://api-uat.bcbank.us/v1/notifications/subscriptions' \ --header 'Authorization: Bearer YOUR_ACCESS_TOKEN'
Response sample
{
"meta": {
"pagination": {
"page_start": 1,
"page_token": "",
"total_size": 2,
"page_size": 100
}
},
"data": [
{
"subscriptionId": "e2a55504-3924-4b48-9d7e-540efcd6fa30",
"topic": "Deposits",
"webhookUrl": "https://your-webhook-endpoint.example.com/notifications/deposits",
"isActive": true,
"createdUtc": "2025-01-15T11:30:00.0000000+01:00",
"updatedUtc": "2025-01-15T11:30:00.0000000+01:00",
"customHeaders": {
"X-Custom-Header": "your-custom-value"
}
},
{
"subscriptionId": "f3b66615-4035-5c59-ae8f-651f9de7cb41",
"topic": "Deposits",
"webhookUrl": "https://backup-webhook.example.com/deposits",
"isActive": false,
"createdUtc": "2025-01-10T09:15:00.0000000+01:00",
"updatedUtc": "2025-01-14T17:45:00.0000000+01:00",
"customHeaders": null
}
]
}delete/v1/notifications/subscriptions/{subscriptionId}Deactivate a subscription
Deactivate a subscription
Deactivates an existing notification subscription. Once deactivated:
- The subscription will no longer receive webhook notifications
- Future deposits will not be matched to this subscription
- In-flight notifications will continue to be delivered
- The subscription record remains in the system but with IsActive=false
Behavior:
- Only the subscription owner can deactivate their own subscription
- Attempting to deactivate another client's subscription returns 404 Not Found
- Deactivating an already inactive subscription is idempotent (returns success)
Idempotency:
This endpoint supports idempotency through the optional Idempotency-Key header:
- If a valid UUID idempotency key is provided, repeated calls with the same key return the same result
- The idempotency key must be a valid UUID format (e.g., "123e4567-e89b-12d3-a456-426614174000")
Required Permission: receive-notifications
This endpoint requires the permission claim receive-notifications 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.
Request parameters
path requiredstring (guid)
Responses
string string requiredAllowed: Deposits
string requiredboolean requiredstring requiredstring object Request sample
curl --request DELETE \
--url 'https://api-uat.bcbank.us/v1/notifications/subscriptions/{subscriptionId}' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN'Response sample
{
"subscriptionId": "e2a55504-3924-4b48-9d7e-540efcd6fa30",
"topic": "Deposits",
"webhookUrl": "https://your-webhook-endpoint.example.com/notifications/deposits",
"isActive": true,
"createdUtc": "2025-01-15T11:30:00.0000000+01:00",
"updatedUtc": "2025-01-15T11:30:00.0000000+01:00",
"customHeaders": {
"X-Custom-Header": "your-custom-value",
"X-Api-Key": "your-api-key"
}
}get/v1/notifications/subscriptions/{subscriptionId}Get subscription
Get subscription
Retrieves a specific notification subscription by its unique identifier.
Response Details:
The response includes:
- Subscription ID (guid)
- Topic (e.g., "Deposits")
- Webhook URL
- Status (IsActive flag)
- Creation and update timestamps
- Client association
Security:
- Only the subscription owner can retrieve their own subscription
- Attempting to retrieve another client's subscription returns 404 Not Found
Required Permission: receive-notifications
This endpoint requires the permission claim receive-notifications 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.
Request parameters
path requiredstring (guid)
Responses
string string requiredAllowed: Deposits
string requiredboolean requiredstring requiredstring object Request sample
curl --request GET \
--url 'https://api-uat.bcbank.us/v1/notifications/subscriptions/{subscriptionId}' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN'Response sample
{
"subscriptionId": "e2a55504-3924-4b48-9d7e-540efcd6fa30",
"topic": "Deposits",
"webhookUrl": "https://your-webhook-endpoint.example.com/notifications/deposits",
"isActive": true,
"createdUtc": "2025-01-15T11:30:00.0000000+01:00",
"updatedUtc": "2025-01-15T11:30:00.0000000+01:00",
"customHeaders": {
"X-Custom-Header": "your-custom-value",
"X-Api-Key": "your-api-key"
}
}Background Jobs
Operationsget/v1/jobsGet All Background Jobs
Get All Background Jobs
Retrieves a paginated list of background jobs for the authenticated client. This endpoint:
- Returns only active jobs (status: Pending or InProgress)
- Completed, failed, or cancelled jobs are not included in this list
- Provides job status information including progress summaries
- Supports pagination for efficient handling of large job datasets
Job Status Information
Each job entry includes:
- JobId: Unique identifier for the batch job
- JobStatus: Current status (Pending, InProgress, Completed, CompletedWithErrors, Cancelled)
- Pending: Job has been created and is waiting to be processed
- InProgress: Job is currently being processed
- Completed: Job has completed successfully with no errors
- CompletedWithErrors: Job has completed but some items failed during processing
- Cancelled: Job has been cancelled and will not be processed further
- EventType: Type of status event (typically "job.status")
- Summary: Progress statistics (Total, Completed, Failed counts)
Pagination
This endpoint uses simple numeric pagination:
- pageStart: 1-based index of the first record to return (default: 1)
- pageSize: Number of records to return (default: 100, maximum: 1000)
- Total Pages: Calculate using
Math.ceil(total_size / page_size)from response metadata
Content Negotiation
Clients must use the HTTP Accept header to indicate the desired response format:
- Set
Accept: application/jsonfor JSON responses (default) - Set
Accept: text/csvfor CSV responses If the Accept header is omitted,application/jsonis assumed.
Base URL
All API requests use the versioned base URL:
https://api.bcbank.us/v1/jobs
Sample Request in JavaScript
async function getAllBackgroundJobs(pageStart = 1, pageSize = 50) {
try {
// Build URL with pagination parameters
let url = 'https://api.bcbank.us/v1/jobs';
const params = new URLSearchParams();
params.append('pageStart', pageStart.toString());
params.append('pageSize', pageSize.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(`Background jobs retrieval failed: ${JSON.stringify(errorData)}`);
}
// Parse JSON response
const result = await response.json();
// Access pagination info
const pagination = result.meta.pagination;
console.log(`Page: ${pagination.page_start}, Size: ${pagination.page_size}, Total: ${pagination.total_size}`);
// Process background jobs
result.data.forEach((job, index) => {
console.log(`Job ${index + 1}:`);
console.log(` Job ID: ${job.jobId}`);
console.log(` Status: ${job.jobStatus}`);
console.log(` Event Type: ${job.eventType}`);
console.log(` Summary:`);
console.log(` Total: ${job.summary.total}`);
console.log(` Completed: ${job.summary.completed}`);
console.log(` Failed: ${job.summary.failed}`);
console.log('---');
});
return result;
} catch (error) {
console.error('Failed to retrieve background jobs:', error.message);
throw error;
}
}
// Example usage:
// Get first 50 jobs
getAllBackgroundJobs(1, 50);
// Get next page
getAllBackgroundJobs(2, 50);
// Get all jobs with default pagination
getAllBackgroundJobs();
Request parameters
query integer (int32)
query integer (int32)
Responses
OK - The request was successful.
object Show properties
object Show properties
integer requiredstring integer requiredinteger requiredarray Show properties
arraystring requiredThe type of event (e.g., "job.completed", "job.failed")
string requiredUnique identifier for the batch job
string requiredJob status (e.g., "Pending", "InProgress", "Completed", "Failed")
object requiredSummary of job execution statistics
Show properties
integer requiredTotal number of items in the batch
integer requiredNumber of items successfully completed
integer requiredNumber of items that failed
Request sample
curl --request GET \ --url 'https://api-uat.bcbank.us/v1/jobs' \ --header 'Authorization: Bearer YOUR_ACCESS_TOKEN'
Response sample
{
"meta": {
"pagination": {
"page_start": {},
"page_token": {},
"total_size": {},
"page_size": {}
}
},
"data": [
{
"eventType": "string",
"jobId": "string",
"jobStatus": "string",
"summary": {
"total": {},
"completed": {},
"failed": {}
}
}
]
}get/v1/jobs/{jobId}Get Job Status
Get Job Status
Retrieves the current status and progress information for a specific background job. This endpoint:
- Returns detailed status information for the specified job
- Provides real-time progress statistics (total, completed, failed counts)
- Shows current job status (Pending, InProgress, Completed, Failed, Cancelled)
- Includes event type information for status tracking
Job Status Information
The response includes:
- JobId: Unique identifier for the batch job
- JobStatus: Current status (Pending, InProgress, Completed, CompletedWithErrors, Cancelled)
- Pending: Job has been created and is waiting to be processed
- InProgress: Job is currently being processed
- Completed: Job has completed successfully with no errors
- CompletedWithErrors: Job has completed but some items failed during processing
- Cancelled: Job has been cancelled and will not be processed further
- EventType: Type of status event (typically "job.status")
- Summary: Progress statistics (Total, Completed, Failed counts)
Callback Notifications
When a job reaches a completed state (Completed or CompletedWithErrors), the system automatically sends a callback notification to the callbackUrl provided during job creation (if specified).
This callback allows you to receive real-time notifications without polling the status endpoint.
Sample Callback Payload:
{
"eventType": "job.completed",
"jobId": "badabb89-8cdb-4d3d-aaf0-c714f487f1bc",
"jobStatus": "Completed",
"summary": {
"total": 1,
"completed": 1,
"failed": 0
}
}
Message Signing
Callback notifications are signed. When your client configuration enables response signing, callbacks use the asymmetric option (RSA-PSS + SHA-256) and include Bcb-Signature, Bcb-Timestamp, Bcb-Nonce, and Bcb-Signature-Version (e.g., rsa-v1). If asymmetry is not configured, callbacks use the HMAC option with your Message Signing Secret and no Bcb-Signature-Version header. See the Message Signing guide for verification steps.
Content Negotiation
Clients must use the HTTP Accept header to indicate the desired response format:
- Set
Accept: application/jsonfor JSON responses (default) - Set
Accept: text/csvfor CSV responses If the Accept header is omitted,application/jsonis assumed.
Base URL
All API requests use the versioned base URL:
https://api.bcbank.us/v1/jobs/{jobId}
Sample Request in JavaScript
async function getJobStatus(jobId) {
try {
const url = `https://api.bcbank.us/v1/jobs/${jobId}`;
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(`Job status retrieval failed: ${JSON.stringify(errorData)}`);
}
// Parse JSON response
const jobStatus = await response.json();
// Display job information
console.log('Job Status:');
console.log(` Job ID: ${jobStatus.jobId}`);
console.log(` Status: ${jobStatus.jobStatus}`);
console.log(` Event Type: ${jobStatus.eventType}`);
console.log(` Progress Summary:`);
console.log(` Total Items: ${jobStatus.summary.total}`);
console.log(` Completed: ${jobStatus.summary.completed}`);
console.log(` Failed: ${jobStatus.summary.failed}`);
console.log(` Progress: ${((jobStatus.summary.completed / jobStatus.summary.total) * 100).toFixed(1)}%`);
return jobStatus;
} catch (error) {
console.error('Failed to retrieve job status:', error.message);
throw error;
}
}
// Example usage:
// Get status for a specific job
getJobStatus('550e8400-e29b-41d4-a716-446655440001');
Request parameters
path requiredThe unique identifier of the background job to retrieve status for.
string
Responses
OK - The request was successful.
string requiredThe type of event (e.g., "job.completed", "job.failed")
string requiredUnique identifier for the batch job
string requiredJob status (e.g., "Pending", "InProgress", "Completed", "Failed")
object requiredSummary of job execution statistics
Show properties
integer requiredTotal number of items in the batch
integer requiredNumber of items successfully completed
integer requiredNumber of items that failed
Request sample
curl --request GET \
--url 'https://api-uat.bcbank.us/v1/jobs/{jobId}' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN'Response sample
{
"eventType": "string",
"jobId": "string",
"jobStatus": "string",
"summary": {
"total": 0,
"completed": 0,
"failed": 0
}
}delete/v1/jobs/{jobId}Cancel Job
Cancel Job
Cancels a background job and stops processing of all pending and in-progress items. This endpoint:
- Cancels the specified job if it's in a cancellable state
- Stops processing of all pending and in-progress items within the job
- Marks cancelled items with appropriate error messages
- Returns the updated job status after cancellation
- Provides immediate feedback on cancellation success
Cancellation Rules
A job can only be cancelled if it's in one of these states:
- Pending: Job has been created but not yet started processing
- InProgress: Job is currently being processed
Jobs in these states cannot be cancelled:
- Completed: Job has already finished successfully
- CompletedWithErrors: Job has finished with some failures
- Cancelled: Job has already been cancelled
What Happens During Cancellation
- Job Status Update: The job status is changed to "Cancelled"
- Item Cancellation: All pending and in-progress items are marked as "Cancelled"
- Error Messages: Cancelled items receive the error message "Job was cancelled by user request"
- Counter Updates: Job completion counters are recalculated from the database
- Immediate Effect: Processing stops immediately for all affected items
Content Negotiation
Clients must use the HTTP Accept header to indicate the desired response format:
- Set
Accept: application/jsonfor JSON responses (default) - Set
Accept: text/csvfor CSV responses If the Accept header is omitted,application/jsonis assumed.
Base URL
All API requests use the versioned base URL:
https://api.bcbank.us/v1/jobs/{jobId}
Idempotency
The API supports idempotency through the optional Idempotency-Key header:
- If no idempotency key is provided, the request is processed normally (duplicates are possible)
- If a valid UUID idempotency key is provided, the system stores the key and associates it with the batch job
- If the same idempotency key is received again, the system returns the previously stored response
- Idempotency keys are user-specific - different users with the same keys don't share cached responses
- The idempotency key must be a valid UUID format (e.g., "123e4567-e89b-12d3-a456-426614174000")
Sample Request in JavaScript
async function cancelJob(jobId) {
try {
const url = `https://api.bcbank.us/v1/jobs/${jobId}`;
const response = await fetch(url, {
method: 'DELETE',
headers: {
'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(`Job cancellation failed: ${JSON.stringify(errorData)}`);
}
// Parse JSON response
const jobStatus = await response.json();
// Display cancellation result
console.log('Job Cancellation Result:');
console.log(` Job ID: ${jobStatus.jobId}`);
console.log(` Status: ${jobStatus.jobStatus}`);
console.log(` Event Type: ${jobStatus.eventType}`);
console.log(` Final Summary:`);
console.log(` Total Items: ${jobStatus.summary.total}`);
console.log(` Completed: ${jobStatus.summary.completed}`);
console.log(` Failed: ${jobStatus.summary.failed}`);
console.log(` Cancelled: ${jobStatus.summary.total - jobStatus.summary.completed - jobStatus.summary.failed}`);
return jobStatus;
} catch (error) {
console.error('Failed to cancel job:', error.message);
throw error;
}
}
// Example usage:
// Cancel a specific job
cancelJob('550e8400-e29b-41d4-a716-446655440001');
Request parameters
path requiredThe unique identifier of the background job to cancel.
string
Responses
OK - The job was cancelled successfully.
string requiredThe type of event (e.g., "job.completed", "job.failed")
string requiredUnique identifier for the batch job
string requiredJob status (e.g., "Pending", "InProgress", "Completed", "Failed")
object requiredSummary of job execution statistics
Show properties
integer requiredTotal number of items in the batch
integer requiredNumber of items successfully completed
integer requiredNumber of items that failed
Request sample
curl --request DELETE \
--url 'https://api-uat.bcbank.us/v1/jobs/{jobId}' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN'Response sample
{
"eventType": "job.status",
"jobId": "550e8400-e29b-41d4-a716-446655440001",
"jobStatus": "InProgress",
"summary": {
"total": 150,
"completed": 45,
"failed": 2
}
}get/v1/jobs/{jobId}/resultsGet Job Results
Get Job Results
Retrieves the detailed results for a specific background job. This endpoint:
- Returns paginated results for all items processed in the job
- Provides detailed information about each item's processing outcome
- Shows processing status, attempts, HTTP responses, and error details
- Includes original payload and result data for auditing
- Supports pagination for efficient handling of large result sets
Job Results Information
Each result entry includes:
- Id: Internal numeric identifier for this item result
- JobId: Identifier of the parent batch job
- ExternalItemId: Client-supplied item identifier from the original batch
- PayloadJson: Original request payload serialized as JSON
- Status: Current processing status (Pending, InProgress, Completed, Failed, Cancelled)
- Attempt: Number of processing attempts made for this item
- HttpStatusCode: HTTP status code returned by the target endpoint
- ResultJson: Response payload from the target endpoint (if successful)
- ErrorMessage: Error details (if processing failed)
Pagination
This endpoint uses simple numeric pagination:
- pageStart: 1-based index of the first record to return (default: 1)
- pageSize: Number of records to return (default: 100, maximum: 1000)
- Total Pages: Calculate using
Math.ceil(total_size / page_size)from response metadata
Content Negotiation
Clients must use the HTTP Accept header to indicate the desired response format:
- Set
Accept: application/jsonfor JSON responses (default) - Set
Accept: text/csvfor CSV responses If the Accept header is omitted,application/jsonis assumed.
Base URL
All API requests use the versioned base URL:
https://api.bcbank.us/v1/jobs/{jobId}/results
Sample Request in JavaScript
async function getJobResults(jobId, pageStart = 1, pageSize = 50) {
try {
const url = `https://api.bcbank.us/v1/jobs/${jobId}/results`;
const params = new URLSearchParams();
params.append('pageStart', pageStart.toString());
params.append('pageSize', pageSize.toString());
const fullUrl = url + '?' + params.toString();
const response = await fetch(fullUrl, {
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(`Job results retrieval failed: ${JSON.stringify(errorData)}`);
}
// Parse JSON response
const result = await response.json();
// Access pagination info
const pagination = result.meta.pagination;
console.log(`Page: ${pagination.page_start}, Size: ${pagination.page_size}, Total: ${pagination.total_size}`);
// Process job results
result.data.forEach((item, index) => {
console.log(`Result ${index + 1}:`);
console.log(` Item ID: ${item.externalItemId}`);
console.log(` Status: ${item.status}`);
console.log(` Attempts: ${item.attempt}`);
console.log(` HTTP Status: ${item.httpStatusCode}`);
if (item.errorMessage) {
console.log(` Error: ${item.errorMessage}`);
}
if (item.resultJson) {
console.log(` Result: ${item.resultJson}`);
}
console.log('---');
});
return result;
} catch (error) {
console.error('Failed to retrieve job results:', error.message);
throw error;
}
}
// Example usage:
// Get first 50 results for a job
getJobResults('550e8400-e29b-41d4-a716-446655440001', 1, 50);
// Get next page of results
getJobResults('550e8400-e29b-41d4-a716-446655440001', 2, 50);
// Get all results with default pagination
getJobResults('550e8400-e29b-41d4-a716-446655440001');
Request parameters
path requiredThe unique identifier of the background job to retrieve results for.
string
query integer (int32)
query integer (int32)
Responses
OK - The request was successful.
object Show properties
object Show properties
integer requiredstring integer requiredinteger requiredarray Show properties
arraystring requiredInternal identifier for this item result.
string requiredIdentifier of the parent batch job that this item belongs to.
string requiredClient supplied item identifier (mirrors the batch Items[i].Id provided at submission time).
string requiredOriginal request payload serialized as JSON for auditing and replay diagnostics.
string requiredCurrent processing status of the item (e.g. Pending, InProgress, Completed, Failed, Cancelled).
integer requiredNumber of processing attempts made for this item (incremented on retry).
integer requiredHTTP status code returned by the target endpoint for the most recent attempt.
string Error message or diagnostic detail if processing failed; otherwise null.
string Serialized JSON response body produced by the target endpoint on success (or last attempt); may be null.
string requiredUTC timestamp when the item result record was created (queued).
string UTC timestamp when the item reached a terminal state (Completed, Failed, Cancelled); otherwise null.
Request sample
curl --request GET \
--url 'https://api-uat.bcbank.us/v1/jobs/{jobId}/results' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN'Response sample
{
"meta": {
"pagination": {
"page_start": {},
"page_token": {},
"total_size": {},
"page_size": {}
}
},
"data": [
{
"id": "string",
"jobId": "string",
"externalItemId": "string",
"payloadJson": "string",
"status": "string",
"attempt": 0,
"httpStatus": 0,
"error": "string",
"resultJson": "string",
"createdUtc": "string",
"finishedUtc": "string"
}
]
}System
Operationsget/v1/system/timeGet system time
Get system time
Returns the current server date and time in ISO-8601 format. This endpoint helps integrators synchronize with the server clock and craft valid date/time windows for other API requests.
The response contains two fields:
- <code>timestamp</code> – Current Bermuda local time in ISO-8601 format with the correct offset (e.g., <code>2025-01-07T14:30:15-04:00</code>).
- <code>timeZone</code> – Display name of the time zone currently in effect (<em>"Atlantic Daylight Time"</em> or <em>"Atlantic Standard Time"</em>).
This allows clients to know both the precise instant and whether Daylight-Saving Time is observed.
Content Negotiation
Clients must use the HTTP Accept header to indicate the desired response format:
- Set
Accept: application/jsonfor JSON responses (default) If the Accept header is omitted,application/jsonis assumed.
Base URL:
All API requests use the versioned base URL:
https://api.bcbank.us/v1/system/time
Sample Request in JavaScript:
async function getSystemTime() {
try {
const response = await fetch('https://api.bcbank.us/v1/system/time', {
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('Server timestamp (Bermuda time UTC-4):', data.timestamp);
return data;
} catch (error) {
console.error('There was a problem retrieving system time:', error.message);
}
}
// Example usage:
getSystemTime();
Responses
OK - The request was successful.
string requiredCurrent server timestamp in ISO-8601 format (e.g., 2025-01-07T14:30:15-04:00)
string requiredCurrent server time zone in IANA format (e.g., "Atlantic Daylight Time")
Request sample
curl --request GET \ --url 'https://api-uat.bcbank.us/v1/system/time' \ --header 'Authorization: Bearer YOUR_ACCESS_TOKEN'
Response sample
{
"timestamp": "2025-01-07T19:30:15.1230000+01:00",
"timeZone": "Atlantic Standard Time"
}