---
title: "Create an external account"
method: POST
path: "/v1/external-bank-accounts"
tags: ["External Bank Accounts"]
---

# Create an external account

`POST /v1/external-bank-accounts`

Create an external account for bank transfers or proxy-based payments.

## Deduplication

Create is find-or-create. Matching differs for bank vs proxy accounts:

**Bank accounts** match by customer plus the **exact set** of normalized bank identifiers you supply (any of `swiftBic`, `iban`, `routingNumber`, `accountNumber` that are present) — **not** by `paymentRails`. All supplied identifiers must match; adding or omitting one (e.g. SEPA with only `iban`, then SWIFT with the same `iban` plus `swiftBic`) produces a different identity and a new account. Reusing the same identifier set with a different rail (e.g. ACH after WIRE) returns the existing account and does **not** add that rail.

**Proxy accounts** match by customer + normalized alias **+ payment rail**. The same alias on another proxy rail creates a separate account.

On a bank-account reuse (`created: false`):

- Existing `paymentRails` stay unchanged.
- Missing create-only fields (branch, beneficiary document, correspondent details) may be backfilled when supplied; conflicting values return 400.
- A closed account (closed via the API) is reopened with the same ID; fixed routes disabled when it was closed stay disabled and must be re-enabled separately.

To add compatible bank rails to an existing account (e.g. ACH onto a WIRE-only US account), use `PATCH /v1/external-bank-accounts/{id}` with the full resulting `paymentRails` list. Do not rely on a second create.

On every create response, check `created`. For bank accounts also check `paymentRails`; for proxy accounts check `paymentRail` (proxies do not return `paymentRails`). HTTP 201 with `created: false` means identity reuse, not a new rail set.

## Field Mapping

We use generic field names that adapt to country-specific identifiers:

| Field | US | UK | EU | India | Mexico | Australia |
|-------|----|----|----|----|----|----|
| `routingNumber` | ABA (9 digits) | Sort code (6 digits) | - | IFSC (11 chars) | - | BSB (6 digits) |
| `accountNumber` | Account number | Account (8 digits) | - | Account number | CLABE (18 digits) | Account number |
| `iban` | - | - | IBAN | - | - | - |

## Bank Account Requirements by Rail

| Rail | Required Fields |
|------|-----------------|
| **ACH/Wire** (US) | `routingNumber` + `accountNumber` |
| **SWIFT** (IBAN countries) | `swiftBic` + `iban` |
| **SWIFT** (US) | `swiftBic` + `accountNumber` (`routingNumber` optional) |
| **SWIFT** (AU) | `swiftBic` + `routingNumber` (BSB) + `accountNumber` |
| **SEPA** | `iban` (swiftBic optional) |
| **Faster Payments** (UK) | `routingNumber` (sort code) + `accountNumber` |
| **IMPS/NEFT** (India) | `routingNumber` (IFSC) + `accountNumber` |
| **SPEI** (Mexico) | `accountNumber` (18-digit CLABE) |

## Proxy Accounts

For instant payment rails (PIX, UPI, PromptPay), provide alias details instead of bank details:
- `aliasType`: phone, email, tax_id, national_id, or random
- `aliasValue`: The identifier value

The payment network resolves the alias to the recipient's account.

## Headers

- `X-API-Key` string

## Request body

