Use this page when a VAS flow appears to work in theory but fails in UAT.
| Symptom | What it usually means | What to do |
|---|---|---|
POST /v1/virtual-accounts returns 202 Pending | The request has been queued, not completed | Poll GET /v1/jobs/{jobId} and then read GET /v1/jobs/{jobId}/results |
Job ends in CompletedWithErrors | One or more submitted items failed | Inspect each item in the job results and use the item httpStatus, error, and resultJson |
Same-currency internal transfer between two virtual accounts returns 400 | Sub account to sub account is not a permitted VAS flow | Use only supported VAS flows; do not implement Sub -> Sub transfers |
GET /v1/virtual-accounts includes unexpected accounts | The endpoint returns settlement, parent, and sub accounts together | Filter by category and keep only CMS Sub Acct for customer-facing lists |
PATCH of clientReference works in the API but not in the portal UI | The API and portal UI are not behaving identically in UAT | Trust the API response, verify with GET /v1/virtual-accounts, and review the UAT limitations page |
| Create request for a non-USD currency fails in job results | That currency is not provisioned for your client | Ask BCB to provision both a Settlement Account and Parent Account in that currency |
POST /v1/virtual-accounts is asynchronous by design.
202 Acceptedmeans the job was queued successfully.- You do not have a usable
virtualAccountNumberyet. - Your next call must be
GET /v1/jobs/{jobId}orGET /v1/jobs/{jobId}/results.
If your application treats Pending as failure, fix that logic first.
CompletedWithErrors means the batch finished but at least one item failed.
Use GET /v1/jobs/{jobId}/results and check each result item:
httpStatuserrorresultJson
Typical pattern:
- successful items have
httpStatus: 200or201and a populatedresultJson - failed items have
httpStatus: 400and a populatederror
Do not assume a batch is unusable just because one item failed.
This is the most common integration mistake.
Even if both accounts:
- belong to the same client
- are in the same currency
- are visible in the same portal
that still does not make Sub -> Sub a valid VAS flow.
- external deposit into a sub account
- Settlement -> Parent -> Sub
- Sub -> Parent -> Settlement
- Sub -> same-name external beneficiary account
- Settlement -> external counterparty
- Sub -> Sub
- Settlement -> Sub direct bypass
- Sub -> Settlement direct bypass
- third-party or joint-account funding where same-name controls are not met
Read the API Flows guide before wiring any money movement logic.
If job results show an error like:
{
"error": "BAD_REQUEST",
"message": "... No parent account with matching currency found"
}the problem is account provisioning, not your request syntax.
For each currency, your client must already have:
- one Settlement Account
- one Parent Account
Use GET /v1/virtual-accounts?currency=EUR to verify whether those account categories exist.
This endpoint is easy to misread.
It returns:
CMS SettlementCMS Parent CateCMS Sub Acct
That means:
- the endpoint is useful for confirming provisioning
- the endpoint is not a pure list of customer sub accounts unless you filter it yourself
If your application stores only "virtual accounts", you should usually keep only rows where:
category === "CMS Sub Acct"If you need to attach your own identifier after account creation, use:
PATCH /v1/virtual-accounts/{virtualAccountNumber}
Example body:
{
"clientReference": "USER-12345-PRIMARY"
}If this fails in the portal UI, retry with the API before assuming the account is immutable. clientReference is specifically designed to remain updateable.
When the portal UI and API do not agree:
- Verify the account with
GET /v1/virtual-accounts/{virtualAccountNumber}. - Verify the account list with
GET /v1/virtual-accounts. - Verify async outcomes through the jobs endpoints.
- Keep the request/response payloads and job IDs for support.
In UAT, do not rely on the portal alone to determine whether a VAS action succeeded.
- Start with the UAT quickstart.
- Check the UAT limitations page.
- Contact api@bcb.bm or your Relationship Manager with the failing payload, job ID, and currency.