SideSwap API documentation
SideSwap API provides JSON RPC v2.0 - https://www.jsonrpc.org/specification (please note that JSON RPC batch requests are not supported).
API is available over WebSocket transports - wss://api.sideswap.io/json-rpc-ws
Testnet API server - wss://api-testnet.sideswap.io/json-rpc-ws
All examples show values from Elements regtest or testnet network. Production server uses Liquid network and so addresses and asset IDs will look different.
Timestamp value is a number of milliseconds since Unix epoch (1 January 1970 UTC).
Changelog
20.02.2025
- Document the
subscribed_valuenotification (can be used to receive peg-in and peg-out hot wallet balances).
06.02.2025
- More information about the Swap API.
- PayJoin corrections (the fee is lower and more assets are accepted).
- Document that the PayJoin UTXOs are of type P2WPKH.
04.02.2025
- Removed outdated API documentation (Instant Swaps and P2P Swaps).
- New market data.
- Removed deprecated
amp_assets(assetsshould be used instead). - Remove deprecated
load_pricesandcancel_prices. - New swaps API (
list_markets,start_quotes,get_quote,taker_sign).
Peg-in/out
Peg-in/out
Initiating new order
Method name - peg. See PegInMinAmount, PegInWalletBalance, PegOutMinAmount and PegOutWalletBalance for information about the server wallet balance and minimum allowed amounts.
Example request:
{
"id": 1,
"method": "peg",
"params": {
"peg_in": true,
"recv_addr": "AzprnS16TAsG7agu3aUwPywS2Ry6mzwBbngDDeob5S3ibciAjHZJKBxx8VmuN9W1XCzT1HBXMsBs4WSe"
}
}
Example response:
{
"id": 1,
"method": "peg",
"result": {
"created_at": 1620801008204,
"expires_at": 0,
"order_id": "379277a67b43320c4f73614323c9a533c7988edc368a7224559f272461fa1209",
"peg_addr": "Azpr42G6VpHn6KrTVa94Q1Lh2vxx3Yhx6rrbfmARmEdBsYvhJ88W4sQL9rzWigqRojHxfqQFEb2ghyux",
"recv_amount": null
}
}
Input
| Parameter | Type | Description |
|---|---|---|
peg_in |
bool | Peg-in/peg-out flag. |
recv_addr |
string | Output address that will receive converted funds (L-BTC for peg-in, BTC for peg-out). |
Output
| Parameter | Type | Description |
|---|---|---|
order_id |
string | Order ID. |
peg_addr |
string | Address to send (BTC for peg-in, L-BTC for peg-out). |
created_at |
timestamp | Timestamp when order was created. |
expires_at |
timestamp | Not used. |
recv_amount |
null | Internal. |
Monitoring status updates
Method name - peg_status (update notifications available).
Example request:
{
"id": 1,
"method": "peg_status",
"params": {
"peg_in": false,
"order_id": "379277a67b43320c4f73614323c9a533c7988edc368a7224559f272461fa1209"
}
}
Example response:
{
"id": 1,
"method": "peg_status",
"result": {
"addr": "Azpr42G6VpHn6KrTVa94Q1Lh2vxx3Yhx6rrbfmARmEdBsYvhJ88W4sQL9rzWigqRojHxfqQFEb2ghyux",
"addr_recv": "bcrt1qmrpdwm8dl3azmwpls5cfagtu67k3y9vmxpn6l8",
"created_at": 1620801008204,
"expires_at": 0,
"list": [
{
"amount": 10000,
"created_at": 1620801122049,
"detected_confs": null,
"payout": null,
"payout_txid": null,
"status": "Insufficient amount",
"total_confs": null,
"tx_hash": "945d6f834767e4e0ee452103ce0c5bca20807c4d2509c5a1ece3008a17592518",
"tx_state": "InsufficientAmount",
"tx_state_code": 1,
"vout": 0
},
{
"amount": 100000,
"created_at": 1620801127153,
"detected_confs": 0,
"payout": 99900,
"payout_txid": null,
"status": "0/2",
"total_confs": 2,
"tx_hash": "eda3265f4bd1e764e769832c9bf4d50135719cb8cff835f724ef0222c126dfdc",
"tx_state": "Detected",
"tx_state_code": 2,
"vout": 1
}
],
"order_id": "379277a67b43320c4f73614323c9a533c7988edc368a7224559f272461fa1209",
"peg_in": false
}
}
Input
| Parameter | Type | Description |
|---|---|---|
peg_in |
bool | Peg-in/peg-out flag. |
order_id |
string | Order ID. |
Output
| Parameter | Type | Description |
|---|---|---|
order_id |
string | Order ID. |
addr |
string | Address to send. |
addr_recv |
string | Address that will receive converted peg. |
created_at |
timestamp | See above. |
expires_at |
timestamp | Not used. |
list |
array | List of Transaction objects. Empty list means no transactions were detected so far (pending state). |
Transaction object:
| Parameter | Type | Description |
|---|---|---|
tx_hash |
string | Transaction id from submitted transaction made by order requestor. |
vout |
number | Transaction output index. |
status |
string | Transaction status (human readable). |
amount |
number | Amount that was sent. |
payout |
number | Amount that will be received. Could be 0 if input amount is less than peg minimum. |
payout_txid |
optional string | Payout txid (available for Done state only). |
created_at |
number | Timestamp when transaction was detected. |
tx_state |
enum | See below. |
tx_state_code |
number | See below. |
detected_confs |
optional number | Detect number of transaction confirmations. Available for Detected state only (and null otherwise). 0 for zero confirmation transaction. |
total_confs |
optional number | Required total number of transaction confirmations before starting processing. Available for Detected state only (and null otherwise). |
Possible tx_state and tx_state_code values:
tx_state |
tx_state_code |
Description |
|---|---|---|
InsufficientAmount |
1 | Output amount does not cover network fee and so is discarded (final state). |
Detected |
2 | Transaction was detected and will be processed after required confirmation count. |
Processing |
3 | Required confirmation count detected and transaction is processing now. |
Done |
4 | Payout is made by the server (final state). |
Server status
Watching server parameters
Method name - subscribe_value / unsubscribe_value. Notification name - subscribed_value.
Send subscribe_value to get the latest value and to subscribe to updates. Send unsubscribe_value to stop receving updates.
Example request:
{
"id": 1,
"method": "subscribe_value",
"params": {
"value": "PegInWalletBalance"
}
}
{
"id": 1,
"method": "unsubscribe_value",
"params": {
"value": "PegInWalletBalance"
}
}
Example response:
{
"id": 1,
"method": "subscribe_value",
"result": {}
}
{
"id": 1,
"method": "unsubscribe_value",
"result": {}
}
Example notification:
{
"method": "subscribed_value",
"params": {
"value": {
"PegInWalletBalance": {
"available": 184900000
}
}
}
}
Input
| Parameter | Type | Description |
|---|---|---|
value |
string | See below |
value can be one of:
| Parameter | Description |
|---|---|
PegInMinAmount |
Get minimum peg-in amount. |
PegInWalletBalance |
Get peg-in wallet balance. |
PegOutMinAmount |
Get minimum peg-out amount. |
PegOutWalletBalance |
Get peg-out wallet balance. |
Output
Empty
Notification
| Parameter | Type | Description |
|---|---|---|
value |
string | See below |
value can be one of PegInMinAmount, PegInWalletBalance, PegOutMinAmount or PegOutWalletBalance:
PegInMinAmount:
| Parameter | Type | Description |
|---|---|---|
min_amount |
number | Minimum allowed peg-in amount. |
PegInWalletBalance:
| Parameter | Type | Description |
|---|---|---|
available |
number | How much L-BTC is available in the hot Liquid Bitcoin wallet (in sats). If the peg-in amount is less than or equal to this amount, it will be paid after 2 confirmations. If the peg-in amount is greater than this amount, it will it will be paid after 102 confirmations. If the bitcoin transaction is not confirmed within 6 hours, the reservation will be released. |
PegOutMinAmount:
| Parameter | Type | Description |
|---|---|---|
min_amount |
number | Minimum allowed peg-out amount. |
PegOutWalletBalance:
| Parameter | Type | Description |
|---|---|---|
available |
number | How much BTC is available in the hot Bitcoin wallet (in sats). If the peg-out amount is less than or equal to this amount, it will be paid after 2 confirmations (around 2 minutes). If the peg-out amount is greater than this amount, it is usually paid within 20-30 minutes. |
Monitoring server status updates
Method name - server_status (update notifications available).
Example request:
{
"id": 1,
"method": "server_status",
"params": null
}
Example response:
{
"id": 1,
"method": "server_status",
"result": {
"elements_fee_rate": 0.000001,
"min_peg_in_amount": 1286,
"min_peg_out_amount": 100000,
"server_fee_percent_peg_in": 0.1,
"server_fee_percent_peg_out": 0.1
}
}
Input
Empty
Output
| Parameter | Type | Description |
|---|---|---|
elements_fee_rate |
number | Internal |
min_peg_in_amount |
number | Minimum amount to send for BTC/L-BTC conversions. |
min_peg_out_amount |
number | Minimum amount to send for L-BTC/BTC conversions. |
server_fee_percent_peg_in |
number | Server fee for Peg-In orders in percents. |
server_fee_percent_peg_out |
number | Server fee for Peg-Out orders in percents. |
Available assets
List all market assets.
Method name - assets.
Example request:
{
"id": 4,
"method": "assets",
"params": {
"all_assets": true,
"embedded_icons": false
}
}
Example response:
{
"id": 4,
"method": "assets",
"result": {
"assets": [
{
"always_show": true,
"asset_id": "144c654344aa716d6f3abcc1ca90e5641e4e2a7f633bc09fe3baf64585819a49",
"contract": null,
"domain": null,
"icon": null,
"icon_url": "https://api-testnet.sideswap.io/assets/icons/144c654344aa716d6f3abcc1ca90e5641e4e2a7f633bc09fe3baf64585819a49.png",
"instant_swaps": false,
"issuance_prevout": null,
"issuer_pubkey": null,
"market_type": null,
"name": "Liquid Bitcoin",
"payjoin": false,
"precision": 8,
"ticker": "L-BTC"
},
{
"always_show": true,
"asset_id": "b612eb46313a2cd6ebabd8b7a8eed5696e29898b87a43bff41c94f51acef9d73",
"contract": {
"entity": {
"domain": "pegx.io"
},
"issuer_pubkey": "0363a0b7136358637e4313df9569597dfb9a89d71cc64248619a5c403e24ec3074",
"name": "PEGx USDt Testnet",
"precision": 8,
"ticker": "USDt",
"version": 0
},
"domain": "pegx.io",
"icon": null,
"icon_url": "https://api-testnet.sideswap.io/assets/icons/b612eb46313a2cd6ebabd8b7a8eed5696e29898b87a43bff41c94f51acef9d73.png",
"instant_swaps": true,
"issuance_prevout": {
"txid": "0d2a690481bf40b700b24458577f1b3ddce0d40d1f1ba013c981bec501752697",
"vout": 3
},
"issuer_pubkey": "0363a0b7136358637e4313df9569597dfb9a89d71cc64248619a5c403e24ec3074",
"market_type": "Stablecoin",
"name": "PEGx USDt Testnet",
"payjoin": true,
"precision": 8,
"ticker": "USDt"
},
{
"always_show": true,
"asset_id": "1f9f9319beeded3aa3751190ec9b2d77df570c3b9e6e84a4aa321c11331e0118",
"contract": {
"entity": {
"domain": "testnet.pegx.io"
},
"issuer_pubkey": "0208a2279847c22a579de226e4867b63e2021a27eff8ce88155e65334994a3ca25",
"name": "SSWP Partners Series B",
"precision": 0,
"ticker": "SSWP",
"version": 0
},
"domain": "testnet.pegx.io",
"domain_agent": "testnet.pegx.io",
"domain_agent_link": "https://testnet.pegx.io",
"icon": null,
"icon_url": "https://api-testnet.sideswap.io/assets/icons/1f9f9319beeded3aa3751190ec9b2d77df570c3b9e6e84a4aa321c11331e0118.png",
"instant_swaps": false,
"issuance_prevout": {
"txid": "02de321c7095e0fdbcadff4c328ef6fabe78fe7ed7dbff490a2e5b3a1f8e779f",
"vout": 3
},
"issuer_pubkey": "0208a2279847c22a579de226e4867b63e2021a27eff8ce88155e65334994a3ca25",
"market_type": "Amp",
"name": "SSWP Partners Series B",
"precision": 0,
"ticker": "SSWP"
},
{
"asset_id": "649f01bd72fbe33a70508e752044a2b0f91cf73612b70e03f337d095daa8b002",
"contract": {
"entity": {
"domain": "pegx.io"
},
"issuer_pubkey": "02969f2588b70238230220f235e65cdce4e0e7c8d1a8b4fd14e860dab7416f3a6d",
"name": "PEGx Test Token Testnet",
"precision": 0,
"ticker": "PXTST",
"version": 0
},
"domain": "pegx.io",
"icon": null,
"icon_url": "https://api-testnet.sideswap.io/assets/icons/649f01bd72fbe33a70508e752044a2b0f91cf73612b70e03f337d095daa8b002.png",
"instant_swaps": null,
"issuance_prevout": {
"txid": "06dedfdcb2a92e59e5ae15d645ae580f24d7186a62f10e75bb9530c1529c7cec",
"vout": 2
},
"issuer_pubkey": "02969f2588b70238230220f235e65cdce4e0e7c8d1a8b4fd14e860dab7416f3a6d",
"market_type": "Token",
"name": "PEGx Test Token Testnet",
"precision": 0,
"ticker": "PXTST"
}
]
}
}
Input
| Parameter | Type | Description |
|---|---|---|
all_assets |
optional bool | List all assets. If true, all assets will be listed (L-BTC, stablecoin, AMP and token). If false, only L-BTC and stablecoin assets will be listed. Default false. |
embedded_icons |
optional bool | Embed asset icons in the response or not (PNG in base64 encoding). Default false. |
Output
| Parameter | Type | Description |
|---|---|---|
assets |
array | Assets list. |
asset_id |
string | Elements Asset ID. |
contract |
optional object | Contact JSON used when the asset was issued. |
icon |
string | Icon in PNG format (base64 encoded). |
icon_url |
string | URL wher asset icon could be downloaded from. |
name |
string | Human readable asset name (for UI only). |
ticker |
string | Ticker symbol (for UI only). |
precision |
number | Precision (digit count after decimal point) to represent amounts (for UI only). |
domain |
optional string | Issuer's domain. |
Swaps API
The swap market operates as a non-custodial exchange for the Liquid Bitcoin network. Clients connect to the server and the server maintains public order books. Limit orders (from makers) and market orders (from takers) are supported. Limit orders can be online or offline. An exchange operation is constructed as a confidential Liquid Bitcoin transaction and settled on the chain.
For online limit orders (maker side), the server requires the list of UTXOs and the receive and change addresses. Clients can then submit an order list.
For offline limit orders (maker side), the server requires a liquid bitcoin transaction with one input and one output. The input must be signed with SIGHASH_SINGLE | ANYONECANPAY hash. The input asset and value and the output asset and value determine the market, trade direction, and price.
For market orders (taker side), the server requires the list of UTXOs and the receive and change addresses, maximum order amount, and trade direction. The server then constructs a PSET (Partially Signed Elements Transaction). More than one market maker can participate in a swap transaction. Online orders can be partially matched. Offline orders can only be fully matched. Online market makers are then requested to sign the PSET. If an online market maker does not sign in time, they will be disconnected and their orders will be temporarily pulled from the order book. Once all maker inputs have been signed (for multi-sig AMP inputs, the server only requires user signatures), the taker receives the quote and has approximately 30 seconds to accept it. The server will repeat this process every 5 seconds, so that takers always have a valid quote.
Hardware wallets are supported (currently Jade only) for offline limit orders and as takers.
Makers pay 0% fee, takers pay 0.2% fee plus a fixed fee to cover the network fee. For asset/asset swaps, the server includes its own L-BTC inputs in the swap transaction to cover the network fee.
The documentation here explains how to use the Swaps API for takers. If you would like to become a market maker, please see the documentation on how to run your own dealer here or contact support.
The actual JSON-RPC method is always "market" in the Swap API. You must specify the desired action in params (e.g., "list_markets": {}", "start_quotes": { ... }"), etc.
Loading available markets
Example request:
{
"id": 1,
"method": "market",
"params": {
"list_markets": {}
}
}
Example response:
{
"id": 1,
"method": "market",
"result": {
"list_markets": {
"markets": [
{
"asset_pair": {
"base": "144c654344aa716d6f3abcc1ca90e5641e4e2a7f633bc09fe3baf64585819a49",
"quote": "b612eb46313a2cd6ebabd8b7a8eed5696e29898b87a43bff41c94f51acef9d73"
},
"fee_asset": "Base",
"type": "Stablecoin"
},
{
"asset_pair": {
"base": "144c654344aa716d6f3abcc1ca90e5641e4e2a7f633bc09fe3baf64585819a49",
"quote": "58af36e1b529b42f3e4ccce812924380058cae18b2ad26c89805813a9db25980"
},
"fee_asset": "Base",
"type": "Stablecoin"
},
{
"asset_pair": {
"base": "58af36e1b529b42f3e4ccce812924380058cae18b2ad26c89805813a9db25980",
"quote": "b612eb46313a2cd6ebabd8b7a8eed5696e29898b87a43bff41c94f51acef9d73"
},
"fee_asset": "Quote",
"type": "Stablecoin"
},
{
"asset_pair": {
"base": "1f9f9319beeded3aa3751190ec9b2d77df570c3b9e6e84a4aa321c11331e0118",
"quote": "144c654344aa716d6f3abcc1ca90e5641e4e2a7f633bc09fe3baf64585819a49"
},
"fee_asset": "Quote",
"type": "Amp"
},
{
"asset_pair": {
"base": "1f9f9319beeded3aa3751190ec9b2d77df570c3b9e6e84a4aa321c11331e0118",
"quote": "b612eb46313a2cd6ebabd8b7a8eed5696e29898b87a43bff41c94f51acef9d73"
},
"fee_asset": "Quote",
"type": "Amp"
},
{
"asset_pair": {
"base": "649f01bd72fbe33a70508e752044a2b0f91cf73612b70e03f337d095daa8b002",
"quote": "144c654344aa716d6f3abcc1ca90e5641e4e2a7f633bc09fe3baf64585819a49"
},
"fee_asset": "Quote",
"type": "Token"
}
]
}
}
}
Example notifications:
{
"method": "market",
"params": {
"market_added": {
"market": {
"asset_pair": {
"base": "649f01bd72fbe33a70508e752044a2b0f91cf73612b70e03f337d095daa8b002",
"quote": "144c654344aa716d6f3abcc1ca90e5641e4e2a7f633bc09fe3baf64585819a49"
},
"fee_asset": "Quote",
"type": "Token"
}
}
}
}
{
"method": "market",
"params": {
"market_removed": {
"asset_pair": {
"base": "649f01bd72fbe33a70508e752044a2b0f91cf73612b70e03f337d095daa8b002",
"quote": "144c654344aa716d6f3abcc1ca90e5641e4e2a7f633bc09fe3baf64585819a49"
}
}
}
}
Input
Empty
Output
| Parameter | Type | Description |
|---|---|---|
markets |
array | List of available markets |
asset_pair |
object | Available market asset pair |
fee_asset |
string | See below |
type |
string | See below |
Possible fee_asset values:
fee_asset |
Description |
|---|---|
Base |
Server fee is paid in the base asset |
Quote |
Server fee is paid in the quote asset |
Possible type values:
type |
Description |
|---|---|
Stablecoin |
Stablecoin market |
Amp |
AMP market |
Token |
Token market |
Notification
Notification is sent from the server when a market is added or removed. It is currently only implemented for token markets.
Same values are used.
Starting quotes
Once the market, amount and trade direction have been selected, the taker can start receiving quotes.
Example request:
{
"id": 1,
"method": "market",
"params": {
"start_quotes": {
"asset_pair": {
"base": "144c654344aa716d6f3abcc1ca90e5641e4e2a7f633bc09fe3baf64585819a49",
"quote": "b612eb46313a2cd6ebabd8b7a8eed5696e29898b87a43bff41c94f51acef9d73"
},
"asset_type": "Base",
"amount": 100000,
"trade_dir": "Sell",
"utxos": [
{
"txid": "3735f0476f7faca89d96e131e8716677fae7a5467a806a838fbfa0f774e12675",
"vout": 0,
"asset": "144c654344aa716d6f3abcc1ca90e5641e4e2a7f633bc09fe3baf64585819a49",
"asset_bf": "35009f539bff708e2516a03528e378a5e6802bc72f87dab03331cc159825d5de",
"value": 100000,
"value_bf": "17a1759dc0f2e4abf76051302c5b8efd90760995bb7fbb0f6d797c988beac74d",
"redeem_script": null
}
],
"receive_address": "tlq1qqdgrc4sntdyg9qen9c4d52e3r6unn0jgv8qgz0fu97fdgeydd2k853xy44n0074cxw32ef3er26y2wu6ddpw7rf4zgk98jcm0",
"change_address": "tlq1qqtexwdwcndn7v3f305w289wr0w69fs2k5kqt7xj4jarvxye3a0menjpshz3yxzvmdn7hq77scanxkf59py6l6jth3pm82ylzy"
}
}
}
Example response:
{
"id": 1,
"method": "market",
"result": {
"start_quotes": {
"fee_asset": "Base",
"quote_sub_id": 1738739962334
}
}
}
Example notifications:
{
"method": "market",
"params": {
"quote": {
"amount": 100000,
"asset_pair": {
"base": "144c654344aa716d6f3abcc1ca90e5641e4e2a7f633bc09fe3baf64585819a49",
"quote": "b612eb46313a2cd6ebabd8b7a8eed5696e29898b87a43bff41c94f51acef9d73"
},
"asset_type": "Base",
"quote_sub_id": 1738739962334,
"status": {
"Success": {
"base_amount": 99721,
"fixed_fee": 80,
"quote_amount": 10121681500,
"quote_id": 1738739962336,
"server_fee": 199,
"ttl": 29697
}
},
"trade_dir": "Sell"
}
}
}
{
"method": "market",
"params": {
"quote": {
"amount": 10000000,
"asset_pair": {
"base": "144c654344aa716d6f3abcc1ca90e5641e4e2a7f633bc09fe3baf64585819a49",
"quote": "b612eb46313a2cd6ebabd8b7a8eed5696e29898b87a43bff41c94f51acef9d73"
},
"asset_type": "Base",
"quote_sub_id": 1738739758669,
"status": {
"LowBalance": {
"available": 100000,
"base_amount": 9979960,
"fixed_fee": 80,
"quote_amount": 975193039771,
"server_fee": 19960
}
},
"trade_dir": "Sell"
}
}
}
{
"method": "market",
"params": {
"quote": {
"amount": 10,
"asset_pair": {
"base": "144c654344aa716d6f3abcc1ca90e5641e4e2a7f633bc09fe3baf64585819a49",
"quote": "b612eb46313a2cd6ebabd8b7a8eed5696e29898b87a43bff41c94f51acef9d73"
},
"asset_type": "Base",
"quote_sub_id": 1738740311060,
"status": {
"Error": {
"error_msg": "No matching orders"
}
},
"trade_dir": "Sell"
}
}
}
Input
| Parameter | Type | Description |
|---|---|---|
asset_pair |
object | Asset pair of the selected market |
asset_type |
string | Which asset is being bought or sold, can be Base or Quote |
trade_dir |
string | Trade direction. Can be Sell or Buy |
amount |
number | Asset amount. The upper limit of the send or receive amount. The actual quote amount may be lower if the order book is smaller. |
utxos |
array | List of UTXO objects. Can be empty if you just want to receive the expected amount. See below for details. |
receive_address |
string | The address to receive the output asset |
change_address |
string | The address to receive the input asset change |
UTXO object. Only P2WPKH (Native SegWit), P2SH-P2WPKH (Nested SegWit), and AMP multi-sig (Nested SegWit) UTXOs are supported. Legacy UTXOs and taproot UTXOs are not supported.
| Parameter | Type | Description |
|---|---|---|
txid |
string | Transaction ID of the UTXO |
vout |
number | Transaction output index |
asset |
string | Asset ID of the UTXO |
value |
number | UTXO value in sats |
asset_bf |
string | UTXO's asset blinding factor |
value_bf |
string | UTXO's value blinding factor |
redeem_script |
optional string | UTXO's redeem script. |
Example redeem_script for P2SH-P2WPKH UTXO: 00142f76ddf91fe5ea5abd1bfc3ffa7d7bb36b2e6ab4. Must be null for Native SegWit (P2WPKH) UTXOs.
Output
| Parameter | Type | Description |
|---|---|---|
fee_asset |
string | Fee asset of the selected market |
quote_sub_id |
number | Unique id of the quote subscribe. It can be used to discard older quotes. |
Notification
Notifications are sent from the server when a new quote is received.
| Parameter | Type | Description |
|---|---|---|
amount |
number | The value used in the request |
asset_pair |
object | The value used in the request |
asset_type |
string | The value used in the request |
trade_dir |
string | The value used in the request |
quote_sub_id |
number | The value from the response |
status |
object | See below |
Success status object.
The swap transaction was successfully constructed and signed by the makers.
| Parameter | Type | Description |
|---|---|---|
quote_id |
number | Quote id |
base_amount |
number | The base amount (total of from all the makers) |
quote_amount |
number | The quote asset amount (the sum of all makers) |
server_fee |
number | The fee paid to the server. Normally 0.2% of the fee asset |
fixed_fee |
number | The fixed fee charged by the server (used to cover the network fee). The fixed fee charged by the server and used to cover the network fee. Does not depend on the amount in the swap. |
ttl |
number | The amount of time in milliseconds while the quote can be accepted (about 25..30 seconds) |
LowBalance status object.
There are not enough UTXOs to cover the requested amount.
| Parameter | Type | Description |
|---|---|---|
available |
number | The sum of the UTXOs. |
base_amount |
number | Same as in the Success status |
quote_amount |
number | Same as in the Success status |
server_fee |
number | Same as in the Success status |
fixed_fee |
number | Same as in the Success status |
Error status object.
A quote can't be constructed with the requested amount.
error_msg | string | Error message.
Actual deliver/receive taker amounts can be calculated using this table.
The total fee (server_fee + fixed_fee) is always paid by the taker. The maker fee is 0.
The fee asset can be either the base asset or the quote asset.
| Base asset | Fee asset | Deliver amount | Receive amount |
|---|---|---|---|
| Sell | Base | base_amount + total_fee |
quote_amount |
| Sell | Quote | base_amount |
quote_amount - total_fee |
| Buy | Base | quote_amount |
base_amount - total_fee |
| Buy | Quote | quote_amount + total_fee |
base_amount |
Where total_fee = server_fee + fixed_fee.
Example calculation for a quote from the L-BTC/USDt market, where the client is trying to exchange 0.001 L-BTC to USDt.
| Field | Value | Comment |
|---|---|---|
asset_type |
Base |
User entered the base asset amount (L-BTC here) |
amount |
100000 | User entered 0.001 L-BTC |
trade_dir |
Sell |
User wants to sell L-BTC |
fee_asset |
Base |
The fee asset is the base asset in this market (L-BTC here) |
base_amount |
99721 | Makers will buy 99721 sats in total |
quote_amount |
10121681500 | Makers will sell 10121681500 sats in total |
fixed_fee |
80 | The fixed fee is 80 sats |
server_fee |
199 | The server's fee is 199 sats (99721*0.002 after rounding) |
total_fee |
279 | server_fee + fixed_fee |
deliver_amount |
100000 | base_amount + total_fee |
receive_amount |
10121681500 | quote_amount |
Because the user is selling the base asset and fee asset is Base in this market, the first line from the deliver/receive table is used.
Receiving the quote PSET
Once the quote is accepted by the user, the PSET should be downloaded from the server for sign.
Example request:
{
"id": 1,
"method": "market",
"params": {
"get_quote": {
"quote_id": 1737044674239
}
}
}
Example response:
{
"id": 1,
"method": "market",
"result": {
"get_quote": {
"pset": "cHNldP8BAgQ...QQAAA==",
"ttl": 17414
}
}
}
Input
| Parameter | Type | Description |
|---|---|---|
quote_id |
number | Quote id |
Output
| Parameter | Type | Description |
|---|---|---|
pset |
string | Base64 encoded unsigned PSET |
ttl |
number | The amount of time in milliseconds while the quote can be accepted |
Signing the quote PSET
After the PSET is downloaded from the server, it should be signed.
GA_psbt_get_details and GA_psbt_sign can be used with GDK.
Example request:
{
"id": 1,
"method": "market",
"params": {
"taker_sign": {
"quote_id": 1737044674239,
"pset": "cHNldP8BAgQ...QQAAA=="
}
}
}
Example response:
{
"id": 1,
"method": "market",
"result": {
"taker_sign": {
"txid": "<SWAP_TXID>",
}
}
}
Input
| Parameter | Type | Description |
|---|---|---|
quote_id |
number | Quote id |
pset |
string | PSET with signed taker inputs |
Output
| Parameter | Type | Description |
|---|---|---|
txid |
string | Swap transaction hash |
Subscribing to market data stream
Use to get a data list of close, high, low and open values. After subscribing server will start sending update notifications whenever market data changes or becomes unavailable.
Example request:
{
"id": 1,
"method": "market",
"params": {
"chart_sub": {
"asset_pair": {
"base": "144c654344aa716d6f3abcc1ca90e5641e4e2a7f633bc09fe3baf64585819a49",
"quote": "b612eb46313a2cd6ebabd8b7a8eed5696e29898b87a43bff41c94f51acef9d73"
}
}
}
}
Example response:
{
"id": 1,
"method": "market",
"result": {
"chart_sub": {
"data": [
{
"close": 100469.56007393716,
"high": 102200.37405336903,
"low": 94807.58951292247,
"open": 102200.37405336903,
"time": "2025-02-03",
"volume": 0.00021202
},
{
"close": 101263.90499695855,
"high": 101263.90499695855,
"low": 100469.56007393716,
"open": 100469.56007393716,
"time": "2025-02-04",
"volume": 0.00100281
}
]
}
}
}
Example notification:
{
"method": "market",
"params": {
"chart_update": {
"asset_pair": {
"base": "144c654344aa716d6f3abcc1ca90e5641e4e2a7f633bc09fe3baf64585819a49",
"quote": "b612eb46313a2cd6ebabd8b7a8eed5696e29898b87a43bff41c94f51acef9d73"
},
"update": {
"close": 99345.41099510375,
"high": 101263.90499695855,
"low": 98768.18869167122,
"open": 100469.56007393716,
"time": "2025-02-04",
"volume": 0.00801925
}
}
}
}
Input
| Parameter | Type | Description |
|---|---|---|
asset_pair |
object | Asset pair of the selected market |
Output
| Parameter | Type | Description |
|---|---|---|
data |
list | List of json objects |
close |
number | Close value |
high |
number | High value |
low |
number | Low value |
open |
number | Open value |
time |
string | Date |
volume |
number | Volume value |
Notification
Notification is sent from the server when there are market data changes.
| Parameter | Type | Description |
|---|---|---|
asset_pair |
object | Asset pair of the selected market |
update |
object | Object with update |
close |
number | Close value |
high |
number | High value |
low |
number | Low value |
open |
number | Open value |
time |
string | Date |
volume |
number | Volume value |
Unsubscribing from market data stream
Use this method to unsubscribe from the market data stream.
Example request:
{
"id": 1,
"method": "market",
"params": {
"chart_unsub": {
"asset_pair": {
"base": "144c654344aa716d6f3abcc1ca90e5641e4e2a7f633bc09fe3baf64585819a49",
"quote": "b612eb46313a2cd6ebabd8b7a8eed5696e29898b87a43bff41c94f51acef9d73"
}
}
}
}
Example response:
{
"id": 1,
"method": "market",
"result": {
"chart_unsub": {}
}
}
Input
| Parameter | Type | Description |
|---|---|---|
asset_pair |
object | Asset pair of the selected market |
Output
Empty
PayJoin
PayJoin API can be used to make transactions when your wallet does not have L-BTC UTXOs for network fees. SideSwap server provides L-BTC UTXOs (P2WPKH) in exchange for some selected assets. Currently USDt and EURx are accepted.
It works as follows:
- Client initiates a new PayJoin request specifying the selected
asset_id(which the server accepts). - Server returns list of confidential L-BTC UTXOs with blinding factors,
priceandfixed_feefor asset fee calculation and two confidential addresses. - Client constructs PSET with own inputs and outputs.
- Client sends unsigned PSET to Server.
- Server verifies PSET and returns PSET with signed L-BTC inputs.
- Client signs its inputs and sends the transaction to the network.
An optional output is added to the server address for the L-BTC change (can be omitted if there is no L-BTC change). A mandatory output is added to the other server address with the asset fee. Outputs are optionally blinded.
Server verifies two own outputs like this:
- Optional L-BTC change is calculated as sum of all L-BTC inputs minus network fee.
- Mandatory asset output must be at least
network_fee*price+fixed_fee(some tolerance for rounding errors is allowed).
Where:
priceis the indicative price of L-BTC in USDt or EURx (e.g. 41234.56) returned by the server.fixed_feeis fixed fee in selected asset (currently equivalent of $0.04), returned by the server.network_feeis the network fee of the transaction (selected by the client).
All communication with the server is done by sending POST requests to the PayJoin API endpoint:
- Production server:
https://api.sideswap.io/payjoin - Testnet server:
https://api-testnet.sideswap.io/payjoin
Failed requests return an HTTP response with status 400 (Bad Request) and a JSON message in this format:
{"error":"asset b612eb46313a2cd6ebabd8b7a8eed5696e29898b87a43bff41c94f51acef9d74 is not allowed"}
Reference PayJoin client implementation (in Rust) from the SideSwap Client available at our GitHub repo.
Get accepted assets
Get a list of accepted assets (currently USDt, EURx, DePix and MEX).
Example request:
{
"accepted_assets": {}
}
Example response:
{
"accepted_assets": {
"accepted_asset": [
{
"asset_id": "485ff8a902ad063bd8886ef8cfc0d22a068d14dcbe6ae06cf3f904dc581fbd2b"
},
{
"asset_id": "a5de979bc31dc731fa94b3661ae19c1e20cd067642c69798cad9011094a26f60"
},
{
"asset_id": "b612eb46313a2cd6ebabd8b7a8eed5696e29898b87a43bff41c94f51acef9d73"
},
{
"asset_id": "58af36e1b529b42f3e4ccce812924380058cae18b2ad26c89805813a9db25980"
}
]
}
}
Input
Empty
Output
| Parameter | Type | Description |
|---|---|---|
asset_id |
string | Asset ID of the accepted asset. |
Start a new PayJoin transaction
This method should be used to start a new PayJoin transaction.
Example request:
{
"start": {
"asset_id": "b612eb46313a2cd6ebabd8b7a8eed5696e29898b87a43bff41c94f51acef9d73",
"user_agent": "Test UA"
}
}
Example response:
{
"start": {
"order_id": "LAjQoEHG0vlGoHIXUXnH",
"expires_at": 1738845699823,
"price": 98367.0,
"fixed_fee": 4000000,
"fee_address": "tlq1qqdwnjna55cxyzvh46awtdzp6af4y7gn058swynwn5jgqa6expavaascw33nhdqc5nscm3rpd9kcy33k0fplgjzgykzj5d8r2w",
"change_address": "tlq1qqd409fxgut7te3spyyn452xn8gcd90zy7tdkf5gtrt7xkwgkksz4qk3xezpzk2nsjydl5z0pqu8ft7uhp0l4wvfgdl2ewuahu",
"utxos": [
{
"txid": "f3b3f73a502c3b6eff173e568f618c4f2cffb643b377f13ede0df479ff59b46b",
"vout": 3,
"script_pub_key": "0014788a4ebb27ae3fcd89bd754ac1aa90d68320977d",
"asset_id": "144c654344aa716d6f3abcc1ca90e5641e4e2a7f633bc09fe3baf64585819a49",
"value": 99442,
"asset_bf": "4bb35575d219d8db6afcd2998b4f6d5c74cb583289caae2ab92a057215c1ac63",
"value_bf": "89cc2b059166e72e2bdbdaee2d0e46f134630191e1129e248d1c63c6f950a42e",
"asset_commitment": "0bd7d9b026878192f215ca3bf4326ca41818abd18d28e9a5958f7955938c0f112a",
"value_commitment": "085649ac89fe748d90377198609b640421174c77e5a215e5127f84240a92cf87ee"
}
]
}
}
Input
| Parameter | Type | Description |
|---|---|---|
asset_id |
string | Selected asset ID. |
user_agent |
string | Arbitrary user agent string. |
Output
| Parameter | Type | Description |
|---|---|---|
order_id |
string | Order ID. |
user_agent |
string | Arbitrary user agent string. |
expires_at |
number | Timestamp when order will expire. |
price |
number | The L-BTC price in the selected asset that should be used to calculate the server fee in the selected asset. |
fixed_fee |
number | The fixed asset fee that should be used to calculate the server fee in the selected asset. |
fee_address |
string | Confidential address for server asset output. |
change_address |
string | Confidential address for L-BTC change output. |
utxos |
array | List of L-BTC UTXOs (P2WPKH, Native Segwit). |
Sign PSET
This method should be used to get the signed PSET.
Example request:
{
"order_id": "",
"pset": "PSET..."
}
Example response:
{
"pset": "PSET..."
}
Input
| Parameter | Type | Description |
|---|---|---|
order_id |
string | Order ID. |
pset |
string | Unsigned PSET in base64 encoding. |
Output
| Parameter | Type | Description |
|---|---|---|
pset |
string | PSET with signed L-BTC inputs (in base64 encoding). |