How to integrate ISA tax wrappers
Integrating tax wrapper functionality for ISAs
- Onboarding
After creating your user, the next onboarding step is the creation of an account group. Tax-wrapped investment account groups must set
type
equal toPERSONAL, ISA
during the account group creation API call:{ "user_id": "413715f2-5401-4b97-8055-034a6b879f8c", "type": "PERSONAL, ISA" }
Note: Tax-wrapped investment accounts are typically only available to (tax) residents of the country which regulates the specific tax wrapper. The account group will not transition to ACTIVE until the customer has confirmed their eligibility by creating a tax residency with an associated tax identification number (‘TIN’).
After creating the account group, you can proceed with creating an account using the standard account creation flow.
- Tax Wrapper Creation
The business rules and logic applicable to a tax-wrapped investment product are managed through the Tax Wrapper entity.
A dedicated API call is available for each tax wrapper type.
POST /isa/wrappers
{ "type": "STOCKS_AND_SHARES_ISA", "is_flexible": "true", "account_group_id": "0d68fea2-66e8-4ea8-b507-276e7a1eb4aa" }
Specifically for STOCKS_AND_SHARES_ISA, we require an additional input parameter:
is_flexible
.Cash ISAs and Stocks & Shares ISAs come in two variations: flexible ISAs and non-flexible ISAs. Both allow customers to withdraw funds or sell assets from their ISA without limitations. Exceptions apply to specific ISA product types such as Fixed Rate ISAs, where withdrawals are allowed but penalised.
For flexible ISAs, end-users can withdraw money and then replace that amount within the same tax year. In addition, a withdrawal will increase the end-user's allowance.
For non-flexible ISAs, withdrawals do not impact your allowance.
Tax Wrapper Status
Once created, Tax Wrappers must pass the tax residency check before they can transition to ACTIVE. To accomplish this, you must create a tax residency as shown in the User Tax Onboarding section.
In addition, the STOCKS_AND_SHARES_ISA account group requires an active tax wrapper in order to transition to ACTIVE.
- Allowance events
Once the Tax Wrapper has been successfully created, the Investment API will automatically create the underlying Allowance resource and confirm its creation via the
ISA_WRAPPER_ALLOWANCE
webhook.{ "id": "295cf14f-368c-450e-b57e-48d115d30fe4", "created_at": "2025-08-01T10:34:43Z", "type": "ISA_WRAPPER_ALLOWANCE.CREATED", "object": { "id": "f1a57a04-1a89-4dab-ae3a-ff9b2a9377c1", "created_at": "2025-10-05T14:48:00.000Z", "updated_at": "2025-10-05T14:48:00.000Z", "tax_wrapper_id": "0d68fea2-66e8-4ea8-b507-276e7a1eb4aa", "tax_year": "2025/2026", "type": "ANNUAL", "status": "ACTIVE, EXPIRED", "currency": "GBP", "total_amount": "20000.00", "used_amount": "1000.00", "remaining_amount": "19000.00", "valid_from": "2025-04-06T00:00:00.000Z", "valid_to": "2026-04-05T23:59:59.000Z", "first_subscription_at": "2025-11-13T00:00:00.000Z" }, "webhook_id": "4a80c45f-204c-4498-ac20-d900a846e166" }
ISA allowance events
The ISA allowance events contain a lot of metadata, but the following values are related to the key business logic for ISA products.
tax_year
: Since the UK tax year runs from April 6th until midnight April 5th, all year references will use theyyyy/yyyy
(e.g.,2025/2026
) format.type
: TheAnnual
type refers to how the regulatory subscription limit renews annually. For 2025/2026 this value is set at £20,000. Regulatory changes to this limit are managed by Upvest and will automatically be applied before the start of the tax year.status
: Once an allowance entity with the typeAnnual
hits thevalid_to
date, it will transition to the statusEXPIRED
. Expired allowances do not roll over. New allowance entities will be created at commencement of the new tax year.Allowance values:
total_amount
: Equals the regulatory determined subscription limit plus any flexible withdrawals in the current tax year.used_amount
: Reflects how much of the regulatory subscription limit has been used or flexible withdrawals replaced determined by cash subscriptions into the tax-wrapped product.remaining_amount
: The mathematical difference betweentotal_amount
and theused_amount
.valid_from
andvalid_to
: Only relevant for Allowance entities with the typeAnnual
.first_subscription_at
: Populated at the first cash subscription.
Allowance events are emitted upon:
- Creation:
ISA_WRAPPER_ALLOWANCE.CREATED
- Every time an inflow takes place into the tax wrapped product:
ISA_WRAPPER_ALLOWANCE.UPDATED
- Every time an outflow takes place from the tax wrapped product:
ISA_WRAPPER_ALLOWANCE.UPDATED
- When hitting the
valid_to date
Time:TAX_WRAPPER_ALLOWANCE.EXPIRED
Supporting flexible ISAs
Where the STOCKS_AND_SHARES_ISA parameter
is_flexible
equalstrue
, the system automatically recognises any withdrawals made within the tax year and adds this to thetotal_amount
ensuring the users are able to replace withdrawals made in that tax year before using their contribution.In the following example of a flexible ISA:
The end user has an existing value of £50,000 in their ISA at the start of the tax year. They are allocated regulatory-determined amount of £20,000 allowance and have made no subscriptions.
{ "total_amount": "20000.00", "used_amount": "00.00", "remaining_amount": "20000.00", }
When they make a subscription, in this example, £1000, the
used_amount
increases and theremaining_amount
decreases by the amount of the subscription.{ "total_amount": "20000.00", "used_amount": "1000.00", "remaining_amount": "19000.00", }
If they then make a withdrawal, in this example, £5,000, both the
total_amount
and theremaining_amount
increase by the amount of the withdrawal.{ "total_amount": "25000.00", "used_amount": " 1000.00", "remaining_amount": "24000.00", }
In the same scenario but with a non-flexible ISA, the allowance would not change due to the withdrawal as shown below.
{ "total_amount": "20000.00", "used_amount": " 1000.00", "remaining_amount": "19000.00", }
- Display allowance status
The Investment API supports a synchronous endpoint to display the current state of allowances to an ISA account holder on your app or website.
GET /isa/wrappers/{tax_wrapper_id}/allowances/
{ "meta": { "offset": 0, "limit": 100, "count": 2, "total_count": 2, "sort": "valid_from", "order": "DESC" }, "data": [ { "allowance_id": "019999a3-8a17-74e6-bfbd-50d9c7705ea0", "tax_wrapper_id": "019999a3-c02a-7043-b100-9c2d76564748", "tax_year": "2024/2025", "type": "ANNUAL", "status": "ACTIVE, EXPIRED", "currency": "GBP", "total_amount": "20000.00", "used_amount": "0.00", "remaining_amount": "20000.00", "first_subscription_at": "2021-07-21T14:10:00.00Z", "created_at": "2024-07-21T14:10:00.00Z", "updated_at": "2024-07-21T14:10:00.00Z", "valid_from": "2024-04-05T23:00:00.00Z", "valid_to": "2025-04-05T22:59:59.999999Z" }, { "allowance_id": "019999a3-8a17-74e6-bfbd-50d9c7705ea0", "tax_wrapper_id": "019999a3-c02a-7043-b100-9c2d76564748", "tax_year": "2023/2024", "type": "ANNUAL", "status": "ACTIVE, EXPIRED", "currency": "GBP", "total_amount": "20000.00", "used_amount": "1000.00", "remaining_amount": "19000.00", "first_subscription_at": "2023-07-21T14:10:00.00Z", "created_at": "2023-07-21T14:10:00.00Z", "updated_at": "2023-07-21T14:10:00.00Z", "valid_from": "2023-04-05T23:00:00.00Z", "valid_to": "2024-04-05T22:59:59.999999Z" } ] }
- Ensure a great ISA user experience
The allowance events are the core of the Investment API’s tax wrapper functionality. The next section outlines how these and our
Get /isa/wrappers/{tax_wrapper_id}/allowances
endpoint can be leveraged to facilitate a great user experience for your customers.Allowance limits across ISA products
Currently the Investment API only supports Stocks & Shares ISAs. However, we can enable a unified allowance UX where a client offers additional ISA products to their end users.
By ingesting allowance events for the Stocks & Shares ISA as input values for an aggregated allowance value, Clients are able to represent a unified UX which outlines the total allowance limit across ISA products, such as Cash ISAs.
Validations on ISA inflow
As Upvest will not have oversight of other ISA types provided by the client, the Investment API will not block inflow into the ISA. This allows the client to manage overall allowance at the user level across cash ISA and Stocks & Shares ISA without creating a more limited check at Upvest for the Stocks & Shares ISA only.
To prevent ISA account holders from breaching ISA subscription rules, the
remaining_amount
field can be leveraged to build front-end validations to prevent a deposit from being processed in the following scenarios:- A deposit exceeding a tax year’s
remaining_amount
- The overall subscription limit, as represented by amount
The remaining amount figure will also take into account any additional allowance created by flexible withdrawals.
Query parameters on Get Allowances
To enable simplified integration, the
tax_year
query parameter allows specification of a particular tax year.GET /isa/wrappers/{tax_wrapper_id}/allowances?tax_year=2025/2026
{ "meta": { "offset": 0, "limit": 100, "count": 1, "total_count": 1, "sort": "valid_from", "order": "DESC", }, "data": [ { "allowance_id": "", "tax_wrapper_id": "", "tax_year": "2025/2026", "type": "ANNUAL", "status": "ACTIVE, EXPIRED", "currency": "GBP", "total_amount": "", "used_amount": "", "remaining_amount": "", "first_subscription_at": "2025-07-21T14:10:00.00Z", "created_at": "2025-07-21T14:10:00.00Z", "updated_at": "2025-07-21T14:10:00.00Z", "valid_from": "2025-04-05T23:00:00.00Z", "valid_to": "2025-04-05T22:59:59.999999Z", } ] }
- A deposit exceeding a tax year’s
- Start trading
The steps outlined in our Order guides detail the steps necessary to place a trade in your newly created ISA accounts.
Depending on the chosen cash model, ISA allowance values are automatically updated upon Virtual Cash increase / decrease or via direct funding methods outlined in our Payment guides.
Associated Allowance events are generated asynchronously.
The Investment API guarantees that only trading in ISA-eligible instruments is facilitated.