Skip to main content
A recipient is a saved set of payout instructions: who the money goes to, over which rail, in which currency. You create one, it gets verified, and from then on you reference it by id when you submit a transfer. The payout rail is the single most important field on a recipient. It decides which provider onboards them, which verification the customer needs, which fields are mandatory, and whether the recipient is usable immediately or has to clear a check first. Almost every surprise on this surface traces back to it.
This is the conceptual guide. For the endpoints themselves — parameters, schemas and worked bodies — see the Recipients API reference.

The rail decides who verifies the customer

Adding a recipient is gated on the customer’s verification — but on the verification belonging to the provider that onboards that rail, not on one global KYC flag.
A customer who can add one recipient may be refused on another. This is the gate working, not a bug. A Bridge restriction blocks Bridge-backed rails and nothing else — it must not stop an AED_LOCAL recipient that Lorum has already verified, a SWIFT recipient Keyrails has verified, or a CRYPTO recipient that touches no fiat account at all.SWIFT is settled by Keyrails, not Bridge, and creates no Bridge counterparty — so it asks for Keyrails onboarding. This is the same verification Generate quote already requires before it will price a SWIFT transfer, so a recipient you can add is one you can pay.Reading, listing and deleting a recipient need only Sumsub KYC, whatever the rail.

Required fields are not fixed

There is no single schema that satisfies every recipient. What you must send depends on the currency and the rail together.
1

Ask what this corridor needs

Get recipient fields answers for a specific country, currency, rail and recipient type, and returns each field’s validation rules and options. Drive your form from it rather than hardcoding a shape.Pass recipientType while you are still creating the recipient.
2

Map each field to the request body

Get recipient fields names each field by a catalogue key. Most keys are also the request field; the ones below are not, and a key sent as-is at the top level is ignored without an error.Each field in the Get recipient fields response also carries requestPath, the exact place to send it.
3

Send the seven that are always required

Whatever the corridor, these are validated on every add:
4

Add the rail-specific coordinates

ifsc for Indian rails, swiftBic for SWIFT, iban for SEPA, sortCode for UK, bankRoutingNumber for US, walletAddress + walletChain for CRYPTO.A US bank recipient (bankType: "us") must also carry accountType, which has to be checking or savings.For Paywho bank transfers, providerBankId: the code of the chosen option on the bankId field. For GBP, bankBranchCode is filled from sortCode when you leave it out.
5

Send the country as an id, in two places

Send countryId — Endl’s numeric id, from List countries — both at the top level and inside recipientAddress, alongside the address lines (addressLine1, addressLine2, city, state, region, postalCode and country).Send both recipientAddress.countryTwoLetter and countryThreeLetter and they are used as sent. Leave out either and it is filled from the top-level countryId; a code you did send is kept.On POBO, also send recipientAddress.countryTwoLetter and countryThreeLetter; POBO does not derive them.institutionalAddress is the receiving bank’s address, with exactly the same fields. It is required for GBP, with a valid UK postcode, and is used as the beneficiary bank address on AED payouts.
Send countryId in two places. Inside recipientAddress it is saved on the recipient. At the top level it is used to check the payout rail and, if you leave out recipientAddress.countryTwoLetter or countryThreeLetter, to fill them in; it is not saved.

Verification: immediate for some rails, asynchronous for others

Whether a new recipient is usable straight away depends — again — on the rail.

Active immediately

CRYPTO, AED_LOCAL, SWIFT and the Paywho-settled rails create no Bridge counterparty. The recipient is saved and marked ACTIVE in the same call. You can pay to it at once.

Verified asynchronously

Bridge-backed fiat rails register an external account with Bridge after the response is sent. The recipient exists immediately, but its counterparty status settles later.
For the second group, poll Get counterparty checks. It reads the recipient’s provider-side state with no side effects, and reports status, counterpartyId, addedToAccountsProvider and statusUpdatedOn. Statuses you may see: OPEN, ACTIVE, CLOSED, FROZEN, PENDING, EDD, DORMANT, and the _L2F variants. Treat the set as open and compare case-insensitively — only ACTIVE means “ready”.
There are no recipient webhooks. Nothing is emitted when a recipient is created, verified, or deleted. Polling Get counterparty checks is the only way to learn that a Bridge-backed recipient has cleared.

India, IMPS and the penny drop

An India customer adding an IMPS + INR recipient whose relationshipToCustomer is SELF triggers a penny-drop verification — a tiny real transfer used to confirm the account exists. It happens inside the add call: it succeeds and the recipient comes back ACTIVE, or it fails and the add fails with the provider’s reason.
Any other INR recipient is refused. IMPS + INR that is not an India customer’s own SELF account returns 400 INR recipients not supported. INR payout recipients are not generally available on this surface today.

