> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stableyard.fi/llms.txt
> Use this file to discover all available pages before exploring further.

# Link a bank account

> Save a bank beneficiary under a UPA using its country-specific fields.

Read [bank account requirements](/api-reference/bank-accounts/get-bank-account-requirements) first for each country's fields and current availability. Linking is available for the United States, the Philippines and Vietnam, and must be enabled for your app. An individual UPA needs approved KYC. A business UPA can link a US/USD bank once its hosted business verification (KYB) is approved.

A linked bank is a saved beneficiary and can belong to a supplier, contractor or the UPA subject. Linking does not prove ownership by the UPA subject.

| Country | On link |
| - | - |
| US | Set up for payouts. Follow `provisioning.nextAction`; the bank becomes `active` once `provisioning.providerProvisioningCompleted` is `true`. |
| PH | Stays `pending_verification`. Choosing a bank from the directory does not verify the account. |
| VN | The beneficiary is verified when it is linked, and the bank is returned `active`. |

Only a US linked bank can be paid. Once it is `active`, create a send Payment with `destination.type: "bank_account"`; see [Off-ramps](/payments/off-ramps). A linked bank cannot receive settlement.

Full bank details are never returned; responses show `accountNumberLast4`. `Idempotency-Key` is required and must contain 1–256 characters after trimming surrounding whitespace. Preserve the original body and key after an uncertain response; changed input conflicts.


## OpenAPI

````yaml openapi.json POST /v2/accounts/{accountId}/bank-accounts
openapi: 3.1.0
info:
  title: Stableyard Partner API
  version: 2.0.0
  x-stableyard-api-version: '2026-09-09'
  x-stableyard-supported-api-versions:
    - '2026-09-09'
  summary: Backend API for UPAs, Payments, activity, and optional financial products.
  description: >

    Use this API from a trusted partner backend with an app ID and app secret.


    ## Recommended integration


    1. Call `GET /v2/partners/config` to verify credentials and discover enabled
    capabilities.

    2. Create a UPA only when your product needs a persistent Stableyard
    account.

    3. Create a receive or send Payment with `POST /v2/payments`.

    4. Redirect a payer to the returned `paymentUrl` or pass the Payment
    credentials to an official Stableyard interface SDK.

    5. Process signed webhooks and fetch the Payment by ID for reconciliation.


    Checkout execution and account-bound browser endpoints are documented in the
    separate Interfaces & SDKs reference.
  x-stableyard-documentation-surface: partner
servers:
  - url: https://prod-api.stableyard.fi
    description: Production
  - url: https://staging-api-v2.stableyard.fi
    description: Sandbox
security: []
tags:
  - name: Authentication
    x-displayName: API authentication
    description: Verify your app ID and app secret before calling UPA APIs.
  - name: Accounts
    x-displayName: UPA Accounts
    description: Create Universal Payment Accounts and manage account settings.
  - name: Deposit Addresses
    description: Create reusable receive addresses and verify inbound deposits.
  - name: Identity & KYC
    description: >-
      Verify the UPA email and run identity verification. Managed vaults and
      fiat payment rails use this same verified UPA identity.
  - name: Vaults
    description: >-
      Create policy-controlled stablecoin vaults and manage policy updates for
      accounts.
  - name: Payments
    description: >-
      Create escrow-first payments, issue partner-authenticated send
      instructions or executions, power public checkout, and reconcile
      collection through final account settlement.
  - name: Balances & Transactions
    description: >-
      Read Stableyard-posted financial activity. Balances are ledger projections
      of activity Stableyard processed; they are not live balances of externally
      controlled wallets.
