EUR accounts

EUR virtual IBAN management

Create, query, and manage EUR multi-currency virtual IBANs for your clients. Same lifecycle patterns as GBP, different endpoints.

What you can do

The EUR virtual IBAN endpoints let you provision EUR accounts, retrieve balances, pull statements, and control account status. Each client can hold one EUR account. The API surface mirrors the GBP endpoints with different paths.

Provision

Create accounts

Provision a EUR virtual IBAN for any Active client. One account per client per currency.

Query

Balances and statements

List all EUR accounts with real-time balances. Pull transaction statements with date filtering and pagination.

Control

Block, unblock, close

Freeze accounts to stop payments, reactivate them, or permanently close when no longer needed.

GBP vs EUR: what changes

The EUR endpoints follow the same patterns as GBP. Three things differ:

Base path

/api/v1/euro/vibans instead of /api/v1/sterling-account

Account type

AccountType: "MCCY" (multi-currency) instead of "GB"

Extra webhook

EUR creation also fires Clients.ClientAssignedAccount alongside Accounts.AccountCreated

Endpoints at a glance

Method Path Description
POST /api/v1/euro/vibans Create a EUR virtual IBAN
GET/api/v1/euro/vibansList all EUR accounts
POST/api/v1/euro/vibans/statementsGet transaction statements
POST.../{reference}/block/{iban}Block an account
POST.../{reference}/unblock/{iban}Unblock an account
POST .../{"{reference}"}/close/{"{iban}"} Close an account (irreversible)

Account lifecycle

EUR accounts follow the same lifecycle as GBP. Blocking is reversible. Closing is permanent.

Processing
→
Active
→
Blocked
→
Active
From Active or Blocked:
→
Closed
(permanent)

Create an account

Provision a EUR virtual IBAN for a client. The client must have Active status and must not already have a EUR account.

Request body

Identical to GBP: just clientReference. Mercury determines the currency from the endpoint path.

Asynchronous

Returns Processing immediately. Listen for Accounts.AccountCreated and Clients.ClientAssignedAccount to confirm.

{
  "clientReference": "CLIENT-001"
}
{
  "Response": {
    "Status": "Processing",
    "Message": "Your account request has been logged and is currently being processed",
    "RequestId": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4",
    "CreatedDate": "2026-02-23T15:26:37Z",
    "ClientReference": "CLIENT-001",
    "RequestedAccountDetails": {
      "AccountName": "Acme Ltd",
      "AccountType": "MCCY",
      "Currency": ["EUR"]
    }
  }
}
{
  "status": "Error",
  "message": "Request validation failed",
  "errors": [
    {
      "propertyName": "clientReference",
      "errorDescription": "The client already has a Virtual IBAN for the currency"
    }
  ]
}
import requests
import base64
import hashlib
import hmac
import uuid
import os

BASE_URL = os.getenv("MERCURY_BASE_URL")
API_KEY = os.getenv("MERCURY_API_KEY")
SECRET_KEY = os.getenv("MERCURY_SECRET_KEY")

nonce = str(uuid.uuid4())
method = "POST"
path = "/api/v1/euro/vibans"
body = '{"clientReference":"CLIENT-001"}'

string_to_sign = "\n".join([API_KEY, method, path, body, nonce])
signature = base64.b64encode(
    hmac.new(SECRET_KEY.encode(), string_to_sign.encode(), hashlib.sha256).digest()
).decode()

headers = {
    "x-api-key": API_KEY,
    "x-nonce": nonce,
    "Authorization": f"HMACSHA256 {signature}",
    "Content-Type": "application/json"
}

response = requests.post(f"{BASE_URL}{path}", headers=headers, data=body.encode("utf-8"))
print(response.json())
const crypto = require("crypto");
const https = require("https");

const BASE_URL = process.env.MERCURY_BASE_URL;
const API_KEY = process.env.MERCURY_API_KEY;
const SECRET_KEY = process.env.MERCURY_SECRET_KEY;

