from compass_api_sdk import CompassAPI, models
with CompassAPI(
api_key_auth="<YOUR_API_KEY_HERE>",
) as compass_api:
res = compass_api.credit.credit_swap(token_in="USDC", token_out="USDT", amount_in="0.01", owner="0x06A9aF046187895AcFc7258450B15397CAc67400", chain=models.CreditSwapRequestChain.BASE, slippage="0.5", gas_sponsorship=False, preview=False, pricing=models.CreditSwapRequestPricing.AUTO)
# Handle response
print(res)import { CompassApiSDK } from "@compass-labs/api-sdk";
const compassApiSDK = new CompassApiSDK({
apiKeyAuth: "<YOUR_API_KEY_HERE>",
});
async function run() {
const result = await compassApiSDK.credit.creditSwap({
tokenIn: "USDC",
tokenOut: "USDT",
amountIn: "0.01",
slippage: "0.5",
owner: "0x06A9aF046187895AcFc7258450B15397CAc67400",
chain: "base",
gasSponsorship: false,
pricing: "auto",
});
console.log(result);
}
run();curl --request POST \
--url https://api.compasslabs.ai/v2/credit/swap \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"owner": "0x06A9aF046187895AcFc7258450B15397CAc67400",
"chain": "base",
"token_in": "USDC",
"token_out": "USDT",
"amount_in": "0.01",
"slippage": "0.5",
"gas_sponsorship": false,
"pricing": "auto"
}
'const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
owner: '0x06A9aF046187895AcFc7258450B15397CAc67400',
chain: 'base',
token_in: 'USDC',
token_out: 'USDT',
amount_in: '0.01',
slippage: '0.5',
gas_sponsorship: false,
pricing: 'auto'
})
};
fetch('https://api.compasslabs.ai/v2/credit/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.compasslabs.ai/v2/credit/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([
'owner' => '0x06A9aF046187895AcFc7258450B15397CAc67400',
'chain' => 'base',
'token_in' => 'USDC',
'token_out' => 'USDT',
'amount_in' => '0.01',
'slippage' => '0.5',
'gas_sponsorship' => false,
'pricing' => 'auto'
]),
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.compasslabs.ai/v2/credit/swap"
payload := strings.NewReader("{\n \"owner\": \"0x06A9aF046187895AcFc7258450B15397CAc67400\",\n \"chain\": \"base\",\n \"token_in\": \"USDC\",\n \"token_out\": \"USDT\",\n \"amount_in\": \"0.01\",\n \"slippage\": \"0.5\",\n \"gas_sponsorship\": false,\n \"pricing\": \"auto\"\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.compasslabs.ai/v2/credit/swap")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"owner\": \"0x06A9aF046187895AcFc7258450B15397CAc67400\",\n \"chain\": \"base\",\n \"token_in\": \"USDC\",\n \"token_out\": \"USDT\",\n \"amount_in\": \"0.01\",\n \"slippage\": \"0.5\",\n \"gas_sponsorship\": false,\n \"pricing\": \"auto\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.compasslabs.ai/v2/credit/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 \"owner\": \"0x06A9aF046187895AcFc7258450B15397CAc67400\",\n \"chain\": \"base\",\n \"token_in\": \"USDC\",\n \"token_out\": \"USDT\",\n \"amount_in\": \"0.01\",\n \"slippage\": \"0.5\",\n \"gas_sponsorship\": false,\n \"pricing\": \"auto\"\n}"
response = http.request(request)
puts response.read_body{
"estimated_amount_out": "2485.123456",
"swap_provider": "market",
"transaction": {
"chainId": "0x2105",
"data": "0x8d80ff0a0000000000000000000000000000000000000000000000000000000000000020",
"from": "0x4A83b4413CF41C3244027e1590E35a0F48403F0c",
"gas": "0x7a120",
"maxFeePerGas": "0x59682f00",
"maxPriorityFeePerGas": "0x3b9aca00",
"nonce": "0x5",
"to": "0x6B90E8B4E3E971E74C1A47a3a20976377E2dB4b1",
"value": "0x0"
}
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>"
}
]
}Swap tokens
Swap one token for another inside a Credit Account.
Exchanges tokens the Credit Account already holds in a single atomic transaction, so idle or borrowed balances can be converted without moving funds out first. Returns an unsigned transaction to sign, the expected output amount, and which route priced the swap.
from compass_api_sdk import CompassAPI, models
with CompassAPI(
api_key_auth="<YOUR_API_KEY_HERE>",
) as compass_api:
res = compass_api.credit.credit_swap(token_in="USDC", token_out="USDT", amount_in="0.01", owner="0x06A9aF046187895AcFc7258450B15397CAc67400", chain=models.CreditSwapRequestChain.BASE, slippage="0.5", gas_sponsorship=False, preview=False, pricing=models.CreditSwapRequestPricing.AUTO)
# Handle response
print(res)import { CompassApiSDK } from "@compass-labs/api-sdk";
const compassApiSDK = new CompassApiSDK({
apiKeyAuth: "<YOUR_API_KEY_HERE>",
});
async function run() {
const result = await compassApiSDK.credit.creditSwap({
tokenIn: "USDC",
tokenOut: "USDT",
amountIn: "0.01",
slippage: "0.5",
owner: "0x06A9aF046187895AcFc7258450B15397CAc67400",
chain: "base",
gasSponsorship: false,
pricing: "auto",
});
console.log(result);
}
run();curl --request POST \
--url https://api.compasslabs.ai/v2/credit/swap \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"owner": "0x06A9aF046187895AcFc7258450B15397CAc67400",
"chain": "base",
"token_in": "USDC",
"token_out": "USDT",
"amount_in": "0.01",
"slippage": "0.5",
"gas_sponsorship": false,
"pricing": "auto"
}
'const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
owner: '0x06A9aF046187895AcFc7258450B15397CAc67400',
chain: 'base',
token_in: 'USDC',
token_out: 'USDT',
amount_in: '0.01',
slippage: '0.5',
gas_sponsorship: false,
pricing: 'auto'
})
};
fetch('https://api.compasslabs.ai/v2/credit/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.compasslabs.ai/v2/credit/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([
'owner' => '0x06A9aF046187895AcFc7258450B15397CAc67400',
'chain' => 'base',
'token_in' => 'USDC',
'token_out' => 'USDT',
'amount_in' => '0.01',
'slippage' => '0.5',
'gas_sponsorship' => false,
'pricing' => 'auto'
]),
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.compasslabs.ai/v2/credit/swap"
payload := strings.NewReader("{\n \"owner\": \"0x06A9aF046187895AcFc7258450B15397CAc67400\",\n \"chain\": \"base\",\n \"token_in\": \"USDC\",\n \"token_out\": \"USDT\",\n \"amount_in\": \"0.01\",\n \"slippage\": \"0.5\",\n \"gas_sponsorship\": false,\n \"pricing\": \"auto\"\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.compasslabs.ai/v2/credit/swap")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"owner\": \"0x06A9aF046187895AcFc7258450B15397CAc67400\",\n \"chain\": \"base\",\n \"token_in\": \"USDC\",\n \"token_out\": \"USDT\",\n \"amount_in\": \"0.01\",\n \"slippage\": \"0.5\",\n \"gas_sponsorship\": false,\n \"pricing\": \"auto\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.compasslabs.ai/v2/credit/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 \"owner\": \"0x06A9aF046187895AcFc7258450B15397CAc67400\",\n \"chain\": \"base\",\n \"token_in\": \"USDC\",\n \"token_out\": \"USDT\",\n \"amount_in\": \"0.01\",\n \"slippage\": \"0.5\",\n \"gas_sponsorship\": false,\n \"pricing\": \"auto\"\n}"
response = http.request(request)
puts response.read_body{
"estimated_amount_out": "2485.123456",
"swap_provider": "market",
"transaction": {
"chainId": "0x2105",
"data": "0x8d80ff0a0000000000000000000000000000000000000000000000000000000000000020",
"from": "0x4A83b4413CF41C3244027e1590E35a0F48403F0c",
"gas": "0x7a120",
"maxFeePerGas": "0x59682f00",
"maxPriorityFeePerGas": "0x3b9aca00",
"nonce": "0x5",
"to": "0x6B90E8B4E3E971E74C1A47a3a20976377E2dB4b1",
"value": "0x0"
}
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>"
}
]
}Body
Swap one token held in the Credit Account for another, in a single atomic transaction, at a firm quote where one covers the pair and at market rate otherwise.
Token to sell (input). Provide a token symbol from a limited set (e.g., 'USDC') or any token address.
"USDC"
"0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"
Token to buy (output). Provide a token symbol from a limited set (e.g., 'USDT') or any token address.
"USDT"
"0xdAC17F958D2ee523a2206206994597C13D831ec7"
Human-readable amount of token_in to swap (token units, not wei).
x > 01.5
The owner's wallet address. Their Credit Account must already exist (create it with /v2/credit/create_account) and hold token_in (deposit with /v2/credit/transfer).
"0x06A9aF046187895AcFc7258450B15397CAc67400"
Target blockchain network where the swap will execute.
arbitrum, base, bsc, ethereum, hyperevm, tempo "base"
Action type identifier for swap operations.
"V2_SWAP"Maximum slippage tolerance as a percentage (e.g., 0.5 = 0.5%). Bounds the market route only; a firm quote fills exactly and ignores it.
0 <= x <= 100.5
Optionally request gas sponsorship. If true, EIP-712 typed data will be returned that must be signed by the owner and submitted to the 'Prepare gas-sponsored transaction' endpoint (/gas_sponsorship/prepare). Gas-sponsored builds always execute at market rate.
false
If true, build a display ESTIMATE: no firm RFQ quote is ever requested (quote_expires_at stays null). NOTE that this guarantees only that no firm quote was spent — it does not guarantee an absent payload: under 'auto' when the firm provider does not cover or cannot currently price the pair, and always under pricing=market, the call falls through to the aggregator and returns a signable market build (an unsigned transaction, or EIP-712 typed data when gas_sponsorship=true), without requiring the account to hold token_in yet. How the estimate is priced follows pricing: on a firm-covered pair whose size the firm provider's live price levels can serve, 'auto' and 'firm' price it from those levels (indicative, transaction stays null — re-call with preview=false for the signable build); otherwise it comes from the market build above (pricing='firm' instead refuses with a typed error). Set it on every call made while a user is exploring parameters, and leave it false only for the build they actually intend to sign — firm quotes are single-use maker commitments, and requesting them for displays that are never executed degrades the pricing this API is offered.
Swap routing policy. 'auto': a firm zero-slippage quote when a firm venue covers the pair, transparent fallback to the market aggregator otherwise. 'firm': never price on the market route; an uncovered pair fails with a typed error instead of silently substituting market pricing — previews included: a preview the firm provider's live price levels cannot price returns the same typed error rather than market numbers. 'market': never route through the firm venue; the swap is priced by the aggregator and bounded by slippage (which firm fills ignore). 'firm' is incompatible with gas_sponsorship (sponsored swaps force market routing).
auto, firm, market "auto"
Response
Successful Response
The swap transaction to sign, plus which route priced it and how long that price holds.
Estimated amount of output token received from the swap. Exact on executable firm builds (a firm quote fills at this amount or reverts). On market builds it is a quote-time estimate, and slippage sets how far below it the transaction's enforced minimum output sits. On preview=true responses reporting 'firm' it is INDICATIVE — computed from the firm provider's live price levels without spending a quote.
^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$Unsigned transaction for direct execution. Present when gas_sponsorship=false — except firm-priced previews (preview=true responses reporting swap_provider='firm'), which carry the estimate only: the firm quote is fetched at execution time, so there is no payload to sign yet. A preview whose response reports swap_provider='market' does carry this signable payload.
Show child attributes
Show child attributes
{
"chainId": "0x2105",
"data": "0x1688f0b900000000000000000000000029fcb43b46531bca003ddc8fcb67ffe91900c762000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000675f4a3d",
"from": "0x4A83b4413CF41C3244027e1590E35a0F48403F0c",
"gas": "0x7a120",
"maxFeePerGas": "0x59682f00",
"maxPriorityFeePerGas": "0x3b9aca00",
"nonce": "0x5",
"to": "0x4e1DCf7AD4e460CfD30791CCC4F9c8a4f820ec67",
"value": "0x0"
}
EIP-712 typed data for gas-sponsored execution. Present when gas_sponsorship=true.
Show child attributes
Show child attributes
{
"domain": {
"chainId": 8453,
"verifyingContract": "0x6B90E8B4E3E971E74C1A47a3a20976377E2dB4b1"
},
"message": {
"baseGas": "0",
"data": "0x8d80ff0a0000000000000000000000000000000000000000000000000000000000000020",
"gasPrice": "0",
"gasToken": "0x0000000000000000000000000000000000000000",
"nonce": "7",
"operation": 1,
"refundReceiver": "0x0000000000000000000000000000000000000000",
"safeTxGas": "0",
"to": "0x93C23AAE4793C14D6DF35D2A2A2234204e1559dA",
"value": "0"
},
"primaryType": "SafeTx",
"types": {
"EIP712Domain": [
{ "name": "chainId", "type": "uint256" },
{
"name": "verifyingContract",
"type": "address"
}
],
"SafeTx": [
{ "name": "to", "type": "address" },
{ "name": "value", "type": "uint256" },
{ "name": "data", "type": "bytes" },
{ "name": "operation", "type": "uint8" },
{ "name": "safeTxGas", "type": "uint256" },
{ "name": "baseGas", "type": "uint256" },
{ "name": "gasPrice", "type": "uint256" },
{ "name": "gasToken", "type": "address" },
{
"name": "refundReceiver",
"type": "address"
},
{ "name": "nonce", "type": "uint256" }
]
}
}
Identifies which route priced the swap. 'market': a DEX aggregator, slippage-bounded. 'firm': a zero-slippage quote that fills exactly or reverts. On preview=true responses 'firm' means the estimate is INDICATIVE, computed from live maker price levels without spending any quote; execution fetches the firm quote at signing time. Always present. This is the authoritative firm-vs-market signal and clients do need to read it: pricing is only what was REQUESTED, and under 'auto' a firm build can fall back to market transparently.
market, firm Deadline of the firm swap quote. Sign and broadcast before it or the transaction reverts on-chain; refresh by re-calling this endpoint (discard the previous payload). Null on market builds and on every preview (a preview never holds a firm quote).
Was this page helpful?