---
title: "Pay a UK account by Faster Payments"
description: "Save a UK sort code and account number as a Faster Payments payee and send a GBP payout from a wallet-backed account."
---
Use this recipe to save a UK sort code and account number as a Faster Payments payee and send a GBP payout from a wallet-backed account.

**Who it is for.** A US marketplace that pays a UK seller's sterling account.

**Status.** Available from wallet-backed accounts to GB, if Gravv has enabled Faster Payments for your business. Not supported from bank-held USD accounts. Gravv does not support CHAPS or BACS.

## Money example

1. The marketplace's wallet-backed USD account holds 3,000.00 USD.
2. The marketplace sends 800.00 USD to Oliver Bennett's UK account.
3. At an example rate of 0.75 GBP per USD, the response shows 600.00 GBP for Oliver in `local_amount`. Gravv debits the account 800.00 USD plus the fee on your plan.

## Before you start

You need the same as for [SEPA](/recipes/bank-payouts/pay-a-euro-account-by-sepa#before-you-start):

- A wallet-backed source account.
- Faster Payments enabled for your business.
- The seller's sort code, account number, name and address.

## Find out what is required

- **Payee rules.** Set `payee_type` to `fps` and `currency` to `GBP`, the only currency allowed. Put the **6-digit sort code** in `routing_number`. Send `account_number` as 4 to 34 letters or digits with no spaces. Also send `account_owner_type`, `bank_name` and `address`.
- **Always send `payee_type` `fps`.** Without it, Gravv guesses the payee type from the details, and a mistyped routing number can turn the payee into a US payee.
- **Indicative rate.** Call [`GET /v1/transfer/rates?currency=GBP`](/api-reference/transfer/get-v1-transfer-rates) and read the item with `direction` `USD_GBP`.

## Steps

### 1. Save the Faster Payments payee

<CodeGroup>
```bash title="cURL"
curl --request POST \
     --url https://api.gravv.xyz/v1/external-accounts \
     --header 'Api-Key: <API_KEY>' \
     --header 'Content-Type: application/json' \
     --header 'Idempotency-Key: 70145bba-a8e7-4f2f-8700-4160600e6cbe' \
     --data '
{
  "customer_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
  "payee_type": "fps",
  "currency": "GBP",
  "account_name": "Oliver Bennett",
  "routing_number": "601613",
  "account_number": "31926819",
  "account_owner_type": "individual",
  "bank_name": "NatWest",
  "address": {
    "address_line1": "221 Baker Street",
    "city": "London",
    "postal_code": "NW1 6XE",
    "country": "GB"
  }
}
'
```
```javascript title="Node"
const response = await fetch("https://api.gravv.xyz/v1/external-accounts", {
  method: "POST",
  headers: {
    "Api-Key": process.env.GRAVV_API_KEY,
    "Content-Type": "application/json",
    "Idempotency-Key": "70145bba-a8e7-4f2f-8700-4160600e6cbe",
  },
  body: JSON.stringify({
    "customer_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
    "payee_type": "fps",
    "currency": "GBP",
    "account_name": "Oliver Bennett",
    "routing_number": "601613",
    "account_number": "31926819",
    "account_owner_type": "individual",
    "bank_name": "NatWest",
    "address": {
      "address_line1": "221 Baker Street",
      "city": "London",
      "postal_code": "NW1 6XE",
      "country": "GB"
    }
  }),
});
console.log(response.status, await response.json());
```
```python title="Python"
import os

import requests

response = requests.post(
    "https://api.gravv.xyz/v1/external-accounts",
    headers={
        "Api-Key": os.environ["GRAVV_API_KEY"],
        "Content-Type": "application/json",
        "Idempotency-Key": "70145bba-a8e7-4f2f-8700-4160600e6cbe",
    },
    json={
        "customer_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
        "payee_type": "fps",
        "currency": "GBP",
        "account_name": "Oliver Bennett",
        "routing_number": "601613",
        "account_number": "31926819",
        "account_owner_type": "individual",
        "bank_name": "NatWest",
        "address": {
            "address_line1": "221 Baker Street",
            "city": "London",
            "postal_code": "NW1 6XE",
            "country": "GB",
        },
    },
)
print(response.status_code, response.json())
```
</CodeGroup>

```json title="Response (HTTP 202)"
{
  "data": {
    "account_name": "OLIVER BENNETT",
    "account_number": "31926819",
    "account_owner_type": "individual",
    "address": {
      "address_line1": "221 Baker Street",
      "city": "London",
      "country": "GB",
      "postal_code": "NW1 6XE"
    },
    "currency": "GBP",
    "customer_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
    "date_created": "2026-10-13T22:41:25.016918Z",
    "id": "7b1a2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
    "institution_name": "NatWest",
    "payee_type": "fps",
    "routing_number": "601613",
    "status": "pending"
  },
  "error": null
}
```

The payee starts as `pending`. Wait for the `external_account.active` webhook before you send the payout.

### 2. Send the payout

<CodeGroup>
```bash title="cURL"
curl --request POST \
     --url https://api.gravv.xyz/v1/transfer \
     --header 'Api-Key: <API_KEY>' \
     --header 'Content-Type: application/json' \
     --header 'Idempotency-Key: c72fcd5c-b78d-4442-b1b3-c89df886eef9' \
     --data '
{
  "customer_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
  "source": {
    "source_type": "internal_account",
    "id": "9b2d6f0e-3c1a-4e8b-a7d5-2f4c6e8a0b13"
  },
  "destination": {
    "destination_type": "external_account",
    "id": "7b1a2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
    "rail": "fps"
  },
  "amount": "800.00",
  "description": "Marketplace payout order 5590",
  "client_reference": "fps-ob-5590"
}
'
```
```javascript title="Node"
const response = await fetch("https://api.gravv.xyz/v1/transfer", {
  method: "POST",
  headers: {
    "Api-Key": process.env.GRAVV_API_KEY,
    "Content-Type": "application/json",
    "Idempotency-Key": "c72fcd5c-b78d-4442-b1b3-c89df886eef9",
  },
  body: JSON.stringify({
    "customer_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
    "source": {
      "source_type": "internal_account",
      "id": "9b2d6f0e-3c1a-4e8b-a7d5-2f4c6e8a0b13"
    },
    "destination": {
      "destination_type": "external_account",
      "id": "7b1a2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
      "rail": "fps"
    },
    "amount": "800.00",
    "description": "Marketplace payout order 5590",
    "client_reference": "fps-ob-5590"
  }),
});
console.log(response.status, await response.json());
```
```python title="Python"
import os

import requests

response = requests.post(
    "https://api.gravv.xyz/v1/transfer",
    headers={
        "Api-Key": os.environ["GRAVV_API_KEY"],
        "Content-Type": "application/json",
        "Idempotency-Key": "c72fcd5c-b78d-4442-b1b3-c89df886eef9",
    },
    json={
        "customer_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
        "source": {
            "source_type": "internal_account",
            "id": "9b2d6f0e-3c1a-4e8b-a7d5-2f4c6e8a0b13",
        },
        "destination": {
            "destination_type": "external_account",
            "id": "7b1a2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
            "rail": "fps",
        },
        "amount": "800.00",
        "description": "Marketplace payout order 5590",
        "client_reference": "fps-ob-5590",
    },
)
print(response.status_code, response.json())
```
</CodeGroup>

```json title="Response"
{
  "data": {
    "amount": "800",
    "amount_currency": "USD",
    "reference": "8e0a2c4e-6f8b-4a0c-b2e4-6a8c0e2f4b56",
    "date_created": "2026-10-13T11:20:00.000Z",
    "transfer_status": "pending",
    "transaction_id": "1c3e5a7c-9e1b-4c3e-a5c7-9e1b3d5f7a67",
    "local_amount": "600",
    "local_currency": "GBP",
    "fee": "2",
    "fee_currency": "USD",
    "requires_approval": false
  },
  "error": null
}
```

### 3. Follow it to the end

The transaction shows `transaction_type` `global_remittance` and `channel` `bank_transfer`. The webhooks carry `workflow_type` `fps_transfer`.

## What can go wrong

| Response | Why | Fix |
| :-- | :-- | :-- |
| 400 `routing number (sort code) required but missing for fps payee: invalid input` | The request has no sort code | Send it in `routing_number` |
| 400 `account number must not contain spaces` | The account number has spaces | Send `31926819`, not `3192 6819` |
| 400 `EUR not supported for fps external accounts: invalid input` | Faster Payments payees are GBP only | Send `"currency": "GBP"` |
| A GBP payee saved with a 9-digit routing number becomes a US payee and fails the USD rule | The request had no `payee_type` | Always send `"payee_type": "fps"` |
| 400 `a recipient with the same account name, account number and bank already exists`, with `data.payee_id` | A payee with the same customer, name, account number and sort code already exists. `60-16-13` and `601613` count as the same sort code | Use `data.payee_id` |
| 400 `account_number (UK sort code + account number) is required for FPS transfers` | The payee has no account number | [Fix the payee](/recipes/bank-payouts/fix-a-payee-that-failed-setup) or save a new one |
| Source, country and rate errors | The same errors as for SEPA, with `GB/GBP` | See [SEPA](/recipes/bank-payouts/pay-a-euro-account-by-sepa#what-can-go-wrong) |

## Webhooks you will receive

You receive the same webhooks as for [SEPA](/recipes/bank-payouts/pay-a-euro-account-by-sepa#webhooks-you-will-receive).

## Testing in sandbox

Sandbox simulates Faster Payments payee setup, and the payee becomes `active` in a few seconds. Everything else works as for [SEPA](/recipes/bank-payouts/pay-a-euro-account-by-sepa#testing-in-sandbox).

## Reference

- [Get rates](/api-reference/transfer/get-v1-transfer-rates)
- [Add an external account](/api-reference/external-accounts/post-v1-external-accounts)
- [Create a transfer](/api-reference/transfer/post-v1-transfer)
