> ## 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.

# Preview a send payment

> Resolve the fee, funding options and next action for a send Payment without creating it.

A read-only preview of the send Payment request (`intent: send`). It resolves the sender, destination, fee, available funding options and next action without creating a Payment. For a crypto send, proceed only when the selected payment source is available.

An enabled Vault source can fund a deposit-address Routing order when `route.required` is `true`; confirm that Payment with its returned managed authorization. A connected-wallet send still requires a direct transfer. Receive Payments do not need a preview.

See [Sending payments](/payments/sending-payments).


## OpenAPI

````yaml openapi.json POST /v2/payments/preview
openapi: 3.1.0
info:
  title: Stableyard Partner API
  version: 2.0.0-staging
  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 intentionally
    documented in the separate Interfaces & SDKs reference. Console endpoints
    are dashboard implementation details and are not part of the partner
    integration contract.
  x-stableyard-documentation-surface: partner
servers:
  - url: https://prod-api.stableyard.fi
    description: Production
  - url: https://staging-api-v2.stableyard.fi
    description: Staging
  - url: http://localhost:3001
    description: Local
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 provider-neutral identity verification.
      Managed vaults and fiat payment rails use this same verified UPA identity.
  - name: Vaults
    description: >-
      Create Safe/Zodiac 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/payments/preview:
    post:
      tags:
        - Payments
      summary: Preview payment
      description: >-
        Read-only preview for the canonical send Payment request. It resolves
        the sender, destination, fee, available funding options, and next action
        without creating a Payment. For crypto Send, proceed only when the
        selected payment source is available. An enabled Vault source can fund a
        deposit-address Routing order when `route.required` is true; confirm the
        same Payment with its returned managed authorization. Connected-wallet
        Send still requires a direct transfer. Receive Payment creation does not
        require a preview.
      operationId: previewPayment
      parameters:
        - 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/CanonicalSendPaymentCreateRequest'
            examples:
              sendToHandle:
                summary: Preview send to Stableyard handle
                value:
                  intent: send
                  sender:
                    accountId: acct_sender
                  destination:
                    type: payment_handle
                    paymentHandle: alice@partner
                  paymentAmount:
                    amount: '1.00'
                    assetCode: USDC
              sendToWallet:
                summary: Preview direct send to raw wallet
                value:
                  intent: send
                  sender:
                    accountId: acct_sender
                  destination:
                    type: crypto_wallet
                    chainId: 8453
                    address: '0x2222222222222222222222222222222222222222'
                    assetCode: USDC
                  paymentAmount:
                    amountAtomic: '1000000'
                    decimals: 6
                    assetCode: USDC
      responses:
        '200':
          description: Canonical Payment preview
          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/CanonicalPaymentPreviewResponse'
              examples:
                directSend:
                  summary: Connected-wallet send preview
                  value:
                    sender:
                      accountId: acct_sender
                    paymentAmount:
                      amount: '10.00'
                      amountAtomic: '10000000'
                      assetType: crypto
                      assetCode: USDC
                      decimals: 6
                      chainId: 8453
                      tokenAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'
                    sourceAmount:
                      amount: '10.05'
                      amountAtomic: '10050000'
                      assetType: crypto
                      assetCode: USDC
                      decimals: 6
                      chainId: 8453
                      tokenAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'
                    destination:
                      type: crypto_wallet
                      chainId: 8453
                      address: '0x2222222222222222222222222222222222222222'
                      assetCode: USDC
                      tokenAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'
                    estimatedSettlementAmount:
                      amount: '10.00'
                      amountAtomic: '10000000'
                      assetType: crypto
                      assetCode: USDC
                      decimals: 6
                      chainId: 8453
                      tokenAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'
                    estimatedFees:
                      totalFeeBps: 50
                      totalFeeAmountAtomic: '50000'
                    paymentSource:
                      id: wallet_123
                      type: vault
                      chainId: 8453
                      assetCode: USDC
                      tokenAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'
                      address: '0x1111111111111111111111111111111111111111'
                    route:
                      required: false
                      sourceChainId: 8453
                      destinationChainId: 8453
                      sourceAssetCode: USDC
                      destinationAssetCode: USDC
                    fundingOptions:
                      - type: vault
                        available: true
                        executionMode: external_transaction
                      - type: vault
                        available: false
                        executionMode: managed_authorization
                        unavailableReason: vault_not_active
                    nextAction:
                      type: transaction
                      createPaymentEndpoint: /v2/payments
                      confirmPaymentEndpoint: /v2/payments/{paymentId}/confirm
        '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:
    CanonicalSendPaymentCreateRequest:
      title: Send payment
      description: >-
        Move funds from an existing UPA payment source to another UPA, payment
        handle, or external crypto wallet. Crypto Send supports direct transfers
        and, when enabled, Vault-funded cross-chain or cross-token Routing. The
        paymentAmount identifies the exact destination asset and amount.
        Commercial fees are calculated on the quoted source input and added on
        top; sourceAmount shows the total sender debit. Routing uses
        exact_output and does not reduce the authorized destination amount for
        slippage. Preview first and stop when the selected source is
        unavailable. Routed Vault sends retain the same canonical Payment ID
        through source funding, destination verification and refund recovery;
        the routing deposit address is an internal execution detail.
      type: object
      additionalProperties: false
      required:
        - intent
        - sender
        - destination
        - paymentAmount
      properties:
        intent:
          type: string
          const: send
        sender:
          $ref: '#/components/schemas/CanonicalAccountLocator'
        destination:
          $ref: '#/components/schemas/CanonicalSendDestination'
        amountMode:
          type: string
          const: deliver_exact
          default: deliver_exact
        mandateId:
          type: string
          minLength: 1
          maxLength: 64
          description: >-
            Optional active Vault mandate authorizing this outgoing occurrence.
            A mandate constrains Vault spending; it does not schedule recurring
            Payments.
          example: vault_mandate_123
        paymentAmount:
          $ref: '#/components/schemas/CanonicalPaymentAmountInput'
        description:
          type: string
          minLength: 1
          maxLength: 500
        externalReference:
          type: string
          minLength: 1
          maxLength: 256
        expiresInSeconds:
          type: integer
          minimum: 60
          maximum: 86400
          default: 600
        metadata:
          type: object
          additionalProperties: true
    CanonicalPaymentPreviewResponse:
      type: object
      additionalProperties: false
      required:
        - sender
        - paymentAmount
        - sourceAmount
        - destination
        - estimatedSettlementAmount
        - estimatedFees
        - paymentSource
        - route
        - fundingOptions
        - nextAction
      properties:
        sender:
          type: object
          additionalProperties: false
          required:
            - accountId
          properties:
            accountId:
              type: string
              example: acct_123
        paymentAmount:
          $ref: '#/components/schemas/CanonicalPaymentAmount'
        sourceAmount:
          anyOf:
            - $ref: '#/components/schemas/CanonicalPaymentAmount'
            - type: 'null'
          description: >-
            Total sender debit in the source asset, including commercial fees
            added to the required routing input. Null when the route is
            unavailable and the source input cannot be quoted.
        destination:
          $ref: '#/components/schemas/CanonicalPaymentDestination'
        estimatedSettlementAmount:
          $ref: '#/components/schemas/CanonicalPaymentAmount'
        estimatedFees:
          type: object
          additionalProperties: false
          required:
            - totalFeeBps
            - totalFeeAmountAtomic
          properties:
            totalFeeBps:
              type: integer
              minimum: 0
              maximum: 10000
            totalFeeAmountAtomic:
              type:
                - string
                - 'null'
              pattern: ^[0-9]+$
              description: >-
                Commercial fee in source atomic units; null when the source
                input cannot be quoted.
        paymentSource:
          type: object
          additionalProperties: false
          required:
            - id
            - type
            - chainId
            - assetCode
            - tokenAddress
            - address
          properties:
            id:
              type: string
            type:
              type: string
              enum:
                - connected_wallet
                - vault
                - deposit_balance
            chainId:
              type: integer
              minimum: 1
            assetCode:
              type: string
            tokenAddress:
              type: string
            address:
              type:
                - string
                - 'null'
        route:
          type: object
          additionalProperties: false
          required:
            - required
            - sourceChainId
            - destinationChainId
            - sourceAssetCode
            - destinationAssetCode
          properties:
            required:
              type: boolean
            sourceChainId:
              type: integer
              minimum: 1
            destinationChainId:
              type: integer
              minimum: 1
            sourceAssetCode:
              type: string
            destinationAssetCode:
              type: string
        fundingOptions:
          type: array
          items:
            type: object
            additionalProperties: false
            required:
              - type
              - available
              - executionMode
            properties:
              type:
                type: string
                enum:
                  - connected_wallet
                  - vault
                  - deposit_balance
                  - external_wallet
              available:
                type: boolean
              executionMode:
                type: string
              unavailableReason:
                type: string
        nextAction:
          type: object
          additionalProperties: false
          required:
            - type
            - createPaymentEndpoint
            - confirmPaymentEndpoint
          properties:
            type:
              type: string
              enum:
                - transaction
                - managed_authorization
            createPaymentEndpoint:
              type: string
              const: /v2/payments
            confirmPaymentEndpoint:
              type: string
              const: /v2/payments/{paymentId}/confirm
    CanonicalAccountLocator:
      title: UPA account locator
      description: >-
        Identify a UPA using either its Stableyard account ID or your own
        external user ID.
      oneOf:
        - title: Stableyard account ID
          type: object
          additionalProperties: false
          required:
            - accountId
          properties:
            accountId:
              type: string
              example: acct_123
        - title: External user ID
          type: object
          additionalProperties: false
          required:
            - externalUserId
          properties:
            externalUserId:
              type: string
              maxLength: 128
              example: user_123
    CanonicalSendDestination:
      title: Send payment destination
      description: >-
        Send to another UPA, a payment handle, or an external crypto wallet.
        External QR and bank rails use their dedicated request variants below.
      oneOf:
        - title: UPA account
          type: object
          additionalProperties: false
          required:
            - type
            - account
          properties:
            type:
              type: string
              const: upa
            account:
              $ref: '#/components/schemas/CanonicalAccountLocator'
        - title: Payment handle
          type: object
          additionalProperties: false
          required:
            - type
            - paymentHandle
          properties:
            type:
              type: string
              const: payment_handle
            paymentHandle:
              type: string
              minLength: 1
              maxLength: 128
              example: alice@partner
        - title: External crypto wallet
          type: object
          additionalProperties: false
          required:
            - type
            - chainId
            - address
            - assetCode
          properties:
            type:
              type: string
              const: crypto_wallet
            chainId:
              type: integer
              minimum: 1
              example: 8453
            address:
              type: string
              minLength: 8
              maxLength: 256
              example: '0x2222222222222222222222222222222222222222'
            assetCode:
              type: string
              example: USDC
            tokenAddress:
              type: string
    CanonicalPaymentAmountInput:
      title: Payment amount
      description: >-
        Specify the payment amount once, either as a human-readable decimal
        string or in token atomic units. Never send both representations.
      oneOf:
        - $ref: '#/components/schemas/CanonicalDecimalPaymentAmountInput'
          title: Decimal amount
        - $ref: '#/components/schemas/CanonicalAtomicPaymentAmountInput'
          title: Atomic amount
    CanonicalPaymentAmount:
      type: object
      additionalProperties: false
      required:
        - amount
        - amountAtomic
        - assetType
        - assetCode
        - decimals
      properties:
        amount:
          type: string
          minLength: 1
          maxLength: 100
          pattern: ^(0|[1-9][0-9]*)(\.[0-9]{1,18})?$
          example: '50.00'
        amountAtomic:
          type: string
          minLength: 1
          maxLength: 80
          pattern: ^[1-9][0-9]*$
          example: '50000000'
        assetType:
          type: string
          enum:
            - crypto
            - fiat
        assetCode:
          type: string
          example: USDC
        decimals:
          type: integer
          minimum: 0
          maximum: 36
          example: 6
        chainId:
          type: integer
          minimum: 1
          example: 8453
        tokenAddress:
          type: string
    CanonicalPaymentDestination:
      title: Resolved payment destination
      oneOf:
        - title: UPA account
          type: object
          additionalProperties: false
          required:
            - type
            - accountId
          properties:
            type:
              type: string
              const: upa
            accountId:
              type: string
        - title: Payment handle
          type: object
          additionalProperties: false
          required:
            - type
            - paymentHandle
            - accountId
          properties:
            type:
              type: string
              const: payment_handle
            paymentHandle:
              type: string
            accountId:
              type: string
        - title: External crypto wallet
          type: object
          additionalProperties: false
          required:
            - type
            - chainId
            - address
            - assetCode
            - tokenAddress
          properties:
            type:
              type: string
              const: crypto_wallet
            chainId:
              type: integer
              minimum: 1
            address:
              type: string
            assetCode:
              type: string
            tokenAddress:
              type: string
        - title: External merchant QR
          type: object
          additionalProperties: false
          required:
            - type
            - country
            - currency
            - dynamic
            - merchant
          properties:
            type:
              type: string
              const: external_qr
            country:
              type: string
              pattern: ^[A-Z]{2}$
              example: PH
            currency:
              type: string
              pattern: ^[A-Z]{3}$
              example: PHP
            dynamic:
              type: boolean
            merchant:
              oneOf:
                - title: Merchant details
                  type: object
                  additionalProperties: false
                  required:
                    - name
                    - city
                  properties:
                    name:
                      type:
                        - string
                        - 'null'
                    city:
                      type:
                        - string
                        - 'null'
                - title: Merchant details unavailable
                  type: 'null'
        - title: External bank beneficiary
          type: object
          additionalProperties: false
          required:
            - type
            - country
            - currency
            - beneficiary
          properties:
            type:
              type: string
              const: external_bank
            country:
              type: string
              pattern: ^[A-Z]{2}$
              example: VN
            currency:
              type: string
              pattern: ^[A-Z]{3}$
              example: VND
            beneficiary:
              type: object
              additionalProperties: false
              required:
                - accountHolderName
                - accountNumberLast4
                - bankCode
                - bankName
                - country
              properties:
                accountHolderName:
                  type:
                    - string
                    - 'null'
                  maxLength: 200
                accountNumberLast4:
                  type:
                    - string
                    - 'null'
                  pattern: ^[A-Za-z0-9]{4}$
                bankCode:
                  type:
                    - string
                    - 'null'
                  maxLength: 64
                bankName:
                  type:
                    - string
                    - 'null'
                  maxLength: 200
                country:
                  type:
                    - string
                    - 'null'
                  pattern: ^[A-Z]{2}$
        - title: Verified linked bank account
          type: object
          additionalProperties: false
          required:
            - type
            - bankAccountId
            - country
            - currency
            - bankName
            - accountNumberLast4
            - rail
          properties:
            type:
              type: string
              const: bank_account
            bankAccountId:
              type: string
              pattern: ^bank_[A-Za-z0-9_-]{3,59}$
              example: bank_123
            country:
              type: string
              pattern: ^[A-Z]{2}$
              example: US
            currency:
              type: string
              pattern: ^[A-Z]{3}$
              example: USD
            bankName:
              type: string
              minLength: 1
              maxLength: 160
              example: Example Bank
            accountNumberLast4:
              type: string
              pattern: ^[A-Za-z0-9]{4,8}$
              example: '6789'
            rail:
              type: string
              minLength: 1
              maxLength: 64
              example: ach
      discriminator:
        propertyName: type
    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: {}
    CanonicalDecimalPaymentAmountInput:
      title: Decimal amount
      description: Recommended for business integrations. For example, `10.00` USDC.
      type: object
      additionalProperties: false
      required:
        - amount
        - assetCode
      properties:
        amount:
          type: string
          minLength: 1
          maxLength: 100
          pattern: ^(0|[1-9][0-9]*)(\.[0-9]{1,18})?$
          example: '50.00'
        assetType:
          type: string
          enum:
            - crypto
            - fiat
          default: crypto
        assetCode:
          type: string
          pattern: ^[A-Z0-9][A-Z0-9._-]{1,23}$
          example: USDC
        chainId:
          type: integer
          minimum: 1
          example: 8453
        tokenAddress:
          type: string
          minLength: 1
          maxLength: 256
    CanonicalAtomicPaymentAmountInput:
      title: Atomic amount
      description: >-
        Use when your application already works in token atomic units.
        `decimals` is required.
      type: object
      additionalProperties: false
      required:
        - amountAtomic
        - decimals
        - assetCode
      properties:
        amountAtomic:
          type: string
          minLength: 1
          maxLength: 80
          pattern: ^[1-9][0-9]*$
          example: '50000000'
        assetType:
          type: string
          enum:
            - crypto
            - fiat
          default: crypto
        assetCode:
          type: string
          pattern: ^[A-Z0-9][A-Z0-9._-]{1,23}$
          example: USDC
        chainId:
          type: integer
          minimum: 1
          example: 8453
        tokenAddress:
          type: string
          minLength: 1
          maxLength: 256
        decimals:
          type: integer
          minimum: 0
          maximum: 36
          example: 6
  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: BadRequest response
              value:
                error:
                  code: bad_request
                  message: The request is invalid
                  details: example
    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 response
              value:
                error:
                  code: bad_request
                  message: The request is invalid
                  details: example
    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 response
              value:
                error:
                  code: bad_request
                  message: The request is invalid
                  details: example
    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: NotFound response
              value:
                error:
                  code: bad_request
                  message: The request is invalid
                  details: example
    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: Conflict response
              value:
                error:
                  code: bad_request
                  message: The request is invalid
                  details: example
    FailedDependency:
      description: Required chain, network, or provider configuration is missing
      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: FailedDependency response
              value:
                error:
                  code: bad_request
                  message: The request is invalid
                  details: example
    TooManyRequests:
      description: >-
        Rate limit, payment-option limit, selection cooldown, or temporary abuse
        block
      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: TooManyRequests response
              value:
                error:
                  code: bad_request
                  message: The request is invalid
                  details: example
  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.