const nonce = crypto.randomUUID();
const method = "POST";
const path = "/api/v1/euro/vibans";
const body = JSON.stringify({ clientReference: "CLIENT-001" });

const stringToSign = [API_KEY, method, path, body, nonce].join("\n");
const signature = crypto
  .createHmac("sha256", SECRET_KEY)
  .update(stringToSign, "utf8")
  .digest("base64");

const url = new URL(path, BASE_URL);
const req = https.request(url, {
  method,
  headers: {
    "x-api-key": API_KEY,
    "x-nonce": nonce,
    "Authorization": `HMACSHA256 ${signature}`,
    "Content-Type": "application/json"
  }
}, (res) => {
  let data = "";
  res.on("data", (chunk) => data += chunk);
  res.on("end", () => console.log(JSON.parse(data)));
});

req.write(body);
req.end();
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.net.http.*;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.UUID;

String baseUrl = System.getenv("MERCURY_BASE_URL");
String apiKey = System.getenv("MERCURY_API_KEY");
String secretKey = System.getenv("MERCURY_SECRET_KEY");

String nonce = UUID.randomUUID().toString();
String method = "POST";
String path = "/api/v1/euro/vibans";
String body = "{\"clientReference\":\"CLIENT-001\"}";

String stringToSign = String.join("\n", apiKey, method, path, body, nonce);
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
String signature = Base64.getEncoder()
    .encodeToString(mac.doFinal(stringToSign.getBytes(StandardCharsets.UTF_8)));

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create(baseUrl + path))
    .header("x-api-key", apiKey)
    .header("x-nonce", nonce)
    .header("Authorization", "HMACSHA256 " + signature)
    .header("Content-Type", "application/json")
    .POST(HttpRequest.BodyPublishers.ofString(body))
    .build();

HttpResponse<String> response = HttpClient.newHttpClient()
    .send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());

List all accounts

Retrieve all EUR virtual IBANs under your distributor. Returns account details, balances, and status for each account.

[
  {
    "ClientReference": "CLIENT-001",
    "ClientName": "Acme Ltd",
    "AccountName": "Acme Ltd",
    "Iban": "GB85CLRB04274893940059",
    "SortCode": "042748",
    "AccountNumber": "93940059",
    "Balance": {
      "CurrencyCode": "EUR",
      "Amount": 1000
    },
    "AvailableBalance": {
      "CurrencyCode": "EUR",
      "Amount": 1000
    },
    "Currency": "EUR",
    "Status": "Active",
    "ExternalReference": "EXT-REF-001",
    "CreatedDate": "2026-02-23T15:26:37Z"
  }
]
Balance

Total funds held in the account, including pending transactions.

Available balance

Funds available for immediate withdrawal or payment. May differ from Balance if transactions are pending.

GB IBAN prefix

EUR accounts still use a GB-prefixed IBAN. This is expected for UK-based accounts holding EUR. Route SEPA payments to this IBAN.

Get statements

Pull transaction history for all EUR accounts. All filter fields are optional. Omit the body entirely to retrieve all available transactions.

Date format

Dates use a {year, month, day} object, not an ISO string. Same format as the GBP statements endpoint. Dates must not be in the future.

{
  "startDate": {
    "year": 2026,
    "month": 1,
    "day": 1
  },
  "endDate": {
    "year": 2026,
    "month": 3,
    "day": 31
  },
  "pageSize": 50
}
[
  {
    "ClientReference": "CLIENT-001",
    "ExternalClientReference": "EXT-REF-001",
    "Date": "2026-02-13",
    "TimeStamp": "2026-02-13T10:46:41Z",
    "EndToEndIdentifier": "E2E-20260213-001",
    "Detail": "Invoice EUR-2026-001",
    "Payments": 0,
    "Receipts": 1000,
    "BankAccount": "GB85CLRB04274893940059",
    "BankReference": "Invoice EUR-2026-001",
    "TransactionType": "Credit"
  }
]

Block and unblock

