# Agency Account Synchronization

## Service description

This service is used to synchronise existing account numbers of a third-party service provider with LHV.

For use with the Confirmation of Payee and Verification of Payee service, refer to [version 2](#account-synchronization-v2) of the account synchronisation service.

## Request <a href="#virtual-iban-open" id="virtual-iban-open"></a>

<mark style="color:green;">`POST`</mark> <https://connect.lhv.com/agent/account/synchronize>

The request supports bulk submission of multiple accounts.

* A maximum of 1,000 accounts (Accounts.Account blocks) can be included per request.
* The service adds new accounts or updates the status of existing ones. Duplicate entries are not checked—existing data is overwritten.
* Valid requests result in immediate account activation by LHV.
* If any entry in the request is invalid, the entire bulk is rejected and an appropriate error code is returned.
* A valid Indirect Scheme Access Service Agreement must be in place for the service provider.

**Usage of Bank Codes**

The Bank Codes field is an optional list of one or two codes that indicate whether an account number should be synchronised with LHV Estonia (LHV EE), LHV United Kingdom (LHV UK), or both. This depends on the customer’s setup and business requirements.

* This feature is available only when connected to the LHV UK Connect API host.
* If no Bank Codes are provided, synchronisation is performed with LHV EE.
* If the Bank Code includes LHVBEE22 or LHVBEE22XXX, the account is synchronised with LHV EE.
* If the Bank Code includes LHVBGB2L or LHVBGB2LXXX, the account is synchronised with LHV UK.
* If the Bank Codes list includes both an LHV EE code (LHVBEE22 or LHVBEE22XXX) and an LHV UK code (LHVBGB2L or LHVBGB2LXXX) as two separate entries, the account is synchronised with both entities.
* If an unsupported Bank Code is provided, the request defaults to LHV UK, but account synchronisation will be rejected.

#### **Headers**

| Name           | Value             |
| -------------- | ----------------- |
| Content-Type   | `application/xml` |
| Client-Code    | `customer value`  |
| Client-Country | `customer value`  |

#### **Body**

{% file src="<https://2266620947-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FHGywduAxJuxV3reZhASh%2Fuploads%2FMK0LxDc7P7JaBsGXvqFr%2Faccount.agent.sync.xsd.xml?alt=media&token=76c4f1b4-5179-43cc-997e-f7661f9c7475>" %}
XML schema
{% endfile %}

XML structure description:

<table data-full-width="true"><thead><tr><th width="102">MULT.</th><th width="171">MESSAGE ELEMENT</th><th width="198">XML TAG</th><th>Description</th></tr></thead><tbody><tr><td>[1..1]</td><td>+MessageRoot</td><td>&#x3C;AgentAccountSyncRequest></td><td></td></tr><tr><td>[0..1]</td><td>++BankCodes</td><td>&#x3C;BankCodes></td><td>List of LHV bank codes where to sync the account. To be used only for LHV UK Connect API host</td></tr><tr><td>[1..2]</td><td>+++BankCode</td><td>&#x3C;BankCode></td><td>* LHVBEE22 or LHVBEE22XXX - use for LHVEE<br>* LHVBGB2L or LHVBGB2LXXX - use for LHVUK</td></tr><tr><td>[1..1]</td><td>++Accounts</td><td>&#x3C;Accounts></td><td>List of accounts</td></tr><tr><td>[1..1]</td><td>+++Account</td><td>&#x3C;Account></td><td>Single account entry with region, account number or IBAN, and current status details.</td></tr><tr><td>[1..1]</td><td>++++Region</td><td>&#x3C;Region></td><td>'GB' or ISO country code (SEPA Scheme Country) used in IBAN.</td></tr><tr><td>[0..1]</td><td>++++AccountNo</td><td>&#x3C;AccountNo></td><td>For 'GB' region UK sort code + account no (14 characters). AccountNo or IBAN or both can exist. AccountNo's for other regions than 'GB' are ignored.</td></tr><tr><td>[0..1]</td><td>++++Iban</td><td>&#x3C;Iban></td><td>IBAN country code must match the value of Region. The BIC code to which the IBAN refers must have a valid Indirect Scheme Access Service Agreement.</td></tr><tr><td>[0..1]</td><td>++++Status</td><td>&#x3C;Status></td><td><p>Status field can contain the following values: <strong>ACTIVE</strong>, <strong>CLOSED</strong>, <strong>INST_RESTRICTED</strong></p><p>Rules:</p><ul><li>If a new account is synced and the field is empty, the default value ACTIVE is applied.</li><li>If an existing account is updated and the field is empty, the status is not changed.</li><li>All three values can be switched between each other. Including the ability to change status from CLOSED to ACTIVE.</li><li>Special rule for INST_RESTRICTED - status affects only incoming SEPA Instant payments. Payments to an account with this status will be automatically returned.</li></ul></td></tr></tbody></table>

#### Examples

{% tabs %}
{% tab title="Without Bank Code" %}
Without Bank Code tag \<BankCodes> routed to EE

```xml
<?xml version="1.0" encoding="UTF-8"?>
<AgentAccountSyncRequest>
    <Accounts>
        <Account>
            <Region>NL</Region>
            <Iban>NL91RAB00417164300</Iban>
            <Status>ACTIVE</Status>
        </Account>
        <Account>
            <Region>NL</Region>
            <Iban>NL32RABO0195610843</Iban>
            <Status>ACTIVE</Status>
        </Account>
    </Accounts>
</AgentAccountSyncRequest>
```

{% endtab %}

{% tab title="UK Bank Code" %}
Account is synced to LHV UK - BankCode = LHVBGB2L

```xml
<?xml version="1.0" encoding="UTF-8"?>
<AgentAccountSyncRequest>
    <BankCodes>
        <BankCode>LHVBGB2L</BankCode>
    </BankCodes>
    <Accounts>
        <Account>
            <Region>GB</Region>
            <AccountNo>40127612345678</AccountNo>
            <Status>ACTIVE</Status>
        </Account>
        <Account>
            <Region>GB</Region>
            <AccountNo>40127612345679</AccountNo>
            <Status>ACTIVE</Status>
        </Account>
    </Accounts>
</AgentAccountSyncRequest>
```

{% endtab %}

{% tab title="UK and EE" %}
Account is synced both to LHV UK and LHV EE

```xml
<?xml version="1.0" encoding="UTF-8"?>
<AgentAccountSyncRequest>
    <BankCodes>
        <BankCode>LHVBGB2L</BankCode>
        <BankCode>LHVBEE22</BankCode>
    </BankCodes>
    <Accounts>
        <Account>
            <Region>CY</Region>
            <Iban>CY17002001280000001200527600</Iban>
            <Status>ACTIVE</Status>
        </Account>
        <Account>
            <Region>CY</Region>
            <Iban>CY46002001280000001200527700</Iban>
            <Status>ACTIVE</Status>
        </Account>
    </Accounts>
</AgentAccountSyncRequest>
```

{% endtab %}

{% tab title="EE Bank Code" %}
Accounts are synced only to EE

```xml
<?xml version="1.0" encoding="UTF-8"?>
<AgentAccountSyncRequest>
    <BankCodes>
        <BankCode>LHVBEE22</BankCode>
    </BankCodes>
    <Accounts>
        <Account>
            <Region>NL</Region>
            <Iban>NL91RAB00417164300</Iban>
            <Status>ACTIVE</Status>
        </Account>
        <Account>
            <Region>NL</Region>
            <Iban>NL32RABO0195610843</Iban>
            <Status>ACTIVE</Status>
        </Account>
    </Accounts>
</AgentAccountSyncRequest>
```

{% endtab %}
{% endtabs %}

### **Response**

**Headers**

| Name         | Value             |
| ------------ | ----------------- |
| Content-Type | `application/xml` |
| X-Bank-Code  | `LHVUK`, `LHVEE`  |

#### Body

{% tabs %}
{% tab title="202" %}
{% hint style="success" %}
Request accepted - no content
{% endhint %}
{% endtab %}

{% tab title="403" %}
{% hint style="danger" %}
Error code and description
{% endhint %}

<pre><code>&#x3C;Errors>
<strong>    &#x3C;Error>
</strong>        &#x3C;ErrorCode>FORBIDDEN&#x3C;/ErrorCode>
        &#x3C;Description>User doesn't exist&#x3C;/Description>
    &#x3C;/Error>
&#x3C;/Errors>
</code></pre>

{% endtab %}
{% endtabs %}

## Response message

Response message is created and can be requests via the Messages services - [messages](https://docs.lhv.com/home/connect/services/messages "mention")

{% hint style="info" %}
HTTP Header Message-Response-Type: AGENT\_ACCOUNT\_SYNC
{% endhint %}

#### Body

{% file src="<https://2266620947-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FHGywduAxJuxV3reZhASh%2Fuploads%2FMK0LxDc7P7JaBsGXvqFr%2Faccount.agent.sync.xsd.xml?alt=media&token=76c4f1b4-5179-43cc-997e-f7661f9c7475>" %}
XML schema
{% endfile %}

**Message structure**

<table><thead><tr><th width="210">MESSAGE ELEMENT</th><th width="276">XML TAG</th><th>Description</th></tr></thead><tbody><tr><td>+MessageRoot</td><td>&#x3C;AgentAccountSyncResponse></td><td></td></tr><tr><td>++Accounts</td><td>&#x3C;Accounts></td><td></td></tr><tr><td>+++Account</td><td>&#x3C;Account></td><td></td></tr><tr><td>++++Region</td><td>&#x3C;Region></td><td></td></tr><tr><td>++++AccountNo</td><td>&#x3C;AccountNo></td><td>Filled if existed in request.</td></tr><tr><td>++++Iban</td><td>&#x3C;Iban></td><td>Filled if existed in request.</td></tr><tr><td>++++Status</td><td>&#x3C;Status></td><td>Account status</td></tr></tbody></table>

#### Examples

{% tabs %}
{% tab title="Successful" %}

```xml
<?xml version="1.0" encoding="UTF-8"?>
<AgentAccountSyncResponse>
    <Accounts>
        <Account>
            <Region>GB</Region>
            <AccountNo>40127612345678</AccountNo>
            <Status>ACTIVE</Status>
        </Account>
        <Account>
            <Region>GB</Region>
            <AccountNo>40127612345679</AccountNo>
            <Status>ACTIVE</Status>
        </Account>
    </Accounts>
</AgentAccountSyncResponse>
```

{% endtab %}

{% tab title="Error" %}
Error related to Master account

```xml
<?xml version='1.0' encoding='UTF-8'?>
<Errors>
    <Error>
        <ErrorCode>MASTER_ACCOUNT_NOT_FOUND</ErrorCode>
        <Description>Master account not found.</Description>
        <Field>account[1].AccountNo, account[1].Iban</Field>
    </Error>
</Errors>
```

{% endtab %}
{% endtabs %}

**Error codes**

Error codes are subject to change.

<table><thead><tr><th width="349">ERROR CODE</th><th>DESCRIPTION</th></tr></thead><tbody><tr><td>​INVALID_REGION</td><td>Invalid Region.</td></tr><tr><td>INVALID_ACCOUNT_NO_OR_IBAN</td><td>Account number invalid.</td></tr><tr><td>ACCOUNT_NO_AND_IBAN_MISMATCH</td><td>AccountNo and AccountNoIban mismatch.</td></tr><tr><td>INVALID_IBAN</td><td>Invalid IBAN.</td></tr><tr><td>MASTER_ACCOUNT_NOT_FOUND</td><td>Master account not found.</td></tr><tr><td>TECHNICAL_ERROR</td><td>Technical error.</td></tr><tr><td>INVALID_REQUEST</td><td>Invalid request.</td></tr></tbody></table>

## Account Synchronization v2

This service is used for synchronizing third-party service provider's existing account numbers with LHV. In this updated version, the service now utilizes JSON format for data exchange and includes additional mandatory fields required for Confirmation of Payee (CoP) compliance. These fields are: name, account category, and opt-out status.

Similar to other services, v2 service is asynchronous—requests are accepted for processing, and results are delivered separately via notifications once available.

A maximum of 1,000 accounts can be included per request.

{% hint style="info" %}
More information about Confirmation of Payee service can be found [here](https://docs.lhv.com/home/connect/services/confirmation-of-payee-services/confirmation-of-payee-responder).
{% endhint %}

## Request <a href="#virtual-iban-open" id="virtual-iban-open"></a>

<mark style="color:green;">`POST`</mark> <https://connect.lhv.com/v2/agent/account/synchronize>

#### **Headers**

| Name           | Value              |
| -------------- | ------------------ |
| Content-Type   | `application/json` |
| Client-Code    | `customer value`   |
| Client-Country | `customer value`   |

#### Body

<table><thead><tr><th width="254">Field</th><th width="75">M/O</th><th>Description</th></tr></thead><tbody><tr><td>BankCodes</td><td>O</td><td>List of LHV bank codes where to sync the account. LHVBGB2L or LHVBGB2LXXX - use for LHVUK</td></tr><tr><td>Accounts.Country</td><td>​M</td><td>Allowed value is ISO country code.</td></tr><tr><td>Accounts.Identification</td><td>M</td><td><p><strong>For 'GB' regions</strong>: UK sort code + account no (14 characters) or IBAN. </p><p><strong>Other than 'GB'</strong>: IBAN country code must match the value of Region. The BIC code to which the IBAN refers must have a valid Indirect Scheme Access Service Agreement.</p></td></tr><tr><td>Accounts.Status</td><td>O</td><td><p>Status field can contain the following values: <strong>ACTIVE</strong>, <strong>CLOSED</strong>, <strong>INST_RESTRICTED</strong></p><p>Rules:</p><ul><li>If a new account is synced and the field is empty, the default value ACTIVE is applied.</li><li>If an existing account is updated and the field is empty, the status is not changed.</li><li>All three values can be switched between each other. Including the ability to change status from CLOSED to ACTIVE.</li><li>Special rule for INST_RESTRICTED - status affects only incoming SEPA Instant payments. Payments to an account with this status will be automatically returned.</li></ul></td></tr><tr><td>Accounts.Name</td><td>O</td><td><p><strong>Mandatory</strong> when  <a href="../confirmation-of-payee-services/confirmation-of-payee-responder">CoP responder service</a> is enabled. </p><p>Max length 140 characters.</p><p>If AccountCategory = <strong>BUSINESS</strong> then legal user name.</p><p>If AccountCategory = <strong>PERSONAL</strong> then private person full name.</p></td></tr><tr><td>Accounts.AccountCategory</td><td>O</td><td><p><strong>Mandatory</strong> when  <a href="../confirmation-of-payee-services/confirmation-of-payee-responder">CoP responder service</a> is enabled.</p><p>Account classification - <strong>PERSONAL</strong> or <strong>BUSINESS</strong></p></td></tr><tr><td>Accounts.CoPOptOut</td><td>O</td><td><p><strong>True</strong> - account is opted out from Confirmation of Payee</p><p><strong>False</strong> - default</p></td></tr></tbody></table>

#### Example

{% tabs %}
{% tab title="UK Bank Code" %}

```json
{
    "BankCodes": [
        "LHVBGB2L"
    ],
    "Accounts": [
        {
            "Country": "GB",
            "Identification": "12345612345678",
            "Status": "ACTIVE",
            "Name": "Account Name First",
            "AccountCategory": "PERSONAL",
            "CopOptOut": false
        },
        {
            "Country": "GB",
            "Identification": "12345687654321",
            "Status": "CLOSED",
            "Name": "Account Name LTD",
            "AccountCategory": "BUSINESS",
            "CopOptOut": true
        }
    ]
}
```

{% endtab %}
{% endtabs %}

### **Response**

**Headers**

| Name         | Value              |
| ------------ | ------------------ |
| Content-Type | `application/json` |
| X-Bank-Code  | `LHVUK`, `LHVEE`   |

#### Body

{% tabs %}
{% tab title="202" %}
{% hint style="success" %}
Request accepted - no content
{% endhint %}
{% endtab %}
{% endtabs %}

## Response message

#### Body

<table><thead><tr><th width="316">Field</th><th width="81">M/O</th><th>Description</th></tr></thead><tbody><tr><td>OriginalMsgId</td><td>M</td><td></td></tr><tr><td>AcceptanceStatus</td><td>M</td><td><p>Status of the file process</p><p><strong>OK</strong> - all accounts are processed successfully</p><p><strong>PARTIAL -</strong> some of the accounts failed to process</p><p><strong>FAILED</strong> - the file was failed to process</p></td></tr><tr><td>Accounts.Data.Country</td><td>M</td><td>Country from request​</td></tr><tr><td>Accounts.Data.Identification</td><td>M</td><td>AccountNo or IBAN from request</td></tr><tr><td>Accounts.Data.Status</td><td>M</td><td>Account status</td></tr><tr><td>Accounts.Data.Name</td><td>O</td><td>Name from request</td></tr><tr><td>Accounts.Data.AccountCategory</td><td>O</td><td>Account category from request</td></tr><tr><td>Accounts.Data.CoPOptOut</td><td>O</td><td>Opt out status</td></tr><tr><td>Accounts.Confirmed</td><td>M</td><td><p>Status of the account process</p><p><strong>true</strong> - account was processed successfully</p><p><strong>false</strong> - account was failed to process</p></td></tr><tr><td>Accounts.ErrorInfo.ErrorCode</td><td>O</td><td>Error code, see the list of error codes and descriptions below.</td></tr><tr><td>Accounts.ErrorInfo.ErrorDescription</td><td>O</td><td>Error description, see the list of error codes and descriptions below.</td></tr></tbody></table>

#### Examples

{% tabs %}
{% tab title="OK" %}

```json
{
  "OriginalMsgId": "",
  "AcceptanceStatus": "OK",
  "Accounts" : [
    {
      "Data": {
        "Country": "GB",
        "Identification": "12345612345678",
        "Status": "ACTIVE",
        "Name": "Account Name First",
        "AccountCategory": "PERSONAL",
        "CopOptOut": false
      },
      "Confirmed": true
    }
```

{% endtab %}

{% tab title="PARTIAL" %}

```json
{
  "OriginalMsgId": "",
  "AcceptanceStatus": "PARTIAL",
  "Accounts" : [
    {
      "Data": {
        "Country": "GB",
        "Identification": "12345612345678",
        "Status": "ACTIVE",
        "Name": "Account Name First",
        "AccountCategory": "PERSONAL",
        "CopOptOut": false
      },
      "Confirmed": true
    },
    {
      "Data": {
        "Country": "GB",
        "Identification": "12345687654321",
        "Status": "CLOSED",
        "Name": "Account Name LTD",
        "AccountCategory": "BUSINESS",
        "CopOptOut": true
      },
      "Confirmed": false,
      "ErrorInfo": {
        "ErrorCode": "NOT_FOUND",
        "ErrorDescription": "Account not found"
      }
    }
  ]
}
```

{% endtab %}

{% tab title="FAILED" %}

```json
{
  "OriginalMsgId": "",
  "AcceptanceStatus": "FAILED",
  "Accounts": {
    "IBAN": "GI75NWBK000000000000001234"
  },
  "Errors": [
    {
      "Code": "INVALID_JSON_REQUEST",
      "Description": "JSON validation error"
    }
  ]
}
```

{% endtab %}
{% endtabs %}

#### Error codes

| ErrorCode                                                 | ErrorDescription                                                          |
| --------------------------------------------------------- | ------------------------------------------------------------------------- |
| ​INVALID\_REGION                                          | Invalid Region.                                                           |
| INVALID\_ACCOUNT\_NO\_OR\_IBAN                            | Account number invalid.                                                   |
| INVALID\_IBAN                                             | Invalid IBAN.                                                             |
| IBAN\_AND\_REGION\_MISMATCH                               | IBAN and region must match.                                               |
| MASTER\_ACCOUNT\_NOT\_FOUND                               | Master account not found.                                                 |
| TECHNICAL\_ERROR                                          | Technical error.                                                          |
| INVALID\_JSON\_REQUEST                                    | Invalid request.                                                          |
| ACCOUNTS\_OVER\_MAXIMUM\_ALLOWED\_LIMIT                   | Maximum 1000 accounts allowed in the file.                                |
| IBAN\_MUST\_EXIST\_FOR\_THIS\_REGION                      | IBAN must exist for this region.                                          |
| CONFIRMATION\_OF\_PAYEE\_NAME\_NOT\_PROVIDED              | Confirmation of Payee name not provided.                                  |
| CONFIRMATION\_OF\_PAYEE\_ACCOUNT\_CATEGORY\_NOT\_PROVIDED | Confirmation of Payee account category (PERSONAL, BUSINESS) not provided. |
| DUPLICATE\_ACCOUNT                                        | Duplicate account.                                                        |
| INVALID\_ACCOUNT\_STATUS                                  | Account status must be ACTIVE or CLOSED.                                  |
| NAME\_TOO\_LONG                                           | Name can be max 140 characters long.                                      |
