Conversions
Quote and execute a currency conversion between assets in your workspace.
Convert one asset in your balance to another (e.g. USDT → BTC). It's a two-step flow: quote a rate, then execute that quote before it expires. Use it to consolidate settled funds into one asset, or to fund a payout in a currency you don't hold.
Before you start: the key needs the convert:write scope, and you need enough available
balance in the sell currency (Balances). Amounts are decimal strings.
1. Quote
Specify exactly one of sell amount ("I want to spend this much") or buy amount ("I want to receive this much") — the other side is computed:
const quote = await ap.conversions.quote({
sellCurrency: "USDT",
buyCurrency: "BTC",
sellAmount: "100", // provide sellAmount OR buyAmount (exactly one)
});
console.log(quote.quoteId, quote.rate, quote.buyAmount);quote = ap.conversions.quote(
sell_currency="USDT",
buy_currency="BTC",
sell_amount="100", # provide sell_amount OR buy_amount (exactly one)
)
print(quote["quoteId"], quote["rate"], quote["buyAmount"])quote, err := ap.Conversions.Quote(ctx, absolutepay.QuoteParams{
SellCurrency: "USDT",
BuyCurrency: "BTC",
SellAmount: "100", // provide SellAmount OR BuyAmount (exactly one)
})
if err != nil {
log.Fatal(err)
}
fmt.Println(quote.QuoteID, quote.Rate, quote.BuyAmount)BODY='{"sellCurrency":"USDT","buyCurrency":"BTC","sellAmount":"100"}'
curl https://api.absolutepay.io/v1/conversions/quote \
-H "Authorization: Bearer $APP_TOKEN" -H "Content-Type: application/json" \
$(sign POST /v1/conversions/quote "$BODY") -d "$BODY"The quote locks a rate and both exact legs (sellAmount/sellCurrency,
buyAmount/buyCurrency) under a quoteId with a short validity window. If it expires, request a
new one — nothing has moved yet.
2. Execute
Pass the quoteId back with the quote's exact legs. This is the step that moves funds:
const order = await ap.conversions.execute({
quoteId: quote.quoteId,
sell: { amount: quote.sellAmount, currency: quote.sellCurrency },
buy: { amount: quote.buyAmount, currency: quote.buyCurrency },
});
console.log(order.orderId, order.status); // "SUCCESS" | "FAILED" | "PENDING"
// Or do both in one call:
const order2 = await ap.conversions.convert({ sellCurrency: "USDT", buyCurrency: "BTC", sellAmount: "100" });order = ap.conversions.execute(
quote_id=quote["quoteId"],
sell={"amount": quote["sellAmount"], "currency": quote["sellCurrency"]},
buy={"amount": quote["buyAmount"], "currency": quote["buyCurrency"]},
)
print(order["orderId"], order["status"]) # "SUCCESS" | "FAILED" | "PENDING"
# Or do both in one call:
order2 = ap.conversions.convert(sell_currency="USDT", buy_currency="BTC", sell_amount="100")order, err := ap.Conversions.Execute(ctx, absolutepay.ConvertExecuteParams{
QuoteID: quote.QuoteID,
Sell: absolutepay.Money{Amount: quote.SellAmount, Currency: quote.SellCurrency},
Buy: absolutepay.Money{Amount: quote.BuyAmount, Currency: quote.BuyCurrency},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(order["orderId"], order["status"]) // "SUCCESS" | "FAILED" | "PENDING"
// Or do both in one call:
_, err = ap.Conversions.Convert(ctx, absolutepay.QuoteParams{SellCurrency: "USDT", BuyCurrency: "BTC", SellAmount: "100"})
if err != nil {
log.Fatal(err)
}BODY='{"quoteId":"quote_123","sell":{"amount":"100","currency":"USDT"},"buy":{"amount":"0.0015","currency":"BTC"}}'
curl https://api.absolutepay.io/v1/conversions \
-H "Authorization: Bearer $APP_TOKEN" -H "Content-Type: application/json" \
$(sign POST /v1/conversions "$BODY") -d "$BODY"quote + execute vs convert()
convert() is the two calls back-to-back using the quote's exact amounts — convenient for
machine-to-machine flows. The rate can move between its two internal steps, so if you need to show
a user the rate before committing, use quote then execute yourself.
Confirm
The result is synchronous — status in the execute response is SUCCESS, FAILED, or PENDING
(no webhook is emitted for conversions). The bought asset appears in your workspace balance once the
order completes; verify with a balance read.
Gotchas
- Conversions are irreversible once executed — there's no undo; you'd have to convert back at the then-current rate.
- Exactly one amount per quote:
sellAmountXORbuyAmount. Sending both (or neither) is a400. - Echo the quote exactly.
executemust carry the quote's exactsellandbuylegs; a mismatched or expired quote is rejected — get a fresh quote and retry. - No
Idempotency-Keyon this endpoint. AquoteIdis single-purpose and short-lived, which bounds double-spend — but if an execute call times out, check transactions before retrying rather than blind-resubmitting. - Amounts are decimal strings (e.g.
"100","0.0015") — never floats.
Full request/response fields are on the conversion endpoints in the API reference.
Next
- Balances & reconciliation — see the converted balance land.
- Send payouts — pay out the asset you just converted into.
- Off-ramp — convert crypto to fiat and withdraw to a bank.
- API reference · Authentication