POST /external-accounts and reference the returned ext_ ID on quotes.
Supported types
Each external account carries a type-specific ID prefix. The prefix tells you which instrument type to select on the quote side.Referencing an external account in a transaction
Reference the external account ID in the quote’sdestination (or source, for cards). The instrument is typed by type, and the id in details carries the ext_ prefix.
US bank destination
network is one of ach, achSameDay, or wire. The accountHolder field is always customer. IBAN (bankIban) and Canadian (bankCanada) destinations follow the same pattern with their respective ext_ IDs.
External wallet destination
id (a registered external account, ext_wlt_ prefix) or blockchainAddress (a raw on-chain address).
Card source or destination
asset: usd; its network is inferred server-side. Reference it as the source to pull from a card or as the destination to push to one. See Debit cards for both directions.
Registering external accounts
Register external accounts withPOST /external-accounts. The body carries an owner, a type, and exactly one per-type detail object whose key matches type; a mismatch is rejected with 422. Optional label and metadata fields round out the request.
The owner selects who the account belongs to:
{ "kind": "customer", "customerId": "cst_..." }for an account owned by the customer.{ "kind": "counterparty", "counterpartyId": "ctp_..." }for an address-book entry owned by one of the customer’s counterparties.
An external wallet is registered per network family: an EVM address registered once is valid across every EVM chain. See Debit cards for the card-specific details.
Provisioning runs synchronously against the configured payment provider: the account starts
pending and flips to active or failed.
Response
Sensitive fields are write-only. Full account numbers, IBANs, card numbers, and CVVs are never stored on reads or echoed back; the response carries only their last-four renderings (accountNumberLast4, ibanLast4, cardNumberLast4). Exactly one per-type response object is populated, selected by type. For bankUs, accountType is always present on reads: checking when it was omitted at create time, otherwise the value you supplied.
Owner rendering
External account responses carryownerDisplayName, an opaque, ready-to-render label for the owner (for example, the customer’s or counterparty’s name). Customer-owned accounts additionally carry a customer summary:
customer is populated on GET /external-accounts, GET /external-accounts/{externalAccountId}, and PATCH /external-accounts/{externalAccountId} responses for customer-owned accounts. Counterparty-owned accounts populate ownerDisplayName from the counterparty and omit customer. See Customer summary on a transaction for the shared shape.
Released sender-attribution holds
When you register awalletExternal account whose address matches inbound transfers held for sender attribution, the create response includes resolvedTransactions: the IDs of the transactions the registration submitted for release. Attribution is asynchronous; each transaction moves from awaitingAction.awaitingSenderAttribution to processing once the provider confirms settlement, so an immediate GET on one of the IDs may still show awaitingAction. The field appears only on the POST create response, never on reads.
Managing external accounts
GET /external-accountslists a customer’s external accounts.customerIdis required;counterpartyIdoptionally narrows the list to one counterparty’s accounts. Paginate withlimit,startingAfter, andendingBefore.GET /external-accounts/{externalAccountId}fetches a single account by ID.PATCH /external-accounts/{externalAccountId}updateslabelandmetadataonly. Financial and identity fields are immutable; to change a destination, register a new account and re-point to it. Any other key in the body is rejected with400.DELETE /external-accounts/{externalAccountId}soft-deletes the account and returns204.
Statuses
Invalid external accounts
When a bank payout to an active US bank external account returns with a confirmed NACHA return code, OMS transitions the account tostatus: invalid and stamps a closed-enum invalidReason on it. The transition fires an externalAccount.statusChanged webhook, and every active virtual account or deposit address that references the invalidated account flips to inactiveActionRequired so it can no longer route new payouts to a known-bad destination.
The identifiers on an external account are immutable; there is no update path that can repair an invalid account. Register a new external account with the corrected details and re-point any dependent virtual accounts or deposit addresses to it to recover.
Wire and SWIFT rails do not currently populate
invalidReason; a wire payout failure surfaces on the transaction itself, not on the destination external account.
Related
- Debit cards: using a card as a funding source or payout destination
- Bank transfers guide: ACH and wire transfer walkthrough
- Transactions: how to use an external account on a quote