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

# Create a pay-through order

> Pay an address on another layer from Lightning. The maker returns a hold invoice; once it is paid, the maker sends the payout to `destination` and then settles the hold. Track it with `GET /v2/swap/{id}`. **The payout leg is controlled by the maker, not locked.** Send an `Idempotency-Key` to make retries safe; check `/v2/version` for `pay_through_idempotency_v1` first. Returns `503 pay_through_disabled` when the maker has not enabled it.



## OpenAPI

````yaml /openapi.json post /v2/swap/pay
openapi: 3.1.0
info:
  title: KaleidoSwap Maker API
  version: v2
  description: >-
    Public HTTP API of the KaleidoSwap maker. Wire-compatible with the Boltz
    `/v2` protocol for submarine, reverse, and chain swaps, with KaleidoSwap
    additions (RGB, atomic swaps, pay-through, LSPS1, swap credentials).
    Integrate through the Swap SDK where possible: it verifies every swap the
    maker proposes.
  contact:
    name: KaleidoSwap
    url: https://kaleidoswap.com
servers:
  - url: https://maker.signet.kaleidoswap.com
    description: Signet (Mutinynet)
security: []
tags:
  - name: Service
    description: Maker identity, version, and capabilities.
  - name: Pairs and quotes
    description: Routes the maker trades, their limits and fees, and quotes.
  - name: Submarine swaps
    description: On-chain → Lightning. You lock on chain; the maker pays your invoice.
  - name: Reverse swaps
    description: >-
      Lightning → on-chain. You pay a hold invoice; the maker locks on chain;
      you claim.
  - name: Chain swaps
    description: On-chain → on-chain. Both sides lock; you claim the maker's lockup.
  - name: Swap status
    description: Swap status over HTTP and WebSocket.
  - name: Recovery
    description: Restore swaps from an xpub and recover swap credentials.
  - name: Atomic RGB swaps
    description: BTC ↔ RGB asset swaps in a single transaction.
  - name: Pay-through
    description: Lightning payment → on-chain payout to any address.
  - name: Lightning channels (LSPS1)
    description: Buy inbound Lightning channels (LSPS1).
  - name: Chain data
    description: The maker's view of chain tips and fees.
paths:
  /v2/swap/pay:
    post:
      tags:
        - Pay-through
      summary: Create a pay-through order
      description: >-
        Pay an address on another layer from Lightning. The maker returns a hold
        invoice; once it is paid, the maker sends the payout to `destination`
        and then settles the hold. Track it with `GET /v2/swap/{id}`. **The
        payout leg is controlled by the maker, not locked.** Send an
        `Idempotency-Key` to make retries safe; check `/v2/version` for
        `pay_through_idempotency_v1` first. Returns `503 pay_through_disabled`
        when the maker has not enabled it.
      operationId: create_pay_through
      parameters:
        - name: Idempotency-Key
          in: header
          description: >-
            Optional secret, caller-generated key (random UUIDv4 or 32-byte
            hexadecimal value). Reuse the same key and request to recover the
            original creation response.
          required: false
          schema:
            type:
              - string
              - 'null'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreatePayThroughRequest'
        required: true
      responses:
        '201':
          description: Swap created; hold invoice minted.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PayThroughCreateResponse'
        '400':
          description: >-
            Malformed destination, amounts or Idempotency-Key, a Lightning
            destination, or a stale pairHash.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '409':
          description: >-
            Idempotency input/attribution mismatch, original creation in
            flight/uncertain, or original invoice no longer payable.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: >-
            No route to that layer, quote/inventory failure, or amount outside
            the card's limits.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: >-
            Over the caller-rate or rolling notional budget; carries
            Retry-After.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: >-
            Pay-through disabled, signing key / database / node / chain provider
            unavailable, or no usable BTC fee rate for a Bitcoin L1 payout.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - {}
        - PartnerAuth: []
        - OrgKey: []