Blocking prevents all payments in and out. Unblocking restores to Active. Both require the client reference and account IBAN as path parameters.

POST /api/v1/euro/vibans/{reference}/block/{iban}
POST /api/v1/euro/vibans/{reference}/unblock/{iban}
{
  "ClientReference": "CLIENT-001",
  "ClientName": "Acme Ltd",
  "AccountName": "Acme Ltd",
  "Iban": "GB85CLRB04274893940059",
  "SortCode": "042748",
  "AccountNumber": "93940059",
  "Balance": { "CurrencyCode": "EUR", "Amount": 1000 },
  "AvailableBalance": { "CurrencyCode": "EUR", "Amount": 1000 },
  "Currency": "EUR",
  "Status": "Blocked",
  "ExternalReference": "EXT-REF-001",
  "CreatedDate": "2026-02-23T15:26:37Z"
}
{
  "ClientReference": "CLIENT-001",
  "ClientName": "Acme Ltd",
  "AccountName": "Acme Ltd",
  "Iban": "GB85CLRB04274893940059",
  "SortCode": "042748",
  "AccountNumber": "93940059",
  "Balance": { "CurrencyCode": "EUR", "Amount": 1000 },
  "AvailableBalance": { "CurrencyCode": "EUR", "Amount": 1000 },
  "Currency": "EUR",
  "Status": "Active",
  "ExternalReference": "EXT-REF-001",
  "CreatedDate": "2026-02-23T15:26:37Z"
}

Close an account

Irreversible

Closing an account is permanent. The account balance must be zero across all currencies before you call this endpoint. Ensure all pending transactions have settled first.

POST /api/v1/euro/vibans/{reference}/close/{iban}
{
  "ClientReference": "CLIENT-001",
  "ClientName": "Acme Ltd",
  "AccountName": "Acme Ltd",
  "Iban": "GB85CLRB04274893940059",
  "SortCode": "042748",
  "AccountNumber": "93940059",
  "Balance": { "CurrencyCode": "EUR", "Amount": 0 },
  "AvailableBalance": { "CurrencyCode": "EUR", "Amount": 0 },
  "Currency": "EUR",
  "Status": "A request to close the account has been logged and is currently being processed",
  "ExternalReference": "EXT-REF-001",
  "CreatedDate": "2026-02-23T15:26:37Z"
}
{
  "status": "Error",
  "message": "Request validation failed",
  "errors": [
    {
      "propertyName": "iban",
      "errorDescription": "Account with the provided Iban has a positive balance in one or more currencies. Cannot close account until balance is zero"
    }
  ]
}

Webhook events

EUR accounts use the same webhook events as GBP. The same gotcha applies: the unblock webhook has Type: "AccountBlocked" in the payload. Always check the Status field.

Event Type field When it fires
AccountCreated AccountCreated IBAN provisioned and active
ClientAssignedAccountClientAssignedAccountIBAN linked to client (EUR only)
AccountCreationFailedAccountCreationFailedProvisioning failed. Check Errors object.
AccountBlockedAccountBlockedAccount frozen, payments stopped
AccountUnBlockedAccountBlockedAccount reactivated. Check Status field, not Type.
AccountClosed AccountClosed Account permanently closed

Common pitfalls

GB IBAN prefix

EUR accounts have a GB-prefixed IBAN (e.g. GB85CLRB...). This is correct for UK-based EUR accounts. Do not reject these IBANs in your validation logic.

Client not Active

All account operations require the parent client to have Active status. If you get a 400 error, verify client status first via GET /api/v1/client/{reference}.

One account per currency

Each client can hold one EUR virtual IBAN. Attempting to create a second returns a 400 error. A client can have both a GBP and EUR account simultaneously.

Unblock webhook Type field

The AccountUnBlocked webhook sends Type: "AccountBlocked". Distinguish block from unblock using the Status field ("Blocked" vs "UnBlocked").

Next steps

Ready to provision EUR accounts?

Open the API reference to try these endpoints in the sandbox.

Create EUR account

Did this page help you?