There is no update

Recipient update was withdrawn from the v0 API. There is no PUT or PATCH on either the recipients surface or the POBO one. To change a recipient’s details, add a new recipient and delete the old one. Transfers already submitted against the old recipient are unaffected — they carry their own copy of the payout details.
This is deliberate: payout instructions that have been verified by a provider should not mutate underneath transactions that referenced them. A new set of details is a new recipient, with its own verification.

Deleting

Delete is a soft delete. The recipient is marked deleted, stops appearing in listings, and can no longer be referenced — then the external account is removed at the provider asynchronously. The response is 200 with a confirmation message, not a recipient object:
Delete recipient — 200
Deleting a recipient that does not exist, belongs to another customer, or is already deleted returns 404.
Several recipients can share one provider-side external account. Deleting one of them leaves the shared account in place for the others — Endl only tears the external account down when the last recipient using it goes.

Listing

List recipients is a POST, not a GET — the filter set is a body, not a query string. size defaults to 0, and size: 0 returns every recipient rather than none. Beyond paging (page, size, sortBy — createdOn,desc is recommended) you can filter on recipientType (INDIVIDUAL, BUSINESS), paymentType (BANK_ACCOUNT, CRYPTO_WALLET), currency (exact, case-insensitive) and search (a substring of first name, last name, currency, email or bank name). Other filter fields are accepted but ignored today. Each item is the full recipient object. Keys with no value are left out, except inside the two address objects, and alias is never returned.

Things that will refuse a recipient

Beyond field validation and the KYC gate, six business rules reject an add:

Scoping and reference ids

Every recipients path is /{userId}/…, and both ids in a path are reference ids, not UUIDs. A customer id that doesn’t resolve — malformed, unknown, deleted or another partner’s — is always 404 ERRREF_1001, field userId. A recipient that is deleted or belongs to a different customer is reported as 404 ERRREC_1000 — Recipient '{recipientId}' not found — never 403. The answer is the same on Get recipient, Delete recipient and Get counterparty checks, so recipient ids cannot be probed across customers. A customer that belongs to another partner is reported the same way as one that does not exist: 404 ERRREF_1001, User with ID '{id}' not found.

Error handling

ERRREC_1000 (404) is the only recipient-domain code: the recipient is deleted or does not belong to this customer. Everything else uses the shared envelope and the ERRCORE_ codes in Errors and the response envelope. Validation and business refusals come back as 400 with the reason in errors[0], written to be shown to a user. Branch on errors[0].code, never on the message text.

Common pitfalls

Unknown keys at the top level are ignored, so a misspelled field reads as a missing one. Inside recipientAddress and institutionalAddress an unknown key is rejected with 400 Invalid value for recipientAddress.<key>. Check the spelling of what you sent — and check you sent currencySymbol, currencyId and relationshipToCustomer, which are required on every add.
There is no recipientCountry field. Send countryId at the top level and inside recipientAddress — the one inside recipientAddress is the country saved on the recipient.
Different providers, different verification. CRYPTO needs Sumsub; SEPA is Bridge-backed and needs Bridge KYC.
SWIFT is settled by Keyrails, not Bridge, so it asks for Keyrails onboarding. Bridge KYC does not satisfy it, and completing it would not help: a SWIFT quote already requires the same Keyrails verification before it will price, so the recipient would be unusable either way.
On a Bridge-backed rail the recipient exists before it is verified. Poll Get counterparty checks until status is ACTIVE.
None is emitted. Recipients produce no events at all — poll.
There is no update endpoint. Add a corrected recipient and delete the old one.
deposit_currency and payout_currency are both mandatory query parameters. There is no unfiltered listing.
It is a POST with a body, and size: 0 means every recipient, not none. Check you are not sending size: 0 expecting an empty page.
You sent the bank as bankId (the Get recipient fields key) or misspelled it. Send it as providerBankId.
Send it as DD-MM-YYYY, for example 25-01-1994.
Path ids are reference ids: customers are cus_…, recipients are rec_…. A wrongly-shaped rec_… id is a 400; a well-formed but unknown one is a 404. A {userId} that doesn’t resolve — a UUID, malformed, unknown or deleted — is always 404 ERRREF_1001.

Glossary

Written against Api-Version: 2026-09.1, from the behaviour of the /api/v0 recipients surface. Rail availability and required fields are configuration and vary by customer and corridor — read them from List supported rails and Get recipient fields rather than hardcoding this page.