paths:
  /v2/accounts/{accountId}/bank-accounts:
    post:
      tags:
        - Accounts
      summary: Link a bank account using its country-specific fields
      description: >-
        Read bank-account-requirements for country-specific fields and
        availability. Linking is available for United States, Philippines and
        Vietnam bank accounts. An individual UPA needs approved KYC; a business
        UPA can link a US/USD bank after its hosted KYB is approved. Both
        require bank linking to be enabled for your app. A linked bank is a
        saved beneficiary, including a supplier, contractor or the UPA subject's
        own bank; linking does not prove ownership by the UPA subject. Bank
        details are stored encrypted. US bank accounts are also set up for
        payouts; the response's `provisioning` object reports progress and any
        `nextAction`. Philippines links stay pending verification; directory
        membership never verifies account ownership. Vietnam beneficiary details
        are verified during linking. To pay a linked bank, create a send Payment
        with its `bankAccountId`; received funds do not settle to a linked bank
        automatically. Full bank details are never returned; responses show
        `accountNumberLast4`. Reuse the same Idempotency-Key with identical
        normalized input; changed input conflicts.
      operationId: createBankAccountByAccountId
      parameters:
        - name: accountId
          in: path
          required: true
          schema:
            type: string
            example: acct_123
          description: Canonical account id returned by the Accounts API.
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 1
            maxLength: 256
            example: bank-beneficiary-supplier-123
          description: >-
            Required retry key for linking a bank account or rail identifier:
            1-256 characters after trimming surrounding whitespace. Retry the
            identical request with the same key; changed input returns a
            conflict.
        - name: Stableyard-Version
          in: header
          required: false
          schema:
            type: string
            enum:
              - '2026-09-09'
          description: >-
            Optional contract-version assertion. Omit it to use the app
            environment's pinned version. A different supported version is
            accepted only after that environment is explicitly migrated.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateBankAccountRequest'
            examples:
              usdBankAccount:
                summary: US checking account
                value:
                  accountHolderName: Alice Doe
                  beneficiaryType: individual
                  country: US
                  currency: USD
                  bankName: Example Bank
                  accountNumber: '000123456789'
                  accountType: checking
                  routing:
                    type: aba
                    routingNumber: '123456780'
                  rail: ach
                  beneficiaryAddress:
                    street1: 1 Market Street
                    city: San Francisco
                    region: CA
                    postalCode: '94105'
                    country: US
                  bankAddress:
                    street1: 1 Example Plaza
                    city: Springfield
                    region: IL
                    postalCode: '62701'
                    country: US
              philippinesBankAccount:
                summary: Philippines account saved pending verification
                description: >-
                  Synthetic bank values. Replace bankCode and bankName with a
                  matching pair from the account-scoped linked-bank directory.
                value:
                  country: PH
                  currency: PHP
                  accountHolderName: Test Person
                  beneficiaryType: individual
                  bankName: Test Bank
                  bankCode: directory_code
                  accountNumber: '0000123456'
                  rail: bank_transfer
              vietnamBankAccount:
                summary: Vietnam account with standalone beneficiary verification
                description: >-
                  Synthetic bank values. Use a Vietnam directory entry and the
                  registered beneficiary name. Requires Vietnam bank linking to
                  be enabled for your app.
                value:
                  country: VN
                  currency: VND
                  accountHolderName: TEST PERSON
                  beneficiaryType: individual
                  bankName: Test Bank
                  bankCode: directory_code
                  accountNumber: '0000123456'
                  rail: bank_transfer
      responses:
        '201':
          description: Linked bank account
          headers:
            Stableyard-Version:
              description: >-
                Effective date-based Stableyard API contract version for this
                response.
              schema:
                type: string
                enum:
                  - '2026-09-09'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CreateBankAccountResponse'
              examples:
                linkedBankAccount:
                  summary: Linked bank account
                  value:
                    bankAccount:
                      id: bank_account_123
                      accountId: acct_123
                      accountHolderName: Alice Doe
                      country: US
                      currency: USD
                      bankName: Example Bank
                      accountNumberLast4: '1234'
                      rail: ach
                      status: active
                      verification:
                        version: 1
                        verifiedAt: '2026-09-01T10:00:00.000Z'
                      disabledAt: null
                      createdAt: '2026-08-28T10:00:00.000Z'
                      updatedAt: '2026-08-28T10:00:00.000Z'
                    settlementDestination:
                      id: destination_123
                      accountId: acct_123
                      type: bank_account
                      status: restricted
                      preferred: false
                      capabilities:
                        directions:
                          - receive
                        settlementSupported: false
                        unavailableReason: linked_bank_receive_settlement_not_enabled
                        country: US
                        currency: USD
                        rail: ach
                      resource:
                        type: bank_account
                        bankAccount:
                          id: bank_account_123
                          accountId: acct_123
                          accountHolderName: Alice Doe
                          country: US
                          currency: USD
                          bankName: Example Bank
                          accountNumberLast4: '1234'
                          rail: ach
                          status: active
                          verification:
                            version: 1
                            verifiedAt: '2026-09-01T10:00:00.000Z'
                          disabledAt: null
                          createdAt: '2026-08-28T10:00:00.000Z'
                          updatedAt: '2026-08-28T10:00:00.000Z'
                      disabledAt: null
                      createdAt: '2026-08-28T10:00:00.000Z'
                      updatedAt: '2026-08-28T10:00:00.000Z'
                    provisioning:
                      providerProvisioningCompleted: true
                      settlementReady: false
                      nextAction:
                        type: none
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '424':
          $ref: '#/components/responses/FailedDependency'
        '429':
          $ref: '#/components/responses/TooManyRequests'
      security:
        - partnerBasicAuth: []
