Request a virtual bank account after onboarding
Create, complete, and monitor a virtual bank account request for an existing sender.
Request an account after onboarding
This workflow is for API merchants managing senders created under their merchant integration. It cannot be used to act on a sender owned by the standalone Sender Portal.
Use the API key and secret associated with the sender's merchant. The sender must use sender-funded deposits; otherwise the response reports deposit_source_not_sender.
Workflow
POST setup-request
→ follow blocker actions
→ GET setup-request until completed
→ GET the sender's available virtual bank accounts1. Create the setup request
POST /v1/senders/{senderId}/virtual-bank-accounts/{currency}/setup-requestUse USD, EUR, GBP, or MXN. No request body or setup-request ID is required.
The operation creates or reuses the sender's current request for that currency. If an available account already exists, the API returns 409 VIRTUAL_BANK_ACCOUNT_ALREADY_EXISTS with a link to retrieve it.
2. Read blockers
{
"data": {
"currency": "EUR",
"status": "waiting_for_data",
"requestedAt": "2026-08-27T08:00:00.000Z",
"completedAt": null,
"blockers": [
{
"code": "missing_data",
"subject": { "type": "ubo", "id": "ubo-456" },
"fields": [{ "name": "uboNationalities", "label": "Nationality" }],
"action": {
"method": "PATCH",
"path": "/v1/senders/sender-123/virtual-bank-accounts/EUR/setup-request/data",
"bodyFields": ["uboNationalities"]
}
},
{
"code": "missing_associate",
"subject": {
"type": "associate",
"roles": ["director"],
"minimumCount": 1
},
"fields": [{ "name": "roles", "label": "Add 1 associate(s)" }],
"action": {
"method": "POST",
"path": "/v1/senders/associates",
"bodyFields": [
"senderId", "linkedUboId", "firstName", "lastName", "birthDate",
"email", "phone", "address", "roles", "nationality", "identity",
"pepDeclaration", "pepQuestionnaire", "sofDocument",
"verificationReport"
]
}
}
]
},
"requestId": 56287106
}The outer requestId is a trace ID. It is not a setup-request identifier and is not passed back to Mesta.
Each user-resolvable blocker identifies the subject, public field, HTTP method, path, and accepted body fields. mesta_admin_action_required means Mesta must resolve the requirement; it does not refer to your operations team.
Common blocker codes:
| Code | What to do |
|---|---|
missing_data | Follow the supplied action and fields |
missing_associate | Create the specified Director or Authorized Representative |
sender_verification_pending | Wait for sender verification |
ubo_verification_pending | Complete or wait for the identified UBO verification |
associate_verification_pending | Complete or wait for the identified representative verification |
sender_inactive | Wait for sender activation |
mesta_admin_action_required | Mesta operations must complete the action |
deposit_source_not_sender | This sender is not configured to fund deposits; the setup-request workflow is unavailable |
The following complete example shows every supported blocker shape. A real response contains only the blockers that apply to that sender and request:
{
"data": {
"currency": "EUR",
"status": "waiting_for_data",
"requestedAt": "2026-08-27T08:00:00.000Z",
"completedAt": null,
"blockers": [
{
"code": "missing_data",
"subject": { "type": "ubo", "id": "ubo-456" },
"fields": [{ "name": "uboNationalities", "label": "Nationality" }],
"action": {
"method": "PATCH",
"path": "/v1/senders/sender-123/virtual-bank-accounts/EUR/setup-request/data",
"bodyFields": ["uboNationalities"]
}
},
{
"code": "missing_associate",
"subject": { "type": "associate", "roles": ["director"], "minimumCount": 1 },
"fields": [{ "name": "roles", "label": "Add 1 associate(s)" }],
"action": {
"method": "POST",
"path": "/v1/senders/associates",
"bodyFields": [
"senderId", "linkedUboId", "firstName", "lastName", "birthDate",
"email", "phone", "address", "roles", "nationality", "identity",
"pepDeclaration", "pepQuestionnaire", "sofDocument",
"verificationReport"
]
}
},
{ "code": "sender_verification_pending" },
{ "code": "ubo_verification_pending", "subject": { "type": "ubo", "id": "ubo-456" } },
{ "code": "associate_verification_pending", "subject": { "type": "associate", "id": "associate-789" } },
{ "code": "sender_inactive" },
{ "code": "mesta_admin_action_required", "subject": { "type": "sender", "id": "sender-123" }, "fields": [{ "label": "Trading address" }] },
{ "code": "deposit_source_not_sender" }
]
},
"requestId": 56287106
}3. Supply setup data
When a blocker points to the setup-data endpoint:
PATCH /v1/senders/{senderId}/virtual-bank-accounts/{currency}/setup-request/dataIt can accept the sender website or tax ID, specific UBO tax IDs or nationalities, and the sender trading address. Documents and associates continue using their dedicated endpoints.
Every successful mutation re-evaluates readiness and may start setup automatically.
4. Poll status
GET /v1/senders/{senderId}/virtual-bank-accounts/{currency}/setup-requestGET can reconcile status from current sender/account facts, but cannot start account setup. Polling is safe from duplicate setup.
The status endpoint always follows the sender's current account configuration. If Mesta changes that configuration while an earlier setup request exists, GET no longer returns the request for the previous configuration and can return VIRTUAL_BANK_ACCOUNT_SETUP_REQUEST_NOT_FOUND. Call POST again to create or reuse the request for the current configuration. An earlier request that had already started provisioning may still finish, but it is not treated as the current request.
| Status | Meaning |
|---|---|
waiting_for_data | Follow blocker actions |
waiting_for_verification | Sender/person verification is pending |
waiting_for_activation | Sender lifecycle gates remain |
ready | Setup can be claimed automatically |
provisioning | Account setup is running |
completed | This setup attempt produced or reconciled an account |
failed | Setup failed with a sanitized state |
cancelled | The request was withdrawn |
5. Retrieve available accounts
After completed, call:
GET /v1/senders/{senderId}/virtual-bank-accounts/{currency}The response is an array so additional accounts for the same currency can be returned in the future. It currently contains at most one account:
{
"data": [
{
"id": "account-123",
"name": "Example Trading Ltd",
"accountNumber": "1234567890",
"currency": "EUR",
"status": "active"
}
],
"requestId": 56287106
}Cancel and request again
DELETE /v1/senders/{senderId}/virtual-bank-accounts/{currency}/setup-requestCancellation is allowed before account setup begins and for failed requests. It is rejected during provisioning and after successful setup. A later POST creates a fresh current request.
Errors to handle
| HTTP | Code | Meaning |
|---|---|---|
| 400 | CAPABILITY_CURRENCY_NOT_SUPPORTED | The currency is not supported by this workflow |
| 400 | CAPABILITY_AUTOMATION_UNAVAILABLE | Automated setup is unavailable for the current configuration |
| 404 | VIRTUAL_BANK_ACCOUNT_SETUP_REQUEST_NOT_FOUND | No current request exists; create one with POST |
| 404 | VIRTUAL_BANK_ACCOUNT_NOT_FOUND | No virtual bank account is available for this currency |
| 409 | VIRTUAL_BANK_ACCOUNT_ALREADY_EXISTS | A virtual bank account is already available; retrieve it with GET |
Updated 7 minutes ago