components:
  schemas:
    CreatePayThroughRequest:
      type: object
      description: Body of `POST /v2/swap/pay`.
      required:
        - destination
      properties:
        asset:
          type:
            - string
            - 'null'
          description: >-
            Destination asset, when the layer carries more than one (Liquid:

            `L-BTC` or `L-USDT`). Optional: with several routes to the layer the

            maker delivers the one that does **not** convert the payer's
            bitcoin,

            so naming an asset is how a payer asks for a conversion rather than

            something they have to know to say.
        destination:
          type: string
          description: >-
            Where the maker delivers: a Liquid address (confidential or
            explicit),

            a Bitcoin address, or an Arkade address. The layer is inferred from

            the address; it must belong to the maker's network.
        invoiceAmount:
          type:
            - integer
            - 'null'
          format: int64
          description: >-
            Sats the payer sends over Lightning (the hold invoice's amount).
            Exactly one of `invoiceAmount` / `payoutAmount` is required.
          minimum: 0
        pairHash:
          type:
            - string
            - 'null'
          description: >-
            Optional `pairHash` rate-lock against the reverse rate card the
            payer

            quoted from; a mismatch is `400 pair_hash_mismatch`.
        payoutAmount:
          type:
            - integer
            - 'null'
          format: int64
          description: >-
            What the destination must receive, in the destination asset's
            smallest

            unit. The maker inverts the rate card to find the invoice amount;
            the

            delivered amount is the card's own net output for that input, so it

            is at least this value.
          minimum: 0
        webhook:
          oneOf:
            - $ref: '#/components/schemas/WebhookConfig'
              description: >-
                Optional HTTPS callback for status changes (Boltz `webhook`
                shape).
            - type: 'null'
    PayThroughCreateResponse:
      type: object
      description: '`POST /v2/swap/pay` response — a pay-through swap.'
      required:
        - id
        - swapAuth
        - invoice
        - paymentHash
        - destination
        - destinationLayer
        - payoutAsset
        - pairId
        - invoiceAmount
        - payoutAmount
        - fees
        - expiresAt
      properties:
        destination:
          type: string
          description: The destination, as accepted.
        destinationLayer:
          type: string
          description: |-
            Destination layer: `BTC_L1`, `BTC_LIQUID`, `LIQUID_LIQUID` or
            `BTC_ARKADE`.
        expiresAt:
          type: integer
          format: int64
          description: Unix timestamp after which the unpaid hold invoice expires.
        fees:
          $ref: '#/components/schemas/PayThroughFees'
        id:
          type: string
        invoice:
          type: string
          description: BOLT11 hold invoice the payer pays.
        invoiceAmount:
          type: integer
          format: int64
          description: Sats the payer sends on Lightning.
          minimum: 0
        pairId:
          type: string
          description: The reverse pair the swap was priced on.
        paymentHash:
          type: string
          description: |-
            The hold invoice's payment hash (hex). Maker-generated: the maker
            settles the hold with the matching preimage after the payout is out.
        payoutAmount:
          type: integer
          format: int64
          description: What the destination receives, in its asset's smallest unit.
          minimum: 0
        payoutAsset:
          type: string
          description: Destination asset ticker (`BTC`, `L-BTC`, `L-USDT`).
        swapAuth:
          type: string
          description: |-
            Per-swap taker credential, 32 bytes hex — see
            `swapAuth`.
    ErrorResponse:
      type: object
      description: Boltz-shaped error envelope.
      required:
        - error
      properties:
        details:
          type:
            - string
            - 'null'
          description: Optional human-readable detail. Present on 4xx; absent on 5xx.
        error:
          type: string
          description: Stable machine-readable error code, e.g. `pair_hash_mismatch`.
    WebhookConfig:
      type: object
      description: |-
        Opt-in HTTPS callbacks for a swap's status changes. ```json
        "webhook": {
          "url": "https://merchant.example/callback",
          "hashSwapId": true,
          "status": ["transaction.confirmed", "invoice.paid"]
        }
        ```
      required:
        - url
      properties:
        hashSwapId:
          type: boolean
          description: >-
            When `true`, the swap id in the callback payload is
            `SHA256(swap_id)`

            — for merchants that don't want correlatable ids on the wire.
        status:
          type:
            - array
            - 'null'
          items:
            type: string
          description: |-
            `None` (the
            field absent) means *every* transition is delivered.
        url:
          type: string
          description: Callback URL.
    PayThroughFees:
      type: object
      description: |-
        The fee snapshot a pay-through was priced at, in the destination asset's
        smallest unit.
      required:
        - protocol
        - network
        - swap
      properties:
        network:
          type: integer
          format: int64
          minimum: 0
        protocol:
          type: integer
          format: int64
          minimum: 0
        swap:
          type: integer
          format: int64
          minimum: 0
  securitySchemes:
    PartnerAuth:
      type: http
      scheme: bearer
      bearerFormat: kld_test_… / kld_live_…
      description: >-
        Secret organization API key from the partner panel, for servers. Sent on
        swap creation as `Authorization: Bearer <key>` to attribute the swap to
        your organization. Optional; an invalid key is rejected. Never use it in
        client-side code.
    OrgKey:
      type: apiKey
      in: header
      name: X-Kaleido-Org-Key
      description: >-
        Public organization key (64 hex characters) for client-side attribution.
        A label, not a credential. Sent on swap creation only. Never combine
        with `PartnerAuth`.

````

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