Several of the guides that currently rank for "variable recurring payments API" list MaximumCumulativeAmount and MaximumCumulativeNumberOfPayments as VRP control parameters. Neither field exists. I checked the published OpenAPI definitions at v3.1.10, v3.1.11 and v4.0.1, and there are zero occurrences in any of them.
That is roughly the state of VRP documentation outside the specification itself: thorough on sweeping versus non-sweeping, silent on everything that actually costs you a sprint.
What Is the Variable Recurring Payments API and Who Has to Offer It?
A VRP is one long-lived consent that authorises many payments underneath it, each validated against limits the customer set when they authenticated. It is not a payment message repeated on a timer. It is a mandate held at the bank, with the bank enforcing the caps.
There are two flavours, and the split is regulatory rather than technical. The CMA mandated that the CMA9 offer open access to the VRP API for sweeping, which means moving money between accounts belonging to the same person. Open Banking Limited states the other half just as plainly: non-sweeping VRPs were not mandated by the CMA, so the CMA9 are not obliged to provide them. Six of the nine (HSBC, Santander, NatWest, Nationwide, Lloyds and Barclays) had sweeping live by the end of 2022. Sweeping is now a real rail, running 7.73 million payments in June 2026, up 6.7% on the month.
Commercial VRP is the one everybody writes about, and it arrived through a scheme rather than a mandate. The UK Payments Initiative went live on 2 June 2026, one quarter later than the Q1 2026 the FCA and PSR had signalled in December 2025.
The current standard is v4.0.1, released 1 April 2026, base path /open-banking/v4.0/pisp. The CMA9 were required to be on v4.0 by the end of March 2025, and running OBL 4.0 in production is a prerequisite for UKPI participation. If you are still building against 3.1.x, you are building against a migration target.
What Endpoints Does the VRP API v4.0.1 Expose?
Six paths, eight operations, and one of them is a trap.
| Method | Path | Purpose |
|---|---|---|
POST | /domestic-vrp-consents | Create the mandate |
GET | /domestic-vrp-consents/{ConsentId} | Read mandate + status |
DELETE | /domestic-vrp-consents/{ConsentId} | Revoke |
PUT | /domestic-vrp-consents/{ConsentId} | Version migration only |
POST | /domestic-vrp-consents/{ConsentId}/funds-confirmation | Balance check |
POST | /domestic-vrps | Execute a payment |
GET | /domestic-vrps/{DomesticVRPId} | Payment status |
GET | /domestic-vrps/{DomesticVRPId}/payment-details | Detailed status history |
The PUT is not an update endpoint. The specification restricts it to migration of consent resource data across API standard versions. You cannot amend a customer's limits with it. Changing a cap means a new consent and a fresh authentication, which surprises most teams arriving from card-on-file.
What Are the Required VRP ControlParameters Fields?
OBDomesticVRPControlParameters has exactly four required fields: VRPType, PSUAuthenticationMethods, MaximumIndividualAmount and PeriodicLimits. Optional: ValidFromDateTime, ValidToDateTime, PSUInteractionTypes, SupplementaryData.
PeriodicLimits is an array with minItems: 1, and every entry requires all four of PeriodType, PeriodAlignment, Amount and Currency. There is no cumulative-total field and no payment-count field anywhere in the object. If your mandate model has a "maximum number of payments" column, the bank will never enforce it. You will.
{
"Data": {
"ControlParameters": {
"VRPType": ["UK.OBIE.VRPType.Other"],
"PSUAuthenticationMethods": ["UK.OBIE.SCA"],
"PSUInteractionTypes": ["OffSession"],
"ValidToDateTime": "2027-09-06T00:00:00+00:00",
"MaximumIndividualAmount": { "Amount": "150.00", "Currency": "GBP" },
"PeriodicLimits": [
{
"Amount": "200.00",
"Currency": "GBP",
"PeriodType": "Month",
"PeriodAlignment": "Calendar"
}
]
},
"Initiation": { }
},
"Risk": { "PaymentContextCode": "TransferToThirdParty" }
}
VRPType is UK.OBIE.VRPType.Sweeping or UK.OBIE.VRPType.Other. PSUAuthenticationMethods is UK.OBIE.SCA or UK.OBIE.SCANotRequired. PSUInteractionTypes is InSession or OffSession, and PeriodType accepts Day, Week, Fortnight, Month, Half-year and Year.
Note the Risk block. It is mandatory on the envelope and has no required properties of its own, which makes it easy to send as {} and forget. Do not. PaymentContextCode carries TransferToSelf against TransferToThirdParty, and that is the field which operationally separates a sweep from a commercial payment. Get it wrong and the bank's risk engine acts on a false assertion.
PeriodAlignment: Should You Use Consent or Calendar?
PeriodAlignment takes Consent or Calendar, and I have not found a single non-specification page that explains the difference. It causes real production failures.
Calendar anchors each period to the calendar: a Month limit resets on the 1st. Consent anchors it to the moment the mandate was authorised: a customer who authenticated on 20 January gets periods running 20 January to 19 February, 20 February to 19 March, and so on.
Take a £200 monthly cap, a regular £150 charge on the 1st, and an occasional £100 catch-up later in the month.
- Under
Calendar, both land inside the same period. £250 against a £200 cap. Rejected. - Under
Consent, for a mandate authorised on the 20th, the 1 March charge sits in the 20 February to 19 March period and the 25 March catch-up sits in the next one. Both pass.
Consent and your effective billing window differs for every customer on your book.
My position: default to Calendar for anything commercial. It is the only setting where your cap means what your finance team thinks it means. Consent earns its place in sweeping, where the period is genuinely relative to the arrangement.
Does VRP Funds Confirmation Reserve the Money?
No, and nothing in the specification says otherwise.
POST /domestic-vrp-consents/{ConsentId}/funds-confirmation takes ConsentId and InstructedAmount and returns FundsConfirmationId, ConsentId, CreationDateTime, InstructedAmount and a FundsAvailableResult whose FundsAvailable is either Available or NotAvailable. That is a read. It places no hold, and the balance can move between your check and your POST /domestic-vrps.
Teams keep building two-phase commits on top of it. Treat it as a hint that improves your success rate and reduces avoidable AM04s, not as a guarantee. It also returns U009 UK.OBIE.Resource.InvalidConsentStatus when the consent is not in AUTH, which makes it a cheap liveness probe.
What Error Codes Can a VRP Payment Return?
The canonical U-code set runs to 45 entries. These are the ones that will actually appear in your logs.
| Code | HTTP | Meaning | Retry? |
|---|---|---|---|
U014 UK.OBIE.Rules.FailsControlParameters | 400 | Breached a cap | Only after the period rolls |
U009 UK.OBIE.Resource.InvalidConsentStatus | 400 | Consent not AUTH | No, re-authenticate |
U008 UK.OBIE.Resource.ConsentMismatch | 400 | Payment contradicts consent | No, fix the request |
U012 UK.OBIE.Rules.AfterCutOffDateTime | 400 | Past the cut-off | Yes, next window |
U013 UK.OBIE.Rules.DuplicateReference | 400 | Reference reused | No, new reference |
U028 UK.OBIE.Reauthenticate | 403 | SCA required again | No, send the customer back |
U029 UK.OBIE.Rules.ResourceAlreadyExists | 409 | Idempotency collision | No, treat as success |
U041 UK.OBIE.ExemptionNotApplied | 400 | Claimed exemption refused | No |
U014 is the useful one. The ASPSP must identify the breaching control parameter in the Field property, so you can tell a MaximumIndividualAmount breach from a PeriodicLimits breach without guessing. Parse it. Retrying a MaximumIndividualAmount failure is pointless at any time; retrying a periodic breach is correct once the window rolls.
Payments also carry ISO 20022 reasons in StatusReason, and these are a different axis entirely: AM04 insufficient funds, AM21 limit exceeded, AC04 closed account, AC06 blocked account, AG01 transaction forbidden, MD07 end customer deceased, FRAD fraudulent origin, DUPL duplicate payment. Only AM04 is meaningfully retryable. AC04, AC06 and MD07 should terminate the mandate in your system immediately, not after three attempts.
Payment status moves through RCVD, PDNG, ACTC, ACCP, ACFC, ACSP, ACWC, ACSC, BLCK, ACCC, ACWP and RJCT. Consent status is the shorter set: AWAU, RJCT, AUTH, CANC, EXPD.
Three headers are required on POST /domestic-vrps: Authorization, x-jws-signature (PS256) and x-idempotency-key. The idempotency key is capped at 40 characters, returns 400 if longer, holds for 24 hours, and the rules require you to wait at least one second before re-sending a duplicate. A UUIDv4 is 36 characters, so prefixing it with anything longer than four characters breaks you in production and never in staging.
How Do You Revoke a VRP Consent?
DELETE /domestic-vrp-consents/{ConsentId} from your side. The bank moves the consent to CANC, fails all future payments against that ConsentId, and emits urn:uk:org:openbanking:events:consent-authorization-revoked. There is a second event worth subscribing to, urn:uk:org:openbanking:events:domestic-vrp-consent-linked-account-update, which fires when the underlying account changes.
The detail people miss: a cancelled consent can be re-authenticated back to AUTH. CANC is not terminal. If your mandate table hard-deletes on revocation, your reconciliation will later show payments against a ConsentId you no longer hold a record for.
Customers revoke in their banking app without telling you, which makes the event subscription mandatory infrastructure.
How Fast Is the VRP API, and What Are the Rate Limits?
OBL's benchmark is a 750ms average time-to-last-byte per endpoint, with a 0.5% daily error-rate ceiling, measured daily. Reality is better: July 2026 saw a 330ms average response time across 2,936,062,491 successful API calls at 99.54% success.
Rate limits are the gap. They are not standardised. A 429 is at each ASPSP's discretion under its own published fair usage policy, and Retry-After is recommended rather than required. So you cannot write one throttle. You need per-ASPSP concurrency limits, a backoff that assumes no Retry-After header, and a queue that degrades per bank rather than globally. This is the same per-institution fragmentation that has shaped every open banking integration in the UK, and VRP does not fix it.
Commercial VRP vs Direct Debit vs Cards: What Does It Cost in the UK?
This is where the vendor content and the economics part company.
Frontier Economics, commissioned by OBL and published 9 April 2025, recommended a fixed per-transaction access fee "consistent with it being 3p-6p, and not greater than 6p", against an estimated ASPSP cost of £0.023 per transaction and an FPS cost of £0.010. UKPI centrally sets that Access Fee through a pricing committee independent of shareholders and participants.
Their head-to-head for large billers, as a percentage of transaction value:
| Value | cVRP @15p | cVRP @23p | Direct Debit | Debit card | Credit card |
|---|---|---|---|---|---|
| £10 | 1.50% | 2.30% | 0.05% | 0.25% | 0.35% |
| £50 | 0.30% | 0.46% | 0.01% | 0.25% | 0.35% |
| £100 | 0.15% | 0.23% | 0.01% | 0.25% | 0.35% |
| £500 | 0.03% | 0.05% | 0.00% | 0.25% | 0.35% |
Frontier's own conclusion is blunt: no scenario is likely to lead to pricing that is competitive with Direct Debit. A large biller pays around 1p per Direct Debit. cVRP does not get close, and only overtakes debit cards somewhere around £75 to £100 per transaction.
Small merchants see a different picture, because their card costs are far worse: the PSR's card-acquiring review put the merchant service charge at roughly 1.8% for merchants under £380k turnover, and gateway fees push the all-in figure towards 3%. Against that, a flat few pence is transformative. Against Bacs at a penny, it is not.
One caution. Wave 1 fee figures circulating in vendor posts, typically a 5.5p access fee plus a 2.5p scheme fee, are attributed to a UKPI pricing framework I could not find published anywhere, and the FCA and PSR statement contains no numbers. Treat them as reported rather than confirmed; the 8p total would sit above Frontier's ceiling.
The other asymmetry is legal, not commercial. The Direct Debit Guarantee gives the payer a full and immediate refund from their own bank for any error, plus around ten working days' notice of a change to amount, date or frequency. VRP has no equivalent. Settlement is irrevocable, there is no chargeback window and no indemnity claim. Frontier flags liability allocation as an open question: minimal for Wave 1 because the use cases are low risk, critical in later waves.
Will Commercial VRP Replace Direct Debit by 2030?
No, and the regulators' own modelling says so.
Frontier projected Wave 1 uptake at roughly 1.2% of the addressable recurring-payments market by year five and 3.4% by year ten, against a maximum addressable Wave 1 market of 4.2 billion transactions a year. The FCA and PSR endorsed those estimates. Wave 1 covers three sectors on the regulators' own list: regulated financial services, regulated utilities, and local and central government. Some vendor pages claim five sectors, adding e-money institutions and charities. Use the regulators' three.
The prediction I would defend: cVRP displaces card-on-file for recurring charges above roughly £75 well before it dents Bacs, and its first real wins are the cases where Direct Debit is structurally bad rather than merely expensive: variable amounts, instant settlement and in-app revocation. Prepaid energy, wallet funding, tax payments, anything where a three-working-day Bacs cycle is the actual problem.
Nobody has published cVRP transaction volumes since the June launch. OBL's page says the service is live and gives no figures, so anyone quoting adoption numbers at you cannot source them.
The regulatory ground is still moving. The joint FCA, PSR and CMA Prioritisation Statement of 20 January 2026 applies only to Wave 1 and expires when the DUAA framework is implemented or in July 2027, whichever comes first. The FCA consults on the long-term framework before the end of 2026.
What This Means for UK Payments Engineers
If you are building on VRP in the next six months:
1. Target v4.0.1. Anything you write against 3.1.x is migration debt, and OBL 4.0 in production is a UKPI prerequisite.
2. Set PeriodAlignment to Calendar for commercial mandates unless you have a specific reason not to, and write the test that proves your cap behaves the same for a customer who authorised on the 1st and one who authorised on the 31st.
3. Delete any MaximumCumulativeAmount handling. Enforce payment counts in your own ledger, because no bank will do it for you.
4. Parse the Field property on U014 and split your retry policy on it. Individual-amount breaches never retry; periodic breaches retry once the window rolls.
5. Terminate mandates on AC04, AC06 and MD07 immediately. These are not transient, and retrying against a deceased customer's account is a complaint waiting to happen.
6. Keep your idempotency key under 40 characters and build the one-second minimum resend delay into your client, not your runbook.
7. Subscribe to the revocation event. Customers cancel in their banking app and you find out from the event or from a failed payment.
8. Throttle per ASPSP, and assume no Retry-After header.
9. Model the cost before you commit. If your average transaction is under £50 and you already have Bacs, the price case is weak. Build on settlement speed and variable amounts instead.
The specification itself is good. It is precise about limits, honest that funds confirmation is not a reservation, and specific about which parameter failed. The problem has never been the standard. It is that almost everything written about it stops where the engineering starts. More from me on UK payments infrastructure at Tom Wang.