- CreateExternalBankAccountDto
  - `correspondentBankName` string — Correspondent/intermediary bank name
  - `correspondentBankSwiftCode` string — Correspondent/intermediary bank SWIFT/BIC code (8 or 11 characters)
  - `correspondentAccountNumber` string — Correspondent/intermediary account number
  - `customerId` string, required — Customer ID
  - `counterpartyId` string — Existing counterparty ID. When provided for a third-party bank account, known counterparty data can be reused.
  - `beneficiaryName` string, required — Full legal name of the account holder
  - `paymentRails` string[], required — Payment rails this account supports. **Bank rails**: ACH, SWIFT, SEPA, WIRE, FASTER_PAYMENTS, IMPS, NEFT, SPEI, etc. **Proxy rails**: PIX, UPI, PROMPTPAY, DUITNOW (require aliasType + aliasValue) Compatible bank rails can be combined on first create (e.g., a US account can support ["ACH", "ACH_SAME_DAY", "WIRE"]). If a bank account with the same exact identifier set already exists, create returns that account without changing its rails — use PATCH to add compatible rails. Supplying a different identifier subset (e.g. IBAN only vs IBAN + SWIFT BIC) creates a new account. Proxy accounts dedupe by alias and rail, so the same alias on another proxy rail creates a new account.
  - `beneficiaryType` 'INDIVIDUAL' | 'BUSINESS' — Beneficiary type (individual or business)
  - `isThirdParty` boolean — Whether the account holder differs from the customer (third-party payment). May require additional compliance checks.
  - `metadata` AccountMetadataDto
    - `nickname` string — Account nickname
    - `purpose` string — Account purpose
    - `tags` string[] — Account tags
  - `aliasType` 'PHONE' | 'EMAIL' | 'NATIONAL_ID' | 'TAX_ID' | 'RANDOM' | 'CORPORATE_ID' — **Required for proxy rails.** The type of alias identifier. Supported alias types vary by rail: - **PIX** (Brazil): phone, email, tax_id (CPF/CNPJ), random - **UPI** (India): phone, random (VPA) - **PromptPay** (Thailand): phone, national_id, tax_id - **DuitNow** (Malaysia): phone, national_id (NRIC), corporate_id - **GhIPSS** (Ghana): phone - **SINPE** (Costa Rica): phone **Note**: Both aliasType and aliasValue must be provided together.
  - `aliasValue` string — **Required for proxy rails.** The alias value. Format depends on aliasType: - **phone**: E.164 format (+5511912345678) - **email**: Standard email format - **tax_id**: Country-specific (Brazil CPF: 11 digits, CNPJ: 14 digits) - **national_id**: Country-specific (Thailand: 13 digits, Malaysia NRIC: 12 digits) - **random**: UUID format or provider-assigned key (e.g., UPI VPA like "user@upi") **Note**: Both aliasType and aliasValue must be provided together. **Normalization**: The value is normalized to lowercase and trimmed before storage. While some identifiers (e.g., UPI VPAs, emails) may display with mixed case, payment rails typically treat them as case-insensitive for routing.
  - `beneficiaryAddress` BeneficiaryAddressDto
    - `addressLine1` string, required — Street line 1. Maximum 35 characters for international wire compatibility. Do not include city, region, or postal code.
    - `addressLine2` string — Street line 2 (apartment, suite, etc.). Maximum 35 characters for international wire compatibility. Do not include city, region, or postal code.
    - `city` string, required — City
    - `state` string — State / Province
    - `postalCode` string, required — Postal code / ZIP code. May be empty for countries without a postal-code system, including the United Arab Emirates.
    - `country` string, required — Country code (ISO 3166-2)
    - `transliterated` TransliteratedAddressDto
      - `addressLine1` string — Transliterated address line 1 (Latin characters)
      - `addressLine2` string — Transliterated address line 2 (Latin characters)
      - `city` string — Transliterated city (Latin characters)
      - `state` string — Transliterated state/province (Latin characters)
  - `beneficiaryPhone` string — Beneficiary phone number in E.164 format
  - `beneficiaryDateOfBirth` string, date — Account holder's date of birth. Required at payout time for individual beneficiaries on supported corridors.
  - `bankName` string — Bank name. Auto-enriched from routing codes (SWIFT/BIC, IFSC, sort code, etc.) if not provided. Required if enrichment is unavailable.
  - `bankAddress` BankAddressDto
    - `addressLine1` string — Address line 1 (optional for bank addresses)
    - `addressLine2` string — Address line 2 (apartment, suite, etc.)
    - `city` string — City
    - `state` string — State / Province
    - `postalCode` string — Postal code / ZIP code (optional for bank addresses)
    - `country` string — Country code (ISO 3166-2)
  - `swiftBic` string — SWIFT/BIC code (8 or 11 characters). - **SWIFT transfers**: Always required - **SEPA**: Optional (IBAN-only supported)
  - `iban` string — IBAN (International Bank Account Number). - **SWIFT to EU/UK**: Required (with swiftBic) - **SEPA/SEPA Instant**: Required (swiftBic optional)
  - `accountNumber` string — Bank account number or equivalent. Usage varies by country: - **US** (ACH/Wire): Account number (with 9-digit routingNumber) - **UK** (Faster Payments): 8-digit account (with 6-digit sort code in routingNumber) - **India** (IMPS/NEFT): Account number (with 11 char IFSC in routingNumber) - **Mexico** (SPEI): 18-digit CLABE (routingNumber not needed) - **Argentina** (COELSA): 22-digit CBU (routingNumber not needed) - **Brazil** (TED): Account number (with bank code in routingNumber)
  - `routingNumber` string — Bank routing code. This field adapts to country-specific identifiers: - **US**: 9-digit ABA routing number - **CA**: 8-9 digits (transit + institution) - **AU**: 6-digit BSB - **UK**: 6-digit sort code - **India**: 11 character IFSC code
  - `branchCode` string — Bank branch code. Required for countries that use separate bank and branch identifiers: - **Japan**: 3-digit branch code (used with 4-digit bank code) - **Brazil**: 4-5 digit agency/branch number - **South Africa**: 6-digit branch code - **New Zealand**: 4-digit branch code - **Bolivia**: 3-letter branch city code (e.g. LPZ, SCZ)
  - `beneficiaryDocumentType` string — Type of the beneficiary's national/tax identification document. Required for payouts on rails whose clearing system carries the beneficiary document — the valid codes are rail-specific: - **Colombia (ACH)**: CC, NIT, CE, PA, PPT, TI, RC, TE, DIE, ND - **Chile (TEF)**: RUT, RUN, PAS, CE - **Paraguay (SIPAP)**: CI, PAS, CRP, CRC, RUC, DNI - **Peru (ACH)**: RUC, DNI, PAS, CE Brazil (TED) and Bolivia take only `beneficiaryDocumentNumber` (Brazil infers CPF vs CNPJ from the digit count). Optional at creation; payouts on these rails fail without it.
  - `beneficiaryDocumentNumber` string — The beneficiary's national/tax identification document number (e.g. CPF/CNPJ digits for Brazil, cédula number for Colombia/Paraguay, RUT for Chile). Format is validated per rail at payout time. Optional at creation; payouts on rails that require it fail without it.
  - `beneficiaryStateProvince` string — The beneficiary's state/department/province, for rails whose clearing system requires it on payouts (Peru ACH, e.g. LIMA). Optional at creation; payouts on those rails fail without it.
  - `bankAccountType` 'checking' | 'savings' — Bank account type (checking vs savings). Required for US ACH, and for payouts on rails whose clearing system carries it (e.g. Brazil TED, Colombia ACH, Chile TEF, Peru ACH) — accounts on those rails cannot receive payouts without it.
  - `currencyCodes` string[] — ISO 4217 currency codes this account can receive. If omitted, inferred from the payment rails. Can only be specified for Hong Kong (CHATS) or SWIFT payment rails.

