Skip to main content
POST
/
simple
Simple swap
curl --request POST \
  --url https://api.leokit.dev/simple \
  --header 'Api-Key: <api-key>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "from_asset": "ETH.ETH",
  "to_asset": "ARB.USDC-0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
  "amount": "0.5",
  "from_address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0",
  "to_address": "0x1234567890AbcdEF1234567890aBcdef12345678",
  "slippage_bps": "100"
}
'
import requests

url = "https://api.leokit.dev/simple"

payload = {
"from_asset": "ETH.ETH",
"to_asset": "ARB.USDC-0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
"amount": "0.5",
"from_address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0",
"to_address": "0x1234567890AbcdEF1234567890aBcdef12345678",
"slippage_bps": "100"
}
headers = {
"Api-Key": "<api-key>",
"Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.text)
const options = {
method: 'POST',
headers: {'Api-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
from_asset: 'ETH.ETH',
to_asset: 'ARB.USDC-0xaf88d065e77c8cC2239327C5EDb3A432268e5831',
amount: '0.5',
from_address: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0',
to_address: '0x1234567890AbcdEF1234567890aBcdef12345678',
slippage_bps: '100'
})
};

fetch('https://api.leokit.dev/simple', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));
<?php

$curl = curl_init();

curl_setopt_array($curl, [
CURLOPT_URL => "https://api.leokit.dev/simple",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'from_asset' => 'ETH.ETH',
'to_asset' => 'ARB.USDC-0xaf88d065e77c8cC2239327C5EDb3A432268e5831',
'amount' => '0.5',
'from_address' => '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0',
'to_address' => '0x1234567890AbcdEF1234567890aBcdef12345678',
'slippage_bps' => '100'
]),
CURLOPT_HTTPHEADER => [
"Api-Key: <api-key>",
"Content-Type: application/json"
],
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
package main

import (
"fmt"
"strings"
"net/http"
"io"
)

func main() {

url := "https://api.leokit.dev/simple"

payload := strings.NewReader("{\n \"from_asset\": \"ETH.ETH\",\n \"to_asset\": \"ARB.USDC-0xaf88d065e77c8cC2239327C5EDb3A432268e5831\",\n \"amount\": \"0.5\",\n \"from_address\": \"0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0\",\n \"to_address\": \"0x1234567890AbcdEF1234567890aBcdef12345678\",\n \"slippage_bps\": \"100\"\n}")

req, _ := http.NewRequest("POST", url, payload)

req.Header.Add("Api-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")

res, _ := http.DefaultClient.Do(req)

defer res.Body.Close()
body, _ := io.ReadAll(res.Body)

fmt.Println(string(body))

}
HttpResponse<String> response = Unirest.post("https://api.leokit.dev/simple")
.header("Api-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"from_asset\": \"ETH.ETH\",\n \"to_asset\": \"ARB.USDC-0xaf88d065e77c8cC2239327C5EDb3A432268e5831\",\n \"amount\": \"0.5\",\n \"from_address\": \"0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0\",\n \"to_address\": \"0x1234567890AbcdEF1234567890aBcdef12345678\",\n \"slippage_bps\": \"100\"\n}")
.asString();
require 'uri'
require 'net/http'

url = URI("https://api.leokit.dev/simple")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Api-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"from_asset\": \"ETH.ETH\",\n \"to_asset\": \"ARB.USDC-0xaf88d065e77c8cC2239327C5EDb3A432268e5831\",\n \"amount\": \"0.5\",\n \"from_address\": \"0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0\",\n \"to_address\": \"0x1234567890AbcdEF1234567890aBcdef12345678\",\n \"slippage_bps\": \"100\"\n}"

response = http.request(request)
puts response.read_body
{
  "quote_id": "01936b4a-7c8e-7890-abcd-ef1234567890",
  "protocol": "chainflip",
  "deposit_address": "0x8a3c1f2d4e5f67890abcdef1234567890abcdef1",
  "amount": "0.5",
  "amount_raw": "500000000000000000",
  "decimals": 18,
  "from_asset": "ETH.ETH",
  "to_asset": "ARB.USDC-0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
  "network": "ETH",
  "expected_amount_out": 499.5,
  "expected_amount_out_usd": 499.5,
  "total_swap_seconds": 120,
  "fees": [
    {
      "type": "Network Fee",
      "asset": "ETH",
      "amount": 0.001,
      "usd": 2.5
    }
  ],
  "payment_uri": "ethereum:0x8a3c1f2d4e5f67890abcdef1234567890abcdef1@1?value=500000000000000000",
  "qr_url": "https://cdn.leokit.dev/qr/01936b4a-7c8e-7890-abcd-ef1234567890.png",
  "expires_at": 1707400000
}
{
"message": "Missing required params: from_asset, to_asset, amount, from_address, to_address",
"code": "MISSING_PARAMS"
}
{
"message": "No quotes available for this pair",
"code": "NO_QUOTES"
}
{
"message": "<string>",
"code": "<string>"
}

