# How to implement ISA transfers

## Overview

With the Upvest API and webhooks clients can easily track and manage ISA transfers.

## Transfer process

The process of ISA transfers requested via API are similar for both external and internal transfers. For internal transfers the only statuses that apply are **NEW**, **PROCESSING**, and **SETTLED**.

External transfers complete all of the following statuses:

| **Status** | **Description** |
|  --- | --- |
| `NEW` | A request for a new ISA Transfer is received. |
| `DISCOVERY` | The Discovery phase with the ceding provider was initiated for the transfer. |
| `DISCOVERY_CONFIRMED` | The Discovery was verified and an instruction can be created for this transfer. |
| `INSTRUCTED` | Transfer is instructed to the ceding provider. |
| `PROCESSING` | Transfer instruction is confirmed by the ceding provider. Transfer is being processed. |
| `SETTLED` | The transfer was completed. |


## Create an ISA transfer

### Example ISA transfer request and response

**POST** `/isa/transfers`

Request

```json
{
  "transfer_type": "ISA_EXTERNAL",
  "user_id": "2dedfeb0-58cd-55f2-ae08-0e41fe0413d9",
  "account_group_id": "48043cd0-e306-4b48-bbdd-6ca5d0967009",
  "direction": "INCOMING",
  "reference": "4XD8Z53CST3LGEZBYO",
  "counterparty": {
    "account_number": "5WJSZB3C8"
  },
  "transfer_value": "10000.00",
  "currency": "GBP",
  "transfer_method": "CASH",
  "transfer_date": "2025-10-10T10:00:00Z",
  "details": {
    "current_year_subscription": {
      "transfer_amount": "2000.00",
      "first_subscription_at": "2025-09-09T12:50:00Z"
    }
  }
}
```

Response

```json
{
  "id": "9637e68f-7065-4131-a072-6d57044ebd8c",
  "created_at": "2024-01-22T14:10:00.00Z",
  "updated_at": "2024-01-22T14:12:34.56Z",
  "direction": "INCOMING",
  "status": "NEW",
  "transfer_type": "ISA_EXTERNAL",
  "user_id": "7e9a0529-d289-4f4a-ae01-c2cd013d582e",
  "account_group_id": "d396b7c3-aa67-488a-8e39-4a1a7cbeb9f4",
  "reference": "b82dc5985558fdr2",
  "transfer_value": "10000.00",
  "currency": "GBP",
  "transfer_method": "CASH",
  "counterparty": {
    "account_number": "1234567891"
  },
  "details": {
    "current_year_subscription": {
      "transfer_amount": "2000.00",
      "first_subscription_at": "2024-01-15T10:00:00.00Z"
    }
  },
  "transfer_date": "2024-01-22T14:10:00.00Z"
}
```

## Request fields

In the transfer request, you must populate the fields marked as Required. Other fields remain optional.

| **Field** | **Required** | **Description** |
|  --- | --- | --- |
| `transfer_type` | Required | The type of transfer: - `ISA_EXTERNAL` - Transfer occurs across different ISA managers, via Equisoft or others. - `ISA_INTERNAL` - Transfer occurs within the same ISA manager. The type of transfer determines required fields. |
| `user_id` | Required | The end user’s unique identifier. |
| `account_group_id` | Required | The account group’s unique identifier. |
| `direction` | Required | Direction of the transfer: - `INCOMING`: Transfer is incoming to the user. - `OUTGOING`: Transfer is outgoing from the user. |
| `reference` | Required | Random string reference created by the provider for the transfer. |
| `counterparty` | Required (for external transfers) | Counterparty of the ISA transfer.Required if `transfer_type` is `ISA_EXTERNAL`. |
| `counterparty.account_number` | Required (for external transfers) | Unique reference of the account group being transferred, (e.g., the ISA reference number). Required if `transfer_type` is `ISA_EXTERNAL`. |
| `transfer_value` | Required (for internal transfers) | Total value of the transfer. For external transfers, this value is an estimate and reflects the amount that the cash balance increases.The actual amount of the transfer may vary by the time the balance is updated. The `transfer_value` amount should account for potential changes in value between the discovery phase and the final transfer.Required if `transfer_type` is `ISA_INTERNAL`. |
| `currency` | Required | The currency of the transfer. Set this equal to `GBP`. |
| `transfer_method` | Required | Method of the ISA transfer. Set this equal to `CASH`. |
| `details` | Required (for internal transfers) | Details of the ISA being transferred.Required if `transfer_type` is `ISA_INTERNAL`. |
| `details`  `.current_year_subscription` | Required (for internal transfers) | Details related to the current year’s subscription of ISA being transferred. Required if `transfer_type` is `ISA_INTERNAL` |
| `details`  `.current_year_subscription`  `.transfer_amount` | Required (for internal transfers) | The amount of the transfer that relates to current tax year's subscriptions and impacts the current tax year's ISA allowance.Required if `transfer_type` is `ISA_INTERNAL` |
| `details`  `.current_year_subscription`  `.first_subscription_at` | Required (for internal transfers) | The date of the first subscription made to the ISA in the current tax year.This is part of the reporting requirements to [HM Revenues and Customs (HMRC)](https://www.gov.uk/government/organisations/hm-revenue-customs), and does not need to be displayed to the end user.This reflects the earliest date of all the positive subscriptions that are being transferred. These subscriptions positively impact the yearly allowance.The sum of the subscriptions must be reflected in `.transfer_amount`.Required if `transfer_type` is `ISA_INTERNAL` |


## Response fields

Only additional fields not present in the request are listed below.

| **Field** | **Required** | **Description** |
|  --- | --- | --- |
| `transfer_date` | Required | The date when the end user initiated the transfer request.Relevant for tax year's end reporting.[RFC 3339-5](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6), [ISO8601 UTC](https://www.iso.org/iso-8601-date-and-time-format.html) |
| `status` | Required | Status of the transfer. The available statuses are explained in the [Transfer process](#transfer-process) section. |