Creating payees
A payee is a saved beneficiary. Every outbound payment references one by payeeId, so creating the payee correctly is the first thing you do in any payment integration. This guide covers what to send, how the requirements change with the destination country, and how to check a payee before you create it.
You need the payees:write scope, and clientId must name a client your credential may act for.
The request
POST /v1/payees
| Field | Required | Description |
|---|---|---|
clientId | Yes | The client that will own the payee. Must be a client your credential may act for, otherwise 403. This may be a sub account client Id |
nameOnAccount | Yes | The account holder's name exactly as the receiving bank holds it. This is the name checked by Confirmation of Payee. |
bankCountry | Yes | ISO country code of the receiving bank. Decides which bank-detail fields are required and how they are validated. |
type | Yes | Individual or Business. Note this differs from accountType on account name verifications, which is Personal or Business. |
country | Yes | ISO country code of the payee themselves, that is their address country. Comes back on the payee as payeeCountry. |
accountNumber | Conditional | Domestic account number. |
iban | Conditional | IBAN, for countries that use one. |
swiftBic | Conditional | BIC of the receiving bank. 8 or 11 characters. |
domesticBankCode | Conditional | Domestic clearing code. For GB this is the six-digit sort code. |
displayName | No | A label for your own use. Defaults to the name on the account. |
email, phoneNumber | No | Contact details for the payee. |
buildingNameNumber, streetName, city, regionState, postalCode | No | The payee's address. Some rails and some corridors require a full address; supply it if you have it. |
intermediaryBics | No | BICs of intermediary banks in the payment route, in order. Up to 10 entries; each must be 8 or 11 characters and known to SWIFT. |
accountNameVerificationId | Conditional | The id of a completed account name verification. Required for GB sort-code payees. Rejected with 400 on any other payee. |
bankCountryandcountryare not the same field
bankCountryis where the receiving bank is;countryis where the payee is. A UK-registered company paying into a Lithuanian account hasbankCountry: "LT"andcountry: "GB".bankCountryis the one that drives validation and rail selection, so getting it wrong is the most common cause of a422here.
Which bank details to send
The four bank-detail fields are all optional in the schema because the combination you need depends on bankCountry. Each country has its own rule set on our side, which is why a request that works for one corridor fails for another.
Rather than encode a country matrix in your client, send what you have and let the API tell you:
- For GB, send
domesticBankCode(the sort code) andaccountNumber. - For countries that use IBANs, send
iban. AddswiftBicwhen the corridor is Swift rather than SEPA. - For everywhere else, send
accountNumberwithswiftBicor the localdomesticBankCode.
You never send bankName. It is resolved from the bank details and returned on the payee.
GB payees need Confirmation of Payee first
A GB sort-code payee cannot be created until the name has been checked against the receiving bank under the UK Confirmation of Payee scheme.
- Call
POST /v1/account-name-verificationswithclientId,accountHolderName,sortCode,accountNumberandaccountType. It needs theverifications:checkscope. - Read the outcome:
answertells you whether the name matched,actualNamegives the real name where the bank discloses it, andreasonCodeexplains a non-match. - Pass the returned
idasaccountNameVerificationIdwhen you create the payee.
A verification that came back with reason code AC01, meaning the account does not exist, cannot be used to create a payee. Correct the details and run the check again.
POST /v1/account-name-verifications enforces maximum lengths on its request fields: accountHolderName 140 characters, sortCode 50 and accountNumber 50. Exceeding one returns 400 with AccountHolderName must be 140 characters or fewer., SortCode must be 50 characters or fewer. or AccountNumber must be 50 characters or fewer.
Send accountNameVerificationId only for a GB payee that has both a domesticBankCode (sort code) and an accountNumber. On any other payee it is now rejected with 400; it used to be accepted and ignored.
IBAN-based checks under the SEPA Verification of Payee scheme are planned but not yet available.
What comes back
201 returns the full payee and its URL in the Location header. Alongside everything you sent, the payee carries fields the platform derives for you:
| Field | Description |
|---|---|
id | Use this as payeeId when creating a payment. |
bankName | Resolved from the bank details you supplied. |
domesticBankCodeType | What kind of domestic code domesticBankCode holds for this country. |
status | The payee's record status. |
accountNameVerification | The payee's Confirmation of Payee result, or null when the payee has none. See The accountNameVerification object. |
supportedPaymentTypes | The rails this payee can actually be paid over. Read it before setting paymentMethod on a payment. |
payeeCountry | The country you sent, under its response name. |
isDeleted, createdAt, channel | Housekeeping: whether the payee has been deleted, when it was created, and where it was created from. |
The accountNameVerification object
accountNameVerification objectaccountNameVerification has the same shape as the POST /v1/account-name-verifications response, and is the verification recorded on the payee.
| Field | Type | Meaning |
|---|---|---|
id | uuid | The verification id. It is the same value as the accountNameVerificationId used to create the payee. |
scheme | string | ConfirmationOfPayee for now. |
answer | string | Match, CloseMatch, NoMatch or Unavailable. |
actualName | string, nullable | The account holder name the scheme returned, where it returns one. |
reasonCode | string, nullable | The scheme reason code, for example PAMM or AC01. |
statusReason | string, nullable | The scheme status reason, where the check could not be delivered. |
createdAt | date-time, nullable | When the verification was performed. |
What each answer means:
| answer | Meaning |
|---|---|
Match | The name matched. |
CloseMatch | Partial match, for example reason PAMM. actualName may carry the name the bank holds. |
NoMatch | A name comparison ran and failed (ANNM, BANM, PANM). |
Unavailable | The check could not be performed for this account: an account-level reason such as AC01 or an opt-out, or a delivery failure. |
When it is populated
accountNameVerification is the verification object only for a GB payee that has a sort code (domesticBankCode) and an accountNumber and was created with a verification. It is null for every other payee: non-GB payees, GB payees identified only by an IBAN, payees with no sort code or account number, and GB sort-code payees whose verification record cannot be found.
The verification shown is the one recorded on the payee, whichever channel created it. That includes payees created in the Portal or by our operators, not only payees created through this API.
Where you can read it
GET /v1/payees/{id} and the 201 body of POST /v1/payees carry accountNameVerification.
Errors worth handling
| Code | Meaning | What to do |
|---|---|---|
400 | The request is malformed or a field is the wrong shape. Also returned when accountNameVerificationId is sent for a payee the verification does not apply to, meaning anything other than bankCountry GB with both domesticBankCode and accountNumber: AccountNameVerificationId only applies to GB payees with a DomesticBankCode (sort code) and AccountNumber. Previously the id was accepted and ignored. | Fix the request. Send accountNameVerificationId only for GB sort-code payees. |
403 | clientId is not a client your credential may act for. | Check the client, not the token. |
404 | The client does not exist. | Check clientId. |
409 | A payee with the same account and bank details already exists. | Reuse the existing payee rather than creating a second one. |
422 | The details are well formed but a business rule rejects them, for example a missing Confirmation of Payee or bank details that do not fit bankCountry. | Read errors. |
500 | The payee was created but could not be read back. Returned as a problem document; previously this case could return a 201 with an empty body. | Do not retry blindly. Look the payee up before creating it again. |
503 | GET /v1/payees/{id} only: the payee has a verification but the account name verification service cannot be reached. Message: Account name verification service unavailable. | Safe to retry, with backoff. |
Deleting a payee
DELETE /v1/payees/{id} returns 204. Deletion is a soft delete: the payee stops appearing in your list but isDeleted on historical records stays truthful, so payments that already reference it keep resolving.
Updated about 1 month ago