How It Works

1. POST /leokit/simple     → Quotes Chainflip & NEAR, picks best, returns deposit + QR
2. User scans QR or sends  → Sends funds to the deposit address
3. POST /leokit/status     → Poll with quote_id for swap completion
Compared to the standard multi-step flow (/quote/deposit), this reduces two API calls to one. Only works with deposit-address-based protocols (Chainflip and NEAR).

Payment URI Standards

The payment_uri follows the wallet standard for the source chain:
Source ChainStandardExample
BTC, LTC, DOGE, DASHBIP-21bitcoin:bc1q...?amount=0.5
ETH, ARB, BASE (native)EIP-681ethereum:0x...@1?value=500000000000000000
ETH, ARB, BASE (ERC20)EIP-681ethereum:0xTOKEN@1/transfer?address=0x...&uint256=
SOL (native)Solana Paysolana:So1...?amount=2
OtherFallbackPlain deposit address

Example: BTC to ETH

curl -X POST https://api.leokit.dev/leokit/simple \
  -H "Content-Type: application/json" \
  -H "Api-Key: YOUR_API_KEY" \
  -d '{
    "from_asset": "BTC.BTC",
    "to_asset": "ETH.ETH",
    "amount": "0.01",
    "from_address": "bc1q...",
    "to_address": "0x1234567890AbcdEF1234567890aBcdef12345678"
  }'

Errors

StatusCodeDescription
400INVALID_ASSETfrom_asset or to_asset is malformed or not in the supported list
400INVALID_ADDRESSfrom_address or to_address not valid for the source/destination chain
400UNSUPPORTED_PAIRNo deposit-address-based route (Chainflip/NEAR) available for the pair
401INVALID_API_KEYMissing or invalid Api-Key header
404NO_QUOTE_AVAILABLEAll deposit-address protocols rejected the pair
500INTERNAL_ERRORQuote or deposit generation failed unexpectedly
See the error codes catalog for the full list.

Authorizations

Api-Key
string
header
required

Demo API-Key (Sandbox): 7037d2b3-9c76-4f62-b730-c544f7570fa4

Body

application/json

Request body for /simple. One-call swap endpoint for deposit-address protocols.

from_asset
string
required

Source asset identifier (CHAIN.SYMBOL-ADDRESS).

Example:

"ETH.ETH"

to_asset
string
required

Destination asset identifier (CHAIN.SYMBOL-ADDRESS).

Example:

"ARB.USDC-0xaf88d065e77c8cC2239327C5EDb3A432268e5831"

amount
string
required

Human-readable amount to swap.

Example:

"0.5"

from_address
string
required

Sender address on the source chain (used as refund address).

Example:

"0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0"

to_address
string
required

Recipient address on the destination chain.

Example:

"0x1234567890AbcdEF1234567890aBcdef12345678"

slippage_bps
string

Slippage tolerance in basis points. Defaults to 150 (1.5%).

Example:

"100"

Response

Simple swap response with quote, deposit address, and QR code.

Response from /simple containing quote, deposit address, and QR code.

quote_id
string<uuid>
required

Quote identifier for tracking via /status.

protocol
enum<string>
required

Protocol selected (always chainflip or near).

Available options:
chainflip,
near
deposit_address
string
required

Address to send funds to.

amount
string
required

Human-readable amount to send.

amount_raw
string
required

Amount in smallest unit (wei, sats, etc.).

decimals
integer
required

Decimal places for the source asset.

from_asset
string
required

Source asset identifier.

to_asset
string
required

Destination asset identifier.

network
string
required

Source chain short name (e.g. ETH, BTC).

expected_amount_out
number
required

Expected output amount (human-readable).

payment_uri
string
required

Chain-specific payment URI (BIP-21, EIP-681, or Solana Pay).

qr_url
string
required

CDN URL of a QR code PNG encoding the payment_uri.

expected_amount_out_usd
number | null

Expected output in USD.

total_swap_seconds
integer | null

Estimated swap time in seconds.

fees
object[]

Fee breakdown.

expires_at
integer<int64> | null

Unix timestamp (seconds) when the deposit channel expires.