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

# Create private send order

> Send funds to another wallet via a private (two-hop) route. Same token in and out.

Pass a `quoteId` from [Get private send quote](/api-reference/private-send/get-private-send-quote).
Quote first, then create the order right away — a stale `quoteId` is rejected with 422.
Send the deposit to `depositAddress` before `expires`.

See the [Private send](/docs/v2/private-send) guide.

This endpoint only supports private same-token routes. If you want to keep one integration for every exchange type, use [Create exchange](/api-reference/exchanges/create-exchange) with a private same-token `quoteId` from [Get quotes](/api-reference/quotes/get-quotes) instead.



## OpenAPI

````yaml https://api-partner.houdiniswap.com/v2/openapi.json post /exchanges/private-send
openapi: 3.0.0
info:
  title: houdiniswap-backend
  version: 2.1.2
  description: Houdiniswap Backend
  license:
    name: ISC
  contact: {}
servers:
  - url: https://api-partner.houdiniswap.com/v2
security: []
paths:
  /exchanges/private-send:
    post:
      tags:
        - Private Send
        - Exchanges
      summary: Create private send order
      description: >-
        Send funds to another wallet via a private (two-hop) route. Same token
        in and out.


        Pass a `quoteId` from [Get private send
        quote](/api-reference/private-send/get-private-send-quote).

        Quote first, then create the order right away — a stale `quoteId` is
        rejected with 422.

        Send the deposit to `depositAddress` before `expires`.


        See the [Private send](/docs/v2/private-send) guide.


        This endpoint only supports private same-token routes. If you want to
        keep one integration for every exchange type, use [Create
        exchange](/api-reference/exchanges/create-exchange) with a private
        same-token `quoteId` from [Get quotes](/api-reference/quotes/get-quotes)
        instead.
      operationId: CreatePrivateSend
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PrivateSendExchangeRequest'
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrderV2PublicResponse'
              examples:
                Example 1:
                  value:
                    houdiniId: hxK7mQp2
                    created: '2026-01-01T12:00:00.000Z'
                    depositAddress: bc1qexampledepositaddress000000000000000000
                    receiverAddress: bc1qexampledestinationaddress000000000000
                    anonymous: true
                    expires: '2026-01-01T12:30:00.000Z'
                    status: 0
                    inAmount: 0.1
                    inSymbol: BTC
                    outAmount: 0.095
                    outSymbol: BTC
                    displayStatus: WAITING_FOR_DEPOSIT
        '403':
          description: Access Denied
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Token not found or disabled
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: >-
            quoteId must be a private same-token send quote (from=to, type
            private).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - apiKey: []
