POST /customers/:id/accounts/fiat/external
Register an existing bank account under the customer. The holder can be the customer or a third party the customer pays, such as a supplier or employee: see account holder. Synchronous: caller supplies the shape-specific bank details (see details by shape) and Seismic materializes the Account at request time.
Registration succeeds when at least one eligible payment route is ready. An unsuccessful additional registration does not hide the usable account. Payments can use only ready registrations; retrying a successful request with the same idempotency key returns the existing account.
Shape is inferred from currency, the bank's country, and rails. For a USD account at a US bank, rails=["ach"] or rails=["wire"] selects the us shape and requires ABA routing details; rails=["swift"] selects the swift shape and requires a BIC while treating correspondent ABA as optional. A USD account at a non-US bank always uses the swift shape. Other currencies retain their corridor shape (EUR → iban, GBP → uk, CNY → cn_cnaps, …). The variant of details must match the inferred shape; mismatches return 400 InvalidAccountFields.
BRL supports two shapes. Seismic picks the one whose field set matches the details you send: a pix_key / pix_key_type body resolves to br_pix (the PIX rail), while a bank_code / agency / account_number body resolves to br_bank (the TED rail).
Shared semantics live on the create-account index.
Not sure which fields a corridor needs? GET /accounts/fiat/external/requirements returns the live per-corridor field list. Fetch it first and drive your account form from the answer.
Each destination registers once per customer: repeating an existing active account's identifying fields is rejected with 400 InvalidRequest. Which fields identify an account varies by shape: see unique keys on the requirements page. Repeating a destination you deleted is not rejected — it restores that account, id and all. See getting a deleted account back.
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
currency | string | number | yes | Currency the account denominates in. By name or numeric id. |
rails | string[] | string | conditional | Settlement rails this destination is paid over. Required to distinguish SWIFT from ACH / domestic wire for a USD account at a US bank. Also accepted as rail. See choosing a rail. |
account_holder | AccountHolderInput | yes | Legal owner of the destination bank account. The server derives response account_holder_name from this block. |
details | one of the shape variants below | yes | Shape-specific bank-identifier fields. Must match the shape inferred from currency, bank country, and rails. |
Choosing a rail
Send rails explicitly on a create whose shape supports more than one rail. For a USD account at a US bank that is ach, wire or swift.
rails takes either a list of names or a single one:
{
"rails": ["ach"]
}{
"rails": ["ach", "wire"]
}The same field is also accepted under the name rail, with either form — that is the name integrations written before this field took a list send, and it keeps working. rails is the canonical spelling and the one the API schema describes, and a body supplying both names is rejected. Rail names are case-insensitive, repeats are collapsed, and an empty list is rejected with 400 InvalidAccountFields rails, as is a name the resolved shape does not support.
Naming one rail registers the account for that rail only, against the bank identifier you supplied in details. Naming several registers that same identifier for each rail named, which asserts that the one identifier receives all of them. Most US banks do receive both ACH and wire on one routing number — but not all, so name several only where the bank has confirmed it.
Where the bank publishes a different routing number per rail, name both rails and send one number for each — see one number or one per rail. A rail the account gains later is added through:
POST /v0/customers/{id}/accounts/fiat/{account_id}/rails
That endpoint carries a routing number of its own. See adding ACH or Wire to an existing account.
Omitting rails currently registers the account for every rail the resolved shape supports, each of them against that same single bank identifier. ARS keeps its existing coelsa default; request t3.0 explicitly. For a USD account at a US bank, omitting rails selects ach and wire against the one routing number; selecting swift requires SWIFT identifiers instead. A US bank often receives wires on a routing number other than its ACH routing number, so one supplied routing number cannot serve rails that use different ones.
rails will therefore become required wherever the resolved shape supports more than one rail, with ARS as the exception. Omitting it on other multi-rail shapes will be rejected with 400 MissingAccountFields rails. ARS keeps its existing coelsa default. Shapes with a single rail — a USD account at a non-US bank, EUR, GBP and the rest — are unambiguous and keep accepting an omitted rails. Accounts you have already registered are untouched: this shapes creates only, with no migration or backfill.
The registered rails come back as rails on the account.
Account holder
Use GET /accounts/fiat/external/requirements for the complete recipe for the selected currency, bank country, holder type, and rail. Holder names and address.country below are always required for their holder type in both production and sandbox; supply them even if the customer’s verified profile contains them. Other address and identity requirements depend on the corridor.
| Field | Type | Required | Notes |
|---|---|---|---|
type | "individual" | "business" | yes | Discriminator for the holder block. |
first_name | string | conditional | Required when type is "individual". |
last_name | string | conditional | Required when type is "individual". |
business_name | string | conditional | Required when type is "business". |
date_of_birth | string (YYYY-MM-DD) | no | Optional for "individual" holders; no corridor currently requires it. Ignored for "business". |
email | string | no | Optional holder contact email. |
address.country | string | yes | ISO-3166 alpha-2 country code. |
address.line1 | string | conditional | Required when the requirements response marks it required for the selected corridor and rail. |
address.line2 | string | no | Optional holder address line 2. |
address.city, address.state, address.postal_code | string | conditional | Check each field in the requirements response; requirements vary by currency, shape, and rail. Omit state or postal_code when the holder's country has no states or regions, or no postal codes, even if the response marks it required. |
is_third_party | boolean | no | Defaults to false. Set true when the account belongs to someone other than the customer. |
relationship | string | recommended | Recipient's relationship to the customer, e.g. VEND for a vendor. Read this field's accepted codes and labels from the requirements response. Send it on every third-party account. See holder relationship and industry. |
industry | string | recommended | Six-digit NAICS code from GET /v0/industries/account-holder. "business" holders only. Send it for a third-party business — see holder relationship and industry. |
Individual holders don't need a date of birth on any corridor today. The
requirements response stays authoritative: if it ever lists
account_holder.date_of_birth as "required" for the selected corridor and
rail, send it in the request. The create endpoint does not fill it from KYC.
Recipient relationship
Send account_holder.relationship for the recipient's relationship to the customer on every third-party account (is_third_party: true). An account the customer owns answers it through is_third_party: false. Fetch the requirements for the selected currency, bank country, destination holder type, and rail; render the account_holder.relationship entry's options as a dropdown.
For example, when registering a business vendor's account, include these fields in the account_holder block alongside its required name and address:
{
"account_holder": {
"type": "business",
"is_third_party": true,
"relationship": "VEND"
}
}details.relationship_to_debtor is a separate field on the SGD, INR, and PHP bank-details shapes. It does not populate account_holder.relationship and is not accepted in USD bank details. Read each field's own options when both appear in a requirements response.
Holder relationship and industry
Some payment setups file a bank account under who its holder is to the customer, and a business account under the industry of the business that owns it. Both fields are optional, but send them:
account_holder.relationshipon every third-party account (is_third_party: true).account_holder.industryon a third-party business's account. For a first-party account, it falls back to the industry on the customer's KYB profile when omitted; a third-party business has nothing to fall back on.
An account missing them can be registered for fewer settlement options, so fewer routes can pay out to it. When no option can register it without them, the account is still created, but it isn't registered for settlement until the missing fields are added with the PATCH below. Until then, a quote paying out to it is rejected with 422 and a missing violation for each field.
Pick the industry from GET /v0/industries/account-holder, the codes accepted for registering the account on every route. A code outside that list is rejected with 400 and a not_in_allowed_set violation on account_holder.industry. Today the list is the whole GET /v0/industries catalog. When the field is omitted on a first-party account and the industry on the customer's KYB profile isn't accepted by any option that could register the account, the create is rejected with 422 and the same violation; send account_holder.industry with the closest listed industry to set this account's own.
To add the industry or the relationship to an account created without them:
{
"industry": "541512",
"relationship": "VEND"
}Both are recorded on the account, and the account is submitted again wherever it was missing. The response is the account; they come back under account_holder on later reads too. Only business holders take an industry.
const account = await client.customers.updateExternalFiatHolder(customerId, accountId, {
industry: "541512",
});Route-specific bank details
Some customers' payment setup includes an additional banking route that needs more bank details than the corridor's default. The requirements endpoint answers without knowing the customer, so it lists those fields as optional. From 2026-11-01, a create is checked against them for each route the account would be registered on:
us(USD at a US bank) registered forach:details.account_type
swift(USD):details.bank_address.line1details.bank_address.citydetails.bank_address.state, unless the bank's country has no statesdetails.bank_address.postal_code, unless the bank's country has no postal codes
Which countries have no states or no postal codes is the state / postal_code answer absent from GET /v0/customers/address-requirements for the bank's country: for example, a bank in Hong Kong is not asked for a postal code, and a bank in the United Kingdom is not asked for a state.
When another route can register the account, a create missing one of them still succeeds, but the account isn't registered on the route that needs it. When no other route can, the create is rejected with 400. Accounts created before 2026-11-01 aren't affected. Sending these fields on every create is always safe, so send them now.
Details by shape
A holder phone takes digits with optional spaces, dashes, parentheses and a leading + (3–32 chars), and must be a real number:
- International form (
+65 8753 1018): it must be valid for its calling code. - National form (
8753 1018): on a shape tied to one country (sg_fast,in_ifsc,ar_cbu,ph_bank,jp_zengin,br_bank), it must be valid for that country.
swift and iban phones in national form are checked for shape only. A number that fails is rejected with 400 InvalidAccountFields details.phone.
shape: "us" (currency USD, ACH / domestic wire)
Send rails: ["ach"] or rails: ["wire"] explicitly — or rails: ["ach", "wire"] where the bank has confirmed one ABA receives both. Some registration paths reject an omitted rail rather than infer it from an ABA number. ACH registration can require account_type; send the actual CHECKING or SAVINGS value. Wire availability depends on the holder type and can require a BIC. Query the requirements endpoint with the same rail and holder type before creating the account.
One number or one per rail
A US bank frequently publishes one ABA for ACH and a different one for wire, so the body takes the routing numbers either way — but not both ways at once:
-
One number for every rail named. Send
routing_numberalone. It is registered for each rail inrails, which asserts the bank receives all of them on it. This is the common case:{ "rails": ["ach", "wire"], "details": { "account_number": "0123456789", "routing_number": "021000021" } } -
One number per rail. Send
ach_routing_numberand/orfedwire_routing_number, and omitrouting_number. Each is registered for its own rail:{ "rails": ["ach", "wire"], "details": { "account_number": "0123456789", "ach_routing_number": "031202084", "fedwire_routing_number": "026009593" } }
Sending routing_number together with either per-rail field is rejected with 400 InvalidRequest — which number serves which rail would otherwise be a guess. Every named rail that takes a routing number must end up with one: rails: ["ach", "wire"] carrying only ach_routing_number is rejected, naming the rail left without one. swift is paid on a BIC, so it takes no routing number and never triggers that rule.
Every routing number supplied is checked against the ABA check digit (the digits weighted 3-7-1, repeating, summing to a multiple of ten) and is rejected with 400 InvalidAccountFields naming the field it failed in.
| Field | Type | Required | Notes |
|---|---|---|---|
account_number | string | yes | 4–17 digits. |
routing_number | string | conditional | Exactly 9 digits (ABA routing number). One number serving every rail named in rails. Required unless the per-rail fields below are used. See one number or one per rail. |
ach_routing_number | string | conditional | Exactly 9 digits. The ABA the bank receives ACH credits on, where that differs from its wire one. Instead of routing_number, not alongside it. |
fedwire_routing_number | string | conditional | Exactly 9 digits. The ABA the bank receives Fedwire credits on, where that differs from its ACH one. Instead of routing_number, not alongside it. |
account_type | CHECKING / SAVINGS | conditional | Required for ACH when requested by the registration recipe. From 2026-11-01, see route-specific bank details. |
phone | string | conditional | Holder phone in E.164 format. |
tax_number | string | conditional | Holder tax identification number in their country of residence (for example a CPF for a holder in Brazil), 2–100 chars. Required for holders in the countries the requirements response lists under required_when. |
id_type, id_number | string | conditional | Individual identity document; use the values returned by requirements. |
registration_type, registration_number | string | conditional | Business registration; use the values returned by requirements. |
bic | string | no | BIC / SWIFT code (8 or 11 chars). Required when the selected wire registration recipe requests it. |
bank_name | string | no | Display name of the bank (2–100 chars). Settlement routes on routing_number. This is for UI / statements. |
bank_address | Address | yes | Physical mailing address registered for the account. |
shape: "swift" (currency USD, rail swift)
A USD account registered for SWIFT, including one held at a US bank. The BIC identifies the destination bank. The ABA of the destination bank's US correspondent goes in intermediary_bank.routing_number: required for an individual account holder from 2026-11-01, optional for a business account holder.
account_number is the IBAN when the bank is in an IBAN country (the EU and EEA, the UK, Switzerland, the Gulf states, …) and the domestic account number elsewhere (the US, Hong Kong, Singapore, …). The requirements response labels the field IBAN or Account number accordingly. A domestic account number for a bank in an IBAN country is rejected with 400 InvalidRequest naming details.account_number; for the UK, Sweden, Czechia, Poland and the other IBAN countries added on 2026-11-14 that rejection applies from that date. GBP accounts at UK banks keep the uk shape with sort code and account number.
| Field | Type | Required | Notes |
|---|---|---|---|
bic | string | yes | BIC / SWIFT code (8 or 11 chars). |
account_number | string | yes | The IBAN at a bank in an IBAN country, otherwise the domestic account number (8–34 alphanumeric). |
phone | string | no | Holder contact phone, 3–32 chars. Some corridors require it. |
tax_number | string | no | Holder tax identification number, 2–100 chars. Some corridors require it. |
swift_payment_code | string | no | Purpose-of-payment code (lowercase letters, digits and _, e.g. ae_swift_str). Required for a bank in the countries the requirements response lists under required_when; the codes accepted for the bank's country are that field's options. |
ifsc | string | no | IFSC of the recipient branch (AAAA0NNNNNN, e.g. HDFC0001234), for a bank in India. |
bank_name | string | yes | Bank display/routing name (2–100 chars). Corridors that route USD off a published bank list (e.g. USD held in HK) validate it against that list. |
routing_number | string | no | Deprecated: send intermediary_bank.routing_number instead. Nine-digit ABA routing number of the US correspondent bank, the same nine digits as intermediary_bank.routing_number. Still accepted; supplying both with different values is rejected. |
intermediary_bank | IntermediaryBank | conditional | The correspondent bank. Its routing_number is required for an individual account holder from 2026-11-01. |
bank_address | Address | yes | Physical mailing address registered for the account. country is always required. Send the full street address too (line1, city, state, postal_code): some routes file it with the account and can't register one without it. From 2026-11-01, see route-specific bank details. |
IntermediaryBank
The correspondent (intermediary) bank the payout is routed through. Every identifier here belongs to the correspondent, never to the destination bank named by the enclosing details block — a wire quoting one bank's code under the other's name is a wire that bounces.
routing_number is required for an individual account holder from 2026-11-01. Every other field is optional, and which ones a corridor asks for varies. GET /v0/accounts/fiat/external/requirements returns the live recipe.
| Field | Type | Required | Notes |
|---|---|---|---|
name | string | no | Display name, 2–100 chars. What the sending bank prints on the payment instruction. |
bic | string | no | The correspondent's own BIC / SWIFT code (8 or 11 chars). Quote this when the correspondent is outside the US and so has no ABA. |
routing_number | string | conditional | Nine-digit ABA of the correspondent, where it is a US bank. Required for an individual account holder from 2026-11-01, optional for a business account holder. Replaces the deprecated top-level routing_number; supplying both with different values is rejected. |
account_number | string | no | The destination bank's account at the correspondent (8–34 uppercase alphanumeric), which a cover payment credits on the way through. An IBAN or a domestic account number. |
country | string | no | ISO-3166-1 alpha-2 country of the correspondent (US, DE, …). Not inferred from the other fields: a BIC's country letters name where the institution is registered, not where the branch that clears the wire sits. |
shape: "uk" (currency GBP)
| Field | Type | Required | Notes |
|---|---|---|---|
sort_code | string | yes | Exactly 6 digits. |
account_number | string | yes | 6–10 digits. |
iban | string | no | Optional cross-border IBAN form (15–34 chars), the SWIFT-routable form of the same sort_code / account_number pair. Supply it when the account will receive non-UK-originated payments. |
bank_name | string | no | Display name of the bank (2–100 chars). |
bank_address | Address | yes |
shape: "iban" (currencies EUR, CHF, NOK, SEK, DKK, AED)
| Field | Type | Required | Notes |
|---|---|---|---|
account_number | string | yes | The IBAN (15–34 chars; country + checksum + BBAN). The requirements response labels this field IBAN. |
bic | string | no | Optional BIC / SWIFT code (8 or 11 chars). |
bank_code | string | no | Domestic bank code (e.g. Swedish clearing number), 1–20 alphanumeric. Some corridors (e.g. SEK) require it. |
phone | string | no | Holder contact phone, 3–32 chars. Some corridors (e.g. AED) require it. |
id_number | string | no | Holder government ID number, 2–100 chars. Individuals only. |
id_type | string | no | Kind of ID id_number carries. Individuals only. Requirements lists the accepted values. |
registration_number | string | no | Business registration number, 2–100 chars. Businesses only. |
registration_type | string | no | Kind of registration registration_number carries. Businesses only. Requirements lists the accepted values. |
bank_name | string | no | Display name of the bank (2–100 chars). |
bank_address | Address | yes |
shape: "cn_cnaps" (currency CNY)
| Field | Type | Required | Notes |
|---|---|---|---|
account_number | string | yes | Chinese domestic bank account number. |
cnaps_code | string | yes | Exactly 12 digits. |
id_number | string | yes | Holder tax / government ID number. |
id_type | string | no | Kind of ID id_number carries. Individuals only. Requirements lists the accepted values. |
registration_number | string | no | Business registration number (e.g. Unified Social Credit Code), 2–100 chars. Businesses only. |
registration_type | string | no | Kind of registration registration_number carries. Businesses only. Requirements lists the accepted values. |
bank_name | string | no | Display name of the bank (2–100 chars). |
branch_name | string | no | Destination bank branch name, 1–100 Hanzi (Chinese characters). Businesses only. |
bank_address | Address | yes | Physical mailing address registered for the account. For business recipients, postal_code carries the bank's 6-digit city code. Seismic derives the bank city and province from it. |
shape: "hk_fps" (currency HKD)
| Field | Type | Required | Notes |
|---|---|---|---|
account_number | string | yes | Destination bank account number. |
bic | string | yes | ISO 9362 BIC / SWIFT code of the destination bank — settlement routes on it. |
bank_name | string | no | Display name of the bank (2–100 chars). |
registration_number | string | no | Business registration number (e.g. Certificate of Incorporation number), 2–100 chars. Businesses only. |
registration_type | string | no | Kind of registration registration_number carries. Businesses only. Requirements lists the accepted values. |
date_of_incorporation | string | no | Date the business was incorporated, YYYY-MM-DD. Businesses only. |
bank_address | Address | yes | Physical mailing address registered for the account. |
shape: "sg_fast" (currency SGD)
| Field | Type | Required | Notes |
|---|---|---|---|
account_number | string | yes | Destination bank account number. |
bank_name | string | yes | Bank display/routing name (2–100 chars). |
phone | string | yes | Holder contact phone for the corridor. |
id_number | string | no | Holder government ID number (NRIC, FIN, passport number, …), 2–100 chars. Individuals only. |
id_type | string | no | Kind of ID id_number carries. Individuals only. Requirements lists the accepted values. |
registration_number | string | no | Business registration number (e.g. UEN), 2–100 chars. Businesses only. |
registration_type | string | no | Kind of registration registration_number carries. Businesses only. |
relationship_to_debtor | string | no | Relationship of the account holder to the customer, as a fixed 4-letter code (SELF, EMPL, VEND, …). Requirements lists the accepted codes with labels. |
bank_address | Address | yes | Physical mailing address registered for the account. |
shape: "in_ifsc" (currency INR)
| Field | Type | Required | Notes |
|---|---|---|---|
ifsc | string | yes | 11 chars: 4 uppercase letters, a literal 0, then 6 uppercase alphanumerics (e.g. HDFC0001234). Routes over IMPS. |
account_number | string | yes | 9–20 digits. |
phone | string | no | Holder contact phone, 3–32 chars. |
id_number | string | no | Holder government ID number, 2–100 chars. Individuals only. |
id_type | string | no | Kind of ID id_number carries. Individuals only. Requirements lists the accepted values. |
registration_number | string | no | Business registration number, 2–100 chars. Businesses only. |
registration_type | string | no | Kind of registration registration_number carries. Businesses only. Requirements lists the accepted values. |
relationship_to_debtor | string | no | Relationship of the account holder to the customer, as a fixed 4-letter code (SELF, EMPL, SUPP, …). Requirements lists the accepted codes with labels per holder type. |
bank_name | string | no | Display name of the bank (2–100 chars). |
bank_address | Address | yes | Physical mailing address registered for the account. |
shape: "mx_clabe" (currency MXN)
| Field | Type | Required | Notes |
|---|---|---|---|
clabe | string | yes | Exactly 18 digits (3 bank + 3 branch + 11 account + 1 checksum). Routes over SPEI. |
tax_number | string | no | Holder tax id (RFC), 10–18 chars. |
bank_name | string | no | Display name of the bank (2–100 chars). |
bank_address | Address | yes | Physical mailing address registered for the account. |
shape: "ar_cbu" (currency ARS)
Accepts rails: "coelsa", rails: "t3.0", or both. Omitting rails keeps the existing coelsa default, including when explicit rail selection is required for other multi-rail shapes. This shape additionally requires account_holder.address.line1. The registration returns 400 without it.
| Field | Type | Required | Notes |
|---|---|---|---|
cbu | string | yes | Exactly 22 digits. |
alias | string | no | 6–20 chars. Letters, digits, dots, and hyphens. |
tax_number | string | yes | Holder CUIT, exactly 11 digits. |
phone | string | yes | Holder contact phone, 3–32 chars. |
id_number | string | no | Holder government ID number (DNI, …), 2–100 chars. Individuals only. |
id_type | string | no | Kind of ID id_number carries. Individuals only. Requirements lists the accepted values. |
registration_number | string | no | Business registration number, 2–100 chars. Businesses only. |
registration_type | string | no | Kind of registration registration_number carries. Businesses only. Requirements lists the accepted values. |
bank_name | string | yes | Display name of the bank (2–100 chars). |
bank_address | Address | yes | Physical mailing address registered for the account. |
shape: "ph_bank" (currency PHP)
Routes over InstaPay and PESONet.
| Field | Type | Required | Notes |
|---|---|---|---|
account_number | string | yes | 6–20 digits. |
bank_name | string | yes | Display name of the bank (2–100 chars). |
phone | string | no | Holder contact phone, 3–32 chars. |
registration_number | string | no | Business registration number, 2–100 chars. Businesses only. |
registration_type | string | no | Kind of registration registration_number carries. Businesses only. Requirements lists the accepted values. |
date_of_incorporation | string | no | Date the business was incorporated, YYYY-MM-DD. Businesses only. |
relationship_to_debtor | string | no | Relationship of the account holder to the customer, as a fixed 4-letter code (SELF, EMPL, SUPP, …). Requirements lists the accepted codes with labels per holder type. |
bank_address | Address | yes | Physical mailing address registered for the account. |
shape: "thb_bank" (currency THB)
Routes over PromptPay.
| Field | Type | Required | Notes |
|---|---|---|---|
account_number | string | yes | 6–20 digits. |
bank_name | string | yes | Display name of the bank (2–100 chars). |
bank_address | Address | yes | Physical mailing address registered for the account. |
shape: "idr_bank" (currency IDR)
Routes over BI-FAST and Artajasa.
| Field | Type | Required | Notes |
|---|---|---|---|
account_number | string | yes | 6–20 digits. |
bank_name | string | yes | Display name of the bank (2–100 chars). |
bank_address | Address | yes | Physical mailing address registered for the account. |
shape: "jp_zengin" (currency JPY)
Routes over Zengin. Supply bank and branch codes separately, preserving leading zeros. The account holder's street address (account_holder.address.line1) is required.
| Field | Type | Required | Notes |
|---|---|---|---|
bank_code | string | yes | 4 digits identifying the bank. |
branch_code | string | yes | 3 digits identifying the branch. |
account_number | string | yes | 7 digits, including leading zeros. |
bank_name | string | yes | Destination bank name. |
phone | string | yes | Account holder phone in international format. |
bank_address | Address | yes | Physical bank address in Japan. |
shape: "ca_eft" (currency CAD)
Routes over EFT.
| Field | Type | Required | Notes |
|---|---|---|---|
institution_number | string | yes | 3 digits — identifies the bank. |
transit_number | string | yes | 5 digits — identifies the branch. |
account_number | string | yes | 7–12 digits. |
bank_name | string | yes | Must match one of the details.bank_name options returned by GET /accounts/fiat/external/requirements for this corridor. |
bank_address | Address | yes | Physical mailing address registered for the account. |
shape: "pk_iban" (currency PKR)
Routes over Raast.
| Field | Type | Required | Notes |
|---|---|---|---|
iban | string | yes | Pakistan IBAN: PK + 2 check digits + 4-letter bank code + 16-char account (24 chars total). |
bank_name | string | no | Display name of the bank (2–100 chars). |
bank_address | Address | yes | Physical mailing address registered for the account. |
shape: "ng_bank" (currency NGN)
Routes over NIP (NIBSS Instant Payment).
| Field | Type | Required | Notes |
|---|---|---|---|
account_number | string | yes | NUBAN account number, exactly 10 digits. |
bank_code | string | yes | Numeric bank code (3–6 digits), the routing key. A NUBAN is only unique within a bank. |
bank_name | string | no | Display name of the bank (2–100 chars). |
bank_address | Address | yes | Physical mailing address registered for the account. |
shape: "br_pix" (currency BRL)
Routes over PIX. Chosen for a BRL request whose details carry pix_key / pix_key_type.
| Field | Type | Required | Notes |
|---|---|---|---|
pix_key | string | yes | The PIX key. Format depends on pix_key_type. |
pix_key_type | string | yes | One of cpf (11 digits), cnpj (14 digits), email, phone (+55 then 10–11 digits), or evp (lowercase-hex UUID). |
bank_address | Address | yes | Physical mailing address registered for the account. |
shape: "br_bank" (currency BRL)
Routes over TED. Chosen for a BRL request whose details carry bank_code / agency / account_number.
| Field | Type | Required | Notes |
|---|---|---|---|
bank_code | string | yes | 3–8 digits (COMPE or ISPB). |
agency | string | yes | 4–8 digits (branch, optionally with a check digit). |
account_number | string | yes | Digits with an optional trailing -N check digit. Up to 20 chars. |
account_subtype | string | yes | cc (checking) or pp (savings). |
tax_number | string | no | Holder CPF (11 digits) or CNPJ (14 digits). |
phone | string | no | Holder contact phone, 3–32 chars. |
id_number | string | no | Holder government ID number, 2–100 chars. Individuals only. |
id_type | string | no | Kind of ID id_number carries. Individuals only. Requirements lists the accepted values. |
registration_number | string | no | Business registration number (e.g. CNPJ), 2–100 chars. Businesses only. |
registration_type | string | no | Kind of registration registration_number carries. Businesses only. Requirements lists the accepted values. |
bank_name | string | no | Display name of the bank (2–100 chars). |
bank_address | Address | yes | Physical mailing address registered for the account. |
shape: "au_bsb" (currency AUD)
Routes over BECS. The BSB is the whole routing key for this corridor, so there is no bank-name field.
| Field | Type | Required | Notes |
|---|---|---|---|
bsb | string | yes | 6 digits — Bank-State-Branch, identifies the bank and the branch together. |
account_number | string | yes | 6–10 digits. |
bank_address | Address | yes | Physical mailing address registered for the account. |
shape: "co_bank" (currency COP)
Routes over ACH Colombia (ach_colombia). The receiving bank matches the beneficiary against their identity document, so the document travels with the account. Only an individual can hold a COP account: account_holder.type must be individual, and the request is rejected with 400 otherwise.
| Field | Type | Required | Notes |
|---|---|---|---|
bank_code | string | yes | 1–8 digits, as published by the Colombian banking association. Requirements lists the accepted values. |
account_number | string | yes | 6–20 digits. |
account_type | string | yes | CHECKING (corriente) or SAVINGS (ahorros). |
id_type | string | yes | Kind of identity document id_number carries: CC (cédula de ciudadanía), CE (cédula de extranjería), NIT, PASS (passport) or PEP (permiso especial de permanencia). |
id_number | string | yes | The holder's identity document number, 4–20 alphanumerics. |
bank_address | Address | yes | Physical mailing address registered for the account. |
Headers
| Header | Value |
|---|---|
Idempotency-Key | Optional, up to 256 characters. Re-POSTing the same (org, key) returns the existing creation request unchanged. |
Response 200
{
"request": {
"id": "req_…",
"customer_id": "2f10…",
"kind": "fiat",
"shape": "us",
"origin": "external",
"currency": "USD",
"rails": ["ach", "wire"],
"status": "completed",
"idempotency_key": "abc-123",
"account_id": "acct_…",
"details": {
"account_number": "0123456789",
"routing_number": "021000021",
"ach_routing_number": "021000021",
"fedwire_routing_number": "021000021",
"bank_name": "JPMorgan Chase Bank",
"account_holder_name": "Acme Inc.",
"bank_address": {
"line1": "1 Wells Fargo Way",
"city": "San Francisco",
"state": "CA",
"postal_code": "94104",
"country": "US"
}
},
"created_at": "2026-05-20T19:45:00Z",
"updated_at": "2026-05-20T19:45:00Z"
},
"account": {
"id": "acct_…",
"customer_id": "2f10…",
"kind": "fiat",
"shape": "us",
"origin": "external",
"currency": "USD",
"rails": ["ach", "wire"],
"status": "active",
"created_at": "2026-05-20T19:45:00Z",
"updated_at": "2026-05-20T19:45:00Z",
"details": {
"account_number": "0123456789",
"routing_number": "021000021",
"ach_routing_number": "021000021",
"fedwire_routing_number": "021000021",
"bank_name": "JPMorgan Chase Bank",
"account_holder_name": "Acme Inc.",
"bank_address": {
"line1": "1 Wells Fargo Way",
"city": "San Francisco",
"state": "CA",
"postal_code": "94104",
"country": "US"
}
}
}
}Errors
- 400 InvalidAccountFields
details: variant doesn't match the shape selected by currency, bank country, and rails (e.g. domestic routing details withrails=["swift"]; or a UK body for USD), or aBRLbody that matches neitherbr_pixnorbr_bank. - 400 InvalidAccountFields
details.routing_number/details.ach_routing_number/details.fedwire_routing_number/details.bic/details.account_number/details.iban/details.sort_code/details.cnaps_code/details.id_number/details.bank_name/details.phone/details.ifsc/details.swift_payment_code/details.clabe/details.cbu/details.tax_number/details.alias/details.pix_key/details.pix_key_type/details.bank_code/details.agency/details.account_subtype: failed format validation. - 400 InvalidRequest: the US body carries
routing_numbertogether withach_routing_numberorfedwire_routing_number. Supply one number for every rail named, or one per rail — never both. - 400 InvalidRequest: a named rail that takes a routing number was left without one. The message names the rail and the field that would carry its number.
- 400 MissingAccountFields
details.routing_number: the US body carries no routing number at all. - 400 MissingAccountFields
details.intermediary_bank.routing_number: from 2026-11-01, an individual account holder's SWIFT body names no correspondent ABA (in eitherintermediary_bank.routing_numberor the deprecated top-levelrouting_number). - 400 InvalidRequest
account_holder.*: missing holder name fields for the selected holdertype, missingaccount_holder.address.country, or missing an address field the destination requires (e.g.account_holder.address.line1forHKDandARSaccounts, or the fullline1/city/state/postal_codeset for every USD account, less any part the holder's country does not have). - 400 InvalidRequest
account_holder.address.postal_code/details.bank_address.postal_code: the postal code doesn't match the format used by itscountry. The message quotes the expected pattern. - 400 InvalidAccountFields
currency: currency isn't a fiat kind, or no fiat shape / default rails can be inferred. - 400 InvalidRequest: the destination is already registered for this customer (or a registration for it is in progress). The duplicate check compares the shape's unique key. The error names the existing account / creation request, and deleting that account is how you re-register it.
- 400 InvalidRequest
account_holder.industry: a business holder's industry isn't listed byGET /v0/industries/account-holder(not_in_allowed_setviolation). - 422 InvalidRequest
account_holder.industry:account_holder.industrywas omitted and the industry on the customer's KYB profile isn't accepted by the only settlement option for the account. Sendingaccount_holder.industryoverrides it. - 501 Unknown: the currency infers to a fiat shape that exists in the enum but is not wired for external-fiat create yet.
- 404: unknown currency.
Example: US bank account
curl -X POST "$SEISMIC_ORCHESTRATION_URL/v0/customers/2f10…/accounts/fiat/external" \
-H "Api-Key: $SEISMIC_ORCHESTRATION_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "content-type: application/json" \
-d '{
"currency": "USD",
"rails": ["ach"],
"account_holder": {
"type": "business",
"business_name": "Acme Inc.",
"address": {
"country": "US"
}
},
"details": {
"account_number": "0123456789",
"routing_number": "021000021",
"bank_name": "JPMorgan Chase Bank",
"bank_address": {
"line1": "270 Park Avenue",
"city": "New York",
"state": "NY",
"postal_code": "10017",
"country": "US"
}
}
}'Example: USD held at a Singapore bank (SWIFT)
A USD multi-currency account at an SG bank can omit routing_number; supply the BIC that identifies the destination bank.
curl -X POST "$SEISMIC_ORCHESTRATION_URL/v0/customers/2f10…/accounts/fiat/external" \
-H "Api-Key: $SEISMIC_ORCHESTRATION_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "content-type: application/json" \
-d '{
"currency": "USD",
"rails": ["swift"],
"account_holder": {
"type": "business",
"business_name": "Acme SG Pte. Ltd.",
"address": {
"country": "SG"
}
},
"details": {
"account_number": "0012345678",
"bic": "DBSSSGSG",
"bank_name": "DBS BANK LTD.",
"bank_address": {
"line1": "12 Marina Boulevard",
"city": "Singapore",
"postal_code": "018982",
"country": "SG"
}
}
}'Example: SWIFT routed through a correspondent bank
Describe the correspondent under intermediary_bank. Only its routing_number is ever required (for an individual account holder, from 2026-11-01); send the rest where the corridor's recipe asks for it.
curl -X POST "$SEISMIC_ORCHESTRATION_URL/v0/customers/2f10…/accounts/fiat/external" \
-H "Api-Key: $SEISMIC_ORCHESTRATION_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "content-type: application/json" \
-d '{
"currency": "USD",
"rails": ["swift"],
"account_holder": {
"type": "business",
"business_name": "Acme HK Ltd.",
"address": {
"country": "HK"
}
},
"details": {
"account_number": "885016968326",
"bic": "AABLHKHH",
"bank_name": "ZA Bank Limited",
"bank_address": {
"line1": "Unit 1301, 100 It St, Cyberport Rd",
"city": "Hong Kong",
"country": "HK"
},
"intermediary_bank": {
"name": "JPMorgan Chase Bank, N.A.",
"bic": "CHASUS33",
"routing_number": "021000021",
"account_number": "0012345678",
"country": "US"
}
}
}'Example: IBAN (EUR / SEPA)
curl -X POST "$SEISMIC_ORCHESTRATION_URL/v0/customers/2f10…/accounts/fiat/external" \
-H "Api-Key: $SEISMIC_ORCHESTRATION_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "content-type: application/json" \
-d '{
"currency": "EUR",
"account_holder": {
"type": "business",
"business_name": "Acme GmbH",
"address": {
"country": "DE"
}
},
"details": {
"account_number": "DE89370400440532013000",
"bank_name": "Deutsche Bank",
"bank_address": {
"line1": "Friedrichstraße 1",
"city": "Berlin",
"postal_code": "10117",
"country": "DE"
}
}
}'Example: PIX (BRL)
The pix_key / pix_key_type fields resolve this BRL request to the br_pix shape.
curl -X POST "$SEISMIC_ORCHESTRATION_URL/v0/customers/2f10…/accounts/fiat/external" \
-H "Api-Key: $SEISMIC_ORCHESTRATION_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "content-type: application/json" \
-d '{
"currency": "BRL",
"account_holder": {
"type": "individual",
"first_name": "Ana",
"last_name": "Souza",
"date_of_birth": "1990-04-12",
"address": {
"country": "BR"
}
},
"details": {
"pix_key": "ana.souza@example.com",
"pix_key_type": "email",
"bank_address": {
"line1": "Av. Paulista 1000",
"city": "São Paulo",
"state": "SP",
"postal_code": "01310-100",
"country": "BR"
}
}
}'Example: PromptPay (THB)
The THB currency resolves to the thb_bank shape.
curl -X POST "$SEISMIC_ORCHESTRATION_URL/v0/customers/2f10…/accounts/fiat/external" \
-H "Api-Key: $SEISMIC_ORCHESTRATION_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "content-type: application/json" \
-d '{
"currency": "THB",
"account_holder": {
"type": "individual",
"first_name": "Somchai",
"last_name": "Prasert",
"date_of_birth": "1990-04-12",
"address": {
"country": "TH"
}
},
"details": {
"account_number": "1234567890",
"bank_name": "Kasikornbank",
"bank_address": {
"line1": "1 Soi Ratburana 27",
"city": "Bangkok",
"postal_code": "10140",
"country": "TH"
}
}
}'Example: BI-FAST (IDR)
The IDR currency resolves to the idr_bank shape.
curl -X POST "$SEISMIC_ORCHESTRATION_URL/v0/customers/2f10…/accounts/fiat/external" \
-H "Api-Key: $SEISMIC_ORCHESTRATION_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "content-type: application/json" \
-d '{
"currency": "IDR",
"account_holder": {
"type": "individual",
"first_name": "Budi",
"last_name": "Santoso",
"date_of_birth": "1987-11-05",
"address": {
"country": "ID"
}
},
"details": {
"account_number": "1234567890",
"bank_name": "Bank Central Asia",
"bank_address": {
"line1": "Jl. M.H. Thamrin No. 1",
"city": "Jakarta",
"postal_code": "10310",
"country": "ID"
}
}
}'Example: EFT (CAD)
The CAD currency resolves to the ca_eft shape.
curl -X POST "$SEISMIC_ORCHESTRATION_URL/v0/customers/2f10…/accounts/fiat/external" \
-H "Api-Key: $SEISMIC_ORCHESTRATION_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "content-type: application/json" \
-d '{
"currency": "CAD",
"account_holder": {
"type": "individual",
"first_name": "Marie",
"last_name": "Tremblay",
"date_of_birth": "1988-02-19",
"address": {
"country": "CA"
}
},
"details": {
"institution_number": "003",
"transit_number": "00022",
"account_number": "1234567",
"bank_name": "Royal Bank of Canada",
"bank_address": {
"line1": "100 King Street West",
"city": "Toronto",
"postal_code": "M5X 1A1",
"country": "CA"
}
}
}'Example: Raast (PKR)
The PKR currency resolves to the pk_iban shape.
curl -X POST "$SEISMIC_ORCHESTRATION_URL/v0/customers/2f10…/accounts/fiat/external" \
-H "Api-Key: $SEISMIC_ORCHESTRATION_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "content-type: application/json" \
-d '{
"currency": "PKR",
"account_holder": {
"type": "individual",
"first_name": "Ayesha",
"last_name": "Khan",
"date_of_birth": "1988-09-03",
"address": {
"country": "PK"
}
},
"details": {
"iban": "PK36SCBL0000001123456702",
"bank_name": "Standard Chartered Bank (Pakistan)",
"bank_address": {
"line1": "I.I. Chundrigar Road",
"city": "Karachi",
"postal_code": "74000",
"country": "PK"
}
}
}'Example: NIP (NGN)
The NGN currency resolves to the ng_bank shape.
curl -X POST "$SEISMIC_ORCHESTRATION_URL/v0/customers/2f10…/accounts/fiat/external" \
-H "Api-Key: $SEISMIC_ORCHESTRATION_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "content-type: application/json" \
-d '{
"currency": "NGN",
"account_holder": {
"type": "individual",
"first_name": "Chidi",
"last_name": "Okafor",
"date_of_birth": "1992-01-20",
"address": {
"country": "NG"
}
},
"details": {
"account_number": "0123456789",
"bank_code": "058",
"bank_name": "Guaranty Trust Bank",
"bank_address": {
"line1": "635 Akin Adesola Street",
"city": "Lagos",
"state": "Lagos",
"postal_code": "101241",
"country": "NG"
}
}
}'Example: BECS (AUD)
The AUD currency resolves to the au_bsb shape.
curl -X POST "$SEISMIC_ORCHESTRATION_URL/v0/customers/2f10…/accounts/fiat/external" \
-H "Api-Key: $SEISMIC_ORCHESTRATION_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "content-type: application/json" \
-d '{
"currency": "AUD",
"account_holder": {
"type": "individual",
"first_name": "Ruby",
"last_name": "Nguyen",
"date_of_birth": "1990-07-04",
"address": {
"line1": "12 Pitt Street",
"city": "Sydney",
"state": "NSW",
"postal_code": "2000",
"country": "AU"
}
},
"details": {
"bsb": "123456",
"account_number": "10458448",
"bank_address": {
"line1": "20 Martin Place",
"city": "Sydney",
"state": "NSW",
"postal_code": "2000",
"country": "AU"
}
}
}'Example: ACH Colombia (COP)
The COP currency resolves to the co_bank shape. The holder must be an individual.
curl -X POST "$SEISMIC_ORCHESTRATION_URL/v0/customers/2f10…/accounts/fiat/external" \
-H "Api-Key: $SEISMIC_ORCHESTRATION_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "content-type: application/json" \
-d '{
"currency": "COP",
"account_holder": {
"type": "individual",
"first_name": "Olivia",
"last_name": "Martin",
"email": "olivia@example.com",
"date_of_birth": "1990-07-04",
"address": {
"line1": "Carrera 7 # 71-21",
"city": "Bogotá",
"state": "DC",
"postal_code": "110231",
"country": "CO"
}
},
"details": {
"bank_code": "1007",
"account_number": "123456789",
"account_type": "SAVINGS",
"id_type": "CC",
"id_number": "1234567890",
"bank_address": {
"line1": "Carrera 7 # 71-21",
"city": "Bogotá",
"state": "DC",
"postal_code": "110231",
"country": "CO"
}
}
}'Adding ACH or Wire to an existing account
When one account is reachable over both ACH and Wire, register the account once, then add the other rail to that account. A bank often publishes a different ABA for each rail, and an account that supports a separate routing number per rail can carry both:
POST /v0/customers/{id}/accounts/fiat/{account_id}/rails
Supply a required Idempotency-Key header and the routing number confirmed by the bank for the requested rail:
{
"rail": "wire",
"routing_number": "021000021"
}The response contains id (the addition request id), rail, and the refreshed account. Its account id is unchanged. An already available rail returns successfully without creating another account. Reusing the same key and body returns the original outcome; reusing it for a different account or body is rejected.
Only active US USD external bank accounts are supported. Where the account supports a separate routing number per rail, a routing number that differs from the account's registers that ABA for the rail being added, and the rails already on the account keep theirs. Where the account's rails share one routing number, supply the account's own — a differing number is rejected, since the addition would otherwise claim a rail the payout does not follow. A rail that already holds a different routing number is not repointed, and that request is rejected too. A failed addition leaves existing rails available; contact support before retrying with a new key. Use the returned account's rails to determine what is available, and select the intended rail when requesting a quote.
const result = await client.customers.addExternalFiatRail(customerId, accountId, {
rail: "wire",
routing_number: "021000021",
idempotencyKey: crypto.randomUUID(),
});