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 accounts

1. Create the setup request

POST /v1/senders/{senderId}/virtual-bank-accounts/{currency}/setup-request

Use 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:

CodeWhat to do
missing_dataFollow the supplied action and fields
missing_associateCreate the specified Director or Authorized Representative
sender_verification_pendingWait for sender verification
ubo_verification_pendingComplete or wait for the identified UBO verification
associate_verification_pendingComplete or wait for the identified representative verification
sender_inactiveWait for sender activation
mesta_admin_action_requiredMesta operations must complete the action
deposit_source_not_senderThis 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/data

It 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-request

GET 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.

StatusMeaning
waiting_for_dataFollow blocker actions
waiting_for_verificationSender/person verification is pending
waiting_for_activationSender lifecycle gates remain
readySetup can be claimed automatically
provisioningAccount setup is running
completedThis setup attempt produced or reconciled an account
failedSetup failed with a sanitized state
cancelledThe 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-request

Cancellation 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

HTTPCodeMeaning
400CAPABILITY_CURRENCY_NOT_SUPPORTEDThe currency is not supported by this workflow
400CAPABILITY_AUTOMATION_UNAVAILABLEAutomated setup is unavailable for the current configuration
404VIRTUAL_BANK_ACCOUNT_SETUP_REQUEST_NOT_FOUNDNo current request exists; create one with POST
404VIRTUAL_BANK_ACCOUNT_NOT_FOUNDNo virtual bank account is available for this currency
409VIRTUAL_BANK_ACCOUNT_ALREADY_EXISTSA virtual bank account is already available; retrieve it with GET

Did this page help you?