Build a swap transaction
Deprecated — use POST /v1/order/swap. This endpoint keeps its original response body so existing integrators keep working; it is not removed. signer is required here.
Deprecated — use POST /v1/order/swap with signer; identical request and response.
Builds an unsigned Solana transaction for a market swap. The client must sign and submit the returned transaction.
Flow:
- Call
GET /v1/quoteto preview the trade. - Call
POST /v1/orders/buildto get the unsigned transaction. - Sign the transaction with the user’s wallet.
- Submit the signed transaction to Solana.
curl --request POST \
--url https://api.archer.exchange/v1/orders/build \
--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/orders/build"
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/orders/build', 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/orders/build",
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/orders/build"
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/orders/build")
.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/orders/build")
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>"
],
"availableSize": "<string>",
"estimatedBaseSize": "<string>",
"estimatedFee": "<string>",
"estimatedPrice": "<string>",
"estimatedQuoteSize": "<string>",
"estimatedTotal": "<string>",
"expiresAt": 123,
"fullyFilled": true,
"makerBooksUsed": 123,
"orderType": "<string>",
"swapMode": "<string>",
"transaction": "<string>",
"worstPrice": "<string>",
"intentId": "<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
Unsigned transaction ready for signing.
Legacy body of the deprecated POST /v1/orders/build and POST /v1/order/market, unchanged from what production has always served. orderType is always "market" and intentId always null — async execution is gone, every order is a sync swap. Same engine and same transaction as POST /v1/order/swap, which returns the cleaner BuildOrderResponse.
Always empty; none configured.
Base size the book could fill.
Base tokens that would trade.
Protocol fee, in quote tokens.
Average execution price.
Quote tokens that would trade, before fees.
Quote tokens paid or received, fees included.
Blockhash expiry (unix seconds).
Always true; a short book is refused, not partially built.
Maker books the transaction attached.
Always "market". Vestigial.
Resolved swap mode: MaxAmountIn or MinAmountOut.
Base64 unsigned VersionedTransaction.
Price of the last level consumed.
Always null. Vestigial.
curl --request POST \
--url https://api.archer.exchange/v1/orders/build \
--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/orders/build"
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/orders/build', 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/orders/build",
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/orders/build"
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/orders/build")
.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/orders/build")
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>"
],
"availableSize": "<string>",
"estimatedBaseSize": "<string>",
"estimatedFee": "<string>",
"estimatedPrice": "<string>",
"estimatedQuoteSize": "<string>",
"estimatedTotal": "<string>",
"expiresAt": 123,
"fullyFilled": true,
"makerBooksUsed": 123,
"orderType": "<string>",
"swapMode": "<string>",
"transaction": "<string>",
"worstPrice": "<string>",
"intentId": "<string>"
}