Quote a swap and build its transaction
Quotes a swap against the current registered maker books and, when signer is given, builds the unsigned transaction that executes it.
- Without
signer: a quote only.quoteResponseis filled,transactionisnull, and nothing touches RPC — cheap enough to call on every input change. The caller’s own maker books (if any) cannot be excluded from such a quote. - With
signer: the same quote plustransaction, base64-encoded and unsigned, for the taker to sign and send. The quote and the transaction come from one run of the matching engine over one book list, so they cannot disagree.
The swapMode parameter controls how size is interpreted:
- Omitted (default):
sizeis always in base tokens. MaxAmountIn:sizeis the maximum input amount (buy → quote tokens, sell → base tokens).MinAmountOut:sizeis the minimum output amount (buy → base tokens, sell → quote tokens).
A size the book cannot cover is refused with INSUFFICIENT_LIQUIDITY; the error carries the size that could be filled. The engine mirrors the on-chain matching engine to the atom.
curl --request POST \
--url https://api.archer.exchange/v1/order/swap \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"market": "u8tnfCb1JSSghuNFquQ2beStYgAN1kmd1f1Lhxbaec4",
"maxSlippageBps": 1,
"size": "<string>",
"accountOwner": "<string>",
"platform": "self",
"preflight": false,
"priorityFeeMicroLamports": 50000,
"signer": "<string>",
"withInstructions": false
}
'import requests
url = "https://api.archer.exchange/v1/order/swap"
payload = {
"market": "u8tnfCb1JSSghuNFquQ2beStYgAN1kmd1f1Lhxbaec4",
"maxSlippageBps": 1,
"size": "<string>",
"accountOwner": "<string>",
"platform": "self",
"preflight": False,
"priorityFeeMicroLamports": 50000,
"signer": "<string>",
"withInstructions": False
}
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
market: 'u8tnfCb1JSSghuNFquQ2beStYgAN1kmd1f1Lhxbaec4',
maxSlippageBps: 1,
size: '<string>',
accountOwner: '<string>',
platform: 'self',
preflight: false,
priorityFeeMicroLamports: 50000,
signer: '<string>',
withInstructions: false
})
};
fetch('https://api.archer.exchange/v1/order/swap', 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.archer.exchange/v1/order/swap",
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([
'market' => 'u8tnfCb1JSSghuNFquQ2beStYgAN1kmd1f1Lhxbaec4',
'maxSlippageBps' => 1,
'size' => '<string>',
'accountOwner' => '<string>',
'platform' => 'self',
'preflight' => false,
'priorityFeeMicroLamports' => 50000,
'signer' => '<string>',
'withInstructions' => false
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <api-key>"
],
]);
$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.archer.exchange/v1/order/swap"
payload := strings.NewReader("{\n \"market\": \"u8tnfCb1JSSghuNFquQ2beStYgAN1kmd1f1Lhxbaec4\",\n \"maxSlippageBps\": 1,\n \"size\": \"<string>\",\n \"accountOwner\": \"<string>\",\n \"platform\": \"self\",\n \"preflight\": false,\n \"priorityFeeMicroLamports\": 50000,\n \"signer\": \"<string>\",\n \"withInstructions\": false\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-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.archer.exchange/v1/order/swap")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"market\": \"u8tnfCb1JSSghuNFquQ2beStYgAN1kmd1f1Lhxbaec4\",\n \"maxSlippageBps\": 1,\n \"size\": \"<string>\",\n \"accountOwner\": \"<string>\",\n \"platform\": \"self\",\n \"preflight\": false,\n \"priorityFeeMicroLamports\": 50000,\n \"signer\": \"<string>\",\n \"withInstructions\": false\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.archer.exchange/v1/order/swap")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"market\": \"u8tnfCb1JSSghuNFquQ2beStYgAN1kmd1f1Lhxbaec4\",\n \"maxSlippageBps\": 1,\n \"size\": \"<string>\",\n \"accountOwner\": \"<string>\",\n \"platform\": \"self\",\n \"preflight\": false,\n \"priorityFeeMicroLamports\": 50000,\n \"signer\": \"<string>\",\n \"withInstructions\": false\n}"
response = http.request(request)
puts response.read_body{
"addressLookupTables": [
"<string>"
],
"quoteResponse": {
"inAmount": "150.600000",
"inputMint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
"outAmount": "1.000000000",
"outputMint": "So11111111111111111111111111111111111111112",
"priceImpactPct": "0.0332",
"slippageBps": 50,
"swapMode": "MaxAmountIn",
"totalFee": {
"builderFee": "0.000000",
"protocolFee": "0.060000"
}
},
"swapMode": "MaxAmountIn",
"transaction": "<string>",
"instructions": {
"addressLookupTables": [
"<string>"
],
"computeBudgetInstructions": [
{
"accounts": [
{
"isSigner": true,
"isWritable": true,
"pubkey": "<string>"
}
],
"data": "<string>",
"programId": "<string>"
}
],
"instructions": [
{
"accounts": [
{
"isSigner": true,
"isWritable": true,
"pubkey": "<string>"
}
],
"data": "<string>",
"programId": "<string>"
}
],
"signer": "<string>"
}
}Authorizations
Body
Base58-encoded market address.
"u8tnfCb1JSSghuNFquQ2beStYgAN1kmd1f1Lhxbaec4"
Maximum allowed slippage in basis points.
x >= 0Trade side.
buy, sell Amount to trade (decimal string). Interpretation depends on swapMode.
The wallet that owns the ArcherAccount this request acts through. With platform it derives the account PDA server-side — you never handle a PDA. Omit for a plain wallet-owned book. Replaces the earlier archerAccount field, which is no longer read.
Platform namespace for accountOwner. Ignored unless accountOwner is set.
self, treadfi Simulate the built transaction before returning it, and reject with the program's reason if it would fail (insufficient balance, slippage, liquidity gone, unauthorised signer). Off by default: a transaction is otherwise returned whether or not the signer could land it right now, which callers that build at quote time rely on. Ignored without signer.
Priority fee for the transaction's compute-budget instruction, in micro-lamports per compute unit. Omitted → the server default.
50000
The wallet that signs the swap: the taker, or with accountOwner the account's owner or delegate. Omit for a quote only: the response then carries quoteResponse and no transaction, and the caller's own maker books (if any) cannot be excluded from the quote. Existing clients may keep sending it as takerAddress; send one name only.
Controls how size is interpreted. When omitted, size is in base tokens.
MaxAmountIn, MinAmountOut Also return the unsigned instructions under instructions, for composing your own transaction instead of signing ours. Omitted or false leaves the response exactly as it was.
Response
The quote, and the transaction when a taker was named.
A swap quote and, when a taker was named, the unsigned transaction built from it. quoteResponse comes from the same engine run as the transaction.
Address lookup tables the transaction references. None are configured; always empty today.
A swap quote. Amounts are what actually leaves and enters the taker's wallet — protocol and builder fees and any Token-2022 transfer fees included — computed by the same engine, over the same maker books in the same order, that POST /v1/orders/build executes.
Show child attributes
Show child attributes
The effective mode, including the default applied when swapMode was omitted.
MaxAmountIn, MinAmountOut Base64-encoded unsigned Solana transaction for the taker to sign and submit. null when the request carried no signer.
Unsigned instructions, present only when the request set withInstructions.
Show child attributes
Show child attributes
curl --request POST \
--url https://api.archer.exchange/v1/order/swap \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"market": "u8tnfCb1JSSghuNFquQ2beStYgAN1kmd1f1Lhxbaec4",
"maxSlippageBps": 1,
"size": "<string>",
"accountOwner": "<string>",
"platform": "self",
"preflight": false,
"priorityFeeMicroLamports": 50000,
"signer": "<string>",
"withInstructions": false
}
'import requests
url = "https://api.archer.exchange/v1/order/swap"
payload = {
"market": "u8tnfCb1JSSghuNFquQ2beStYgAN1kmd1f1Lhxbaec4",
"maxSlippageBps": 1,
"size": "<string>",
"accountOwner": "<string>",
"platform": "self",
"preflight": False,
"priorityFeeMicroLamports": 50000,
"signer": "<string>",
"withInstructions": False
}
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
market: 'u8tnfCb1JSSghuNFquQ2beStYgAN1kmd1f1Lhxbaec4',
maxSlippageBps: 1,
size: '<string>',
accountOwner: '<string>',
platform: 'self',
preflight: false,
priorityFeeMicroLamports: 50000,
signer: '<string>',
withInstructions: false
})
};
fetch('https://api.archer.exchange/v1/order/swap', 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.archer.exchange/v1/order/swap",
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([
'market' => 'u8tnfCb1JSSghuNFquQ2beStYgAN1kmd1f1Lhxbaec4',
'maxSlippageBps' => 1,
'size' => '<string>',
'accountOwner' => '<string>',
'platform' => 'self',
'preflight' => false,
'priorityFeeMicroLamports' => 50000,
'signer' => '<string>',
'withInstructions' => false
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <api-key>"
],
]);
$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.archer.exchange/v1/order/swap"
payload := strings.NewReader("{\n \"market\": \"u8tnfCb1JSSghuNFquQ2beStYgAN1kmd1f1Lhxbaec4\",\n \"maxSlippageBps\": 1,\n \"size\": \"<string>\",\n \"accountOwner\": \"<string>\",\n \"platform\": \"self\",\n \"preflight\": false,\n \"priorityFeeMicroLamports\": 50000,\n \"signer\": \"<string>\",\n \"withInstructions\": false\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-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.archer.exchange/v1/order/swap")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"market\": \"u8tnfCb1JSSghuNFquQ2beStYgAN1kmd1f1Lhxbaec4\",\n \"maxSlippageBps\": 1,\n \"size\": \"<string>\",\n \"accountOwner\": \"<string>\",\n \"platform\": \"self\",\n \"preflight\": false,\n \"priorityFeeMicroLamports\": 50000,\n \"signer\": \"<string>\",\n \"withInstructions\": false\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.archer.exchange/v1/order/swap")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"market\": \"u8tnfCb1JSSghuNFquQ2beStYgAN1kmd1f1Lhxbaec4\",\n \"maxSlippageBps\": 1,\n \"size\": \"<string>\",\n \"accountOwner\": \"<string>\",\n \"platform\": \"self\",\n \"preflight\": false,\n \"priorityFeeMicroLamports\": 50000,\n \"signer\": \"<string>\",\n \"withInstructions\": false\n}"
response = http.request(request)
puts response.read_body{
"addressLookupTables": [
"<string>"
],
"quoteResponse": {
"inAmount": "150.600000",
"inputMint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
"outAmount": "1.000000000",
"outputMint": "So11111111111111111111111111111111111111112",
"priceImpactPct": "0.0332",
"slippageBps": 50,
"swapMode": "MaxAmountIn",
"totalFee": {
"builderFee": "0.000000",
"protocolFee": "0.060000"
}
},
"swapMode": "MaxAmountIn",
"transaction": "<string>",
"instructions": {
"addressLookupTables": [
"<string>"
],
"computeBudgetInstructions": [
{
"accounts": [
{
"isSigner": true,
"isWritable": true,
"pubkey": "<string>"
}
],
"data": "<string>",
"programId": "<string>"
}
],
"instructions": [
{
"accounts": [
{
"isSigner": true,
"isWritable": true,
"pubkey": "<string>"
}
],
"data": "<string>",
"programId": "<string>"
}
],
"signer": "<string>"
}
}