Skip to main content
POST
Register a payout bank account
Requires scope: manage:pay-outs — see Required scopes. Allow-lists a beneficiary bank account so it can receive pay-outs. The owning party comes from the path, never the body.
This is the only endpoint that accepts raw rail credentials. The sensitive one — the account number on US_ACH, the IBAN on SEPA — is encrypted at rest immediately and is never returned: this response and every read path expose only accountNumberLast4 or ibanLast4. Routing numbers and BICs are public bank identifiers and are returned in full.
bankAddress is the beneficiary bank’s postal address, not the recipient’s. All components are required, and country must be a valid ISO 3166-1 alpha-2 code. Two rails: US_ACH requires fiatCurrency: USD and ACH railDetails; SEPA requires fiatCurrency: EUR and an iban (with an optional bic). Supply beneficiaryPhoneNumber on every registration — some destinations refuse a beneficiary without it, and a bank account cannot be edited afterwards. beneficiaryEmail is optional and never sent to the payment provider. A new account starts PENDING and becomes ACTIVE once activated for pay-outs. See Pay-outs. Next: pair it with a deposit asset by creating a payout route.

Errors

The codes this endpoint can return, in addition to the standard errors. Branch on code, never the message.

Authorizations

Headers

x-tenant-id
string<uuid>

Which tenant the request is scoped to, among those your token grants. Omit it when the token grants exactly one tenant; it is required when the token grants more than one. A supplied value must exactly match a tenant the token grants.

Absent when required, blank, malformed, or naming a tenant the token does not grant — each gets the same generic 403 forbidden, which reveals neither whether a tenant exists nor which ones you may use. Send the header once: a repeated header is rejected the same way.

Example:

"3fa85f64-5717-4562-b3fc-2c963f66afa6"

Path Parameters

partyId
string<uuid>
required

Unique party identifier

Body

application/json

Allow-lists a beneficiary bank account as a pay-out destination. The owning party comes from the path, never the body.

rail
enum<string>
required

The fiat rail a payout bank account settles over. The rail decides which credentials the bank account carries and which fiat currency it must use.

  • US_ACH — US ACH transfer. Requires fiatCurrency: USD; railDetails carries the ACH account and routing numbers.
  • SEPA — SEPA credit transfer. Requires fiatCurrency: EUR; railDetails carries an IBAN and an optional BIC.
Available options:
US_ACH,
SEPA
fiatCurrency
string
required

ISO 4217 currency. Must be consistent with the rail — US_ACH requires USD, SEPA requires EUR. A mismatch yields 400 invalid-currency.

Maximum string length: 3
Example:

"USD"

label
string
required

Human-readable label for this destination

Maximum string length: 255
accountHolderName
string
required

Name on the beneficiary bank account

Maximum string length: 255
railDetails
object
required

Raw rail credentials, in the variant matching the request's rail: US_ACH takes the ACH account and routing fields, SEPA takes the IBAN and optional BIC. Send exactly the variant matching the rail. A request missing the matching variant's required fields is rejected with that rail's validation error — invalid-account-number / invalid-routing-number / invalid-account-type, or invalid-iban / invalid-bic.

bankName
string
required
Maximum string length: 255
bankAddress
object
required

Structured postal address of the beneficiary's bank — not the recipient's own address. All components are required on registration, and country must be a valid ISO 3166-1 alpha-2 code; anything missing or invalid yields 400 invalid-bank-address.

beneficiaryEmail
string<email>

Beneficiary contact email, kept on the bank account as your own record of who the destination pays. It is not sent to the payment provider — where a provider needs an address, it receives a Venly-controlled one, so the provider's operational and pricing mail never reaches your beneficiary. Optional; omitting it never refuses a registration.

Maximum string length: 255
Example:

"finance@acme.com"

beneficiaryPhoneNumber
string

Beneficiary contact phone in E.164 form (leading +, no spaces or punctuation). Unlike the email, it is forwarded to the payment provider verbatim and not normalised, so a non-E.164 number is rejected here rather than failing the route registration later. Some destinations refuse a beneficiary without it — a USD route fails terminally with beneficiary-data-incomplete — and a bank account cannot be edited after registration, so supply it on every bank account you register.

Maximum string length: 16
Pattern: ^\+[1-9][0-9]{7,14}$
Example:

"+12125550123"

Response

Bank account registered (masked)

success
boolean

Indicates whether the request was successful

result
object

Masked view of an allow-listed payout bank account.