Skip to main content
POST
Create a submarine swap

Authorizations

Authorization
string
header
required

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.

Body

application/json

Body of POST /v2/swap/submarine — Boltz-shaped, camelCase. Accepts both the maker's native shape (pairId + preimageHash + fromAmount) and the stock Boltz SDK shape (from + to + invoice, with the hash and on-chain amount derived server-side).

refundPublicKey
string
required

The taker's 33-byte compressed refund public key, hex.

beneficiary
string | null

A kaleidoswap: beneficiary handoff carrying the invoice to pay, in place of invoice. This is how a payer funds a swap that pays someone else: the recipient's wallet emits one string and the payer's passes it through, rather than the payer knowing to pull an invoice out of it. The maker checks the request's network and expiry, and the swap is atomic exactly as it always was — the lockup commits to the recipient's payment hash, so the maker can only claim it by paying them.

from
string | null

Boltz: on-chain currency symbol (e.g. "BTC"). Combined with to into a pairId when pairId is absent.

fromAmount
integer<int64> | null

Amount, in the from-asset's smallest unit, the taker will lock on-chain. Optional for a BTC↔BTC submarine: derived from the invoice amount + the pair's fees (Boltz expectedAmount). For a Liquid submarine (L-BTC or L-USDT) the invoice is authoritative and this legacy field is accepted only when it equals the canonical inverse quote.

Required range: x >= 0
invoice
string | null

The BOLT11 invoice the taker wants paid over Lightning — the maker pays it once the taker's lockup/VHTLC confirms, then claims the lockup with the preimage the payment reveals. Its payment hash must equal preimage_hash. Boltz-shaped submarine: the user supplies the invoice to be settled.

invoiceAmount
integer<int64> | null

With offer: the Lightning amount, in sats, to request from a variable-amount offer. Optional for a fixed-amount offer, and must equal its amount when given. Rejected without offer.

Required range: x >= 0
offer
string | null

BOLT12 alternative to invoice: an lno1… offer the taker wants paid. The maker fetches an invoice from it at create time (without paying), binds the swap to that invoice's payment hash — returned as preimageHash — and releases the payment once the lockup confirms. Mutually exclusive with invoice and with an explicit preimageHash.

pairHash
string | null

Optional pairHash rate-lock: the hash the taker quoted against. When present it's verified against the pair's current rate card and a mismatch is rejected with 400 pair_hash_mismatch.

pairId
string | null

Trading-pair key, e.g. "BTC/BTC". Optional when from+to are given.

preimageHash
string | null

The taker's BOLT11 payment hash — SHA256(preimage), 32 bytes hex. Optional: derived from invoice when absent (Boltz behaviour).

to
string | null

Boltz: Lightning currency symbol (e.g. "BTC").

webhook
object | null

Optional HTTPS callback for status changes (Boltz webhook shape). Persisted on the swap row; the dispatcher reads it on each SwapUpdate.

Response

Swap created.

acceptZeroConf
boolean
required

Whether the maker accepts a 0-conf deposit. Always false — the swap engine has no zero-conf path. Present because stock Boltz clients require it (non-Option in their CreateSubmarineResponse).

address
string
required

P2TR lockup address (or ark1… VHTLC / el1… Liquid HTLC).

bip21
string
required

BIP-21 funding URI for the taker's wallet (bitcoin:<addr>?amount=<btc>). Empty for Arkade/Liquid lockups, which are not bitcoin: URIs.

claimPublicKey
string
required

33-byte compressed maker pubkey (hex) used in the MuSig2 aggregate.

expectedAmount
integer<int64>
required

Amount the taker must lock on-chain (Boltz expectedAmount).

Required range: x >= 0
id
string
required

Swap id (26-character string).

swapAuth
string
required

Per-swap taker credential, 32 bytes hex. Issued once, here. Present it as X-Swap-Auth on POST /v2/swap/{id}/rate-decision; without it the maker can't tell the taker from anyone else who happens to know the swap id.

swapTree
object
required

swapTree returned on every swap creation + status response.

timeoutBlockHeight
integer<int32>
required

Refund-leaf timelock (block height for BTC/Liquid; unix-ts for Arkade — see the persisted form for which).

Required range: x >= 0
assetId
string | null

Swap asset for Liquid routes (L-USDT); omitted on BTC/Arkade routes.

feeAssetId
string | null

Elements fee/policy asset for Liquid routes (L-BTC).

internalHop
object | null

Only when invoice is a hold invoice of this maker: the swap that minted it, which this one pays in-process instead of over Lightning. One hash binds both: the claim of that swap's lockup reveals the preimage that lets the maker claim this deposit. Only an Arkade deposit paying a reverse to an RGB lockup is admitted.

invoiceAmount
integer<int64> | null

BOLT12 (offer) creates only: the Lightning amount, in sats, the fetched invoice is for and the maker will pay.

Required range: x >= 0
preimageHash
string | null

BOLT12 (offer) creates only: the payment hash of the invoice the maker fetched from the offer — the hash the lockup commits to, which the taker could not know in advance. 32 bytes hex.

referralId
string | null

Boltz compatibility field. The maker currently has no referral attribution and returns JSON null.

rgb
object | null

RGB routes only (from on rgb_l1): how to lock the RGB asset in the swap tree's P2TR address. expectedAmount is then the asset amount in the contract's units, not sats.