Authentication scopes —
isa_transfers:adminFor more information, refer to Authentication scopes.
An active ISA tax wrapper — The receiving account group must have a Stocks and Shares ISA tax wrapper in status
ACTIVE.For more information, refer to How to integrate ISA tax wrappers.
Webhook handler ready — Set up a webhook endpoint and subscribe to
ISA_TRANSFER.*events. Creating a transfer is asynchronous and there is no endpoint to read a transfer back, so webhooks are the only way to observe its progress.For more information, refer to Implementing webhooks.
A transfer within the same ISA manager moves cash from an end user's existing ISA into their Upvest-supported Stocks and Shares ISA. You create the transfer through the Investment API, and Upvest credits the account group and applies any current year subscription to the end user's annual ISA allowance.
Upvest has no visibility of the source ISA, so you supply two things the API cannot derive: the cash amount to credit, and how much of that amount relates to the current tax year. For background on the stages and the allowance rules, see the ISA transfers overview.
The Investment API currently supports incoming, cash settled transfers within the same ISA manager. Transfers between different ISA managers, outgoing transfers, and in-specie settlement are planned for a future release.
Each status change emits a matching ISA_TRANSFER.* webhook event.
| Status | Description |
|---|---|
NEW | The transfer has been created and has not started processing. |
PROCESSING | The transfer is being processed. |
SETTLED | The transfer is complete. The cash has been credited and any current year subscription has been applied to the allowance. This status is terminal. |
CANCELLED | The transfer has been cancelled and no funds move. This status is terminal. |
POST /isa/transfers
This operation requires an idempotency-key header containing a randomly generated UUID. Reuse the same value when retrying a request so the transfer is not created twice. For more information, refer to Idempotency.
The response returns the created transfer with status NEW.
{
"direction": "INCOMING",
"type": "NO_ISA_MANAGER_CHANGE",
"method": "CASH",
"user_id": "4b2e2e64-7544-4c3f-a98d-dfdc03d487aa",
"account_group_id": "79e9f9a2-dd29-4b54-9cca-b4c31956beb3",
"cash_amount": "10000.00",
"currency": "GBP",
"counterparty": {
"account_number": "5WJSZB3C8"
},
"current_year_subscription": {
"tax_year": "2025/2026",
"cash_amount": "3000.00",
"first_subscription_at": "2025-09-14T12:10:00.00Z"
}
}| Field | Required/Optional | Description |
|---|---|---|
direction | Required | The direction of the transfer. Currently, only INCOMING (funds move into the Upvest-supported Stocks and Shares ISA) is supported. |
type | Required | The type of the transfer. Currently, only NO_ISA_MANAGER_CHANGE (the transfer occurs within the same ISA manager) is supported. |
method | Required | The settlement method of the transfer. Currently, only CASH is supported. |
user_id | Required | Unique identifier of the end user making the transfer. |
account_group_id | Required | Unique identifier of the account group that receives the cash. This account group must hold an ACTIVE ISA tax wrapper. |
currency | Required | Currency of the transfer, as an ISO 4217 code. Currently, only GBP is supported. |
cash_amount | Conditional | Total cash amount of the transfer, as a decimal string with up to nine digits and two decimal places, for example "10000.00". Required for NO_ISA_MANAGER_CHANGE transfers. |
counterparty.account_number | Conditional | The unique reference of the account group being transferred, such as the ISA reference number of the source ISA. Maximum 28 characters. Required when counterparty is provided. |
current_year_subscription | Conditional | Details of the part of the transfer that relates to the current tax year. Required for NO_ISA_MANAGER_CHANGE transfers where the end user has subscribed to the source ISA in the current tax year. |
current_year_subscription.tax_year | Conditional | The current tax year in YYYY/YYYY format, for example "2025/2026". Required when current_year_subscription is provided. |
current_year_subscription.cash_amount | Conditional | The part of cash_amount that relates to current tax year subscriptions and so counts towards the current year ISA allowance. Required when current_year_subscription is provided. |
current_year_subscription.first_subscription_at | Optional | The date and time of the first subscription made to the source ISA in the current tax year. RFC 3339-5, ISO8601 UTC. |
current_year_subscription.cash_amount must not exceed cash_amount. Only the current year portion counts towards the annual allowance — the remainder is treated as previous years' balance and does not affect the allowance.
Only the fields not present in the request are listed below.
| Field | Required/Optional | Description |
|---|---|---|
id | Required | Unique identifier of the ISA transfer, as a UUID. |
created_at | Required | Date and time when the resource was created. RFC 3339-5, ISO8601 UTC. |
updated_at | Required | Date and time when the resource was last updated. RFC 3339-5, ISO8601 UTC. |
status | Required | Status of the transfer: NEW, PROCESSING, SETTLED, or CANCELLED. See Transfer lifecycle. |
When a transfer reaches SETTLED:
- The cash is credited to the account group, and the credit appears as a cash transaction of type
ISA_TRANSFER. You can retrieve it through the cash transactions endpoint, and it also triggers aCASH_TRANSACTION.EXECUTEDwebhook event whoseobject.typeisISA_TRANSFER. - Where the transfer included a
current_year_subscription, the used amount on the receiving wrapper's annual allowance increases and anISA_WRAPPER_ALLOWANCE.UPDATEDevent is sent. Update the allowance on the source ISA to reflect the amount that moved.