## Response `201`

External account created, reused, or reopened successfully. Bank reuse preserves existing paymentRails (other create-only fields may backfill). Proxy reuse matches alias+rail. Check `created` on the body; bank responses also include `paymentRails`, proxy responses include `paymentRail`.

- ExternalAccountResponseDto
  - `id` string, required — Account ID
  - `customerId` string, required — Customer ID
  - `counterpartyId` string, nullable — Counterparty ID when this is a third-party recipient account
  - `type` 'EXTERNAL_BANK' | 'EXTERNAL_PROXY', required — Account type
  - `status` 'IN_REVIEW' | 'ACTIVE' | 'CLOSED', required — Account status
  - `beneficiaryType` 'INDIVIDUAL' | 'BUSINESS', required — Beneficiary type
  - `beneficiaryName` string, required — Beneficiary name
  - `metadata` AccountMetadataDto
    - `nickname` string — Account nickname
    - `purpose` string — Account purpose
    - `tags` string[] — Account tags
  - `paymentRail` 'ACH' | 'ACH_SAME_DAY' | 'WIRE' | 'FEDWIRE' | 'FED_NOW' | 'RTP' | 'EREBOR' | 'EREBOR_RAIL' | 'BALANCE' | 'SWIFT' | 'SEPA' | 'SEPA_INSTANT' | 'TIPS' | 'FASTER_PAYMENTS' | 'BACS' | 'CHAPS' | 'ELIXIR' | 'NICS' | 'EFT' | 'INTERAC' | 'NPP' | 'BECS' | 'UPI' | 'IMPS' | 'IMPS_WITH_FIRC' | 'NEFT' | 'RTGS' | 'BI_FAST' | 'ARTAJASA' | 'PIX' | 'TED' | 'TEF' | 'SPEI' | 'COELSA' | 'SINPE' | 'CIPS' | 'CFXPS' | 'CHATS' | 'ZENGIN' | 'KFTC' | 'FAST_SG' | 'MEPS' | 'DUITNOW' | 'PROMPTPAY' | 'INSTAPAY' | 'PESONET' | 'NAPAS' | 'BEFTN' | 'SLIPS' | 'ZAHAV' | 'GHIPSS' | 'NIBSS' | 'PESALINK' | 'RTC_ZA' | 'TZS_RTGS' | 'EGP_ACH' | 'JOD_ACH' | 'NPSS' | 'MADA' | 'QPS' | 'DOP_ACH' | 'GTQ_ACH' | 'HNL_ACH' | 'PEN_ACH' | 'JMD_ACH' | 'USD_ACH_SV' | 'USD_ACH_EC' | 'CLP_TEF' | 'PSE' | 'COP_ACH' | 'BOB_RTGS' | 'PYG_ACH' | 'CERTIS' | 'DKK_TIPS' | 'SENT' | 'NKS' | 'BANKGIROT' | 'HKD_FPS' | 'IBFT' | 'TRY_FAST', required — Primary payment rail for this account
  - `paymentRails` string[] — All payment rails this account supports (bank accounts only)
  - `beneficiaryAddress` object, nullable — Beneficiary address (bank accounts only)
    - `addressLine1` string
    - `addressLine2` string
    - `city` string
    - `state` string
    - `postalCode` string
    - `country` string
  - `beneficiaryPhone` string, nullable — Beneficiary phone number
  - `beneficiaryDateOfBirth` string, date — Account holder's date of birth
  - `bankName` string, nullable — Bank name (bank accounts only)
  - `bankAddress` object, nullable — Bank address (bank accounts only)
    - `addressLine1` string
    - `addressLine2` string
    - `city` string
    - `state` string
    - `postalCode` string
    - `country` string
  - `swiftBic` string, nullable — SWIFT/BIC code (bank accounts only)
  - `iban` string, nullable — IBAN (bank accounts only)
  - `accountNumber` string, nullable — Bank account number (bank accounts only)
  - `routingNumber` string, nullable — Bank routing code (ABA routing number, sort code, BSB, IFSC, etc.)
  - `branchCode` string, nullable — Bank branch code (for countries like Japan, Brazil, South Africa that use separate branch identifiers)
  - `beneficiaryDocumentType` string — Type of the beneficiary's national/tax identification document (rail-specific codes, e.g. CC/NIT for Colombia, RUT for Chile)
  - `beneficiaryDocumentNumber` string — The beneficiary's national/tax identification document number
  - `beneficiaryStateProvince` string — The beneficiary's state/department/province (rails that require it on payouts, e.g. Peru ACH)
  - `correspondentBankName` string, nullable — Correspondent/intermediary bank name (SWIFT)
  - `correspondentBankSwiftCode` string, nullable — Correspondent/intermediary bank SWIFT/BIC code (SWIFT)
  - `correspondentAccountNumber` string, nullable — Correspondent/intermediary account number (SWIFT)
  - `bankAccountType` 'checking' | 'savings', nullable — Bank account type (bank accounts only)
  - `currencyCodes` string[], nullable — Supported currency codes
  - `aliasType` 'PHONE' | 'EMAIL' | 'NATIONAL_ID' | 'TAX_ID' | 'RANDOM' | 'CORPORATE_ID', nullable — Type of proxy alias (proxy accounts only)
  - `aliasValue` string, nullable — The proxy alias value (proxy accounts only)
  - `createdAt` string, date-time, required — Account creation date
  - `updatedAt` string, date-time, required — Account last update date
  - `created` boolean — Present on create responses. `true` = a new account was inserted. `false` = an existing account matched (bank: customer + the exact normalized identifier set supplied; proxy: customer + alias + rail) and was reused. For bank accounts, existing `paymentRails` are not updated by create — use PATCH to add rails; missing create-only fields may still be backfilled and conflicting values return 400. For proxy accounts, inspect `paymentRail` (proxies do not return `paymentRails`).

## Other responses

- `401` — Unauthorized - Invalid or missing authentication credentials

## Changes

- **2026-09-04** `7d6487f295d7` — 1 breaking, 1 warning
  - added `#/components/schemas/BeneficiaryAddressDto` to the `beneficiaryAddress` request property `allOf` list
  - removed `#/components/schemas/AddressDto` from the `beneficiaryAddress` request property `allOf` list

[Change history](https://skmtc.dev/infinite/apis/infinite-api/changes/v1/external-bank-accounts/post.md)

---

[API](https://skmtc.dev/infinite/apis/infinite-api.md) · [All operations](https://skmtc.dev/infinite/apis/infinite-api/llms.txt) · [OpenAPI document](https://skmtc.dev/infinite/apis/infinite-api/revisions/da62fa03793e?raw)
