GBP accounts
GBP account management
Create, query, and manage Sterling virtual IBANs for your clients. Full lifecycle from provisioning through to closure.
What you can do
The Sterling account endpoints let you provision GBP virtual IBANs, retrieve balances, pull statements, and control account status. Each client can hold one GBP account.
Create accounts
Provision a GBP virtual IBAN for any Active client. One account per client per currency.
Balances and statements
List all accounts with real-time balances. Pull transaction statements with date filtering and pagination.
Block, unblock, close
Freeze accounts to stop payments, reactivate them, or permanently close when no longer needed.
Endpoints at a glance
Account lifecycle
GBP accounts move through a defined set of statuses. Blocking is reversible. Closing is permanent.
Create an account
Provision a GBP virtual IBAN for a client. The client must have Active status and must not already have a GBP account.
Only one field required: clientReference. This is the Mercury-assigned reference returned when you onboarded the client via POST /api/v1/client.
Returns a Processing status immediately. Listen for the Accounts.AccountCreated webhook to confirm the IBAN is ready.
{
"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": "GB",
"Currency": ["GBP"]
}
}
}{
"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/sterling-account"
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/sterling-account";
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/sterling-account";
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 GBP virtual accounts under your distributor. Returns account details, balances, and status for each account.
[
{
"ClientReference": "CLIENT-001",
"ClientName": "Acme Ltd",
"AccountName": "Acme Ltd",
"Iban": "GB71CLRB04082700001159",
"SortCode": "040827",
"AccountNumber": "00001159",
"Balance": {
"CurrencyCode": "GBP",
"Amount": 1000
},
"AvailableBalance": {
"CurrencyCode": "GBP",
"Amount": 1000
},
"Currency": "GBP",
"Status": "Active",
"ExternalReference": "EXT-REF-001",
"CreatedDate": "2026-02-23T15:26:37Z"
}
]Total funds held in the account, including pending transactions.
Funds available for immediate withdrawal or payment. May differ from Balance if transactions are pending.
Use GET /api/v1/client/{reference}/accounts to retrieve both GBP and EUR accounts for a single client.
Get statements
Pull transaction history for all GBP accounts. All filter fields are optional. Omit the body entirely to retrieve all available transactions.
Dates use a {year, month, day} object, not an ISO string. 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-15",
"TimeStamp": "2026-02-15T08:38:16Z",
"EndToEndIdentifier": "E2E-20260215-001",
"Detail": "Invoice GBP-2026-001",
"Payments": 500,
"Receipts": 0,
"BankAccount": "GB71CLRB04082700001159",
"BankReference": "Invoice GBP-2026-001",
"TransactionType": "Debit"
}
]Payments field contains the amount. Receipts will be 0. TransactionType is "Debit".
Receipts field contains the amount. Payments will be 0. TransactionType is "Credit".
Block and unblock
Blocking an account prevents all payments in and out. Unblocking restores it to Active. Both require the client reference and the account IBAN as path parameters.
POST /api/v1/sterling-account/{reference}/block/{iban}POST /api/v1/sterling-account/{reference}/unblock/{iban}{
"ClientReference": "CLIENT-001",
"ClientName": "Acme Ltd",
"AccountName": "Acme Ltd",
"Iban": "GB71CLRB04082700001159",
"SortCode": "040827",
"AccountNumber": "00001159",
"Balance": { "CurrencyCode": "GBP", "Amount": 1000 },
"AvailableBalance": { "CurrencyCode": "GBP", "Amount": 1000 },
"Currency": "GBP",
"Status": "Blocked",
"ExternalReference": "EXT-REF-001",
"CreatedDate": "2026-02-23T15:26:37Z"
}{
"ClientReference": "CLIENT-001",
"ClientName": "Acme Ltd",
"AccountName": "Acme Ltd",
"Iban": "GB71CLRB04082700001159",
"SortCode": "040827",
"AccountNumber": "00001159",
"Balance": { "CurrencyCode": "GBP", "Amount": 1000 },
"AvailableBalance": { "CurrencyCode": "GBP", "Amount": 1000 },
"Currency": "GBP",
"Status": "Active",
"ExternalReference": "EXT-REF-001",
"CreatedDate": "2026-02-23T15:26:37Z"
}Close an account
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/sterling-account/{reference}/close/{iban}{
"ClientReference": "CLIENT-001",
"ClientName": "Acme Ltd",
"AccountName": "Acme Ltd",
"Iban": "GB71CLRB04082700001159",
"SortCode": "040827",
"AccountNumber": "00001159",
"Balance": { "CurrencyCode": "GBP", "Amount": 0 },
"AvailableBalance": { "CurrencyCode": "GBP", "Amount": 0 },
"Currency": "GBP",
"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
Five webhook events cover the full account lifecycle. Listen for these to track account state changes in real time rather than polling.
The Accounts.AccountUnBlocked webhook has Type: "AccountBlocked" in the payload, not "AccountUnBlocked". You must check the Payload.Status field to distinguish between block and unblock events. Status will be "Blocked" or "UnBlocked".
{
"Type": "AccountCreated",
"Payload": {
"OwnerReference": "CLIENT-001",
"Owner": "Acme Ltd",
"Currencies": ["GBP"],
"Identifiers": [
{ "Identifier": "GB71CLRB04082700001159", "Kind": "Iban" }
],
"Status": "Active",
"TimestampCreated": "2026-02-23T15:26:37.5612949Z"
},
"Nonce": "VkPweAa3fHcJTAowEv3P1g=="
}{
"Type": "AccountCreationFailed",
"Payload": {
"OwnerReference": "CLIENT-001",
"OwnerName": "Acme Ltd",
"Currencies": ["GBP"],
"AccountIdentifiers": { "Iban": null, "Bban": null },
"Errors": {
"FieldName": ["error description"]
}
},
"Nonce": "XrNcCDMvPN3KvfcU4f+U9Q=="
}{
"Type": "AccountBlocked",
"Payload": {
"OwnerReference": "CLIENT-001",
"Owner": "Acme Ltd",
"Identifiers": [
{ "Identifier": "GB71CLRB04082700001159", "Kind": "Iban" }
],
"Status": "Blocked"
},
"Nonce": "1BSubJoGnKN+uN2kVYx0bw=="
}{
"Type": "AccountBlocked",
"Payload": {
"OwnerReference": "CLIENT-001",
"Owner": "Acme Ltd",
"Identifiers": [
{ "Identifier": "GB71CLRB04082700001159", "Kind": "Iban" }
],
"Status": "UnBlocked"
},
"Nonce": "1BSubJoGnKN+uN2kVYx0bw=="
}{
"Type": "AccountClosed",
"Payload": {
"OwnerReference": "CLIENT-001",
"OwnerName": "Acme Ltd",
"AccountIdentifiers": {
"Iban": "GB71CLRB04082700001159",
"Bban": "CLRB04082700001159"
},
"Status": "Closed"
},
"Nonce": "O/Brp8hOfXNOvDFuJ8p0vw=="
}Common pitfalls
All account operations require the parent client to have Active status. If you get a 400 error, verify the client status first via GET /api/v1/client/{reference}.
Each client can hold one GBP virtual IBAN. Attempting to create a second returns a 400 error. Check existing accounts with GET /api/v1/sterling-account first.
The statements endpoint expects dates as {year, month, day} objects, not ISO 8601 strings. Future dates return a 400 error.
You cannot close an account with a positive balance. Transfer or withdraw all funds first, wait for settlement, then close. The API will reject with a clear error message.
Next steps
Send GBP payments
Submit Faster Payments from your GBP accounts.
→EUR accountsEUR virtual IBAN management
Same patterns, EUR endpoints and SEPA payments.
→Error handlingError handling best practices
Parse errors, implement retries, build resilient integrations.
→Ready to provision accounts?
Open the API reference to try these endpoints in the sandbox.
Create GBP accountUpdated about 2 hours ago