components:
  schemas:
    PrivateSendExchangeRequest:
      description: Create a private same-token order from a prior private-send quote.
      properties:
        addressTo:
          type: string
          description: Destination wallet address where funds will be sent
          minLength: 1
          maxLength: 200
        quoteId:
          type: string
          description: >-
            Quote ID from a prior quote response.

            Amount, from token, to token, and swap provider are retrieved from
            the provided quote.

            For CEX exchanges, if the exchange fails with the chosen swap
            provider, it will fallback to the next best route.
        markup:
          type: number
          format: double
          description: |-
            Partner markup for this request, as a percentage (0.5 = 0.5%).
            Accepted range: 0–4. This value overrides your account’s default
            markup for this trade. Send 0 to apply no markup, or leave the field
            empty / set it to null if no markup is requested. Providers that do
            not support the requested markup will be excluded.
          example: 0.5
          minimum: 0
          maximum: 4
        refundAddress:
          type: string
          description: |-
            Sender's wallet address for refunds if a fixed-rate swap fails.
            Required when the quote was created with fixed: true.
          maxLength: 200
        refundExtraId:
          type: string
          description: >-
            Memo/tag for refundAddress on memo-bearing chains (e.g. XRP
            DestinationTag,

            Stellar memo, TON comment). Ignored when the destination chain has
            no memo concept.
          maxLength: 64
        destinationTag:
          type: string
          description: Destination tag / memo (e.g. for XRP, XLM)
          maxLength: 64
      required:
        - addressTo
        - quoteId
      type: object
      additionalProperties: false
    OrderV2PublicResponse:
      properties:
        fixed:
          type: boolean
        refundAddress:
          type: string
        houdiniId:
          type: string
        created:
          type: string
          format: date-time
        modified:
          type: string
          format: date-time
        receiverAddress:
          type: string
        anonymous:
          type: boolean
        expires:
          type: string
          format: date-time
        status:
          $ref: '#/components/schemas/OrderStatus'
        inAmount:
          type: number
          format: double
        inSymbol:
          type: string
        outAmount:
          type: number
          format: double
        outSymbol:
          type: string
        depositTag:
          type: string
          description: Memo/tag required when depositing funds for assets that use one
        notified:
          type: boolean
        eta:
          type: number
          format: double
          description: ETA time, depending on swap
        inAmountUsd:
          type: number
          format: double
          description: USD value of the input amount at order creation time.
        outAmountUsd:
          type: number
          format: double
        inCreated:
          type: string
          format: date-time
        id:
          type: string
        nonRefundable:
          type: boolean
        metadata: {}
        isDex:
          type: boolean
        actionRequired:
          type: boolean
        outToken:
          $ref: '#/components/schemas/Token'
        inToken:
          $ref: '#/components/schemas/Token'
        inStatus:
          $ref: '#/components/schemas/Status'
        rerouted:
          type: boolean
          description: >-
            True when the route that executed is not the one that was quoted,

            because the quoted route failed and a fallback was used. The amounts
            may

            differ from the quote — compare `inAmount` against `quotedInAmount`
            and

            `outAmount` against `quotedOutAmount`.
        quotedInAmount:
          type: number
          format: double
          description: >-
            The deposit amount originally quoted, present only when the order
            was

            rerouted. `inAmount` is what the fallback route actually asks for;
            on an

            exact-out order this is the side that moves.
        quotedOutAmount:
          type: number
          format: double
          description: >-
            The payout originally quoted, present only when the order was
            rerouted.

            `outAmount` is what the fallback route will actually pay; on an
            exact-in

            order this is the side that moves.
        displayStatus:
          $ref: '#/components/schemas/DisplayStatus'
        receiverTag:
          type: string
          nullable: true
          description: Memo/tag required when receiving funds for assets that use one
        swapName:
          type: string
          description: >-
            Name of the exchange handling the deposit leg. Omitted on private
            orders,

            which withhold the provider, and on multiswap orders that have not
            yet

            been assigned one.
        multiId:
          type: string
          description: Multi ID. Present only on orders created as part of a batch.
        outStatus:
          $ref: '#/components/schemas/Status'
          description: >-
            Status of the payout leg. Present only on private orders — public
            orders

            settle in a single leg and never carry one.
        outTransactionOutHash:
          type: string
          description: >-
            Payout transaction hash of the second leg. Present only on private
            orders,

            and only once that leg has paid out. Public orders report their
            payout

            hash on `inTransactionOutHash` instead.
        orderFinishedReceived:
          type: string
          format: date-time
          description: >-
            Date and time when the order received status 4. Stamped only when an
            order

            finishes; orders that expire, fail or refund never receive one.
        depositAddress:
          type: string
          description: |-
            The CEX deposit address where the user must send funds. Omitted on
            multiswap orders whose per-order initialization did not complete.
      required:
        - houdiniId
        - created
        - receiverAddress
        - anonymous
        - expires
        - status
        - inAmount
        - inSymbol
        - outAmount
        - outSymbol
        - notified
        - eta
        - inAmountUsd
        - outAmountUsd
        - inCreated
        - id
        - isDex
        - actionRequired
        - outToken
        - inToken
        - inStatus
        - displayStatus
      type: object
      additionalProperties: false
    ErrorResponse:
      properties:
        message:
          type: string
        code:
          type: string
        requestId:
          type: string
      required:
        - message
        - code
      type: object
      additionalProperties: false
    OrderStatus:
      description: |-
        - **-2** Order is being initialized (label: INITIALIZING)
        - **-1** Order initialized (label: NEW)
        - **0** Waiting for deposit confirmation (label: WAITING)
        - **1** Deposit is being confirmed (label: CONFIRMING)
        - **2** Exchange is in progress (label: EXCHANGING)
        - **3** Order is going through anonymization (label: ANONYMIZING)
        - **4** Order completed successfully (label: FINISHED)
        - **5** Order has expired (label: EXPIRED)
        - **6** Order failed (label: FAILED)
        - **7** Order was refunded (label: REFUNDED)
        - **8** Order was deleted (label: DELETED)
      enum:
        - -2
        - -1
        - 0
        - 1
        - 2
        - 3
        - 4
        - 5
        - 6
        - 7
        - 8
      type: number
    Token:
      properties:
        icon:
          type: string
        id:
          type: string
        address:
          type: string
          nullable: true
        chain:
          type: string
        decimals:
          type: number
          format: double
          default: 0
        symbol:
          type: string
          default: ''
        name:
          type: string
          default: ''
        created:
          type: string
          format: date-time
        modified:
          type: string
          format: date-time
        chainData:
          $ref: '#/components/schemas/Chain'
        description:
          type: string
          nullable: true
        mainnet:
          type: boolean
        enabled:
          type: boolean
        unverified:
          type: boolean
        hasDex:
          type: boolean
        hasCex:
          type: boolean
        hasBundler:
          type: boolean
          description: >-
            Indicates whether the token can be used in a bundle (multiswap)
            swap.

            True for CEX-routable Solana tokens, and for EVM native assets plus

            Pimlico-listed ERC-20s on Pimlico-supported chains.
        hasSelfPrivate:
          type: boolean
          description: >-
            Indicates if token supports private (self-to-self) swaps.

            Stored field computed when token is saved.

            True when token has CEX support AND at least 2 enabled CEX swap
            provider mappings.
        cexTokenId:
          type: string
          default: ''
        rank:
          type: number
          format: double
          nullable: true
        cgId:
          type: string
          nullable: true
        marketCapChange24h:
          type: number
          format: double
          description: 24h market cap change percentage from CoinGecko.
        circulatingSupply:
          type: number
          format: double
          description: Token circulating supply from CoinGecko.
        price:
          type: number
          format: double
          nullable: true
        marketCap:
          type: number
          format: double
          nullable: true
        volume:
          type: number
          format: double
          nullable: true
        fdv:
          type: number
          format: double
          nullable: true
        change:
          type: number
          format: double
          nullable: true
        priority:
          type: number
          format: double
          nullable: true
        warningMessage:
          type: string
        securityScan:
          $ref: '#/components/schemas/TokenSecurityScan'
          description: >-
            Last security verdict for this token, with the provider's full

            response and an `expiresAt` driving re-scan. Absent until the token
            has

            been selected as a swap source or destination at least once.
      required:
        - icon
        - id
        - chain
        - created
        - chainData
      type: object
      additionalProperties: false
    Status:
      description: |-
        - **0** New swap
        - **1** Waiting for confirmation
        - **2** Being confirmed
        - **3** Exchange in progress
        - **4** Sending to destination
        - **5** Swap completed
        - **6** Swap failed
        - **7** Swap refunded
        - **8** Verifying swap
        - **9** Swap expired
        - **10** Fallback mode
      enum:
        - 0
        - 1
        - 2
        - 3
        - 4
        - 5
        - 6
        - 7
        - 8
        - 9
        - 10
      type: number
    DisplayStatus:
      enum:
        - WAITING_FOR_DEPOSIT
        - DEPOSIT_DETECTED
        - EXCHANGE_IN_PROGRESS
        - SENDING_TO_INTERMEDIARY
        - REACHED_INTERMEDIARY
        - INITIATING_SECOND_EXCHANGE
        - SECOND_EXCHANGE_IN_PROGRESS
        - SENDING_TO_RECEIVER
        - SWAP_COMPLETED
        - EXPIRED
        - FAILED
        - REFUNDED
        - DELETED
      type: string
    Chain:
      properties:
        icon:
          type: string
        addressValidation:
          type: string
        tokenAddressValidation:
          type: string
        id:
          type: string
        created:
          type: string
          format: date-time
        modified:
          type: string
          format: date-time
        name:
          type: string
        shortName:
          type: string
        memoNeeded:
          type: boolean
          nullable: true
        hashUrl:
          type: string
        explorerUrl:
          type: string
        addressUrl:
          type: string
        priority:
          type: number
          format: double
        kind:
          type: string
        chainId:
          type: number
          format: double
          nullable: true
        enabled:
          type: boolean
        shortNameV1:
          type: string
      required:
        - icon
        - addressValidation
        - tokenAddressValidation
        - id
        - created
        - name
        - shortName
        - explorerUrl
        - addressUrl
        - kind
        - enabled
        - shortNameV1
      type: object
      additionalProperties: false
    TokenSecurityScan:
      properties:
        provider:
          type: string
          description: Screening provider that produced this verdict.
        resultType:
          $ref: '#/components/schemas/TokenScanResult'
        providerResultType:
          type: string
          description: >-
            The provider's own `result_type` string, kept unmapped so a verdict
            we

            don't model yet is still visible to support instead of being erased.
        maliciousScore:
          type: number
          format: double
          description: >-
            Provider `malicious_score`, 0..1. Arrives as a string; stored as a
            number.
        features:
          items:
            $ref: '#/components/schemas/TokenScanFeature'
          type: array
          default: []
        unscannedReason:
          $ref: '#/components/schemas/TokenScanUnscannedReason'
        unscannedDetail:
          type: string
          description: >-
            Free-text detail behind `unscannedReason` (provider message,
            status…).
        scannedAt:
          type: string
          format: date-time
        expiresAt:
          type: string
          format: date-time
          description: When this verdict goes stale and the token should be re-scanned.
      required:
        - scannedAt
        - expiresAt
      type: object
      additionalProperties: false
    TokenScanResult:
      description: >-
        Normalized verdict for a swap-token security scan.


        Branch on this, never on individual `features` — the provider (Blockaid)

        already aggregates its features into the verdict, and the feature
        catalogue

        changes underneath us (ids get added, renamed and deprecated).


        `UNSCANNED` is the explicit fourth state the ticket calls for: provider

        outage, rate limit, timeout, unsupported chain, missing credentials or a

        verdict string we don't recognise. It always means *fail open* — an
        external

        scanner being unavailable must never block a swap.
      enum:
        - Benign
        - Warning
        - Malicious
        - Unscanned
      type: string
    TokenScanFeature:
      description: >-
        One provider feature. Stored verbatim, with **no allowlist** — Blockaid
        adds,

        renames and deprecates feature ids (INORGANIC_VOLUME is already
        deprecated),

        so hardcoding a subset goes stale. Reference/context for FE copy and
        admin

        visibility only.
      properties:
        featureId:
          type: string
        type:
          type: string
          description: >-
            Provider severity for this feature: Malicious | Warning | Benign |
            Info.
        description:
          type: string
      type: object
      additionalProperties: false
    TokenScanUnscannedReason:
      description: >-
        Why a token ended up `UNSCANNED`. Diagnostic only — never a branching
        input.
      enum:
        - NOT_CONFIGURED
        - UNSUPPORTED_CHAIN
        - NATIVE_TOKEN
        - RATE_LIMITED
        - TIMEOUT
        - PROVIDER_ERROR
        - NO_RESULT
        - SCAN_PENDING
        - NOT_A_TOKEN
        - UNKNOWN_RESULT_TYPE
      type: string
  securitySchemes:
    apiKey:
      type: apiKey
      name: Authorization
      in: header

````