Price a conversion, payout, or withdrawal
Prices an asset pair with no resource ids and no recipient. Takes your own margin on a conversion or payout quote, so you can show your customer the price the redeeming order charges; a withdrawal quote refuses it. Returns one or more options and an expiry. A replay always reprices — this route carries no idempotency-key.
curl --request POST \
--url https://api.sandbox.conduit.financial/v2/quotes \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"source": {},
"destination": {},
"amount": "<string>",
"markupBps": 50000,
"markupAmount": "<string>",
"destinationCountry": "<string>"
}
'import requests
url = "https://api.sandbox.conduit.financial/v2/quotes"
payload = {
"source": {},
"destination": {},
"amount": "<string>",
"markupBps": 50000,
"markupAmount": "<string>",
"destinationCountry": "<string>"
}
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({
source: {},
destination: {},
amount: '<string>',
markupBps: 50000,
markupAmount: '<string>',
destinationCountry: '<string>'
})
};
fetch('https://api.sandbox.conduit.financial/v2/quotes', 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.sandbox.conduit.financial/v2/quotes",
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([
'source' => [
],
'destination' => [
],
'amount' => '<string>',
'markupBps' => 50000,
'markupAmount' => '<string>',
'destinationCountry' => '<string>'
]),
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.sandbox.conduit.financial/v2/quotes"
payload := strings.NewReader("{\n \"source\": {},\n \"destination\": {},\n \"amount\": \"<string>\",\n \"markupBps\": 50000,\n \"markupAmount\": \"<string>\",\n \"destinationCountry\": \"<string>\"\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.sandbox.conduit.financial/v2/quotes")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"source\": {},\n \"destination\": {},\n \"amount\": \"<string>\",\n \"markupBps\": 50000,\n \"markupAmount\": \"<string>\",\n \"destinationCountry\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.sandbox.conduit.financial/v2/quotes")
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 \"source\": {},\n \"destination\": {},\n \"amount\": \"<string>\",\n \"markupBps\": 50000,\n \"markupAmount\": \"<string>\",\n \"destinationCountry\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"id": "<string>",
"sourceAssetRef": {
"code": "USD",
"chain": "ethereum"
},
"destinationAssetRef": {
"code": "USD",
"chain": "ethereum"
},
"lockSide": "source",
"amount": {
"code": "USD",
"amount": "<string>",
"chain": "ethereum"
},
"options": [
{
"id": "<string>",
"rail": "rtp",
"rate": {
"referenceRate": "<string>",
"totalSpreadBps": "<string>",
"endUserRate": "<string>"
},
"fees": [
{
"type": "fixed",
"assetAmount": {
"code": "USD",
"amount": "<string>",
"chain": "ethereum"
},
"owner": "conduit",
"charge": "conversion"
}
],
"sourceAmount": {
"code": "USD",
"amount": "<string>",
"chain": "ethereum"
},
"destinationAmount": {
"code": "USD",
"amount": "<string>",
"chain": "ethereum"
},
"recipientAmount": {
"code": "USD",
"amount": "<string>",
"chain": "ethereum"
},
"totalDebit": {
"code": "USD",
"amount": "<string>",
"chain": "ethereum"
}
}
],
"expiresAt": "2026-01-15T09:30:00.000Z",
"createdAt": "2026-01-15T09:30:00.000Z"
}{
"type": "INVALID_OID_FORMAT",
"title": "Invalid Object ID Format",
"status": 400,
"detail": "A path or query parameter expected a valid object identifier but received a value that does not match the expected format.",
"resolution": "Verify that all IDs in the request URL and query parameters are correctly formatted. IDs are typically prefixed strings like 'cus_...', 'app_...', or 'doc_...'.",
"docs": "https://conduit-v2.mintlify.app/errors#invalid-oid-format",
"instance": "/v2/...",
"correlationId": "00469ea4-52c1-4ffa-bd05-9f28b236a5fe",
"timestamp": "2026-01-15T09:30:00.000Z"
}{
"type": "API_KEY_MISSING",
"title": "API Key Missing",
"status": 401,
"detail": "The request did not include an API key. All API requests must be authenticated.",
"resolution": "Include your API key in the 'x-api-key' header with every request.",
"docs": "https://conduit-v2.mintlify.app/errors#api-key-missing",
"instance": "/v2/...",
"correlationId": "00469ea4-52c1-4ffa-bd05-9f28b236a5fe",
"timestamp": "2026-01-15T09:30:00.000Z"
}{
"type": "FEATURE_NOT_ENABLED",
"title": "Feature Not Enabled",
"status": 403,
"detail": "Your account does not have access to this feature. Features are enabled on a per-account basis.",
"resolution": "Contact support to request access to this feature, or check your account settings to verify which features are enabled.",
"docs": "https://conduit-v2.mintlify.app/errors#feature-not-enabled",
"instance": "/v2/...",
"correlationId": "00469ea4-52c1-4ffa-bd05-9f28b236a5fe",
"timestamp": "2026-01-15T09:30:00.000Z"
}{
"type": "UNSUPPORTED_PAIR",
"title": "Unsupported Pair",
"status": 422,
"detail": "The requested source and destination asset pair is not supported. `details` carries `sourceChain` and `destinationChain` alongside `sourceAsset` and `destinationAsset` — `null` for a fiat asset, which carries no chain — so you can tell a chain-specific refusal from an asset-wide one.",
"resolution": "Submit a supported source/destination asset combination and chain, or contact Conduit if this pair should be available.",
"docs": "https://conduit-v2.mintlify.app/errors#unsupported-pair",
"instance": "/v2/...",
"correlationId": "00469ea4-52c1-4ffa-bd05-9f28b236a5fe",
"timestamp": "2026-01-15T09:30:00.000Z"
}{
"type": "RATE_LIMITED",
"title": "Rate Limited",
"status": 429,
"detail": "Too many requests. This error is returned by three independent checks: the per-organization bucket applied to every authenticated API request; the per-IP bucket applied to unauthenticated traffic before an API key is validated; and the per-IP bucket applied when repeated invalid API keys are submitted from the same address. Honor the Retry-After header (also exposed as retryAfterSeconds in the body) before retrying. Current limits and remaining budget are visible in X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset on rate-limited route responses.",
"resolution": "Sleep until Retry-After seconds have elapsed, then retry. For sustained workloads exceeding the per-organization defaults, request a rate-limit increase through your support contact.",
"docs": "https://conduit-v2.mintlify.app/errors#rate-limited",
"instance": "/v2/...",
"correlationId": "00469ea4-52c1-4ffa-bd05-9f28b236a5fe",
"timestamp": "2026-01-15T09:30:00.000Z",
"retryAfterSeconds": 3
}{
"type": "INTERNAL_ERROR",
"title": "Internal Error",
"status": 500,
"detail": "An unexpected error occurred while processing your request.",
"resolution": "Retry the request after a brief delay. If the error persists, contact support and include the correlationId from the error response for investigation.",
"docs": "https://conduit-v2.mintlify.app/errors#internal-error",
"instance": "/v2/...",
"correlationId": "00469ea4-52c1-4ffa-bd05-9f28b236a5fe",
"timestamp": "2026-01-15T09:30:00.000Z"
}Authorizations
Body
Show child attributes
Show child attributes
Show child attributes
Show child attributes
source, destination Your own margin on the order this quote prices, in basis points, to two decimal places. Conduit folds it into every option's rate, so endUserRate is the marked-up rate your customer receives and totalSpreadBps includes it. The order that redeems the option charges the same margin and accrues it to you, and it must not declare a margin of its own. Not available on a withdrawal quote, which nothing redeems; declare the margin on POST /v2/payouts instead. Requires markup to be enabled for your organization.
0.01 <= x <= 99999.99Must be a multiple of 0.01Your own margin on the order this quote prices, as a flat amount per transaction, in the quote's source asset. A value finer than that asset's precision is refused. A flat amount cannot sit inside a rate, so it behaves exactly as Conduit's own fixed fee, and which side it moves depends on lockSide. On a SOURCE-locked quote it is carved out of the principal, so your customer receives less and totalDebit is unchanged. On a DESTINATION-locked quote it is added, so totalDebit rises and your customer pays more. Either way it appears in every option's fees as an entry owned by you. The order that redeems the option charges the same margin and accrues it to you, and it must not declare a margin of its own. Not available on a withdrawal quote, which nothing redeems; declare the margin on POST /v2/payouts instead. Requires markup to be enabled for your organization.
Presence discriminates the quote mode alongside whether source/destination share the same asset: different assets + no country prices a conversion; different assets + a country prices a conversion and a payout, unless both sides are fiat, which is refused; the same asset + a country prices a withdrawal; the same asset with no country is refused.
Response
^qte_[0-9A-Za-z]{22}$Show child attributes
Show child attributes
Show child attributes
Show child attributes
source, destination The amount this quote locked, in the asset of the side named by lockSide.
Show child attributes
Show child attributes
Show child attributes
Show child attributes
ISO 8601 timestamp
"2026-01-15T09:30:00.000Z"
ISO 8601 timestamp
"2026-01-15T09:30:00.000Z"
curl --request POST \
--url https://api.sandbox.conduit.financial/v2/quotes \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"source": {},
"destination": {},
"amount": "<string>",
"markupBps": 50000,
"markupAmount": "<string>",
"destinationCountry": "<string>"
}
'import requests
url = "https://api.sandbox.conduit.financial/v2/quotes"
payload = {
"source": {},
"destination": {},
"amount": "<string>",
"markupBps": 50000,
"markupAmount": "<string>",
"destinationCountry": "<string>"
}
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({
source: {},
destination: {},
amount: '<string>',
markupBps: 50000,
markupAmount: '<string>',
destinationCountry: '<string>'
})
};
fetch('https://api.sandbox.conduit.financial/v2/quotes', 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.sandbox.conduit.financial/v2/quotes",
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([
'source' => [
],
'destination' => [
],
'amount' => '<string>',
'markupBps' => 50000,
'markupAmount' => '<string>',
'destinationCountry' => '<string>'
]),
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.sandbox.conduit.financial/v2/quotes"
payload := strings.NewReader("{\n \"source\": {},\n \"destination\": {},\n \"amount\": \"<string>\",\n \"markupBps\": 50000,\n \"markupAmount\": \"<string>\",\n \"destinationCountry\": \"<string>\"\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.sandbox.conduit.financial/v2/quotes")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"source\": {},\n \"destination\": {},\n \"amount\": \"<string>\",\n \"markupBps\": 50000,\n \"markupAmount\": \"<string>\",\n \"destinationCountry\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.sandbox.conduit.financial/v2/quotes")
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 \"source\": {},\n \"destination\": {},\n \"amount\": \"<string>\",\n \"markupBps\": 50000,\n \"markupAmount\": \"<string>\",\n \"destinationCountry\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"id": "<string>",
"sourceAssetRef": {
"code": "USD",
"chain": "ethereum"
},
"destinationAssetRef": {
"code": "USD",
"chain": "ethereum"
},
"lockSide": "source",
"amount": {
"code": "USD",
"amount": "<string>",
"chain": "ethereum"
},
"options": [
{
"id": "<string>",
"rail": "rtp",
"rate": {
"referenceRate": "<string>",
"totalSpreadBps": "<string>",
"endUserRate": "<string>"
},
"fees": [
{
"type": "fixed",
"assetAmount": {
"code": "USD",
"amount": "<string>",
"chain": "ethereum"
},
"owner": "conduit",
"charge": "conversion"
}
],
"sourceAmount": {
"code": "USD",
"amount": "<string>",
"chain": "ethereum"
},
"destinationAmount": {
"code": "USD",
"amount": "<string>",
"chain": "ethereum"
},
"recipientAmount": {
"code": "USD",
"amount": "<string>",
"chain": "ethereum"
},
"totalDebit": {
"code": "USD",
"amount": "<string>",
"chain": "ethereum"
}
}
],
"expiresAt": "2026-01-15T09:30:00.000Z",
"createdAt": "2026-01-15T09:30:00.000Z"
}{
"type": "INVALID_OID_FORMAT",
"title": "Invalid Object ID Format",
"status": 400,
"detail": "A path or query parameter expected a valid object identifier but received a value that does not match the expected format.",
"resolution": "Verify that all IDs in the request URL and query parameters are correctly formatted. IDs are typically prefixed strings like 'cus_...', 'app_...', or 'doc_...'.",
"docs": "https://conduit-v2.mintlify.app/errors#invalid-oid-format",
"instance": "/v2/...",
"correlationId": "00469ea4-52c1-4ffa-bd05-9f28b236a5fe",
"timestamp": "2026-01-15T09:30:00.000Z"
}{
"type": "API_KEY_MISSING",
"title": "API Key Missing",
"status": 401,
"detail": "The request did not include an API key. All API requests must be authenticated.",
"resolution": "Include your API key in the 'x-api-key' header with every request.",
"docs": "https://conduit-v2.mintlify.app/errors#api-key-missing",
"instance": "/v2/...",
"correlationId": "00469ea4-52c1-4ffa-bd05-9f28b236a5fe",
"timestamp": "2026-01-15T09:30:00.000Z"
}{
"type": "FEATURE_NOT_ENABLED",
"title": "Feature Not Enabled",
"status": 403,
"detail": "Your account does not have access to this feature. Features are enabled on a per-account basis.",
"resolution": "Contact support to request access to this feature, or check your account settings to verify which features are enabled.",
"docs": "https://conduit-v2.mintlify.app/errors#feature-not-enabled",
"instance": "/v2/...",
"correlationId": "00469ea4-52c1-4ffa-bd05-9f28b236a5fe",
"timestamp": "2026-01-15T09:30:00.000Z"
}{
"type": "UNSUPPORTED_PAIR",
"title": "Unsupported Pair",
"status": 422,
"detail": "The requested source and destination asset pair is not supported. `details` carries `sourceChain` and `destinationChain` alongside `sourceAsset` and `destinationAsset` — `null` for a fiat asset, which carries no chain — so you can tell a chain-specific refusal from an asset-wide one.",
"resolution": "Submit a supported source/destination asset combination and chain, or contact Conduit if this pair should be available.",
"docs": "https://conduit-v2.mintlify.app/errors#unsupported-pair",
"instance": "/v2/...",
"correlationId": "00469ea4-52c1-4ffa-bd05-9f28b236a5fe",
"timestamp": "2026-01-15T09:30:00.000Z"
}{
"type": "RATE_LIMITED",
"title": "Rate Limited",
"status": 429,
"detail": "Too many requests. This error is returned by three independent checks: the per-organization bucket applied to every authenticated API request; the per-IP bucket applied to unauthenticated traffic before an API key is validated; and the per-IP bucket applied when repeated invalid API keys are submitted from the same address. Honor the Retry-After header (also exposed as retryAfterSeconds in the body) before retrying. Current limits and remaining budget are visible in X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset on rate-limited route responses.",
"resolution": "Sleep until Retry-After seconds have elapsed, then retry. For sustained workloads exceeding the per-organization defaults, request a rate-limit increase through your support contact.",
"docs": "https://conduit-v2.mintlify.app/errors#rate-limited",
"instance": "/v2/...",
"correlationId": "00469ea4-52c1-4ffa-bd05-9f28b236a5fe",
"timestamp": "2026-01-15T09:30:00.000Z",
"retryAfterSeconds": 3
}{
"type": "INTERNAL_ERROR",
"title": "Internal Error",
"status": 500,
"detail": "An unexpected error occurred while processing your request.",
"resolution": "Retry the request after a brief delay. If the error persists, contact support and include the correlationId from the error response for investigation.",
"docs": "https://conduit-v2.mintlify.app/errors#internal-error",
"instance": "/v2/...",
"correlationId": "00469ea4-52c1-4ffa-bd05-9f28b236a5fe",
"timestamp": "2026-01-15T09:30:00.000Z"
}