components:
  schemas:
    CreateBankAccountRequest:
      description: Country-specific bank inputs.
      oneOf:
        - type: object
          additionalProperties: false
          properties:
            country:
              type: string
              const: US
            currency:
              type: string
              const: USD
            accountHolderName:
              type: string
              title: Recipient name
              minLength: 1
              maxLength: 160
            beneficiaryType:
              type: string
              title: Beneficiary type
              enum:
                - individual
                - business
              default: individual
            bankName:
              type: string
              title: Bank name
              minLength: 1
              maxLength: 160
            accountNumber:
              type: string
              title: Account number
              minLength: 4
              maxLength: 17
              pattern: ^[0-9]{4,17}$
              writeOnly: true
              x-normalize: digits
            accountType:
              type: string
              title: Account type
              enum:
                - checking
                - savings
            routing:
              type: object
              additionalProperties: false
              properties:
                type:
                  type: string
                  const: aba
                routingNumber:
                  type: string
                  title: ABA routing number
                  minLength: 9
                  maxLength: 9
                  pattern: ^[0-9]{9,9}$
                  writeOnly: true
                  x-normalize: digits
                  description: >-
                    Use the routing number for the selected ACH, Fedwire, or
                    FedNow rail.
              required:
                - type
                - routingNumber
            rail:
              type: string
              title: Rail
              enum:
                - ach
                - fedwire
                - fednow
              default: ach
            beneficiaryAddress:
              type: object
              additionalProperties: false
              properties:
                street1:
                  type: string
                  title: Street
                  minLength: 1
                  maxLength: 160
                street2:
                  type: string
                  title: Street 2
                  minLength: 1
                  maxLength: 160
                city:
                  type: string
                  title: City
                  minLength: 1
                  maxLength: 100
                region:
                  type: string
                  title: State / region
                  minLength: 1
                  maxLength: 100
                postalCode:
                  type: string
                  title: Postal code
                  minLength: 1
                  maxLength: 24
                country:
                  type: string
                  title: Country code
                  minLength: 2
                  maxLength: 2
                  pattern: ^[A-Z]{2}$
                  x-normalize: uppercase
              required:
                - street1
                - city
                - region
                - postalCode
                - country
              title: Beneficiary address
            bankAddress:
              type: object
              additionalProperties: false
              properties:
                street1:
                  type: string
                  title: Street
                  minLength: 1
                  maxLength: 160
                street2:
                  type: string
                  title: Street 2
                  minLength: 1
                  maxLength: 160
                city:
                  type: string
                  title: City
                  minLength: 1
                  maxLength: 100
                region:
                  type: string
                  title: State / region
                  minLength: 1
                  maxLength: 100
                postalCode:
                  type: string
                  title: Postal code
                  minLength: 1
                  maxLength: 24
                country:
                  type: string
                  title: Country code
                  minLength: 2
                  maxLength: 2
                  pattern: ^[A-Z]{2}$
                  x-normalize: uppercase
              required:
                - street1
                - city
                - region
                - postalCode
                - country
              title: Bank address
          required:
            - country
            - currency
            - accountHolderName
            - bankName
            - accountNumber
            - accountType
            - routing
            - beneficiaryAddress
            - bankAddress
          title: United States bank account
        - type: object
          additionalProperties: false
          properties:
            country:
              type: string
              const: PH
            currency:
              type: string
              const: PHP
            accountHolderName:
              type: string
              title: Recipient name
              minLength: 1
              maxLength: 160
            beneficiaryType:
              type: string
              title: Beneficiary type
              enum:
                - individual
                - business
              default: individual
            bankName:
              type: string
              title: Bank name
              minLength: 1
              maxLength: 160
            bankCode:
              type: string
              title: Bank code
              minLength: 1
              maxLength: 64
              pattern: ^[A-Za-z0-9_-]+$
              x-bank-directory: true
            accountNumber:
              type: string
              title: Account number
              minLength: 4
              maxLength: 34
              pattern: ^[0-9]{4,34}$
              writeOnly: true
              x-normalize: digits
            rail:
              type: string
              const: bank_transfer
              default: bank_transfer
          required:
            - country
            - currency
            - accountHolderName
            - bankName
            - bankCode
            - accountNumber
          title: Philippines bank account
        - type: object
          additionalProperties: false
          properties:
            country:
              type: string
              const: VN
            currency:
              type: string
              const: VND
            accountHolderName:
              type: string
              title: Recipient name
              minLength: 1
              maxLength: 160
              x-normalize: vietnam_name
            beneficiaryType:
              type: string
              title: Beneficiary type
              enum:
                - individual
                - business
              default: individual
            bankName:
              type: string
              title: Bank name
              minLength: 1
              maxLength: 160
            bankCode:
              type: string
              title: Bank code
              minLength: 1
              maxLength: 64
              pattern: ^[A-Za-z0-9_-]+$
              x-bank-directory: true
            accountNumber:
              type: string
              title: Account number
              minLength: 4
              maxLength: 34
              pattern: ^[0-9]{4,34}$
              writeOnly: true
              x-normalize: digits
            rail:
              type: string
              const: bank_transfer
              default: bank_transfer
          required:
            - country
            - currency
            - accountHolderName
            - bankName
            - bankCode
            - accountNumber
          title: Vietnam bank account
      discriminator:
        propertyName: country
    CreateBankAccountResponse:
      type: object
      additionalProperties: false
      required:
        - bankAccount
        - settlementDestination
        - provisioning
      properties:
        bankAccount:
          $ref: '#/components/schemas/BankAccount'
        settlementDestination:
          $ref: '#/components/schemas/SettlementDestination'
        provisioning:
          type: object
          additionalProperties: false
          required:
            - providerProvisioningCompleted
            - settlementReady
            - nextAction
          properties:
            providerProvisioningCompleted:
              type: boolean
              description: True once the bank account is set up for payouts.
            settlementReady:
              type: boolean
              description: >-
                Whether received funds can settle automatically to this bank.
                Currently `false` for every bank; to pay a linked bank, create a
                send Payment with its `bankAccountId`.
            nextAction:
              type: object
              additionalProperties: true
              required:
                - type
              properties:
                type:
                  type: string
                  enum:
                    - none
                    - complete_provider_onboarding
                    - contact_support
                url:
                  type: string
                  format: uri
                  description: >-
                    Short-lived hosted onboarding URL. Returned only in the
                    current response when action is required.
                expiresAt:
                  type:
                    - string
                    - 'null'
                  format: date-time
    BankAccount:
      type: object
      additionalProperties: false
      required:
        - id
        - accountId
        - accountHolderName
        - country
        - currency
        - bankName
        - accountNumberLast4
        - rail
        - status
        - verification
        - disabledAt
        - createdAt
        - updatedAt
      properties:
        id:
          type: string
          example: bank_account_123
        accountId:
          type: string
          example: acct_123
        accountHolderName:
          type: string
          example: Alice Doe
        country:
          type: string
          pattern: ^[A-Z]{2}$
          example: US
        currency:
          type: string
          pattern: ^[A-Z]{3}$
          example: USD
        bankName:
          type: string
          example: Example Bank
        bankCode:
          type: string
          maxLength: 64
          description: >-
            Public country-directory bank code when supplied for a local bank
            link.
        accountNumberLast4:
          type: string
          example: '1234'
        rail:
          type:
            - string
            - 'null'
          example: ach
        status:
          type: string
          enum:
            - pending_verification
            - active
            - restricted
            - disabled
        verification:
          type: object
          additionalProperties: false
          required:
            - version
            - verifiedAt
          properties:
            version:
              type: integer
              minimum: 0
            verifiedAt:
              type:
                - string
                - 'null'
              format: date-time
        disabledAt:
          type:
            - string
            - 'null'
          format: date-time
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
    SettlementDestination:
      type: object
      additionalProperties: false
      required:
        - id
        - accountId
        - type
        - status
        - preferred
        - capabilities
        - resource
        - disabledAt
        - createdAt
        - updatedAt
      properties:
        id:
          type: string
          example: destination_123
        accountId:
          type: string
          example: acct_123
        type:
          type: string
          enum:
            - crypto_wallet
            - bank_account
            - payment_rail_identifier
          example: crypto_wallet
        status:
          type: string
          enum:
            - pending_verification
            - active
            - restricted
            - disabled
          example: active
        preferred:
          type: boolean
        capabilities:
          type: object
          additionalProperties: true
          description: >-
            What this destination supports. `settlementSupported` must be true
            before this destination can be selected.
          example:
            directions:
              - receive
            settlementSupported: true
            unavailableReason: null
            network:
              code: base
              chainId: 8453
              chainFamily: evm
            assets:
              - symbol: USDC
                tokenAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'
                decimals: 6
        resource:
          type: object
          additionalProperties: true
          description: >-
            Masked view of the linked wallet, bank account, or rail identifier.
            Tokens and full identifiers are never returned.
          example:
            type: crypto_wallet
            connectedWalletId: wallet_123
            chainId: 8453
            address: '0x1111111111111111111111111111111111111111'
            walletKind: external
            label: Primary wallet
            ownershipVerificationStatus: unverified
        disabledAt:
          type:
            - string
            - 'null'
          format: date-time
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
    ErrorResponse:
      type: object
      additionalProperties: false
      required:
        - error
      properties:
        error:
          type: object
          additionalProperties: false
          required:
            - code
            - message
          properties:
            code:
              type: string
              minLength: 1
              maxLength: 128
              example: bad_request
            message:
              type: string
              minLength: 1
              maxLength: 1000
              example: The request is invalid
            details: {}
  responses:
    BadRequest:
      description: Bad request
      headers:
        Stableyard-Version:
          description: >-
            Effective date-based Stableyard API contract version for this
            response.
          schema:
            type: string
            enum:
              - '2026-09-09'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            example:
              summary: bad_request
              value:
                error:
                  code: bad_request
                  message: The request is invalid
    Unauthorized:
      description: Unauthorized
      headers:
        Stableyard-Version:
          description: >-
            Effective date-based Stableyard API contract version for this
            response.
          schema:
            type: string
            enum:
              - '2026-09-09'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            example:
              summary: unauthorized
              value:
                error:
                  code: unauthorized
                  message: Authentication is required
    Forbidden:
      description: The app secret does not include the required scope
      headers:
        Stableyard-Version:
          description: >-
            Effective date-based Stableyard API contract version for this
            response.
          schema:
            type: string
            enum:
              - '2026-09-09'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            example:
              summary: forbidden
              value:
                error:
                  code: forbidden
                  message: The credential does not allow this operation
    NotFound:
      description: Not found
      headers:
        Stableyard-Version:
          description: >-
            Effective date-based Stableyard API contract version for this
            response.
          schema:
            type: string
            enum:
              - '2026-09-09'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            example:
              summary: not_found
              value:
                error:
                  code: not_found
                  message: The resource was not found
    Conflict:
      description: Conflict
      headers:
        Stableyard-Version:
          description: >-
            Effective date-based Stableyard API contract version for this
            response.
          schema:
            type: string
            enum:
              - '2026-09-09'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            example:
              summary: idempotency_conflict
              value:
                error:
                  code: idempotency_conflict
                  message: >-
                    The Idempotency-Key was already used with a different
                    request
    FailedDependency:
      description: This feature is not configured for your app or environment
      headers:
        Stableyard-Version:
          description: >-
            Effective date-based Stableyard API contract version for this
            response.
          schema:
            type: string
            enum:
              - '2026-09-09'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            example:
              summary: chain_config_missing
              value:
                error:
                  code: chain_config_missing
                  message: The requested network is not configured for this environment
    TooManyRequests:
      description: Too many requests. Retry after the `Retry-After` interval.
      headers:
        Stableyard-Version:
          description: >-
            Effective date-based Stableyard API contract version for this
            response.
          schema:
            type: string
            enum:
              - '2026-09-09'
        Retry-After:
          description: Seconds until the caller should retry.
          schema:
            type: integer
            minimum: 1
        RateLimit-Limit:
          description: Quota for the most constrained policy.
          schema:
            type: integer
            minimum: 1
        RateLimit-Remaining:
          description: Requests remaining in that policy window.
          schema:
            type: integer
            minimum: 0
        RateLimit-Reset:
          description: Seconds until that policy window resets.
          schema:
            type: integer
            minimum: 0
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            example:
              summary: rate_limited
              value:
                error:
                  code: rate_limited
                  message: Too many requests
  securitySchemes:
    partnerBasicAuth:
      type: http
      scheme: basic
      description: >-
        HTTP Basic auth. Username is the Stableyard app ID. Password is the app
        secret. The optional Stableyard-Version request header must match the
        environment pin.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.