Make a payout to an external account

Learn about open-loop payouts and how to make one.

An open-loop payout is where a payment is made to an external account from a merchant account. There's no need for the external account to have previously made a payment via TrueLayer.

Before you start

To make an open-loop payout, you need:

  • A merchant account and its id
  • These details about the external account receiving the payment:
    • The account_holder_name
    • The account_identifier (sort code and account number or IBAN)
    • The account holder's date_of_birth

As with all Payments API requests, you also need to:

  • Set up request signing so you can create a Tl-Signature header for your request.
  • Generate an access token to include as a bearer token for your request.
    This should also have the appropriate scopes (payments for a single payment).

You should also provide an Idempotency-Key with each of your payout requests.

Create a payout to an external account

To create an open-loop payout, make a POST request to /payouts endpoint, providing the parameters below. You must select external_account as the beneficiary.type for an open-loop payout.

ParameterDescription
merchant_account_idThe unique ID of the merchant account to pay out from.
amount_in_minorThe amount in minor units. Minor units are the smallest units of a currency, depending on the number of decimals.

For example: 1 GBP = 100 pence.
currencyCurrency of the payment in ISO 4217.

You cannot make a payment from GBP currency to a EUR account, or the opposite. The beneficiary account is specified in the beneficiary.account_identifier object.
beneficiary.typeShould be external_account for an open-loop payout.
beneficiary.referenceA reference for the payment.
beneficiary.account_holder_nameThe name of the external account holder.

If making a payout to an external business account, this should be the company name.

You must provide this information for AML purposes.
beneficiary.account_identifierThe identifier for the beneficiary's account.

This can be sort_code_account_number or iban, which both contain further objects to provide the relevant identifiers.

Note that you cannot make payments from a GBP account to a EUR account, or the other way round.
beneficiary.date_of_birthThe date of birth of the external account holder.

If making a payout to an external business account, this should be the date the company was founded.

You must provide this information for AML purposes.

🚧

Integration options

Although the example on this page uses HTTP, we also offer complete .NET and Java libraries you can use to integrate payout creation.

This is an example of a open-loop payout creation request using HTTP.

POST /payouts HTTP/1.1
Content-Type: application/json; charset=UTF-8
Idempotency-Key: random
Tl-Signature: {SIGNATURE}
Authorization: Bearer {TOKEN}
Host: api.truelayer.com
{
  "beneficiary": {
    "type": "external_account",
    "account_identifier": {
      "type": "sort_code_account_number"
    },
    "reference": "Winnings",
    "account_holder_name": "Pa Yout",
    "date_of_birth": "1990-01-31"
  },
  "merchant_account_id": "AB8FA060-3F1B-4AE8-9692-4AA3131020D0",
  "amount_in_minor": 100
  "currency": "GBP"
}

In this example, the account_holder_name and date_of_birth fields have been completed. This is required for AML purposes.

Below is an example of a successful response, including the payout id:

{  
  "id": "0cd1b0f7-71bc-4d24-b209-95259dadcc20"  
}

User details to collect

When you create an open-loop payout, you provide user details as part of the beneficiary object. The available fields in the beneficiary object are account_holder_name, date_of_birth and address.

As part of an open-loop payout you must provide a minimum of:

  • The name of the payer.
  • The date of birth of the payer.

📘

User details for businesses

If you are making a payment to a business using the external_account method for the beneficiary, provide the business name, business founding date and business address.

The example request below shows an open-loop payout creation request with the mandatory user detail objects account_holder_name and date_of_birth completed. It also includes values for the non-mandatory address object.

POST /payouts
{
  "merchant_account_id": "c6ba13f2-35ef-4556-a99e-a6afd6275044",
  "amount_in_minor": 100,
  "currency": "GBP",
  "beneficiary": {
    "type": "external_account",
    "reference": "Withdrawal",
    "account_holder_name": "John Smith",
    "account_identifier": {
      "type": "sort_code_account_number",
      "sort_code": "<sort code>",
      "account_number": "<account number>"
    },
    "date_of_birth": "1992-08-03",
    "address": {
      "address_line1": "1 Hardwick St",
      "address_line2": "Clerkenwell",
      "city": "London",
      "state": "London",
      "zip": "EC1R 4RB",
      "country_code": "GB"
    }
  },
  "metadata": {
    "prop1": "value1",
    "prop2": "value2"
  }
}

Monitor the status of a payout

To keep track of the status of a closed-loop payout, you can:

To make a GET request to the /payouts/{id} endpoint, use the payout ID as a path parameter.

curl --request GET \
     --url https://api.truelayer.com/payouts/id \
     --header 'accept: application/json; charset=UTF-8'

This is an example response for a successful open-loop payout with a status of executed:

{
    "id": "fb976298-dc3a-4207-b399-c1084ee8232c",
    "merchant_account_id": "200552da-13da-43c5-a9ba-04ee1502ac57",
    "amount_in_minor": 1,
    "currency": "GBP",
    "beneficiary": {
        "type": "external_account",
        "account_holder_name": "Pa Yout",
        "account_identifier": {
            "type": "sort_code_account_number",
            "sort_code": "040668",
            "account_number": "00013279"
        },
        "account_identifiers": [
            {
                "type": "sort_code_account_number",
                "sort_code": "040668",
                "account_number": "00013279"
            }
        ],
        "reference": "Reference Exmample"
    },
    "scheme_id": "internal_transfer",
    "status": "executed",
    "created_at": "2023-02-08T16:20:26.987609393Z",
    "authorized_at": "2023-02-08T16:20:27.216404095Z",
    "executed_at": "2023-02-08T16:20:28.183Z"
}